我已经实现了级联的光传播体积算法(尚无间接阴影),用于此处和此处详细介绍的实时漫反射全局照明。它工作正常,但我仍在尝试特别修复一个工件。
简短的摘要
如果您已经知道算法的工作原理,则可以跳过此步骤。
该算法的工作原理是将照明信息以球谐函数的形式存储在3D网格中,其中最初,网格每个单元中的数据来自渲染扩展的阴影图(反射阴影图)),还包括颜色和常规信息(深度除外)。这个想法是,光源看到的基本上所有像素都是间接照明第一次反弹的原因,因此您将所需的信息存储在用于阴影映射的普通深度缓冲区旁边,并对所有数据进行采样以初始化3D网格。然后,通过(对于每次迭代)将信息在一个单元中传播到它的6个直接邻居(上,下,左,右,上,下),以迭代方式传播3D网格中的信息。要使用网格中的信息来照亮场景,请在场景上应用全屏传递,并且对于每个栅格化像素,您都可以获得可用的栅格化表面的世界空间位置(例如,来自延迟阴影中的G缓冲区),因此您知道屏幕上某个像素所属的网格单元。
这在大多数情况下都可以正常工作,这是两个没有模拟GI的图像,只是一个硬编码的环境术语,其次是带有LPV算法的图像。注意表面上的彩色反射,更好的深度细节等。
问题
在光照阶段查找单元格时,使用三线性插值法(使用硬件纹理过滤器)可在单元格中心,其相邻单元格和实际查找的纹理坐标之间平滑地插值数据。本质上,此插值模拟了在单元中心的照明信息到在查找信息的中心附近的具体像素的传播。这是必需的,因为否则照明将看起来非常粗糙且难看。但是,由于三线性内插法未考虑在单元中编码的照明信息的光传播方向(请记住,它是在球谐函数中),因此光可能会错误地传播到所查找的像素。例如,如果在单元格中编码的辐射仅向(1,0,0)(
当网格中的像元大小比场景中的曲面大时,这会导致光不正确地穿过壁渗出(这是必要的,因为您需要大的像元以尽可能少的传播迭代将光传播到场景中)。看起来是这样的:
如您所见(从右上角的阴影轮廓中看到),场景被场景上方左上角的定向光源照亮。而且,由于只有一个单元将中庭的外部与内部隔开,因此光线会流过,并且左侧的墙会被错误地照亮。
实际问题
作者提出了一种手动各向异性过滤的形式来解决此问题。他给出了朝向表面法线n方向的辐射梯度(我假设是从当前单元格采样的SH系数),如下所示:
和州
因此,通过将辐射方向导数与实际辐射方向进行比较,可以计算出该点的辐射分布是否开始于其三线性插值。
我的问题:
在等式中,函数c(x)似乎是点(x)的SH系数。因此,辐射梯度似乎像正常的数值导数一样被计算为点x-(n / 2)和x +(n / 2)处SH系数的加权差。但是,在我的上下文中,c(x)是什么?目前,我假设c(x)指的是表面位置(x)上的三线性插值系数,但是我不确定,因为我不知道该如何为您提供有关方向的更多信息SH系数的分布。
然后,如何使用该渐变来确切地更改从单元采样的光照应用于表面的方式?作者只是写了“将辐射方向导数与实际辐射方向进行比较”,但这是相当模糊的。
他提到使用“中心差分方案”,并引用这些幻灯片的SH系数的中心差分,并且还引用本文足见其梯度的推导,但现在我不能从中得出任何有用的结论。