实时渲染,一般有三种渲染方法,多光源一次渲染,多光源多次渲染和延迟着色。
多光源一次渲染:对于每个物体,计算所有光源对其的影响来对该物体进行渲染
for each object do
for each light do
framebuffer = light_model(object,light);
- 1
- 2
- 3
这是一个简单的方法,但是存在一些问题和缺陷。
第一个问题由于光照是针对每一个物体进行的,因此*之前渲染着色的对象能够被之后渲染着色的对象所取代*,换句话讲,对隐藏对象进行着色是浪费的。
第二个问题是如何在可编程渲染管线中,在一次渲染过程中管理多个光源。此外,该方法很难与阴影算法进行集成。
多光源多次渲染:对于每一个光照计算过程,执行所有光照计算。因此,对于每一个光源,所有被该光源影响的物体会被渲染。
for each light do
for each object affected by light do
framebuffer += light_model(object,light);
- 1
- 2
- 3
与第一个方法类似,
第一个问题:隐藏曲面会造成渲染的浪费。
第二个问题:光照首先对于每一个光源计算,然后对每一个物体计算。有可能有一些计算过程(例如,顶点转换和三角面片设置[Moller02])由于同一个物体在另外一个光照计算中被再次处理而重复计算。
第三个问题:由于光源排序和物体排序时互斥的,因此很难执行此操作。
延迟着色:原理,将每个像素点的属性存储在显存里面用于后面的渲染,后面的渲染则是一个像素一个像素的渲染,每个像素都会独立的渲染。
在上面两种渲染方法,延迟着色有很大的优势,特别是在效率上面,时间复杂度要小很多
for each object do
G-buffer = lighting properties of object;
for each light do
framebuffer += light_model(G-buffer,light);
- 1
- 2
- 3
- 4
延迟着色还有一些其它优势。例如,一旦几何处理和光源处理进行解耦分离,很容易进行批操作。