Shadow Mapping (C++/OpenGL)
A small C++/OpenGL I wrote in my spare evenings that creates shadows for objects within a 3D scene using Shadow Mapping. Within the scene there is a light with is used to perform lighting calculations for diffuse, specular etc. results for each object, which is also used to generate a shadow map by using the lights position, the results of the shadow map are combined with the diffuse and specular results.
Two passes are made for each frame, the first is the shadow pass which creates a depth buffer based on the lights' position in the scene. The second pass uses the depth buffer from the first pass, object textures and materials to produce the final image of the objects with lighting and shadows. At the end of the second pass after the final fragment colour to computed, gamma correction is applied before outputting the result.
Feature list:
Get the source from GitHub: https://github.com/LewisWard/Shadow-Mapping
Two passes are made for each frame, the first is the shadow pass which creates a depth buffer based on the lights' position in the scene. The second pass uses the depth buffer from the first pass, object textures and materials to produce the final image of the objects with lighting and shadows. At the end of the second pass after the final fragment colour to computed, gamma correction is applied before outputting the result.
Feature list:
- Shadow Mapping
- Basic Lighting
- Gamma Correctness
Get the source from GitHub: https://github.com/LewisWard/Shadow-Mapping
Development Process and Code Samples
To begin with, I worked on implementing shadows, after setting up a window and some other basic requirements. After I got shadows working I then added lighting, that produces the diffuse and specular values used on objects. After I implemented lighting I then added Gamma Correction.
The implementation of shadows was straight forward, I created a framebuffer that had a depth component using a texture compare mode. By using the texture compare mode it meant that OpenGL would compare the values between textures in the texture hardware than me explicitly doing this operation in the shader.
The implementation of shadows was straight forward, I created a framebuffer that had a depth component using a texture compare mode. By using the texture compare mode it meant that OpenGL would compare the values between textures in the texture hardware than me explicitly doing this operation in the shader.
Once the texture was generated and attached to the framebuffer, the next step was to rendered the scene from the light's perspective in make the depth buffer that would be used in the second pass for shadows. For this, I used a light view and projection matrix, these are different from the view and projection matrix used by the camera. As I used a 'sampler2DShadow' for the depth buffer, I enabled 'GL_POLYGON_OFFSET_FILL' and set the offset on the X and Y to 4.
After the shadow pass is complete, I then draw the scene as if I would normally but also pass it the depth buffer created in the shadow pass. In order to use the shadow buffer a bias matrix is required that scales the buffer from [-1, 1] coordinates to [0, 1] coordinates so it can be used like a texture. |
To access the depth buffer for the shadows within the fragment shader 'textureProj' is used with the sampler and texture coordinates, these texture coordinates are created in the vertex shader by multiplying the bias matrix with the vertex position. The half vector, used for lighting calculations, is also calculated within the vertex shader and passed for the fragment shader. All other lighting calculations are performed in the fragment shader, once the final colour is computed (lighting, shadows and texture) gamma correction is applied then the final colour with gamma correction is outputted from the fragment shader.
Some licenses for open source textures used.
Stone: http://opengameart.org/content/stone-pavement-ground-tile
Wood: http://opengameart.org/content/wood-texture-tiles
Stone: http://opengameart.org/content/stone-pavement-ground-tile
Wood: http://opengameart.org/content/wood-texture-tiles