1. 先说体积雾:
1.1) 体积雾绘制有两个让人匪夷所思的地方,一个就是渲染到renderTexture,深度缓存从32-bit浮点数pack到32-bit的A8R8G8B8,关于pack的原理及精度差异,可以在http://www.cnblogs.com/infintyward/p/3199317.html这篇文章中找到,就不再做具体解释。
1.2) 体积雾的另外一个使用的很奇妙的地方就是RenderState的设置,书上描述如下:
D3DRS_ALPHABLENDENABLE = TRUE
D3DRS_BLENDOP = ADD
D3DRS_SRCBLEND = ONE
D3DRS_DESTBLEND = ONE
其实还少了一个,那就是ZENABLE必须要设置为FALSE,至于Z测试的Campare Function和ZWriteEnable,就不用管了,ZENABLE都false了,这两个都是浮云。
2. 关于体积雾和实际场景混合:
这里边pass#1专门用来绘制场景深度(假设用到的renderTexture名称为SolidDepth),然后在绘制体积雾的pass#2(假设renderTexture名称为Frontface)及pass#3(假设renderTexture名称为Backface)中,在pass#2,pass#3中要对已经绘制好的SolidDepth进行采样,分别跟体积雾的深度进行比较,将较小深度的绘制进新的renderTexture。自己写代码的时候犯了一个错误,如下图:
即只有在茶壶区域范围内才能看到体积雾,出了茶壶区域,就看不到体积雾了,代码检查了一遍又一遍,就是找不到错误,后来跟光盘中的程序对比,也没发现错在哪。
无意间将光盘程序在show pass菜单模式下运行,发现光盘中的show pass下确实跟我自己从头开始写的代码有区别,而且区别还很明显。如下图:
pass#1中已经很明显了,错就错在pass#1中绘制深度的renderTexture的clear color我设置为了0,而其实要设置为1。
发现错误后,原因就好找了,因为既然是深度,那么深度在清零的时候就要清零为1(最远处),这样在pass#2、pass#3手动做Z值大小比较时,会将较小的Z直接绘制进新的renderTexture。如果清屏为0,也就是说一上来Z值就最小了pass#2,和pass#3中大象的深度不管是多少,都不可能比0小,所以也就绘制不到新的renderTexture中了。
//endl...