unity, WaterProDaytime注意事項。


一,多個WaterProDaytime不要公用material。

原因是:水面material的shader(FXWaterPro.shader)引用了reflectionTexture,而水面1的reflectionTexture是由水面1的reflectionCamera渲染出來的。水面2的reflectionTexture是由水面2的reflectionCamera渲染出來的。由於水面1的reflectionCamera與水面2的reflectionCamera的觀察方向不同,所以必須用兩個不同的camera,所以得到的reflectionTexture也是不同的,那么如果水面1和水面2的material用同一個,它們的shader引用的reflectionTexture就只能是同一個,這與水面1與水面2的reflectionTexture不同相矛盾,所以水面1和水面2必須用不同的matrial。(用refractionTexture來分析也是一樣)。(如果好奇多個水面使用同一個matrial會發生什么,可以做一下試驗,結果就是當攝像機旋轉到某個角度時水面的reflection和refraction效果會發生奇怪的跳變)。

如果我們要在場景中同時添加兩個Water,正確的做法是:

(1)由WaterProDaytime.prefab創建兩個實例Water1和Water2。

(2)將WaterProDaytime.mat復制出兩個副本,WaterProDaytime1.mat和WaterProDaytime2.mat。

(3)用WaterProDaytime1.mat替換Water1原來的material,用WaterProDaytime2.mat替換Water2原來的material。

同理,即使場景中只放一個Water,也應該將WaterProDaytime.mat復制一個副本替換原來的material,以避免原prefab的material被污染。

 

二,WaterProDaytime在Orthographic相機上的bug。

對於Orthographic相機,如果water在視截體內且water平面與相機視線平行,unity將報出“Screen position out of view frustum”這個error。報錯行是Water.cs腳本中的reflectionCamera.Render(),但經過分析可以確定是reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane)這一句導致的,更具體地說是unity的Camera.CalculateObliqueMatrix這個API的實現有bug/對Orthographic相機支持不完善/根本就不支持Orthographic?亦或是Camera.CalculateObliqueMatrix正確完成了自己的計算,但Camera.Render()中對於Camera.CalculateObliqueMatrix的特殊情況下的計算結果沒有作出正確的理解。

Camera.CalculateObliqueMatrix(clipPlane)在文檔中的解釋是:

Calculates and returns oblique near-plane projection matrix.

Given a clip plane vector, this function returns camera's projection matrix which has this clip plane set as its near plane.

(關於obliqueMatrix還可以參考:

http://forum.unity3d.com/threads/problem-camera-calculateobliquematrix.252916/

http://www.terathon.com/code/oblique.html

http://aras-p.info/texts/obliqueortho.html

http://www.terathon.com/lengyel/Lengyel-Oblique.pdf)

也就是說,oblique投影矩陣與普通投影矩陣(透視投影矩陣和正交投影矩陣)的差別是:普通投影矩陣所描述的視截體近平面與錐軸垂直,而oblique投影矩陣所描述的視截體近平面是斜的(與錐軸不垂直)。

如下圖所示,左圖中紅色的是透視投影視截體,右圖中紅色的是oblique投影視截體。由於水面是反射面,所以渲染反射圖象時必須以視截體被水面所截的截面作為視口,即“斜視口”,所以必須將反射相機轉化成oblique投影模式。reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane)就是干這個事兒。

不過對於一些特殊情況,得不到有限的 斜視口 ,如下兩圖:

   

上面左圖是透視投影下得不到有限斜視口的例子,右圖是正交投影下得不到斜視口的例子。

不過對WaterProDaytime進行測試我發現在其在透視投影相機下總是不會報error的(至少我沒測到反例),這說明Camera.CalculateObliqueMatrix在透視投影下還是工作良好而且Camera.Render能正確理解Camera.CalculateObliqueMatrix的計算結果。但對於正交投影相機,經過測試,如上面右圖所示,當water與錐軸平行且在h1之下或在h2之上時安全,但在h1和h2之間時會報error。

由於這是unity自已API的問題,完美的解決只能等官方修正。

但work around是有的,就是:

(1)把Water.cs中的

reflectionCamera.Render();

改成:

if(cam是正交投影相機&&視線與本水面平行){

  reflectionCamera.Render();

}

(2)把Water.cs中的

refractionCamera.Render(); 

改成:

if(cam是正交投影相機&&視線與本水面平行){

  refractionCamera.Render();

}

 

三,WaterProDaytime不能在cubemap中反射。

如下圖,其中動態cubemap球體用下面日志中的方法做的:http://www.cnblogs.com/wantnon/p/4480727.html

當球體的Camera_cubeMapRealTime的Culling Mask選為“除Water外所有物體”,效果如下:

但是當球體的Camera_cubeMapRealTime的Culling Mask選為Everything,效果變成:

顯然是不正常的。原因我還不清楚。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM