An Implemention of Realtime Gobal Illumination
前言:CG画面的“效果”最重要,至于达到这一效果所使用的技术倒是其次,一切的一切对于观众来说都是透明的。即使是Pixar都认为仅仅One Bounce Indirect Illumination对构建一个足够真实可信的光照效果足矣。看过这里的SII,我想你对Realtime Gobal Illumination的实现又会有一些新的认识。我实现了真实可信的Indirect Illumination效果,对比3dsmax附带的mental ray所得到的效果,同样不开阴影,我觉得我的画质更胜一筹。提供我的Demo下载,不过有个小小的BUG :-)期盼好心人帮我看一下。
Splatting Indirect Illumination(以下简称SII)是我目前所看过最简单的实现Indirect Illumination间接光照方法。它结合了Shadow Mapping与Defered Shading,大部分使用了Reflective Shadow Map(以下简称RSM)技术的思想。虽然说技术很简单,完全没有Realtime Raytracing夸张的计算量,也没有Realtime Radiosity的局限,是一种很适合实时渲染程序尤其是游戏的技术,用来实现逼真可信的Indirect Illumination间接光照效果,再结合现有的Local Illumination算法如IBL光照,Ambient Occlusion等,完全可以实现电影级别的渲染质量。这一点在Pixar的设计思想中就有所提及。
SII是源自于RSM的算法,所以在实现SII前需要解释一下RSM。RSM由4个Render Target(以下简称RT)组成:Depth Component、World Space Coordinates、World Space Normal、Flux。前面三者都很大众化了,直接绑定浮点纹理到FramebufferObject在Fragment Shader中输出就可以了,而最后一个Flux需要解释。
在RSM的思路中,每一个在Light View的Depth Map中出现的点,都是对场景的间接光照效果有贡献的,这里叫做pixel light。对于每一个pixel light,我们可以首先设想它是无限小的,那么它在ω方向上发出的光强就是,
同理,对于点x及其向量n来说,pixel light对它光照的贡献就是,
然后,我们可以近似的认为,场景中每一个点的光照都可以通过积分这些pixel light的贡献获得,
对于Glossy物体,如果使用类似于Phong的光照模型我们有,
对于原始的RSM算法,从RSM贴图中收集gather所有的象素点进行计算耗费很大,于是在SII中就采用了改进的策略,采样。这里我们先不做处理,使用Hammersley点集分布。如下图,样本数目为64,
下面准备开始实现。
1、首先我们从LightView渲染整个场景,渲染到World Position、World Normal、Flux 3张RenderTarget中去。
2、然后我们准备Defering Shading RenderTarget,也就是从摄像机渲染场景,得到World Position、World Normal、Diffuse、Specular、Shininess等光照计算需要的参数。
3、使用点集采样[1]中得到的纹理,再输出到同[1]中相同的RT中去。
4、在最终渲染遍中,使用[2]、[3]中的数据进行光照计算。
在这个里面有几个技巧,第一个是怎样快速的生成RTs,答案当然是MRT。我使用了GL_RGBA_FLOAT16_ATI作为FBO的Attachment,相比GL_RGBA32F_ARB,FP16格式可以保证足够的精度,最重要的是硬件可以做GL_LINEAR过滤,而FP32硬件只支持NEAREST过滤。在我的7300GO上使用两种浮点纹理,效果几乎没有任何差别,而通过内存监测可以得知FP32让一切都变得很巨大。
这里是只使用一个VPL进行渲染得到的黑白效果图,可以看到Local Illumination的效果很明显。右边是使用了64个VPLs得到的效果
这里是使用3dsmax的mental ray渲染的,使用了一个SpotLight,没有开启GI,因为开了GI后Photon Mapping得到的图简直惨不忍睹,实在没有耐心去调整参数。
导出整个3DS场景,这是实时渲染的结果,使用了一个Spot Texture,仅仅是为了玩 :-)。同样,没有渲染阴影。
这是使用了128个VPLs后渲染得到的场景。为了简化计算我把SpotLight当成了Point Light。
在这个经典的Cornel Box中站立着圣母、圣子的雕像,左边右边分别是红色与绿色的Diffuse面,雕像的身上体现了两种漫反射颜色的影响,天花板上也有浅浅的红色和绿色。如果再加上阴影和Ambient Occlusion和IBL那么效果将更加的完美,在这里我成功的实现了间接光照,最重要的是,一切的一切都是实时的。
DEMO可以在这里下载,不过有个小小的BUG,渲染几个Frame后就黑屏了,不知道是不是缓冲切换的问题还是其他什么的,我还不是很清楚,如果你看程序麻烦帮我看看,有结果的可以联系我,谢谢!