Шейдерная оптимизация теневого объема (GLSL) - PullRequest
1 голос
/ 25 марта 2010

Мне интересно, есть ли способ оптимизировать этот вершинный шейдер.
Этот вершинный шейдер проецирует (в направлении света) вершину на дальнюю плоскость, если она находится в тени.
Цель этого шейдера - создать объект теневого объема, который окружает тень самого объекта.

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;
  }
}

1 Ответ

1 голос
/ 27 марта 2014

Если вы не хотите касаться своего основного алгоритма (как предложил Майкл Даум в своем комментарии), вы можете заменить некоторые части своего кода:

uniform mat4 infiniteProjectionMatrix;

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

где infiniteProjectionMatrix - настраиваемая матрица проекции, в которой дальняя плоскость установлена ​​на бесконечность (см. http://www.terathon.com/gdc07_lengyel.pdf на слайде 7) и выглядит примерно так:

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

Поскольку вы проецируете на бесконечность, вам не нужен масштабный коэффициент "100000.0", а смещением "gl_ModelViewMatrix * gl_Vertex" можно пренебречь (по сравнению с бесконечной длиной вектора lightDir).

...