通过将每个单独的光源应用于片段的结果相加,可以很容易地扩展为容纳多个光源,例如:如果有大量光源,此过程将非常缓慢;对于
N
灯,此方法需要对每个片段进行phong阴影计算N
次。 是否存在更好的方法来渲染具有大量光源(数百个,数千个等)的场景?
#1 楼
是的,但是您需要进行范式转换。您习惯的称为前向渲染。提交几何图形,然后立即进行着色过程。在基本的正向渲染中,您可以为每个光源在着色器内循环,也可以为每个光源执行一次遍历,然后将结果混合在一起(使用加法混合)。
但是事情发展了很多。输入:Deferred Rendering
现在,这么多变种详细描述了所有变种,在这里给出的答案将远远超过可接受的范围。因此,在这里我仅描述Deferred阴影的要点,还有很多其他资源可以使用google轻松找到,希望阅读此书后您将拥有正确的关键字以找到所需的内容。
基本思想是将阴影推迟到管道之后。您有两个主要步骤:
渲染几何图形以及着色到多个渲染目标所需的所有信息。这意味着通常在基本实现中,您将具有深度缓冲区,该缓冲区包含几何体的法线和反照率颜色。您很快就会发现,您需要其他有关材料的信息(例如,粗糙度,“金属”因子等)。
这张来自维基百科的图片显示了三个缓冲区(颜色,深度和法线)
缓冲区的数量,类型和内容再次在不同的项目中使用的方法差异很大。您将找到名称为GBuffers的一组缓冲区。
之后就是应用实际照明的时间。在每个光源的照明过程中,您要绘制取决于光源类型的光量:
对于定向光,您要渲染全屏四边形。
对于点光源,您渲染一个球体,其半径取决于点光源的衰减。
对于聚光灯,可以渲染一个圆锥体,圆锥体的尺寸再次取决于光源的特性。
在此遍历的像素着色器中,您传递GBuffer并使用其中的信息执行照明和着色。这样,与传统的正向渲染相比,您只处理受明显影响的光影响的每个像素。
它也有很多缺点,最明显的是透明对象的处理以及带宽和视频内存的更高消耗。但是处理各种材料模型也比较棘手。
您还有其他缺点(因为有很多信息可用于后处理),并且也很容易实现。但这对于很多灯来说已经不是最酷的事情了。
较新的技术是例如Tiled渲染技术。这些方法的主要思想是在屏幕空间“图块”中细分场景,并为每个图块分配影响它的灯光。这既以延迟方式又以向前方式存在。当您在图块中具有各种深度不连续性时,这些技术会导致一些问题,但是通常比经典延迟方法要快,并且可以解决各种问题。例如,在优点中,使用平铺延迟功能时,每个亮片读取一次GBuffers,并且同一平铺块中的像素一致地处理相同的灯光。
在这方面的进一步发展是“聚簇阴影”,它在概念上类似于基于图块的方法,它具有3D范围的聚簇而不是屏幕空间图块。该方法处理深度不连续性问题更好,并且通常比平铺方法执行得更好。
重要说明:我已经介绍了延迟着色的基础知识。周围有多种变体,优化和改进,因此我敦促您尝试一个简单的版本,然后对其他技术(例如我上面提到的一种)进行一些研究。
评论
$ \ begingroup $
这是Tiled和Clustered的两个源代码资源
$ \ endgroup $
–RichieSams
2015年8月9日在18:52