Basic Shadow Mapping

Shadow Mapping | Thursday 23 October 2008 1:28 am

Shadow mapping works in that it checks if a point is visible from the light or not. If a point is visible from the light then it’s obviously not in shadow, otherwise it is. The basic shadow mapping algorithm can be described as short as this:

  1. Render the scene from the lights view and store the depths as shadow map
  2. Render the scene from the camera and compare the depths, if the current fragments depth is greater than the shadow depth then the fragment is in shadow
Shadow mapping example

It’s the implementation of it that is hard.

The two big problem areas with shadow mapping:

  • Hard to select an appropriate bias (epsilon)
  • Hard to get rid of artifacts at shadow edges

Projective texturing ( the method used to transform the fragment depth to the light space (where the shadow map is) for comparision)
http://developer.nvidia.com/object/Projective_Texture_Mapping.html
http://en.wikipedia.org/wiki/Projective_texture_mapping

OpenGL fixed-function pipeline implementation of shadow mapping:
http://www.paulsprojects.net/tutorials/smt/smt.html

A GLSL implementation of shadow mapping (in one of the posts)
http://www.gamedev.net/community/forums/topic.asp?topic_id=316147

Another GLSL shadow mapping shader:
http://sombermoon.com/shadowmappingdoc.html

DirectX9 shadow mapping example with source
http://msdn.microsoft.com/en-us/library/bb147372(VS.85).aspx

Nvidias implementation of shadow mapping with source for both OpenGL and DirectX.
http://developer.nvidia.com/object/hwshadowmap_paper.html

Shadow mapping in XNA
http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series3/Shadow_mapping.php
http://msdn.microsoft.com/en-us/library/bb975671.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

Scene Graph

Scene Management | Saturday 18 October 2008 12:14 am

A scene graph is a tree structure that tries to structure the objects in a scene accordingly to transformations, textures, materials and much more instead of just the geometrical representation of objects like for example a quadtree does. All games does contain a scene graph in some way, in the most simple form it could just be a root node and all other rendered objects as child nodes to the root node.

Here’s a list of useful links concerning scene graphs. Most links are borrowed from a post on gamedev.net but copied to this post so that I could remove broken links and include new ones.

  • Scene Graph Basics
  • Scene Graph design/implementation issues/notes etc
  • SG State Sorting
  • Shader/Material System/Integration
  • Optimizations for scene graphs
  • Spatialization
  • Most of this list was copied from the following gamedev.net forum thread.
    http://www.gamedev.net/community/forums/topic.asp?topic_id=349829

    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

    Gaussian Blur Filter Shader

    Image Enhancements | Saturday 11 October 2008 9:01 pm

    There are different ways to perform blur and this is one of the most common way to do it in a shader. It’s a two step method with first a horizontal blur and then a vertical blur. By splitting the work in two directions (two passes) you can save a lot of computation.

    The method can be divided in the following parts:

    1. Render the scene you want to blur to a texture (could be downsampled)
    2. Render a screen aligned quad with the horizontal blur shader to a texture
    3. Render a screen aligned quad with the vertical blur shader to the screen or texture depending on what you want to use it for

    The following image shows how the blur works when splitted up in two directions.

    Separable blur filter

    Here’s the horizontal blur shader.

    Vertex Shader (GLSL) . This shader screen align a quad with width 1. Any method to render a screen aligned quad will work. So you’re free to use other shaders.

    varying vec2 vTexCoord;
     
    // remember that you should draw a screen aligned quad
    void main(void)
    {
       gl_Position = ftransform();;
      
       // Clean up inaccuracies
       vec2 Pos;
       Pos = sign(gl_Vertex.xy);
     
       gl_Position = vec4(Pos, 0.0, 1.0);
       // Image-space
       vTexCoord = Pos * 0.5 + 0.5;
    }

    Fragment Shader (GLSL) 

    uniform sampler2D RTScene; // the texture with the scene you want to blur
    varying vec2 vTexCoord;
     
    const float blurSize = 1.0/512.0; // I've chosen this size because this will result in that every step will be one pixel wide if the RTScene texture is of size 512x512
     
    void main(void)
    {
       vec4 sum = vec4(0.0);
     
       // blur in y (vertical)
       // take nine samples, with the distance blurSize between them
       sum += texture2D(RTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 0.05;
       sum += texture2D(RTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 0.09;
       sum += texture2D(RTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 0.12;
       sum += texture2D(RTScene, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 0.15;
       sum += texture2D(RTScene, vec2(vTexCoord.x, vTexCoord.y)) * 0.16;
       sum += texture2D(RTScene, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 0.15;
       sum += texture2D(RTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 0.12;
       sum += texture2D(RTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 0.09;
       sum += texture2D(RTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 0.05;
     
       gl_FragColor = sum;
    }

    And here’s the vertical blur shader.

    Vertex Shader (GLSL) (the same as for the blur in horizontal direction)

    varying vec2 vTexCoord;
     
    // remember that you should draw a screen aligned quad
    void main(void)
    {
       gl_Position = ftransform();;
      
       // Clean up inaccuracies
       vec2 Pos;
       Pos = sign(gl_Vertex.xy);
     
       gl_Position = vec4(Pos, 0.0, 1.0);
       // Image-space
       vTexCoord = Pos * 0.5 + 0.5;
    }

    Fragment Shader (GLSL) 

    uniform sampler2D RTBlurH; // this should hold the texture rendered by the horizontal blur pass
    varying vec2 vTexCoord;
     
    const float blurSize = 1.0/512.0;
     
    void main(void)
    {
       vec4 sum = vec4(0.0);
     
       // blur in y (vertical)
       // take nine samples, with the distance blurSize between them
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y - 4.0*blurSize)) * 0.05;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y - 3.0*blurSize)) * 0.09;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y - 2.0*blurSize)) * 0.12;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y - blurSize)) * 0.15;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y)) * 0.16;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y + blurSize)) * 0.15;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y + 2.0*blurSize)) * 0.12;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y + 3.0*blurSize)) * 0.09;
       sum += texture2D(RTBlurH, vec2(vTexCoord.x, vTexCoord.y + 4.0*blurSize)) * 0.05;
     
       gl_FragColor = sum;
    }

    And this is a scene without blur.

    Scene before bluring

    And this is the same scene but with gaussian blur.

    Blured Scene

    You can tweak the blur radius to change the size of the blur and change the number of samples in each direction.

    Cost for separable blur shader : 9+9 = 18 (number of texture samples)
    Cost for shader if blured in one pass: 9*9 = 81 (number of texture samples)
    So splitting up in two directions saves a lot.

    The gaussian weights are calculated accordingly to the gaussian function with standard deviation of 2.7. These calculations were done in the excel document found [2].

    Here’s a description of blur shaders and other image processing shaders in DirectX:
    [1] http://ati.amd.com/developer/shaderx/ShaderX2_AdvancedImageProcessing.pdf

    More info about calculating weights for separable gaussian blur:
    [2] http://theinstructionlimit.com/?p=40

    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

    Shader Programming Guides

    Shaders | Thursday 9 October 2008 5:16 pm

    Here are some links to a couple of quick guides and references that’s useful when writing shaders.

    The OpenGL GLSL shader language Quick Reference Guide.
    http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf

    The full specification of GLSL 1.20.8.
    http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf

    The full specification of GLSL 1.30.08
    http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.08.pdf

    GPU Programming guide from Nvidia for both OpenGL and DirectX.
    http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide.pdf

    Guide to write shaders in DirectX9 in HLSL
    http://msdn.microsoft.com/en-us/library/bb944006(VS.85).aspx

    Guide to write shaders in DirectX10 in HLSL
    http://msdn.microsoft.com/en-us/library/bb509703(VS.85).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
    « Previous PageNext Page »