Unity Crest Ocean System源码如何阅读与?

摘要:1.前言 crest是一款海洋模拟插件,其开源的基础版本位于github(https:github.comwave-harmoniccrest),年末清下Flag。 1.1.对比Boat Attack 之前基于BoatAttack(
1.前言 crest是一款海洋模拟插件,其开源的基础版本位于github(https://github.com/wave-harmonic/crest),年末清下Flag。 1.1.对比Boat Attack 之前基于BoatAttack(https://github.com/Unity-Technologies/BoatAttack)做过一套水体方案,对比下两者。 - Boat Attack Water BoatAttack没有水下渲染,无吃水线 Lod只有mesh做了远处简化处理,没有系统级Lod的设计。 水体交互通过叠加Gerstner波形实现,但有叠加上限限制。 无FFT波形,只有Gerstner波。 无船只水体交互,只有深度差泡沫效果,海浪是粒子特效。 - Crest 基础版本无吃水线,但有完善水下渲染实现。 完整的大规模海面LOD方案,大量ComputeShader处理,但也提供常规VF Shader兼容性支持,需手动开关。 波形模拟做了封装处理,可自由切换FFT与Gerstner,可自定义某块区域用哪一种。 查询接口做了封装处理,一套接口可以支持异步和非异步。 船只与水体可配置波浪等交互,海浪是GPU Instancing的面片特效。 1.2 插件结构 以github上开源的基础版本为例,Examples.unity场景有所有效果演示 核心逻辑在OceanRenderer中,但要让海洋正常运行需要一定层级结构配置,例如参考BoatScene.unity Shader部分较为清晰,主要在Ocean.shader中,包含折射、反射、泡沫、SSS等基础的海水实现。 展开OceanRenderer的Debug菜单后,可显示Tile、线框等。 2.Tile & ShiftingOrigin 2.1 Tile拼接 在OceanRenderer脚本处勾选showOceanTileGameObjects即可显示隐藏的Chunk对象 具体代码在OceanBuilder的GenerateMesh中。 所有Tile都是独立Mesh,替换为Unlit shader查看,会发现有接缝: Shader中通过SnapAndTransitionVertLayout函数,进行坐标偏移修复,解决接缝问题。 unlit shader: 切回带Snap函数的shader: 但感觉实际上也可以用类似geo mipmap的做法,离线生成一张带顶点缝合的大型Mesh, 实时跟着Camera走(缺点是不好按Tile优化): 2.2 ShiftingOrigin实现原理 当实际坐标大于某阈值时,直接让transform.position减去一定偏移量,实现拉回,从而避免 因浮点数偏差而导致模型出现撕扯问题。 维基百科(http://wiki.unity3d.com/index.php/Floating_Origin) 插件实现: public class ShiftingOrigin : CustomMonoBehaviour { ... void FixedUpdate() { var newOrigin = Vector3.zero; if (Mathf.Abs(transform.position.x) > _threshold) ... if (Mathf.Abs(transform.position.y) > _threshold) ... if (Mathf.Abs(transform.position.z) > _threshold) ... if (newOrigin != Vector3.zero) { MoveOrigin(newOrigin); } } } 2.3 Texel对齐 为了避免偏移时无法对齐mesh网格,实际还会进行一步Texel偏移操作。 即用最小lod网格的尺寸进行坐标量化,避免shader通过世界坐标采样噪声贴图时, 因为浮点数采样到完全不同的中间位置,造成抖动感。
阅读全文