级联阴影映射查找决策/ gl_FragCoord.z

3
我已经按照nvidia SDK(http://developer.download.nvidia.com/SDK/10.5/Samples/cascaded_shadow_maps.zip)中的方法实现了级联阴影映射,但我的查找似乎不起作用。
这是一张描绘当前状态的图片:http://i.imgur.com/SCHDO.png 问题是,我立刻就进入了第一个分割,即使我离它很远。正如您所看到的,其他的分割甚至没有被考虑过。
我认为这个问题可能来自于主引擎使用的不同投影矩阵。它与我提供给算法的矩阵不同,但我也尝试将相同的矩阵传递到着色器中进行计算:gl_Position = matProj * gl_ModelViewMatrix * gl_Vertex
然而,这确实没有改变任何事情。我仍然只有一个分割。
以下是我的着色器:
[vertex]
varying vec3 vecLight;
varying vec3 vecEye;
varying vec3 vecNormal;
varying vec4 vecPos;
varying vec4 fragCoord;
void main(void)
{
    vecPos = gl_Vertex;
    vecNormal = normalize(gl_NormalMatrix * gl_Normal);
    vecLight = normalize(gl_LightSource[0].position.xyz);
    vecEye = normalize(-vecPos.xyz);

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

[片段](只有阴影部分)

vec4 getShadow()
{
    vec4 sm_coord_c = texmat_3*vecPos;
    float shadow = texture2D(smap_3, sm_coord_c.xy).x;
    float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

    vec4 shadow_c = vec4(1.0, 1.0, 1.0, 1.0) * s;

    if(gl_FragCoord.z < vecFarbound.x)
    {
      vec4 sm_coord_c = texmat_0*vecPos;
      float shadow = texture2D(smap_0, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(0.7, 0.7, 1.0, 1.0) * s;
    }
    else if(gl_FragCoord.z < vecFarbound.y)
    {
      vec4 sm_coord_c = texmat_1*vecPos;
      float shadow = texture2D(smap_1, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(0.7, 1.0, 0.7, 1.0) * s;
    }
    else if(gl_FragCoord.z < vecFarbound.z)
    {
      vec4 sm_coord_c = texmat_2*vecPos;
      float shadow = texture2D(smap_2, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(1.0, 0.7, 0.7, 1.0) * s;
    }

    return shadow_c;
}

因某种原因,无论我在场景中的位置在哪里,gl_FragCoord.z都小于vecFarbound.x。 (还请注意左侧的阴影区域,这个随着我将相机移动得更高而增加,很快就占据了整个场景..)

我已经检查了vecFarbound的值,并且它们与nvidia代码中的值相似,因此我认为我计算它们是正确的。

有没有办法检查gl_FragCoord.z的值?

1个回答

1

在我的旧CSM实现中,我只是使用了相机空间中的距离。

float tempDist = 0.0;
tempDist = dot(EyePos.xyz, EyePos.xyz);
if (tempDist < split.x) ...
else if (tempDist < split.y) ...
...

这个解决方案对我来说比较简单易懂,我能更好地控制分割。当您使用Z值(在剪辑空间中)时,可能会出现一些由于Z值不是线性的问题。

我建议在viewSpace中进行分割测试,然后(如果有效)使用gl_FragCoord.z..


很酷,我会试一下!非常感谢,我真的只是在这个部分挣扎。我很快就会回报。 - Lngly
请问您是如何计算分割向量的呢?目前我是基于每个分割的z值和投影矩阵来计算的。但是似乎您的建议对我并不起作用。 - Lngly
我基于 http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html,该文中将视图空间中的分裂给出,并使用提议的方程进行设置......请查看此链接中的“实用分割方案”。 - fen
抱歉,直到现在我才有时间去尝试它。 对于我的当前设置,我正在以完全相同的方式计算那些分割点,其中zNear从1.0f开始,zFar到100.0f 这将产生3个分割值:12.XXf、33.XXf和100.0f 我将这些值发送到着色器并将其与眼距离(就像你上面发布的那样)进行比较,并获得以下结果:http://i.imgur.com/mypTA.png其中,蓝色表示《split.x,绿色表示《split.y,红色表示《split.z正如你在这里看到的那样,这与我的截锥体根本不匹配:http://i.imgur.com/wqDaJ.png 我不太确定我错了什么。有任何想法吗? - Lngly
啊,我也得把分裂平方一下,对吧? - Lngly
是的,是的...我当然比较平方距离...抱歉我没有指出来。 - fen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接