【问题标题】:How to use a single shadow map for multiple point light sources?如何为多个点光源使用单个阴影贴图?
【发布时间】:2012-03-28 11:48:19
【问题描述】:

据我了解,阴影映射是通过从灯光的角度渲染场景以创建深度图来完成的。然后从摄像机的 POV 重新渲染场景,并为场景中的每个点(GLSL 中的片段)计算从那里到光源的距离;如果它与你的阴影贴图中的匹配,那么它就在光中,否则它就在阴影中。

我刚刚阅读了this tutorial,以了解如何使用点/全向光进行阴影映射。

在第 12.2.2 节中说:

我们为所有光源使用一个阴影贴图

然后在 12.3.6 下它说:

1) 计算当前像素到光源的平方距离。
...
4) 将计算出的距离值与获取的阴影贴图值进行比较,以确定我们是否处于阴影中。

这大致就是我上面所说的。

我不明白的是,如果我们将所有灯光烘焙到一个阴影贴图中,那么我们需要将距离与哪个灯光进行比较?烘焙到地图中的距离不应该对应任何东西,因为它是所有灯光的混合,不是吗?

我确定我遗漏了一些东西,但希望有人可以向我解释一下。


另外,如果我们使用单个阴影贴图,我们如何为所有光源混合它?

对于单个光源,阴影贴图只存储最近物体到光源的距离(即深度图),但对于多个光源,它会包含什么?

【问题讨论】:

    标签: graphics 3d rendering shadow-mapping


    【解决方案1】:

    你过早地缩短了句子:

    我们为所有光源使用一个阴影贴图,创建一个图像 具有多通道渲染并为每个灯光执行一个通道 来源。

    因此,阴影贴图一次包含单个光源的数据,但它们只使用一个贴图,因为它们一次只渲染一个灯光。

    我认为这涉及到您的第二个问题 - 光是相加的,因此您只需将多个光的结果加在一起即可组合它们。在 GPU Gems 的案例中,它们直接在帧缓冲区中相加,这无疑是因为当时 GPU 上可用的存储纹理采样器数量相对有限。现在您可能希望在帧缓冲区和直接在片段着色器中进行组合。

    由于浮点舍入误差累积,您通常还应用“如果像素小于或等于阴影缓冲区中的距离加上一点点,则像素被点亮”而不是完全相等的测试。

    【讨论】:

    • 我认为那句话的其余部分只是意味着他们通过为每个光源渲染到相同的贴图(可能是附加的)来构建阴影贴图;并不是说他们清除并重新使用它。现在这更有意义了……虽然很遗憾——我真的希望我能用一张阴影贴图逃脱:p
    • 如果您翻转事物并使用通常称为延迟渲染的东西,您就可以做到。您从相机渲染场景以输出深度 + 法线 + 每个像素的一些表面信息,然后为每个光绘制一个全屏四边形,该四边形有效地迭代相机渲染。即使您的 GPU 只能输出 8 位 RGBA(在移动世界中仍然很常见),您也可以在多个通道中对多个纹理执行第一个位。
    • 太棒了。你刚刚为我打开了一罐全新的蠕虫。我正在制作游戏,大多数对象都是静态的(或很少更改),所以我正在考虑为所有静态对象预先计算阴影贴图,保留一份副本,并仅为移动的对象更新它。我想支持尽可能多的灯光,所以我认为每秒 60 次从不同角度重新渲染场景 100 次对我来说是不可能的。但是阴影贴图会占用活动纹理,不是吗?为了最终的渲染过程,我必须一次绑定所有这些,不是吗?
    • 最后的 pass 只需要那些尚未在帧缓冲区中累积的灯光。如果您的对象和灯光是完全静态的并且您有足够的存储空间,您可以准备仅包含静态对象的部分光照贴图,以便在每一帧中添加其他对象。虽然听起来延迟可能会更快 - 特别是如果您的任何灯光在帧内有很好的距离切断(在这种情况下,它们不需要应用于每个像素)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    相关资源
    最近更新 更多