Franck Freiburger
Franck Freiburger

Reputation: 28478

Shadow volume shader optimization (GLSL)

I wondering if there is a way to optimize this vertex shader.
This vertex shader projects (in the light direction) a vertex to the far plane if it is in the shadow.
The aim of this shader is to create a shadow volume object that enclose the shadow of the object itself.

void main(void) {
  vec3 lightDir = (gl_ModelViewMatrix * gl_Vertex 
                   - gl_LightSource[0].position).xyz;

  // if the vertex is lit
  if ( dot(lightDir, gl_NormalMatrix * gl_Normal) < 0.01 ) {

    // don't move it
    gl_Position = ftransform();
  } else {

    // move it far, is the light direction
    vec4 fin = gl_ProjectionMatrix * (
                 gl_ModelViewMatrix * gl_Vertex 
                 + vec4(normalize(lightDir) * 100000.0, 0.0)
               );
    if ( fin.z > fin.w ) // if fin is behind the far plane
      fin.z = fin.w; // move to the far plane (needed for z-fail algo.)
    gl_Position = fin;
  }
}

Upvotes: 1

Views: 2147

Answers (1)

user3461716
user3461716

Reputation:

If you don't want do touch your principal algorithm (as Michael Daum suggested in his comment) you could replace some parts of your code:

uniform mat4 infiniteProjectionMatrix;

if(...) {
   ...
} else {
   gl_Position = infiniteProjectionMatrix * vec4(lightDir, 0.0);
}    

where infiniteProjectionMatrix is a customized projection matrix where the far plane has been set to infinity (see http://www.terathon.com/gdc07_lengyel.pdf on slide 7) and looks something like:

*  0  0  0
0  *  0  0
0  0 -1  *
0  0 -1  0

Since you are projecting to infinity you don't need the "100000.0" scaling factor and the "gl_ModelViewMatrix * gl_Vertex" offset can be neglected (compared to the infinite length of the lightDir vector).

Upvotes: 1

Related Questions