Forward Shadow Mapping

Shadow Mapping | Thursday 16 October 2008 2:26 am

This technique for shadow mapping does the reverse when comparing depths. Instead of the normal case of comparing depths in light space, this method suggest that the comparison should be done in eye space. This requires the depth buffer from the lights’ view and from the camera’s view at the time of the comparison. This method is probably most useful when doing deferred lightning.

Forward Shadow Mapping

Link to the paper “Forward Shadow Mapping”
http://www.cs.unc.edu/~zhangh/shadow.html

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Screen Space

Cameras | Sunday 5 October 2008 12:10 pm

The last step of transformations (world to screen) when rendering is to get the rendered objects to screen space. This is a 2D space with the origin in the middle of the screen. After the vertex shader but before the fragment shader the fragments will be normalized device coordinates and will automatically be transformed to screen space. The fragments x,y coordinates will be mapped to the x and y coordinates on the screen (the exact mapping is set by viewportbounds). And the z coordinates will be mapped to the depth buffer (z-buffer) as the following [-1] -> [near clip plane limit] and [1] -> [far clip plane limit].

The viewport mapping is the following [-1,1] in X is mapped to the left to right of the viewport range. The [-1,1] in Y is mapped to the bottom to top of the viewport range

Framents will automatically be transformed to screen space before the fragment shader, you just need to set the viewport mapping with the following OpenGL call.

glViewport(0, screenHeight/2, screenWidth/2, screenHeight/2);

You can access the current fragment depth in a fragment shader with the variable gl_FragDepth which in default is the same as gl_FragCoord.z. The screen coordinates can be accessed in the variable gl_FragCoord.xy.

Information about pixel shaders in DirectX (most is the same in OpenGL):
http://www.gamedev.net/columns/hardcore/dxshader3/

A quick reference guide to GLSL:
http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf

Description of the mapping in DirectX:
http://msdn.microsoft.com/en-us/library/bb219690.aspx

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Clip Space

Cameras | Sunday 5 October 2008 2:53 am

Before rendering something all objects need to be projected to the screen ( a plane ). The first step, to project to the screen, is to project entities to clip space.

The mostly used projection type in games is perspective projection and therefore only this kind of projection will be explained. An other type of projection is parallel projection which is a projection that will keep parallel lines parallel. Perspective projection gives a field of view and objects appears to be smaller when further away which will feel realistic. The projection volume is set up as the following image shows.

The Projection Volume

You apply a projection to the entities that is in eye space to get them to clip space. This is the space that will soon decide if the vertex will be culled or not. Together with homogenization it can be thougt as a mapping from the projection volume to a cube with sizes 2 (in OpenGL) and with origin at 0,0,0. This mapping is showed in the image below.

Projection volume mapped to a cube

In OpenGL you can access the projection matrix if you set the matrix mode to projection:

glMatrixMode(GL_PROJECTION);

The following vertex shaders shows some ways to transform a vertex to clip space. The fastest way is the third shader that uses the highly optimized ftransform() function.

void main()
{
    // vertex in clip space
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}
void main()
{
    // vertex in clip space
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
void main()
{
    // vertex in clip space
    gl_Position = ftransform();
}

One side effect from applying perspective projection is that you end up with a non-linear z-buffer. The buffer will be more detailed closer to the screen which is often good. More about this in the z-buffer article.

After applying projection to a point p = (x,y,z,w) you will end up with a w value that is most probably not zero or one. This means you need to divide all components by this value to obtain normalized device coordinates. This will happen automatically between the vertex shader and fragment shader. Clipping will also be performed between these.

Information about different ways to transform vertices to clip space inside of a vertex shader:
http://www.lighthouse3d.com/opengl/glsl/index.php?minimal

Description of different 3D spaces:
http://vesta.astro.amu.edu.pl/Library/Linux/LinFocus/May1998/article6.html

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Linear depth texture

Rendering Methods | Sunday 28 September 2008 11:06 pm

In some occasions a linear depth texture is preferred over the usual non-linear depth buffer (z-buffer). The linearized depth could for example be used when doing SSAO or depth of field. Rendering linear z-buffers is very easy and only the following lines of code is required ( a float texture should be set as render target):

Vertex shader:

varying float depth;
void main()
{
    vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; // this will transform the vertex into eyespace
    depth = -viewPos.z; // minus because in OpenGL we are looking in the negative z-direction
    gl_Position = ftransform();
}

Fragment shader:

varying float depth;
void main()
{
    gl_FragColor.r = depth;
}

 
You might want to scale the depth in the vertex shader to a more appropriate range as the the distance will otherwise be the same as the distance from the camera to the vertex. The following vertex shader will map the near and far distances to 0..1 which is often a good idea.

varying float depth;
void main()
{
    vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; // this will transform the vertex into eyespace
    depth = (-viewPos.z-near)/(far-near); // will map near..far to 0..1
    gl_Position = ftransform();
}

Here’s how the shader looks like if you render a cube.

Linear Depth Rendering of a Cube

Link to a page about the depth buffer in DirectX
http://www.mvps.org/directx/articles/linear_z/linearz.htm

A good introduction to the depth buffer in OpenGL
http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks