在模擬水體或鏡面的效果是,周圍的環境會反射在這些平面上。一般的做法把反射後環境渲染在一張texture上(RTT),再把這張texture作爲水面(或鏡面)的紋理最終渲染出來.
1. reflection plane 的確認。也就是水面或鏡面的平面plane是的位置。我們只要反射水平面以上的東西,所以,這個reflection plane 也是clip plane; 注意plane 的法線方向,所謂的平面上方是指在法線方向一側. 所以 plane{0,1,0,0} 和plane {0,-1,0,0}是不一樣的.
2. reflection plane 的變換
與 固定管線不同, programmable pipeline 的Plane變換髮生在 view和porj投射後的空間。最終要變換到clip空間,還要對變換矩陣作iverse 和 transpose:
matWVP = matWorld*matView* matProj;
D3DXMatrixInverse(&matWVP,0,&matWVP);
D3DXMatrixTranspose(&matWVP,&matWVP);
D3DXPlaneTransform(&clipUpPlane,&ReflectPlaneUp,&matWVP);
3. reflection 矩陣. DirectX 提供接口D3DXMatrixReflect( &g_matReflect,&ReflectPlane); 可以取得相對於ReflectPlane 的反射矩陣.
然後
matWorld = matWorld*g_matReflect;
matWorldViewProj = matWorld*matView* matProj;
就是反射後的視口變換矩陣.
4.計算GetScreenTexCoords
我們已經把經平面反射後的世界渲染到一個texture( 該texture的長寬跟窗口等同),如何影射到反射面呢?
在 vertex shader階段,已經計算好了頂點的視口座標,據此得到ScreenTexCoords:
float4 vResult;
vResult.x = ( vPos.x * 0.5 + vPos.w * 0.5 );
vResult.y = ( vPos.w * 0.5 - vPos.y * 0.5 );
vResult.z = vPos.w;
vResult.w = vPos.w;
在 pixel shader中,vResult.xy/vResult.w 作爲紋理座標 就可以了
float4 texColor = tex2D( texSampler,(texCoord2.xy / texCoord2.w) );
源碼在web:http://file.mofile.com/ 提取碼:6890315678898997