2009-08-25

Radiosity Rendering Algorithm.

辐射度算法是一种全局光照算法。基本思路如下:
1. 首先,根据外部光源,得到一幅直接光照生成的光照图。
2. 然后,以此光照图+外部光源为光源,对场景进行辐射。
3. 迭代2过程。

Hugo Elias 的解释非常形象,以场景中的每个面片看到的“场景”为光源,计算此面片的亮度。

算法伪代码:

load scene

divide each surface into roughly equal sized patches

initialise_patches:
for each Patch in the scene
if this patch is a light then
patch.emmision = some amount of light
else
patch.emmision = black
end if
patch.excident = patch.emmision
end Patch loop

Passes_Loop:each patch collects light from the scene
for each Patch in the scene
render the scene from the point of view of this patch
patch.incident = sum of incident light in rendering
end Patch loop

calculate excident light from each patch:
for each Patch in the scene
I = patch.incident
R = patch.reflectance
E = patch.emmision
patch.excident = (I*R) + E
end Patch loop

Have we done enough passes?
if not then goto Passes_Loop

代码解释

initialize patches:(初始化面片)
一开始,所有的面片都是黑的,除了那些能自身辐射出光线的面片。因此,那些能辐射光线的面片的出射光强的初始值应被初始化伪它的辐射光强。其他面片的辐射光强都应为0。

Passes Loop(遍历循环):
代码多次重复这个循环直到场景有了可接受的光照效果。每次循环之后,也就多模拟了一次光在场景中的反射。

each patch collects light from the scene(每个面片从场景中收集光强)
如果我之前在文章中解释的那样,每个面片都被它能够看见的其他面片照亮。要达到这个目的,可以简单地把把场景渲染到面片的视角,然后把它所看的光强相加。我将在下一小节更详细地解释这一步。

calculate excident light from each patch(为每个面片计算出射光强):
计算出有多少光强抵达面片之后,我们现在可以计算出有多少光强离开面片(被反射)。
这个过程必须被循环多次以达到一个好的效果。如果渲染器还需要一个循环,我们就调转到标记"Passes Loop"。

Reference:
1. English:http://freespace.virgin.net/hugo.elias/radiosity/radiosity.htm
2. Chinese:http://dev.gameres.com/Program/Visual/3D/Radiosity_Translation.htm

没有评论: