1. 简介
辐射度算法是一种经典的全局光照算法,它可以解决光线跟踪等直接照明方法中所不能表现的真实世界中的照明现象问题。虽然渲染的结果表现力强,但是问题之一就是算法的耗费较大,由于其原理就是对各个多边形面片进行着色,而且常常需要较多的迭代次数才能达到比较理想的效果,因此算法原理虽然比较简单,但效率就成为一个重要的瓶颈。
2. 辐射度算法原理
辐射度算法的原理就是模拟真实世界中的光照原理,在场景中的每个位置收集所有在该位置所能看到的颜色信息,然后对这些颜色信息进行汇总处理,作为最终该位置的颜色并对当前的位置进行着色。在现实世界中,这个位置就代表了无穷多个无限小的像素点,但在计算机中却不可能做到这样一点,因此只能进行近似的模拟操作,这就是将几何空间场景进行分割处理,得到一些相对于整个场景来说很小的多边形面片,然后以这些面片为单位来代替现实世界中的无限小的像素点进行渲染着色。当然,如果我们对整个场景分割得越发细小,得到的最终光照效果也就是越好,但随之而来的代价就是渲染的时间越长。
关于详细的辐射度算法原理,这里就不再详述了,可以参见:http://freespace.virgin.net/hugo.elias/radiosity/radiosity.htm
进行面片分割预处理操作之后的场景基本上如下图所示:
我使用的是八叉树来对场景进行均匀分割,当然,为了统一化,在操作前首先要对场景进行单位化,不过也可以根据场景的大小与场景的表现范围进行有选择的统一化方法,只要保证能在分割过程中控制最终面片的大小与整个场景的比例关系即可。对于每个面片的渲染着色,直接使用OpenGL的渲染管线来实现,这个操作代价不大,毕竟只是对多边形面片列表作无特效的渲染,一般显卡上效率即可达到每秒八九百帧。
当完成上述预处理操作之后即可以对每个面片进行渲染着色,流程如下:
For each radiosity shading time
For each polygon in polygon list
For each camera position
Render the scene
Get the color buffer:CB
End for
Compute the final Color for this polygon
End for
Use theColor list to update the scene
End for