If you look back at some of my previous images, you'll see a graininess when a dielectric is in the scene. It turns out that I was discarding intersections incorrectly and those grainy spots are where the default color (black) is showing through. Now that is fixed, my images are much higher quality. I've put together the following animation as a potential final project.
I like this animation because it shows nested spheres with different dielectrics, uses Perlin noise as a texture for the plane and for bump mapping, and uses Perlin noise to vary the specular power across the outer sphere.
Things I don't like are the aliasing in the distance and the sky. Some warmth needs to be added, but I like the mysteriousness of the dark image. Somehow I'll have to balance those two things. I'd like some sort of "sky" that adds the warmth.
Thursday, April 30, 2009
Monday, April 27, 2009
7 spheres, no hatch marks
I've finally removed the hatch marks from my spheres. The specular highlight is a bit strong in this image, but I'm just thrilled to have figured out the problem. It seems that every intersection was adding energy to the scene and some of the rays in the refraction would intersect the same point again. This would happen until maximum depth was reached or until they finally escaped the surface.
Click for a larger image:
Click for a larger image:
Thursday, April 23, 2009
Sphere Movie
I made my first movie! I build a script to render the images, converted them to png and then used ffmpeg to smoosh them together into a .mov:
http://cs.unm.edu/~jbowles/cs413/ani.mov
Here's the command line I used to build the movie:
http://cs.unm.edu/~jbowles/cs413/ani.mov
Here's the command line I used to build the movie:
ffmpeg -f image2 -i %04d-ani.png -r 25 -b 10000k -s 640x360 ani.mov
Sunday, April 19, 2009
Bumpy Spheres
Ken Perlin is a genius. Here are two images using Perlin noise to perturb the normals on the sphere to give it a bumpy feeling. Click on the images for larger versions:
The best part is that no special geometry was used. These are just two simple spheres! This is so fun! I'm inspired to sing "Come on Feel the Noise" by Quiet Riot.
The best part is that no special geometry was used. These are just two simple spheres! This is so fun! I'm inspired to sing "Come on Feel the Noise" by Quiet Riot.
Turbulence
Starting work on creating turbulent textures using Perlin noise. Click on the image for larger vesion:
I used the improved noise reference implementation and translated from Java to C++. Then I added the turbulence function on top of the noise function.
This is kinda fun. It's a black sphere with black and white turbulence on a black background, so all you see are the white and grey parts.
I used the improved noise reference implementation and translated from Java to C++. Then I added the turbulence function on top of the noise function.
This is kinda fun. It's a black sphere with black and white turbulence on a black background, so all you see are the white and grey parts.
Friday, April 17, 2009
Assignment #7 - Dielectrics
Source code is available here
To download and build:
Here is the requested seven spheres image. It took 1838 seconds to render. This is a 1024x1024 image with 1000 samples per pixel. Click on the image to view the full size version. The following command line was used to generate the image:
Without dielectrics, it took 2235 seconds. What? That doesn't make any sense.
Here's an interesting up close image of the center sphere. It has an index of refraction of 2.0. The reflections are particularly nice, but those bands are not. Click on the image to view the 1024x1024 version.
The obj model I used was an ashtray. My obj model reader chokes on anything that isn't a triangle, so the model ends up with some weird holes.
The index of refraction is 1.2, image is 512x512 with 1000 samples per pixel. This took 1512 seconds to render.
I'm not too happy with my choice of a background. Some Perlin noise would have been nice, but I haven't implemented it yet.
Here's the same ashtray, but without dielectrics. It took 2655 seconds to render. What's up with things taking longer to render with less rays? That doesn't sound right to me. I'm beginning to question my timings.
This image really shows the lack of quality of my .obj model viewer.
Implementing the reflection / refraction pairs was fairly straightforward, after much reflection (ha!) on the math. Initially, I was not careful in my implementation of Snell's law and the Fresnel term and had some pretty strange images.
The refracted ray is determined by Snell's law. If total internal reflection is found, the no refracted ray is computed and its "power" is set to zero and all energy is devoted to the reflected ray.
If there is a refracted ray, the power of both the reflected and refracted rays are computed and multiplied by the color of the resulting rays.
Another field was added to the Ray class: index of refraction. This allows the code to easily keep track of the current index of reflection with regard to whether or not the incoming ray originated inside of an object or not.
I believe I understand the banding issue: rays are sent out and bounce round the sphere a few times, each contributing a little bit more to the scene. Some areas have more bounce than others and reveal the sampling pattern used to sample the image.
I'm not sure about the best way to fix this problem. Each ray shouldn't increase its contributing each time it reflects or refracts.
To download and build:
wget http://cs.unm.edu/~jbowles/cs413/a6/jbowles-assign6.tar.bz2
tar zxf jbowles-assign6.tar.bz2
cd jbowles-assign6
make
Here is the requested seven spheres image. It took 1838 seconds to render. This is a 1024x1024 image with 1000 samples per pixel. Click on the image to view the full size version. The following command line was used to generate the image:
./raytracer --width=1024 --height=1024 \
--maxdepth=20 --eye=0,0,1000 \
--up=0,1,0 --lookat=0,0,0.0 \
--reflections --shadows --samples=1000
Without dielectrics, it took 2235 seconds. What? That doesn't make any sense.
Here's an interesting up close image of the center sphere. It has an index of refraction of 2.0. The reflections are particularly nice, but those bands are not. Click on the image to view the 1024x1024 version.
The obj model I used was an ashtray. My obj model reader chokes on anything that isn't a triangle, so the model ends up with some weird holes.
The index of refraction is 1.2, image is 512x512 with 1000 samples per pixel. This took 1512 seconds to render.
./raytracer --width=512 --height=512 --maxdepth=20 \
--eye=0,60,-60 --up=0,0,1 --lookat=0,0,0.0 \
--reflections --shadows --samples=1000 \
--outfile=ashtray_glass.ppm
I'm not too happy with my choice of a background. Some Perlin noise would have been nice, but I haven't implemented it yet.
Here's the same ashtray, but without dielectrics. It took 2655 seconds to render. What's up with things taking longer to render with less rays? That doesn't sound right to me. I'm beginning to question my timings.
This image really shows the lack of quality of my .obj model viewer.
Implementing the reflection / refraction pairs was fairly straightforward, after much reflection (ha!) on the math. Initially, I was not careful in my implementation of Snell's law and the Fresnel term and had some pretty strange images.
The refracted ray is determined by Snell's law. If total internal reflection is found, the no refracted ray is computed and its "power" is set to zero and all energy is devoted to the reflected ray.
If there is a refracted ray, the power of both the reflected and refracted rays are computed and multiplied by the color of the resulting rays.
Another field was added to the Ray class: index of refraction. This allows the code to easily keep track of the current index of reflection with regard to whether or not the incoming ray originated inside of an object or not.
I believe I understand the banding issue: rays are sent out and bounce round the sphere a few times, each contributing a little bit more to the scene. Some areas have more bounce than others and reveal the sampling pattern used to sample the image.
I'm not sure about the best way to fix this problem. Each ray shouldn't increase its contributing each time it reflects or refracts.
Hatch marks explained?
I believe that I understand the source of the hatch marks. It may not be a problem so much with regular sampling but with each ray that is traced adding energy to the scene.
For example:
1) A ray is sent out and intersects a glass sphere
2) That ray has two components: reflection and refraction
3) The refracted ray travels through the sphere, and refracts/reflects again
4) The reflected ray bounces around the sphere, adding energy. This reflected ray eventually reaches the maximum allowed tracing depth, and the color is set to black, which is resulting in what appears to be a grainy noise.
Some areas have more energy added than others. When I ignore reflected rays within the sphere, a very different image without the grid appears:
This problem isn't solved, but it show a serious problem with my implementation. A light source doesn't put out infinite energy and each bounce doesn't add energy to the scene.
For example:
1) A ray is sent out and intersects a glass sphere
2) That ray has two components: reflection and refraction
3) The refracted ray travels through the sphere, and refracts/reflects again
4) The reflected ray bounces around the sphere, adding energy. This reflected ray eventually reaches the maximum allowed tracing depth, and the color is set to black, which is resulting in what appears to be a grainy noise.
Some areas have more energy added than others. When I ignore reflected rays within the sphere, a very different image without the grid appears:
This problem isn't solved, but it show a serious problem with my implementation. A light source doesn't put out infinite energy and each bounce doesn't add energy to the scene.
Thursday, April 16, 2009
7 sphere with orthographic projection
Here are the seven spheres with an orthographic projection.
Those hatch marks look pretty regular in the center of the picture. It's almost like my sampling pattern is emerging. Hmmm.
Here's a midget in a bikini:
Is my sampling grid becoming visible in the sphere? Is this the source of the "hatch marks?"
Those hatch marks look pretty regular in the center of the picture. It's almost like my sampling pattern is emerging. Hmmm.
Here's a midget in a bikini:
Is my sampling grid becoming visible in the sphere? Is this the source of the "hatch marks?"
Extracting frames from a Panasonic MTS file
MTS files are just an mpeg4 file. The command line utility ffmpeg will let you extract the frames:
Building:
Example usage with an HD camera
This will rip all the frames into waa-%03d.png.
Building:
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
./configure
make && make install
Example usage with an HD camera
ffmpeg -i 00000.MTS -s hd1080 -f image2 waa-%03d.png
This will rip all the frames into waa-%03d.png.
7 spheres
Here's my image of 7 spheres. I'm completely underwhelmed.
Indices of refraction: center: 2.0, the others range from 2.1 to 2.6. The outside index of refraction is 1.0. This scene has almost as much as a vacuum as my brain. I'm just not getting this.
This image is horrible and I'm about ready to scrap my entire raytracer. You can see just how horrible it is by clicking on it to view the 1024x1024 version. There's 1000 samples/pixel and it took 1072 seconds to render.
Indices of refraction: center: 2.0, the others range from 2.1 to 2.6. The outside index of refraction is 1.0. This scene has almost as much as a vacuum as my brain. I'm just not getting this.
This image is horrible and I'm about ready to scrap my entire raytracer. You can see just how horrible it is by clicking on it to view the 1024x1024 version. There's 1000 samples/pixel and it took 1072 seconds to render.
Hatch marks
What's up with those hatch marks? Is my sphere just too dark? Should I pick light grey instead of almost black? I dunno.
I've picked three variables to change and see when the hatch marks show up:
Only when refraction is enabled do we see the hatch marks. This narrows it down to the following:
Things that did not remove the hatch marks:
Removing tone mapping
Removing specular highlights
Removing the specular highlight does not remove the hatch marks. I'm not going to bother posting a pic. It looks like the sphere with everything enabled, just no specular highlight.
I've picked three variables to change and see when the hatch marks show up:
- Are the refracted rays rendered?
- Is the diffuse component rendered?
- Are the reflected rays rendered?
Image | Refract | Diffuse | Reflection | Hatching |
no | no | no | no | |
yes | no | no | yes | |
no | yes | no | no | |
yes | yes | no | yes | |
no | no | yes | no | |
yes | no | yes | yes | |
no | yes | yes | no | |
yes | yes | yes | yes |
Only when refraction is enabled do we see the hatch marks. This narrows it down to the following:
- Specular highlights
- Direction of refracted ray
- Fresnel term
- Tone mapping
- And probably about 10 other things
Things that did not remove the hatch marks:
Removing tone mapping
Removing specular highlights
Removing the specular highlight does not remove the hatch marks. I'm not going to bother posting a pic. It looks like the sphere with everything enabled, just no specular highlight.
Tuesday, April 14, 2009
Changing from floats to doubles
In an attempt to remove some of the banding I'm seeing, I've changed from floats to doubles:
Index of refraction 1.33, double precision floating point:
Index of refraction 1.33, single precision floating point:
Difference image of the two:
The banding is gone, but now I'm seeing some ellipse shaped dark spots that I didn't expect to see.
The next three images use an index of refraction of 2.69.
Double precision:
Single precision:
Difference:
Index of refraction 1.33, double precision floating point:
Index of refraction 1.33, single precision floating point:
Difference image of the two:
The banding is gone, but now I'm seeing some ellipse shaped dark spots that I didn't expect to see.
The next three images use an index of refraction of 2.69.
Double precision:
Single precision:
Difference:
Friday, April 10, 2009
Fixed Phong shading
Here are the results with the fixed Phong shading:
Index of refraction 1.33, camera farther:
Index of refraction 1.33, camera closer:
Index of refraction 2.69, camera farther:
Index of refraction 2.69, camera closer:
I don't like the amount of noise in these images. There are 512 samples per pixel. A relatively lame sample selection process is being used: lay them all out on a regular grid and use a random number generator to jitter the samples within their grid boundaries. This doesn't seem to be any better than simply choosing 512 pixels laid out on a regular grid.
Index of refraction 1.33, camera farther:
Index of refraction 1.33, camera closer:
Index of refraction 2.69, camera farther:
Index of refraction 2.69, camera closer:
I don't like the amount of noise in these images. There are 512 samples per pixel. A relatively lame sample selection process is being used: lay them all out on a regular grid and use a random number generator to jitter the samples within their grid boundaries. This doesn't seem to be any better than simply choosing 512 pixels laid out on a regular grid.
Thursday, April 9, 2009
Carefully checking math
Turns out that I was a bit sloppy with my Snell's law implementation. Here are some new images that look a bit more correct:
Index of refraction: 1.33, camera farther
Index of refraction: 1.33, camera closer
Index of refraction: 2.69, camera farther
Index of refraction: 2.69, camera closer
That blue square is a messed up specular reflection. Looks like I might be a bit sloppy with my Blinn-Phong model, too.
Index of refraction: 1.33, camera farther
Index of refraction: 1.33, camera closer
Index of refraction: 2.69, camera farther
Index of refraction: 2.69, camera closer
That blue square is a messed up specular reflection. Looks like I might be a bit sloppy with my Blinn-Phong model, too.
Clamping reflection power
Here are images using the same code as before, but with the reflection power clamped to 1.0:
Index of refraction 1.0 to 1.0:
Index of refraction 1.0 to 1.33:
Index of refraction transition from 1.33 to 1.00
What's up with that light blue square? Is that a crappily rendered specular highlight?
Ok, back to reflections. These images look much better to me, but I'm not sure if they are correct. I expect a large reflection in the 1.33 image as it is sitting over an infinite plane.
Index of refraction 1.0 to 1.0:
Index of refraction 1.0 to 1.33:
Index of refraction transition from 1.33 to 1.00
What's up with that light blue square? Is that a crappily rendered specular highlight?
Ok, back to reflections. These images look much better to me, but I'm not sure if they are correct. I expect a large reflection in the 1.33 image as it is sitting over an infinite plane.
Adding a Fresnel term
I've attempted to add a Fresnel term to the dielectric.
To start, I rendered a sphere with an index of refraction of 1.00, no Fresnel term, no reflections:
Here's another sphere, no reflections, index of refraction 1.33:
Now with a Fresnel term, index of refraction 1.00:
Also with a Fresnel term, index of refraction 1.33:
Those last two images don't look quite right. The reflections are way too strong and are pretty blown out.
I believe that I'm using the equations at http://en.wikipedia.org/wiki/Fresnel_equations to add the Fresnel term.
To start, I rendered a sphere with an index of refraction of 1.00, no Fresnel term, no reflections:
Here's another sphere, no reflections, index of refraction 1.33:
Now with a Fresnel term, index of refraction 1.00:
Also with a Fresnel term, index of refraction 1.33:
Those last two images don't look quite right. The reflections are way too strong and are pretty blown out.
I believe that I'm using the equations at http://en.wikipedia.org/wiki/Fresnel_equations to add the Fresnel term.
Tuesday, April 7, 2009
Dielectrics
Here's a couple of images of a pieces of "green glass." In this first image, both mediums have an index of refraction of 1.0:
In this next image, the index of refraction starts as 1.00, but then changes to 1.39:
Reflections are currently not implemented. Notice where total internal reflection begins? Notice how the rays are bent away from the viewpoint? This is what I would expect when the index of refraction becomes greater.
Here's an example where the transition is from 1.39 to 1.00:
Notice how the rays are bent towards the viewpoint?
I suspect that these images may be correct, well, as correct as they can be without implementing reflections and using a Fresnel term to make sure that energy is conserved.
I'm using Snell's law to calculate the direction of the refracted rays
In this next image, the index of refraction starts as 1.00, but then changes to 1.39:
Reflections are currently not implemented. Notice where total internal reflection begins? Notice how the rays are bent away from the viewpoint? This is what I would expect when the index of refraction becomes greater.
Here's an example where the transition is from 1.39 to 1.00:
Notice how the rays are bent towards the viewpoint?
I suspect that these images may be correct, well, as correct as they can be without implementing reflections and using a Fresnel term to make sure that energy is conserved.
I'm using Snell's law to calculate the direction of the refracted rays
Subscribe to:
Posts (Atom)