Unity海洋shader笔记①

不久前玩了神秘海域4和盗贼之海,对游戏中形状生动颜色通透的大海产生了兴趣,于是开始查着资料学习自己动手写一个海洋的水效渲染。这个shader基本是边学边写的,编写过程中我学到了很多新的知识。
目前的效果:

波形

主要参考了GPU Gems的Chapter 1。
Chapter 1. Effective Water Simulation from Physical Models
实时水面模拟与渲染
海面波形是由多个不同频率分量单个波形叠加起来的,相对较为真实的方法是对真实采样的海面波形做FFT得到一个二维频谱,再在应用程序中通过IFFT还原为水波的高度数据。不过在此我还是先使用一种较为简单并且能直观地在GPU中计算的叠加Gerstner波的方法。使用这种波顶点会不仅有高度分量y的变化,同时在xz平面也会有一定的位移,我们在控制xz平面顶点位移大小的同时也控制了波峰是尖还是平缓。
Shader中我使用了12种不同波长,每种波长的分量是6个方向不同的同频率波的叠加,于是最后用72个波的叠加得到了目前的效果。

水面颜色渲染

总体上来讲我们将得到的颜色分为反射分量,折射分量以及加性的高光分量,折射和反射分量的比重用菲涅尔效应的公式计算。这里采用了一种快速菲涅尔方法:

float R_0 = (_AirRefractiveIndex - _WaterRefractiveIndex) / (_AirRefractiveIndex + _WaterRefractiveIndex);
R_0 *= R_0;
return  R_0 + (1.0 - R_0) * pow((1.0 - saturate(dot(I, N))), _FresnelPower);

参考链接


反射分量

在应用了波形和法线贴图后,海水的表面就不再是镜面,因此完全正确的反射颜色就不再是镜面反射。当然我们仍然可以计算正确反射的天空盒子颜色,但是由于这里采样的只有天空盒子于是其他物体便不会出现在反射中。然而正确不是首要考虑的因素,在这里我仍然使用了镜面反射的反射贴图。

获取镜面贴图的方式非常直观,直接在当前相机关于水平面的对称位置再生成一个(视线也对称)相机采样即可。注意这里为了只正确反射水面上的物体,我们需要将对生成的对称相机的近端裁剪平面修改为水面。在脚本中使用cam.CalculateObliqueMatrix(clipPlane)可以得到以clipPlaneclipPlane

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值