• 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,效果变成:

    显然是不正常的。原因我还不清楚。

  • 相关阅读:
    css小技巧: select的css控制
    js中不存在exit函数,程序的运行中断停止,可使用return
    转载: WebCore渲染之一:基础
    转载: WEB架构师成长系列索引
    js:<form></form>中有<a>按钮时不能跳转?
    小心得:前台与后台的数据传递
    php session和cookie使用说明
    css 字体使用
    转载: PHP引用(&)使用详解
    三层架构下的增删改查 荣
  • 原文地址:https://www.cnblogs.com/wantnon/p/4569096.html
Copyright © 2020-2023  润新知