Welcome to Thamine & Steven's CS283 Project 3
Introduction:
Welcome to our CS283 project3: "Real-Time Rendering".
How we implemented shadow mapping and environment mapping:
We implemented shadow mapping using a two-pass algorithm which rendered the scene first from the light's point of view (POV) and then from the camera's POV. We start off with init(), where we initialize our shadow map and our environment map respectively. When we initialize shadow mapping, we simply initialize the frame buffer and the textures used for our shadow map. In the first pass, we generate a 2D Sampler which stores the depth values of the scene from the lights position. In the second iteration, we generate shadow coordinates in the vertex shader in order to sample the depth map. In order to do this, we kept track of the modelview, projection and bias matrices from each light's POV. We pass the shadow coordinates into the fragment shader which samples the depths from the shadow map to determine whether the fragment should be shaded. We also used anti-aliasing to smoothen out shadows by sampling from 16 coordinates in our shadow map and averaging the results.
Shadow mapping was by far the hardest part of the project because all of the transformations and sampling techniques had to be correct in order to see any change in our scene. We spent alot of time debugging this part and experimented with glsl version higher than 130. In the end, we chose version #120 for the vertex shader, and we used version #130 for the fragment shader, as it provided things like textureProj and textureSize features that we could use. We set up uniform variables in the vertex and fragment shaders so that we could use glGetUniformLocation and work with the shadow map and environment map variables.
We also implemented environment mapping using cube maps. When we initialize environment mapping, we select our texture and bind it to our environment map texture variable. Then we load our pictures onto specific faces of our environment map texture. The texture for each face of the cube is generated and applied independently. We followed the Red Book very closely in its implementation of environment maps and it helped alot with debugging the transformation matrices and reflected directions in the vertex shader.
The .exe file is also included in our source code.
Things we implemented:
-Shadow Mapping
-Environment Mapping (Specifically cube mapping)
-Environment Mapping with Reflections as the Add-on
Scene 1:
Scene 2:
Scenes:
Our first scene features five spheres, a mirror, a textured floor and a large encompassing sphere which surrounds the whole scene. A point light source was placed in front of the spheres and the shadows are projected onto the textures and the spheres. The camera is inside a very large sphere that uses environment mapping to make it seem like there is a sky above the camera. As our camera moves around the scene, we see that the mirror reflects the environment map (i.e. the sky map). We animate the spheres by pressing 'p', toggle the environment map by pressing 'q', and toggle the shadow maps by pressing 'e'. We've also implemeted a fully functioning camera that can rotate about its own axis, zoom, and move across the scene.
Our second scene contains the same elements as our first, but we added in a reflective teapot, as well as a red diffuse sphere with convolutions of Lambertian and Phong components of the environment map, which acts as our add-on.
Troubles we encountered:
Initially, it was really difficult to set up the shaders because there weren't many resources online and GLSL had many versions to it (version #120, #140, etc.) and we didn't really know what to go off of. We ended up sticking with version #120 for the vertexshader and version #130 for the fragmentshader.
After we generated a shadow map, we had a bizarre error that mapped the shadow not only onto the ground, but also on all the pillars in our initial scene. We ended up manipulating parts of the code and implemented glCull into our code.
For environment mapping, we had some trouble with displaying our texture. We started off by editting out own photos and seeing if it appeared on our object. We had some trouble using the string class and though our printf's told us the files were being called, we couldn't figure out what it was. We decided to go with the loadTexture function and pass in our .bmp files into our environment map texture.
Overall:
We felt like this was one of the harder projects, not conceptually, but implementing because of the vast GLSL libraries and various aspects to the implementation. We were also handling a lot of functions we have never really seen before or touched on, so it took us a while to really understand the documentation we found online.