使用多种光源进行高效渲染


10

要使用phong阴影渲染具有单个光源的场景,可以基于材质和光源的环境/漫反射/镜面反射分量计算传递到片段着色器中的每个片段的最终颜色。

通过将将每个单独光源应用于片段的结果加在一起,可以很容易地扩展它以适应多个光源:

final_color = (0, 0, 0, 1)
for each light:
    final_color += apply_light(material, light)
final_color = clamp(final_color, (0,0,0,1), (1,1,1,1))

但是,在有大量光源的情况下,此过程非常缓慢;对于N灯光,这种方法需要计算phong阴影N每个片段的时间。

有没有更好的方法来渲染具有大量光源(数百个,数千个等)的场景?

Answers:


15

是的,但是您需要进行范式转换。

您习惯的称为前向渲染。提交几何图形,然后立即进行着色过程。在基本的正向渲染中,您可以为每个光源在着色器内循环,也可以为每个光源执行一次遍历,然后将结果混合在一起(使用加法混合)。

但是事情发展了很多。输入:延迟渲染

既然有这么多变体来详细描述它们,那么这里给出的答案将远远超过可接受的范围。因此,在这里我仅描述Deferred阴影的要点,还有很多其他资源可以使用google轻松找到,希望阅读此书后,您将拥有正确的关键字以找到所需的内容。

基本思想是将阴影推迟到管道之后。您有两个主要步骤:

  1. 渲染几何图形以及着色到多个渲染目标所需的所有信息。这意味着通常在基本实现中,您将具有深度缓冲区,该缓冲区包含几何体的法线和反照率颜色。您很快就会发现,您需要其他有关材料的信息(例如粗糙度,“金属”因子等)。

这张来自维基百科的图片显示了三个缓冲区(颜色,深度和法线)

在此处输入图片说明

同样,不同项目之间使用的缓冲区的数量,类型和内容也有很大不同。您将找到名称为GBuffers的一组缓冲区。

  1. 之后是应用实际照明的时间。在每个光源的照明过程中,您要绘制一个取决于光源类型的光量:
    • 对于定向光,可以渲染全屏四边形。
    • 对于点光源,您渲染一个球体,其半径基于点光源的衰减。
    • 对于聚光灯,可以渲染一个圆锥体,圆锥体的尺寸又取决于光源的特性。

在此过程的像素着色器中,您传递GBuffer并使用其中的信息执行照明和着色。这样,与传统的正向渲染相比,您只处理受明显影响的光影响的每个像素。

它还具有各种缺点,最明显的是透明对象的处理以及带宽和视频存储器的更高消耗。但是处理各种材料模型也比较棘手。

您还有其他缺点(因为有很多信息可用于后处理),并且也很容易实现。但这对于很多灯来说已经不是最酷的事情了。

较新的技术例如是平铺渲染技术。这些方法的主要思想是在屏幕空间“图块”中细分场景,并为每个图块分配影响它的灯光。这既以延迟方式又以向前方式存在。当您在图块中具有各种深度不连续性时,这些技术会导致一些问题,但通常比经典延迟方法要快,并且可以解决各种问题。例如,在优点中,使用平铺延迟功能时,每个点亮的片段读取一次GBuffers,并且同一平铺块中的像素会一致地处理相同的灯光。

在这方面的进一步发展是“ 聚类阴影”,它在概念上类似于基于图块的方法,具有3D范围的聚类而不是屏幕空间图块。与平铺方法相比,该方法可以更好地处理深度不连续性问题,并且通常性能更好。

重要说明:我已经介绍了延迟着色的基础知识。周围有多种变体,优化和改进,因此我敦促您尝试一个简单的版本,然后对其他技术(例如我上面提到的一种技术)进行一些研究。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.