Requirements: Direct3D 11, Visual Studio 2012
Source code: Omnidirectional Shadow Maps
These days shadow mapping algorithm for constructing shadows on curved surfaces seems to dominate in game and film industries. The idea behind it is the following. It is assumed that you are located at the light source and render the scene from its position to a texture [1],[2]. All the points that could be seen from this position are lit and all the others are in shadow. To determine visible surfaces from the light source, you could render the scene to Z-buffer, which is called shadow (depth) map, discarding writing to color buffer. After, another render pass is executed from the viewer position. The position of each rasterized fragment is transformed to light clip space. Its z-coordinate defines its distance to the light. If it is greater than a corresponding one in the shadow map, then the fragment is shadowed otherwise it is not.
The described above technique will work alright for the case we have a spot light. Should we have a point (omni) light source which emits light in all directions, the approach above should be modified. This time we create 6 shadow maps with a separate view matrix having field of view 90 degrees along +x, -x, +y, -y, +z, -z coordinate axes so that to cover all the space around the light source. Cube texture could be the right choice for storing such kind of data.
In the vertex shader we calculate world space vertex position and world space direction from the light source to the vertex and pass them as attributes to the geometry shader. Using instancing mechanism of geometry shader we are able to render all the shadow maps in one pass [3]. The semantic SV_GSInstanceID provides the index of the shadow map we process and allows us to choose the proper light view projection matrix to calculate clip space position of the vertex and redirect the primitive to the proper face of cube texture via another semantic SV_RenderTargetArrayIndex. In the pixel shader we receive interpolated world space light direction, the length of which is written to the shadow map.
During the shading pass, we again use vertex shader to calculate world space light direction and pass it to the pixel shader. In the pixel shader, the interpolated light vector is used to sample the cube shadow map for the stored distance and its length as a comparison value.
Interaction:
Press "space" button to launch/stop torus animation.
References:
1. Tomas Akenine-Möller, Eric Haines, Nathaniel Hoffman. 2008. "Real-Time Rendering"
2. Elmar Eisemann, Michael Schwarz, Ulf Assarsson, Michael Wimmer. 2012. "Real-Time Shadows"
3. Jason Zink, Matt Pettineo, Jack Hoxley. 2011. "Practical Rendering and Computation with Direct3D 11"
4. Gerasimov Philipp, "Omnidirectional Shadow Mapping" in GPU Gems, Addison-Wesley, pp.193-2003, 2004.
September 9, 2012
Shadow Volumes
Requirements: Direct3D 11, Visual Studio 2010
Source Code: Shadow Volumes
This is another algorithm [1], [2] which allows to cast shadows on arbitrary surfaces and handle self-shadowing of the occluding objects as well. Suppose you have a light source located at some point in space and a triangle. Now, project a ray through that point and each vertex of the triangle at the infinity. You will have an infinity pyramid. All the points within the volume of the pyramid below the triangle will be shadowed. That is why, it is often called "shadow volume".
Let us assume the camera is located outside the shadow volume and looks along the ray at some view sample. Each time the ray goes through the front-face of the shadow volume, we increment a counter. The moment it goes through the back-face of the shadow volume, that is exits it, we decrement the counter. We can claim, in the end, that view sample is illuminated if the counter is zero; otherwise, it is shadowed. To imitate ray intersection with shadow volumes, stencil buffer could be used.
The steps of the algorithm are the following:
1. Clear stencil buffer with zero values.
2. Render the whole scene writing only ambient lighting components to the color buffer and updating depth buffer.
3. Disable writing to color and depth buffer. Depth test itself still should be done. Render font and back faces of the shadow volumes incrementing and decrementing, correspondingly, values in stencil buffer.
4. Render the whole scene again with alpha blending enabled writing only diffuse and specular material-light interaction components if stencil test passes equality to zero.
The approach above demands us to generate shadow volumes for each triangle in the mesh (three quadrilaterals per pyramid) for all the objects in the scene and, after, render them to stencil buffer. Usually, this is very resource and time-consuming and can hardly be applied in practice.
In fact, only silhouette edges of the mesh should produce shadow volume quadrilaterals [1]. A silhouette edge is an edge which separates front-facing and back-facing triangles of the mesh toward the light source. To efficiently identify them, the mesh should have a triangle adjacency list topology. Then, geometry shader can be used to calculate normals of two neighboring triangles and direction from the edge to the light source [3]. If it gets out, indeed, to be a silhouette edge, than two vertices defining the opposite edge of the quadrilateral are generated, and the primitive is passed further to the rasterizer.
Interaction:
Press "space" button to launch/stop torus animation.
References:
1. Tomas Akenine-Möller, Eric Haines, Nathaniel Hoffman. 2008. "Real-Time Rendering"
2. Elmar Eisemann, Michael Schwarz, Ulf Assarsson, Michael Wimmer. 2012. "Real-Time Shadows"
3. Jason Zink, Matt Pettineo, Jack Hoxley. 2011. "Practical Rendering and Computation with Direct3D 11"
Source Code: Shadow Volumes
This is another algorithm [1], [2] which allows to cast shadows on arbitrary surfaces and handle self-shadowing of the occluding objects as well. Suppose you have a light source located at some point in space and a triangle. Now, project a ray through that point and each vertex of the triangle at the infinity. You will have an infinity pyramid. All the points within the volume of the pyramid below the triangle will be shadowed. That is why, it is often called "shadow volume".
Let us assume the camera is located outside the shadow volume and looks along the ray at some view sample. Each time the ray goes through the front-face of the shadow volume, we increment a counter. The moment it goes through the back-face of the shadow volume, that is exits it, we decrement the counter. We can claim, in the end, that view sample is illuminated if the counter is zero; otherwise, it is shadowed. To imitate ray intersection with shadow volumes, stencil buffer could be used.
The steps of the algorithm are the following:
1. Clear stencil buffer with zero values.
2. Render the whole scene writing only ambient lighting components to the color buffer and updating depth buffer.
3. Disable writing to color and depth buffer. Depth test itself still should be done. Render font and back faces of the shadow volumes incrementing and decrementing, correspondingly, values in stencil buffer.
4. Render the whole scene again with alpha blending enabled writing only diffuse and specular material-light interaction components if stencil test passes equality to zero.
The approach above demands us to generate shadow volumes for each triangle in the mesh (three quadrilaterals per pyramid) for all the objects in the scene and, after, render them to stencil buffer. Usually, this is very resource and time-consuming and can hardly be applied in practice.
In fact, only silhouette edges of the mesh should produce shadow volume quadrilaterals [1]. A silhouette edge is an edge which separates front-facing and back-facing triangles of the mesh toward the light source. To efficiently identify them, the mesh should have a triangle adjacency list topology. Then, geometry shader can be used to calculate normals of two neighboring triangles and direction from the edge to the light source [3]. If it gets out, indeed, to be a silhouette edge, than two vertices defining the opposite edge of the quadrilateral are generated, and the primitive is passed further to the rasterizer.
Interaction:
Press "space" button to launch/stop torus animation.
References:
1. Tomas Akenine-Möller, Eric Haines, Nathaniel Hoffman. 2008. "Real-Time Rendering"
2. Elmar Eisemann, Michael Schwarz, Ulf Assarsson, Michael Wimmer. 2012. "Real-Time Shadows"
3. Jason Zink, Matt Pettineo, Jack Hoxley. 2011. "Practical Rendering and Computation with Direct3D 11"
Projection Shadows (Multiple Light Sources)
Requirements: Direct3D 11, Visual Studio 2010
Source Code: Projection Shadows (Multiple Light Sources)
This is the extension of the previous demo for the case we have got a few point light sources.
Source Code: Projection Shadows (Multiple Light Sources)
This is the extension of the previous demo for the case we have got a few point light sources.
Projection Shadows
Requirements: Direct3D 11, Visual Studio 2010
Source Code: Projection Shadows
Projection shadow could be a good option when object casts shadow on a planar surface.
References:
1. Tomas Akenine-Möller, Eric Haines, Nathaniel Hoffman. 2008. "Real-Time Rendering" pp. 333-336
2. Elmar Eisemann, Michael Schwarz, Ulf Assarsson, Michael Wimmer. 2012. "Real-Time Shadows" pp. 21-26
3. Jason Zink, Matt Pettineo, Jack Hoxley. 2011. "Practical Rendering and Computation with Direct3D 11"
Source Code: Projection Shadows
Projection shadow could be a good option when object casts shadow on a planar surface.
References:
1. Tomas Akenine-Möller, Eric Haines, Nathaniel Hoffman. 2008. "Real-Time Rendering" pp. 333-336
2. Elmar Eisemann, Michael Schwarz, Ulf Assarsson, Michael Wimmer. 2012. "Real-Time Shadows" pp. 21-26
3. Jason Zink, Matt Pettineo, Jack Hoxley. 2011. "Practical Rendering and Computation with Direct3D 11"
Blinn-Phong Lighting
Requirements: Direct3D 9, Visual Studio 2010
Source code: Blinn-Phong Lighting
This demo presents Blinn-Phong shading mode for a torus object. Essentially, it demonstrates the quality of the image for the three cases:
1. Shading is done totally in vertex shader (per vertex shading)
2. Shading is done both in vertex and pixel shaders (per pixel shading)
3. Shading is done totally in pixel shader (true per pixel shading)
References:
1. Edward Angel, David Shreiner. 2011. "Interactive Computer Graphics: a Top-Down Approach with Shader Based OpenGL" - 6th ed. pp. 257-298
2. Kris Gray. 2003. "DirectX 9. Programmable Graphics Pipeline"
Source code: Blinn-Phong Lighting
This demo presents Blinn-Phong shading mode for a torus object. Essentially, it demonstrates the quality of the image for the three cases:
1. Shading is done totally in vertex shader (per vertex shading)
2. Shading is done both in vertex and pixel shaders (per pixel shading)
3. Shading is done totally in pixel shader (true per pixel shading)
References:
1. Edward Angel, David Shreiner. 2011. "Interactive Computer Graphics: a Top-Down Approach with Shader Based OpenGL" - 6th ed. pp. 257-298
2. Kris Gray. 2003. "DirectX 9. Programmable Graphics Pipeline"
August 7, 2012
Hello, hello!
My name is Mykola and I work as a game programmer for Ubisoft Entertainment (Ukraine) on Assassin's Creed project under a PC platform.
Subscribe to:
Posts (Atom)