雪地痕迹效果Shader

Posted by Nathan on August 27, 2021

雪地痕迹效果Shader

Demo

引言

最近随着黑神话:悟空预告片的大火,随之引起关注的就是它惊人的雪地物理效果。这篇文章小小的蹭一下热度,简单的讲一下最近所学,雪地轨迹shader。

技术原理

曲面细分

我们的轨迹痕迹shader主要用到了Tessellation(曲面细分)技术。曲面细就如它的字面意义一样,我们通过编写shader,将一个多面体分成多个多面体。就像这个示例图一样。我们可以通过曲面细分技术把一个正方体逐渐转换成一个球体。

读到这里,读者可能会觉得曲面细分和我们要做的痕迹效果并没有什么关系,实际不然,曲面细分是我们做雪地痕迹效果的前置。因为我们要对平面的多面体进行操作来实现痕迹的效果,所以我们需要较高多面体的平面作为我们的操作对象。然而一般的平面并不具有那么多的多面体,所以我们此时需要先对平面进行曲面细分,这样我们才能实现更加真实的痕迹效果。

读者可以看一下下面这张图片,左边是未细分的平面,右边则是已经细分的平面。相比大家可以清楚的看到两者多面体数量的巨大的差别。

曲面细分

讲完了曲面细分的用处,接下来讲一下如何实现轨迹的效果。实际上原理上来讲很简单,也就是我们会给shader传一个texture,这个texture会标记当前的轨迹,然后我们的shader根据轨迹的uv进行平面顶点的向下位移,这样就实现了轨迹的效果。

这一张图就是刚刚讲的原理的一个例子,左图是一张记录了轨迹的texture,右图是根据轨迹texture生成的轨迹。

轨迹

代码实现

项目下载:https://github.com/moecia/UnityShader/tree/main/Assets/SnowTrack

限于篇幅这里仅介绍一下每个代码的作用,就不在本文中放源代码了。读者可以在上面的链接找到代码和完整项目。

SnowTrack.shader 这个代码是基于Unity Distance-based tessellation修改的代码。代码会让平面根据Track texture中红色的部分进行向下的displacement,以达到显示轨迹的效果。

DrawTracks.shader 这个代码主要是用于Track map的生成,这里需要和DrawTracks.cs 或 WheelTracks.cs结合来实现track map的实时绘制。

WheelTracks.cs 根据车轮在平面的位置绘制轨迹。

DrawTrack.cs 根据鼠标在平面的点击位置来绘制轨迹。

SnowFall.shader 这部分代码用于对Track Map Texture进行修改,通过随机在Map上覆盖红色轨迹来达到填充雪地的效果。需要和SnowNoise.cs共同使用来实现实时雪地填充。

SnowNoise.cs 获取Track Map并根据SnowFall.shader的逻辑来实时填充Track Map,以达到需额滴填充的效果。

参考资料

Unity曲面细分: https://docs.unity3d.com/2018.4/Documentation/Manual/SL-SurfaceShaderTessellation.html