Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 8 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,17 @@
# HW 6: Ray marching and SDFs

## Goal
In this assignment, you will be implementing SDF operators on various primitives and use a ray marcher to render them. Ray marching is a technique for rendering implicit surfaces where the ray-primitive intersection equation cannot be solved analytically.
I used ray-marching and sine distance fields to create an animated robot. The final project can be found at https://tabathah.github.io/Project6-RayMarching-Implicit-Surfaces. Here are some pictures of the final product:

**Warning**: this assignment diverges significantly from marching cubes, so switching options midway can be costly for your time and effort.
![](./robot1.PNG) ![](./robot2.PNG)

## Base code framework
For every fragment in the scene, I cast a ray from the camera position to the fragment. I then march down this ray, evaluating how far I should I march by the closest value based on sine distance fields of the objects in my scene, until I reach a sine distance field value less than a certain epsilon value.

We have provided a preview scene, and a toggle for the ray marcher rendering. When you correctly implement the ray marcher, the image should match the preview scene containing the simple geometry. Your ray marching calculation should be performed in the fragment shader.
I implemented the following primitive shapes and operators for sine distance fields, using IQ's SDF notes (http://iquilezles.org/www/articles/distfunctions/distfunctions.htm) as a reference.

### Ray Marcher (25 pts)
I wrote SDF methods for Sphere, Box, Cone, Cylinder, and Torus. I also wrote operators, union, intersection, and subtraction, to combine them. I also wrote a function that took in a point and a matrix that included translation and rotation (scale was dealt with manually in the parameters of the SDFs), and applied the inverse of these transformations on the point to put it in world space, rather than local object space.

The ray marcher should generate a ray direction, and march through the scene using the distances computed from sphere tracing.
I also wrote a function to compute the normal of the point using the SDFs, and computed a simple Lambertian shader.

**Note**: Your scene won't be rendered until you have implemented the SDFs for primitives below.
To animate my robot, I passed time in as a uniform, and translated the neck/head, the arms, and the legs based on the time value.

- Generate Rays (15 pts): for each fragment inside the fragment shader, compute a ray direction for the ray marcher
- Sphere Tracing (10 pts): compute the nearest distance from the scene SDFs and update the ray marching's step size.

### SDF (50 pts)
##### Implement primitive SDFs (15pts):
These are simple primitives with well-defined SDFs. We encourage trying other SDFs not listed here, they are interesting!
- Sphere (3pts)
- Box (3pts)
- Cone (3pts)
- Torus (3pts)
- Cylinder (3pts)

##### Useful Operators (15pts)
To create constructive geometry, and interesting shapes (such as holes, bumps, etc.), implement the following operators to combine your primitive SDFs.
- Intersection (2pts)
- Subtraction (3pts)
- Union (2pts)
- Transformation (8pts)
- translation and scaling
##### Compute normals based on gradient (15 pts)

Compute the normals to use for shading your surface.
- Read Chapter 13 of [Morgan McGuire's notes](http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf)
##### Material (5pts)
Implement a simple Lambert material. Additional materials can earn extra points.

### Custom Scene (25 pts)
##### Create a mechanical device or a scene of your choice using all operators
- intersection, subtraction, union, transformation (20pts)
##### Animate the scene (5pts)
Use time as an input to some of your functions to animate your scene!

## Extra credits (Up to 30 pts)
- Implement SDF for [Mandelbulb](https://www.shadertoy.com/view/XsXXWS) (10pts)
- You need to implement naive raymarching (not sphere tracing) to get this to work
- Lighting effects
- Soft shadowing using secondary rays (5pts)
- Ambient occlusion (10pts)
- Additional materials besides Lambert. (5pts each)
- Additional SDFs besides the listed primitive. (5pts each)

## Resources
http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf

## Submission
- Update `README.md` to contain a solid description of your project
- Publish your project to gh-pages. `npm run deploy`. It should now be visible at http://username.github.io/repo-name
- Create a [pull request](https://help.github.com/articles/creating-a-pull-request/) to this repository, and in the comment, include a link to your published project.
- Submit the link to your pull request on Canvas.

## Deploy
- `npm run build`
- Add and commit all changes
- `npm run deploy`
- If you're having problems with assets not linking correctly, make sure you wrap you're filepaths in `require()`. This will make the bundler package and your static assets as well. So, instead of `loadTexture('./images/thing.bmp')`, do `loadTexture(require('./images/thing.bmp'))`.
The program runs very slow right now. I created bounding volumes to optimize the SDF computing, but this didn't seem to do much. I suspect the problem is in my ray casting, as I was having trouble doing camera computations in the CPU, so I do them in the GPU. I hope to fix this in the near future.
Binary file added robot1.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added robot2.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/glsl/pass-vert.glsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
varying vec2 f_uv;
varying mat4 viewMat;
varying mat4 projMat;

void main() {
f_uv = uv;
viewMat = modelViewMatrix;
projMat = projectionMatrix;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Loading