The goal of this project was to create an attractive rendering in Anaglyph 3D. For the subject matter I chose a cheesy movie monster as a homage to 50's style 3D films. In addition to the Anaglyph 3D, my goals are to create an original monster model, implement bump mapping for a more realistic textured skin, and do subsurface scattering to make the skin look more realistic. I wanted to create something artistically similar to a creature like Godzilla, or the creature for the black lagoon.
While this is not a feature of the renderer, it was still a signifigant and involving step. The commercial game Spore where you create creatures using an in game 3D creature editor includes a special feature to export to the Collada (.dae) model format. After creating a cheesy movie monster model in the game I successfully created a .dea to .obj converter in Java after closely reviewing the file formats, using an XML parser. Unfortunately, while I was able to output a .obj file correctly, there were junk polygons accross the model, rendering the model useless. With a sad heart I had to shelve my home grown solution and tried to import the model with Blender instead. While unsuccessful, I received some reassurance about my converter's correctness by seeing the same junk polygon data rendered from Blender's Collada importer. The successful solution came about after searching other people's troubles and I found the roundabout method of using the AutoDesk FBX Converter, and then using that to convert the Collada file to a FBX file, and then the FBX file to the final output of obj (for some reason converting from dae to obj directly lead to the same junk polygon problem). Finally, after all that work, I had a working model, which then needed more work. Because I wanted the eyes, teeth, and claws to be different materials from the body I had to manually select them in Blender using its dangerous interface and then export them as multiple obj files containing each model component seperately. After several messups learning this foeign program requiring me to infuriuratingly restart my attempts multiple times while I learned, I finally, finally had a working model that I could just use in my renderer. After all this hard work I could finally get to the real work. Additional changes were also made to simplify the geometry by deleting internal vertices and body parts that were not seen to speed up rendering with the more advanced techniques, particularly in the face area.
As the 3D Anaglyph feature was the main gimmick of my project and most eye catching, I workied on that first. To get it to work I modified the core camera mechanics. The camera now took a new special float called angle, which would be angle between the two eyes from the lookat point, which was now recorded instead of discarded to generate the view direction. It did this by rotating across the view direction across y-axis by the angle and then multiplying that unit direction vector by the distance from the eye to the focal point, and then adding it to the focal point. This allowed the camera eyeRay method to then be able to return 2 different eye rays based on a left right eye enumeration. To finish the effect, in the raytracing function, after rendering the first pixel normally, it would then render the second pixel using the new right eye, checking first if the angle was not 0 and thus warranting the 3D effect. The first left pixel was stripped of the green and blue components and the second right pixel was stripped of the red component. The 2 pixels were then be combined using a screen blend which took the complement (1-color) of both pixels multiplied them together, and then took the complement again. Figuring out the screen function took some extra work and experimentation in Photoshop as the documentation describing a screen blend I found from Adobe neglected to say what the inverse was exactly, and that there was the need to do a third complement after the multiplication. The result was a 3D anaglyph rendering. Because the color components that were stipped are complements of each other when combined the image could be in full color, however, vibrant colors detract from the 3D effect, so moderately desaturated colors were chosen to best illustrate the effect.
After getting the initial effect, I wanted to make the creature look more realistic. To do this I first wanted to make the skin look less uniform and boring. To do this I made a special shader that instead of returning a color, returned a normal. I modified a special compound material that combined multiple material shades by addition or multiplication by adding a special bump shader whos intention was to return the normal rather than the color. The hit data that I then sent subsequently to the other compound materials was altered with the injected normal data, allowing me to use any previous shader with the new bump mapped normals. To generate the new normals themself, I generated a random tangent using perlin noise, and took the halfway vector of that and the normal, and used those values to create the new normal.
I was able to implement Single Scattering on a surface by refracting the ray and taking samples along that vector towards the light source. These samples were again refracted and the final scattering value was computed based on the equations in Henrik's paper. Unfortunately I was unable to implement multi scattering. The single scattering when applied to the model with the diffuse shading gave the model a richer less uniform look by dampening the bump map in more direct light and made the texture look a bit more realistic. The sphere on the left is rendered with a normal diffuse lambert while the sphere on the right is rendered with the single scattering subsurface lighting to illustrate the difference.
Above: With subsurface lighting the texture on the stomach and face are less uniform and harsh.
Below: The final rendering with all the techniques described and soft shading.