为什么阴影贴图着色器向后工作?

Why are shadowmapping shaders working backwards?

我目前正在研究阴影贴图着色器,出现的一个问题是为什么我们首先对表面进行阴影处理 (lambert/phong),然后将阴影映射到它们上面,而不是仅仅附加地照亮像素?这让我觉得与光的工作方式相反。

如果我们使用阴影贴图,这意味着我们已经创建了一个纹理,告诉我们哪个屏幕 space 像素暴露在光源下。为什么我们需要进行整个 lambert\phong 计算呢?为什么不直接从组合阴影贴图中获取照明?

这是我看到的伪算法:

  1. 默认情况下输出图像的所有像素都是全黑的。
  2. 生成不发光的反照率屏幕纹理
  3. 为灯光生成阴影贴图
  4. 修改输出图像。我们只修改暴露在光源下的像素(匹配阴影贴图深度+-偏差,无论如何),根据光强度、衰减等使暴露的像素更亮
  5. Select下一盏灯
  6. 转到第 3 步

如果这将是具有正确光强度的图像的结果。现在我们将强度纹理乘以反照率纹理得到最终图像。据我所知,这一次只需要 3 个纹理,是不是太多了?

我认为人们还没有这样做一定是有原因的,我想我只是需要有人指出原因。

阴影贴图在大小和位深度方面都受到纹理精度的限制。

基于光向量和法线的分析着色具有很高的准确性(忽略法线贴图的主题)而且还可以对同一现象的不同方面进行建模。在重叠的同时,它们提供了更准确的表示。 即使您去除了非漫反射项,例如镜面反射,仅几何形状(深度通道捕获的唯一数据)也无法捕获许多方面,例如微面和小规模自阴影。

另外,Shadow mapping本身就是一个二元运算,你需要积累很多样本("taps")或者通过某种方式处理输出以获得半影或者任何中间值。

所以在实践中许多 "terms" 确实是可加的,阴影贴图只是一个相乘的分量,因为它提供了额外的遮挡信息。

这是来自 Unity 的粗略示例,底部的图像是屏幕的捕获 -space 阴影缓冲区。顶部有镜面反射和漫反射项。