关于开源项目介绍:HDRP-Water-云影

6次阅读

共计 3178 个字符,预计需要花费 8 分钟才能阅读完成。

【博物纳新】专栏是 UWA 旨在为开发者 举荐新鲜、易用、乏味的开源我的项目 ,帮忙大家在我的项目研发之余发现世界上的热门我的项目、前沿技术或者令人惊叹的视觉效果,并摸索将其利用到本人我的项目的可行性。 很多时候,咱们并不知道本人想要什么,直到某一天咱们遇到了它。

明天举荐的两个我的项目来自 UWA 开源库:
1)HDRP Water
2)云影

01 HDRP Water

ShaderGragh 是继 2018 版之后呈现的一种针对 Shader 的可视化编程工具,通过在 ShaderGragh 面板中编辑各种成果模块的连贯形式,能够实现不同的成果。该工具将编辑 Shader 代码的操作简单化和可视化,也进步了 Shader 的编辑效率。

该我的项目是通过 ShaderGragh 制作的简略水面着色器。通过对该项目标学习,读者不仅能够对该工具有初步的意识,还能够对水面的实现原理有所理解。

一、原理概述

该我的项目从原理上能够划分为三局部:顶点稳定、法线流动和边缘着色。

  1. 顶点稳定:该局部次要计算通过 3 个参数各不相同的波叠加之后,立体上各个顶点的纵向位移法则。
  2. 法线流动:顶点的法线信息是通过法线贴图获取的,通过管制法线贴图的 UV 坐标偏移来实现水面的流动成果。
  3. 边缘着色:该局部次要通过深度图检测水面边缘,而后在边缘处加上了色彩突变成果。

二、具体实现

1. 顶点稳定
在渲染管线中,对顶点的编辑通常会放在顶点着色器(下图中的 Vertex 模块)中:
<

图中顶点着色器次要就是在计算 Position,而从上半局部可知,可控输出包含 3 个波的波长、波速和振幅。

关上上图的 3WaveGenerator,能够发现这三个作为输出的波的解决形式简直雷同,只不过每局部对应的参数稍作变换,目标是使得三种波之后的叠加防止谐振,从而让最终叠加后的波形显得更加天然。拿其中一个波来看,能够看到只有波的 x 和 z 值参加了计算(如下图),因为这里要先模仿水波的横向流传局部:

之后,通过乘上工夫参数产生实时偏移,来模仿波在 xz 面上的流传,也就是最终水波的流动成果:

然而咱们晓得,波的横向流传并不是真的把波上的某个顶点随着波的流传方向“运送”过来,其作用的只是顶点在纵向的振动地位而已。所以这里计算顶点的 x 和 z 归根结底是为了算纵坐标,这里通过正弦函数求得:

并且三个波通过计算而叠加之后,作用的也只有模型上各点的纵坐标而已:

但咱们要晓得该纵坐标是蕴含了波的流传个性的,因为它是依据 x、z 坐标和工夫算进去的。所以此时如果观看模型,它曾经能够稳定,且参加叠加的波越多、差异越大,稳定就会越天然,不过因为法线信息尚未更新,因而远处的顶点是看不出起伏状态的(如下图)。

2. 法线流动
之所以称顶点为“稳定”,法线为“流动”,是因为顶点只是在纵轴上静止,而法线贴图是在程度方向静止。而贴图的“流动”,其实就是对贴图采样点的定时偏移。其次要局部如下图:

值得一提的是该 Shader 同时输出了两张法线贴图(如下图)。其中第一张法线贴图描述的比拟平缓、平稳(下图左),旨在塑造波长较大的水波,而第二张贴图比拟轻微、柔和(下图右),旨在塑造细小的波纹:

个别状况下,水面的法线贴图是须要有两张的,因为这样能够塑造出不同波长的水波相互干预的场景。下图为单张法线贴图输出(左)和两张法线贴图输出(右)的效果图,能够看进去左边的水面描述了更多细小的波纹。

3. 边缘着色
边缘须要通过深度来判断,下图中,下面的框是在拿以后点的深度,上面的框是在计算以后点对应的像素在深度图中的深度:

这里用两个深度的差将作为边缘色的分母进行除法(下图中 Divide 局部),那么能够晓得只有深度差比拟小的时候能力显现出边缘色,也合乎事实中“靠近边缘才会显著变色”的状况。最初通过 Clamp 把色彩限度在正当范畴:

下图别离是增加了边缘着色(左)与不增加(右)的成果,可见增加该性能会让场景变得更丰盛、实在。

02 云影

在以自上而下视角为主的游戏(策略或建设类)中,云影是比拟常见的性能。通过管制其形态、挪动等各种参数,能够真切地反映出天气的变动,这对游戏场景的视觉效果及氛围衬托都起到了比拟重要的作用。

本篇的 Unity Cloud Shadows 就是一种动静、高效的云影工具,不仅能够很不便地调节云影的多种参数,也不会对性能造成很大压力。

一、原理概述

该工具的实现次要依附的就是光源的 Cookie 性能。官网解释:“如果创立蕴含 Alpha 通道的纹理并将其调配给光源的 Cookie 变量,则会从光源投射掠影。掠影的 Alpha 遮罩会调制光源亮度,从而在表面上产生亮点和暗点。这是场景减少复杂性或气氛的好办法。”

该性能的地位如下:

二、具体实现

当使用光源的 Cookie 时,即便场景中没有物体,Frame Debugger 中也会呈现下图中 <unknown scope> 下的 Draw Dynamic,而 Draw Dynamic 就是在画云影,也就是下图中的噪声图:

图 1:Frame Debugger

而后,咱们来看一下 CloudShadows.cs。其实最外围的就是 RenderCloudShadows 这个函数,从它的 Blit 函数中咱们能够看到,在每一个云层所属的 for 循环中,有且只有一个 Pass 会被执行:

图 2:RenderCloudShadows 函数(from CloudShadows.cs)

那具体是怎么被渲染的呢,咱们看这个材质球的 Shader,也就是 CloudShadows.shader,几种 Pass 工整排列(如下图),别离对应上图红框中不同的混合模式,当然这个混合模式是能够从内部间接抉择的。

图 3:不同混合模式对应的 Pass(from CloudShadows.shader)

几个 Pass 次要是从片元着色器作了辨别,下图以 FragSubtract 类型的片元着色器举例。从图中能够看到,咱们只在乎 a 通道的后果,这是因为 Cookie 性能只会辨认指标 Texture 的 a 通道。

图 4:FragSubtract 函数(from CloudShadows.shader)

这一点也能够在 Frame Debugger 中失去体现,只有点击下图中的 a 通道时,Game 窗口才会显现出图像,而其余通道不会让 Game 窗口显出内容:

图 5:Frame Debugger 中 Draw Dynamic 的 a 通道

该工具提供了许多种云影的预制体,不过每种预制体的差异其实就是下图右侧的三种模式的调节办法不同而已。咱们能够看到调节形式次要有三种:混合设置(叠加、差值等)、云层设置(速度、方向等)和贴图设置(噪声图抉择等)。

图 6:该工具的预制体

该工具的用法其实并不局限于噪声图,按照 Cookie 的个性,任何有通明通道的 Texture 都能够被附在该工具上,而后进行叠加、挪动等,用法比拟灵便。效果图如下:

图 7:整体效果图

三、Tips

看图 2 的 309 行,其实全篇始终都有两个 RT:m_RenderTexture1 和 m_RenderTexture2,并且 312 行还要替换一下两个 RT 的援用,为何呢?

其实只是在配合 Blit 函数,它须要有两个 RT 作为输出,所以咱们不得不多创立一个作为“替补”,这也就是为何在下图中,每次都只须要重置 m_RenderTexture1 了,毕竟咱们只须要操作一个,因为只须要一个 RT 传给 Cookie。

图 8:每次只重置 m_RenderTexture1(from CloudShadows.cs)

四、性能剖析

通过 UWA GOT Online 在低端机型光荣畅玩 9A(4GB RAM)上进行了性能测试后,失去了下图的 FPS 曲线,其中两头凹陷处是开启了云影性能的时刻。

图 9:FPS 曲线图

能够看出云影开启之后,FPS 均值放弃在原来程度,而当咱们看具体堆栈,代码层面减少了插件中的 CloudShadows.Update,不过耗时很低,大概 0.7ms:

图 10:CPU 耗时曲线图

该插件是一个轻便又简略的插件,值得一试。

正文完
 0