Unity引擎制作海面效果
大家好,我是阿赵。
上一篇的结束时,海面效果已经做成这样了:
这个Shader的复杂程度已经比较高了:
不过还有一些美中不足的地方。
1、 海平面没有反射到天空球
2、 在近岸边看得到水底的部分,水底的砂石没有变化,按道理应该是有水的折射,导致画面会出现扭曲才对。
我这个例子,其实是没有做这两点的。不过也可以分享一下思路。
一、 反射
反射的做法有多种。
如果是要实时真实的反射,可以参考Unity很早之前的水的例子,那个类似于镜面反射的效果,其实是在正常摄像机上增加了一个相对计算出位置的摄像机,拍摄出反射应该出现的画面,然后再通过RenderTexture赋予给材质球。由于是真的有个摄像机在拍摄,所以算是真正的实时反射,假如有个什么物体在水面上经过,也会倒影在水面上。
但这样做等于是把大部分的物体都渲染两次,性能不是特别的好。所以如果不是想产生真实的倒影,只是想把天空的氛围倒影在水面上,其实就比较简单了,做一个Matcap的假反射,然后通过乘以一个强度,再叠加在漫反射颜色上面就可以了。
二、 折射
如果需要折射,一般的做法是通过GrabTexture功能,抓取一张屏幕帧画面,然后对其进行扭曲。ASE也自带了这个节点。
需要注意的地方有几点:
1、 如果想完全用扭曲代替后面的画面,那么就不能用透明度混合,而要当他不透明物体渲染。不然会出现扭曲的画面和正常的画面同时出现。
2、 注意性能
GrabTexture是抓取当前帧的画面,性能其实不是很好的,如果不勾选CustomGrabPass,那么它就可能会抓取多次,性能就更不好了。
所以我们一定要勾选CustomGrabPass,这样它会每帧只抓取一次,然后赋予给这张指定名字的贴图,这样性能稍微会好一些。
3、 UV
所谓的对这张GrabTexture做扭曲,其实就是修改它的UV坐标而已。
获取当前的UV坐标,可以用GrabScreenPosition节点来做。然后通过各种手段,比如叠加噪声图、法线图来小范围改变UV坐标。等
关于这个反射和折射的问题,由于这个海面的例子没做,所以我之后再找另外的例子来说明吧。