【问题标题】:Cascaded Shadow Mapping lookup decision / gl_FragCoord.z级联阴影映射查找决策 / gl_FragCoord.z
【发布时间】:2012-05-06 20:32:03
【问题描述】:

我在 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 但这并没有改变任何事情。我最终还是只有一个分裂。

这是我的着色器:

[顶点]

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 的值?

【问题讨论】:

    标签: opengl glsl


    【解决方案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..

    【讨论】:

    • 酷,我试试这个!非常感谢,我真的只是在这部分苦苦挣扎。我会尽快报告。
    • 请问您当时是如何计算分割向量的?现在我将它基于每个拆分的 z 值和投影矩阵。你的提议似乎不适合我。
    • 我基于http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html,其中拆分在 viewSpace 中给出并使用建议的方程式设置....查看此链接中的“实用拆分方案”。
    • 抱歉,直到现在才来得及尝试。我以相同的方式计算这些拆分,对于我当前的设置,我的 zNear 从 1.0f 开始,zFar 到 100.0f 这会产生 3 个拆分值:12.XXf、33.XXf 和 100.0f 我将它们发送到着色器并将其与眼睛距离(如您在上面发布的)与以下结果进行比较:i.imgur.com/mypTA.png 其中蓝色代表 i.imgur.com/wqDaJ.png 我不太确定我在这里缺少什么。有什么想法吗?
    • 啊,我也得把裂片弄平,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多