【问题标题】:OpenGL shadow mapping with deferred rendering, position transformation具有延迟渲染、位置变换的 OpenGL 阴影映射
【发布时间】:2015-03-16 13:17:39
【问题描述】:

我正在使用延迟渲染,我将眼睛空间位置相应地存储在纹理中:

顶点:

gl_Position = vec4(vertex_position, 1.0);

几何:

vertexOut.position = vec3(viewMatrix * modelMatrix * gl_in[i].gl_Position);

片段:

positionOut = vec3(vertexIn.position);

现在,在第二个通道(照明通道)中,我尝试使用从这个 vec4 计算的 UV 坐标对我的阴影贴图进行采样

vec4 lightSpacePos = lightProjectionMatrix * lightViewMatrix * lightModelMatrix * vec4(position, 1.0);

使用的位置与位置纹理存储和采样的位置相同。 在进行此计算之前,我是否需要使用逆相机视图矩阵转换位置?要将其带回世界空间还是应该如何进行?

【问题讨论】:

    标签: opengl shadow-mapping


    【解决方案1】:

    通常,阴影映射是通过比较当前片段的窗口空间 Z 坐标(这是深度纹理存储的内容)与光线来完成的。这必须使用共同的参考方向来完成,因此需要从光线的角度重新投影当前片段的位置。

    您现在拥有视图空间位置,它与您的 当前 相机相关,并不是特别有用。要有效地做到这一点,您需要世界空间位置。如果你通过逆视图矩阵变换视图空间位置,你可以得到它。

    给定世界空间位置,从光的角度转换为剪辑空间:

    // This will be in clip-space
    vec4 lightSpacePos = lightProjectionMatrix * lightViewMatrix * vec4 (worldPos);
    
    // Transform it into NDC-space by dividing by w
    lightSpacePos /= lightSpacePos.w;
    
    // Range is now [-1.0, 1.0], but you need [0.0, 1.0]
    lightSpacePos = lightSpacePos * vec4 (0.5) + vec4 (0.5);
    

    假设默认深度范围,lightSpacePos 现在可以使用了。 xy 包含要从阴影贴图中采样的纹理坐标,z 包含用于比较的深度。

    如需更详尽的解释,请参阅following answer


    顺便说一下,你会想从你的 G-Buffer 中消除你的位置纹理以达到合理的性能。仅给定深度、投影和视图矩阵就很容易重建世界或视图空间位置,并且所涉及的算术比额外的纹理获取要快得多。以足够的精度存储额外的纹理来表示 3D 空间中的位置将消耗每帧大量的内存带宽,并且完全没有必要。

    This article 来自 OpenGL Wiki 解释了如何执行此操作。你可以更进一步,回到世界空间,这比视图空间更可取。您可能需要稍微调整深度缓冲区以获得足够的精度,但它仍然比单独存储位置更快。

    【讨论】:

    • 如果不清楚,view-space 和 eye-space 是一回事。此外,camera-space(正如 OpenGL Wiki 文章所说的那样)是这个坐标空间的另一个词。
    猜你喜欢
    • 2016-12-22
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 2014-05-17
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多