|
先来一个效果图,看起来其实有点卡通。
以前我曾经写过一个利用视差映射实现的云海,效果不错,但是在平视的时候就露馅了,因为毕竟只是个片而已。利用模型顶点便宜就是来解决这个问题。
方法是看的Roman Papush大神的一个视频,过程还是很简单的,链接在这,不过需要科学上网。他是用shadergraph连出来的,这里我们还是用代码生写好了。
https://www.youtube.com/watch?v=Y7r5n5TsX_E
首先,我们需要一个合适的模型,上图展示了模型的细化过程,这种布线方式更加均匀,不论从哪个方向拉伸顶点,都不会有太明显的变形。你可以试试用标准横平竖直的布线,差别很明显。按这种方式细化下去,最后我选择了两个级别,一个24000面的 一个90000多面的,最后我会都放进测试工程里,大家可以对比看看,有点差距,但不是那么明显,手机上用一个两万多的面足够了。
接下来进入shader。
原视频中用了shadergraph自带的noise生成,这里我自己找了一张图,其实并不是那么合适,大家可以自己再找找有没有更合适的,原则上要足够平滑,云嘛,总是很丝滑的,如果图片黑白变化太大,你会发现,云波动的时候会有抖的现象,我这个图就有一点。- v2f vert (appdata v)
- {
- v2f o;
- //用两个方向获取噪波图的运动
- o.CloudUV01 = v.uv + _Time.x* _Speed;
- o.CloudUV02 = v.uv - _Time.x* _Speed;
- o.noisePos.x = tex2Dlod(_NoiseTex, float4(o.CloudUV01, 0, 0)).r;
- o.noisePos.y = tex2Dlod(_NoiseTex, float4(o.CloudUV02, 0, 0)).r;
- o.worldPos = mul(unity_ObjectToWorld, v.vertex);
- o.vertex = UnityObjectToClipPos(v.vertex);
- //让云的Y轴扰动起来
- o.vertex.y += o.noisePos.x* o.noisePos.y * _Height ;
- //以中心开始 将圆变成一个碗的形状,因为边缘太低,可能会露出一些不必要的场景。
- o.vertex.y -= pow(distance(float2(0, 0), o.worldPos.xz) / _DcurvatureRadius, 3);
- o.screenPos = ComputeScreenPos(o.vertex);
- UNITY_TRANSFER_FOG(o,o.vertex);
- return o;
- }
复制代码 这里是顶点函数,一开始我们先采样了两遍云的贴图,运动方向相反,然后乘到一起,目的就是增加随机感,做过海水扰动的应该都能明白,然后把这个扰动乘以一个可调节的参数再给到模型的Y轴上,这样云的模型就动起来了,非常简单对吧。
接下来的Y轴又加了一个算法,就是利用平面顶点的距离来抬高Y轴,这样可以让云的模型变成一个碗状,如下图
图上弯曲的有点过分,演示而已,目的就在于可以隐藏一下边界,否则天际线看起来过于平并且过于低,具体高度可以根据自己场景需求来调节。- fixed4 frag(v2f i) : SV_Target
- {
- //采样摄像机深度图
- float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, (i.screenPos));
- float depth = LinearEyeDepth(depthSample);
- float borderLine = saturate((depth - i.screenPos.w)/2 - _DepthBiasFactor);
- //获取遮罩图
- float mask = saturate(i.noisePos.x * i.noisePos.y);
- //利用噪波图来融合顶底两个颜色
- float4 col = ( _TopColor*mask) +(_BottomColor *(1-mask));
- //设置与物体交接的地方透明
- col.a = borderLine;
- // apply fog
- UNITY_APPLY_FOG(i.fogCoord, col);
- return col;
- }
复制代码 上面是片元函数,一开始我们先采样了一下相机的深度图,用来检测是不是与模型有交叉,从而实现边界透明的效果。跟海水的岸边,浪花是同样的方法。
嗯,看上去顺眼多了。
接下来我又重新获取了噪波图的高度(也就是亮度),把它当作遮罩融合了两个高低的颜色,来做最终输出。下面是我用两个极端颜色来展示的。
这样基本就大功告成了,如果想要效果更好一些,可以再加一张不同纹理的燥波图,不同大小的纹理叠加起来效果会更好,这里我就不展示了。
工程里高模和低模都有,大家可以自己看看差别。
MeshCloud.unitypackage
4M
· 百度网盘 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|