「UE5水材质」单层水着色模型的概念;如何用来渲染基于物理水面效果!...
Game艺视界原创文章原创 40217 0
实名

通过了实名认证的内容创造者

发布于 2023-7-10 16:20:03

您需要 登录 才可以下载或查看,没有账号?注册

x

水的基本流动原理非常简单,主要原理是利用UV动画来模拟水的流动。首先准备一张水波纹的法线贴图,使用Panner节点来制作UV动画。给X轴或Y轴一个合适de速度值,观察UV移动的速度
我们可以将水体渲染的要点总结为:漫反射(Diffuse)
镜面反射(Specular)
法线贴图(Normal Map)
折射(Reflection)
通透感(Translucency)

基于深度的查找表方法(Depth Based LUT Approach)
次表面散射(Subsurface Scattering)
白沫(Foam/WhiteCap)
流动表现(Flow)
水下雾效(Underwater Haze)

其中,漫反射,镜面反射,法线贴图,折射等都是比较常见的技术下文将对水体渲染的难点,通透感(Translucency),白沫(Foam/WhiteCap)渲染分别进行总结
关于水体通透感(Translucency)的表现方案,可以将业界主流方案总结为如下三个流派:LUT方法(Look-Up-Table Approach)
次表面散射近似方法(Sub-Surface Scattering,SSS Approximation Approach)
混合型方案。 即同时将LUT与次表面散射近似两种方案结合使用的方法。典型的例子如《刺客信条3》

2ff85f37cb95fcef8297dd6cc7d04294.jpg


#基于深度的查找表方法
(Depth Based LUT Approach)
Depth Based-LUT方法的思路是,计算视线方向的水体像素深度,然后基于此深度值采样吸收/散射LUT(Absorb/Scatter LUT)纹理,以控制不同深度水体的上色,得到通透的水体质感表现

26a75617304645ce6e93bf9cda222c76.jpg








其中,视线方向的水体像素深度值计算思路如下图中的蓝色箭头所示的橘褐色区间


图 蓝色箭头所示的橘褐色区间为视线方向的水体像素深度

#表面散射近似方法
(Sub-Surface Scattering Approximation Approach)
可用于水体通透感表现的次表面散射(Sub-Surface Scattering,SSS)的近似方案有很多种,这边推荐两种:[SIGGRAPH 2019] Crest Ocean System改进的《盗贼之海》SSS方案。
[GDC 2011] 寒霜引擎的Fast SSS方案



[SIGGRAPH 2019] Crest Ocean System改进的《盗贼之海》SSS方案经过Crest Ocean System改进的《盗贼之海》的SSS方案可以总结如下:假设光更有可能在波浪的一侧被水散射与透射
基于FFT模拟产生的顶点偏移,为波的侧面生成波峰mask
根据视角,光源方向和波峰mask的组合,将深水颜色和次表面散射水体颜色之间进行混合,得到次表面散射颜色
将位移值(Displacement)除以波长,并用此缩放后的新的位移值计算得出次表面散射项强度

对应的核心实现代码如下float v = abs(i_view.y);

half towardsSun = pow(max(0., dot(i_lightDir, -i_view)),_SubSurfaceSunFallOff);

half3 subsurface = (_SubSurfaceBase + _SubSurfaceSun * towardsSun) *_SubSurfaceColour.rgb * _LightColor0 * shadow;

subsurface *= (1.0 - v * v) * sssIndensity;

col += subsurface;其中,sssIndensity,即散射强度,由采样位移值计算得出

图 《Crest Ocean System》中基于次表面散射近似的水体表现



图 《盗贼之海(Sea of Thieves)》中基于次表面散射近似的水体表现



图 《盗贼之海(Sea of Thieves)》中基于次表面散射近似的水体表现

#白沫的渲染方案
白沫(Foam),在有些文献中也被称为Whitecap,White Water,是一种复杂的现象。即使白沫下方的材质具有其他颜色,白沫也通常看起来是白色的。出现这种现象的原因是因为白沫是由包含空气的流体薄膜组成的。随着每单位体积薄膜的数量增加,所有入射光都被反射而没有任何光穿透到其下方。这种光学现象使泡沫看起来比材质本身更亮,以至于看起来几乎是白色的


图 海洋中的白沫

对于白沫的渲染而言,白沫可被视为水面上的纹理,其可直接由对象交互作用,浪花的飞溅,或气泡与水表面碰撞而产生白沫的渲染方案,按大的渲染思路而言,可以分为两类:基于动态纹理(dynamic texture)
基于粒子系统(particle system)

按照类型,可以将白沫分为三种:浪尖白沫
岸边白沫
交互白沫

#流动表现

流型图(Flow Map),也常被称为矢量场图(Vector Field Map),本质上是一种基于矢量场平移法线贴图的着色技术,或者可以理解为一种UV动画,由VALVE的Vlachos在SIGGRAPH 2010上的talk《Water Flow in Portal 2》被大众所熟知。值得一提的是,VALVE在2010年就超前地使用了Houdini来制作flow map



Flow Map除了用于水体的渲染以外,任何和流动相关的效果都可以采用Flow Map,如沙流,以及云的运动等效果


图 基于Flow Map的水体渲染 Unity




图 基于Flow Map的水体渲染 UDK

Flow Map的核心思想是预烘焙2D方向信息到纹理,以在运行时基于UV采样,对流动感进行模拟



以上内容引用知乎《真实感水体渲染技术总结》致敬作者
完整版:https://zhuanlan.zhihu.com/p/95917609

# UE单层水着色模型 #介绍单层水材质着色模型的概念,以及它是如何用来渲染基于物理水面效果
单层水(Single Layer Water) 材质着色模型是一种借助单深度层来提供高效半透明方法的材质。这是一种基于物理的着色模型,支持适当的光散射、吸收、反射和折射以及水面阴影





#单层水的实现单层水着色模型使用自定义渲染通道来实现透明效果,可以在使用不透明(Opaque) 或 遮罩(Masked) 等混合模式时实现。材质的半透明在基础通道和延迟光照之后运行,但先于常规半透明渲染、后期处理以及渲染管道中的其他所有内容

单层水着色是一种包含参与介质的均匀体积,使用了散射和Schlick相函数,并受不透明或遮罩水表面的影响。表面的透明度隐含在体积着色模型中。折射也由体积函数处理,它在扭曲示例之前会读取表面下方的深度和颜色

在材质编辑器中,Single Layer Water Material 节点有四个输入:散射系数、吸收系数、PhaseG和水后色度。这些输入将定义水的外观。主材质节点的不透明度(Opacity) 输入将处理水的半透明度,从而控制体积的双向散射分布函数(BSDF)和表面的双向反射分布函数(BRDF)之间的比率


你可以使用RenderDoc执行帧捕获,以便你查看GPU捕获中单层水通的发生位置。当使用单层水通道时,BasePass已经渲染和点亮。完全点亮的场景和深度将用作单层水通道的输入,读取缓冲区,即如何为不透明或遮照材质实现折射和半透明


在进行列表中的第一项之前,你可以使用可选步骤下采样折射读取的场景颜色和深度缓冲区。这样可以加快渲染速度,但会使渲染在水面以下的对象外观略微模糊(或分辨率低)


1.所有带有SingleLayerWater的对象都使用用户定义的材质渲染到GBuffer(包括深度)中
2.运行计算着色器,根据GBuffer中的MaterialID对所有SingleLayerWater进行平铺分类
3.生成的屏幕图块用于间接绘制屏幕空间反射(SSR)通道,该通道运行并输出到单独的缓冲区
4.生成的屏幕图块再次用于运行间接绘制全屏通道,以便合成反射捕获、天空和水面上新计算的屏幕空间反射


#单层水低端系统和移动支持
对于低端系统和平台(例如移动设备和低端桌面),会使用替代渲染路径,跳过单层水的某些功能,以便提高性能。最简单的替代方法是,将材质还原为简单的半透明材质,没有体积积分或屏幕空间反射


创建材质时,在 细节(Details) 面板中设置以下内容


混合模式:不透明(Opaque) 或 遮照(Masked)
着色模型:SingleLayerWater


将 Single Layer Water Material 输出节点添加到材质图表。此输出表达式就光散射和吸收、各向异性或各向同性方向性(PhaseG)以及水面下表面上的颜色效果(例如焦散和阴影)定义了水的外观。



#散射系数 (scattering coefficients)
散射系数 输入表示光在介质中的粒子(在本例中为水)上散射的速率。介质中发生的光散射量决定了介质中对象的光和颜色的情况。当穿过介质(如玻璃或一瓶水)的散射量较小时,介质看起来透明。光不会在介质中散射那么多,从而使光更容易穿过。在大量散射的情况下,光散射更多,从而阻止其穿过介质。这会导致介质看起来更浑浊或更不透明,如橙汁或牛奶


散射量会影响光在介质中的传播方式,并直接影响对象在其体积内时物体的外观。例如,介质中有三个立方体(红色、绿色和蓝色),并且材质设置为仅散射蓝光,请注意与没有散射的材料(右)相比,散射的蓝光如何影响所有立方体的颜色(左)



将此概念应用于默认的水材质,请注意与完全没有散射相比,应用一定散射量时的外观。当没有散射时,光不会以相同的方式反射或分散,因此立方体的可见位置比光散射时更深



散射量越高,水看起来就越浑浊。光在介质中散射得更多,对象就下沉得越深,就越难看到它们。下面的示例演示了具有不同数量的光散射的效果,从较低的数量到非常高的数量渐进,然后到完全无法看到表面之下的立方体



#吸收系数
吸收系数输入定义了光穿透水(或参与介质)体积的难易程度。每个颜色通道(RGB)或光的波长以不同的方式穿透水,有些穿透性会更好。当光被它所穿过的介质吸收时,就会消光,这意味着失去颜色。对象越是深度进入吸收系数高的介质,其颜色消散的可能性就越大

吸收系数将控制哪些颜色的光在介质中可能被更快地吸收。小系数允许光轻松穿过介质,使外观更透明。当光源穿过介质时,大系数会更快地衰减光,使其看起来不那么透明
下面的示例显示了三个立方体(红色、绿色和蓝色)移动到介质中更深的地方。当对这些原色(红色 = 0.0033、绿色 = 0.0016、蓝色 = 0.0011)使用中等吸收系数时,结果显示了每种颜色在深入介质中时如何消散。首先红色消失,然后是绿色,最后是蓝色



使用与上述相同的值和设置以及默认水材质,三个原色立方体在浸入水中并向下深入时都会失去颜色。它们的颜色以相同的顺序消失



TIP

使用默认水材质时,吸收系数值反向。值越大,颜色消失得越快。光穿过体积的距离用米的倒数表示,即1除以材质中的吸收距离。
采用的距离设置如下所示:



#PhaseG函数
PhaseG 参数将控制光在水中散射的整体向前或向后方向。更具体地说,该参数将控制散射光相对于太阳方向的各向异性方向性
PhaseG可以为正值或负值,其中正值会增加向(向前)太阳散射的光量,负值会增加从太阳(向后)散射的光量。根据当前视图和太阳在天空中的位置,这可以使水看起来更亮或更暗


当PhaseG值为0时,它的光方向性是各向同性的,这意味着光在所有方向上的散射都相同
该相位函数使水的形状更明确,尤其是存在波浪时。这是因为在发生折射后,传播会改变方向,从而增加了通过水散射的光量变化


#水下的色度
水下的色度输入将增加水下表面的亮度。这种类型的效果可用于你的材质中,能驱动焦散或阴影的明暗程度
下图的对比展示了水下表面的可见焦散


这就是材质的视觉效果,在水材质上方可见。在水面下方移动不会改变水下表面的亮度,也不会在这些表面上实际投射焦散或阴影


#水不透明度
当通过材质设置使用单层水时,主材质节点上的不透明度(Opacity) 输入将控制水的可见参数。不透明度的量将控制允许进入体积和散射的光量。它还将控制你可以通过体积看到多远。不透明度值越大越不透明,不允许光线穿透表面。较低的值允许所有光线穿过表面,因此你可以看到水中更远的距离


如果不透明度低或没有不透明度,还允许单层水材质输出表达式的其他属性不受阻碍地运行。在下表中,水材质的不透明度值为没有、部分或最大允许有全部、部分光或没有光通过体积。完全不透明材质(不透明度 = 1)看起来是黑色,因为不允许光线通过表面散射到水中


以上内容引用UE官方文档
https://docs.unrealengine.com/4.27/zh-CN/RenderingAndGraphics/Materials/MaterialProperties/LightingModels/SingleLayerWater/想要更全面使single layer water发挥作用
①水面下场景需要更复杂一些,水下地形或者植物岩石等环境,才能更好的表现透射②光照环境:如日出日落,月夜或者说24小时的天气切换,更好的表现水的散射效果③具有波浪效果的顶点形变,能更好的观察到水体透光。一个大平面+平整的地形,并且只有固定方向的直射阳光,和简单的法线波纹,如果是这样环境半透也可以描述所需要的效果案例分享



创建水材质球



设置为单层水材质Single Layer Water Material
①通常PhassG设置为-0.1(个人使用)

②镜面反射;粗糙度;透明度



③我将使用像素深度,用反射除以我们的距离,我们将设置它为5000;然后使用钳制(限制)节点



④使用线性插值,这是最大与最小折射链接如折射




⑤水散射与吸收;除以水吸收颜色;然后除以我们的 alpha 我们在这里调用强度

⑥乘以颜色除以1000

⑦ 一个进入散射;一个进入吸收




设置吸收



设置散射




#添加水面法线

创建全局UVS控制;
添加UV坐标;为这个全局平铺乘以一个常量(调整uvTiling);为速度我们需要两个分量速度x,速度y



我们使用一些引擎函数制作法线扰动



#噪波制作(避免我们水面很平)

找一张纹理噪波贴图;使用全局UV然后乘以常量;乘以定点法线并且要偏移;然后减去偏移量;使用顶点着色翻转绿通道相乘



#泡沫制作
找一张泡沫纹理;制作Tiling;流速;最后连接入颜色
同时要将粗糙度、法线、透明度合并到相应通道中



较简单水效果







延申阅读知乎👉:
https://zhuanlan.zhihu.com/p/627027935
本期笔记分享就到这里,我们下期见!

评分

参与人数 3元素币 +19 活跃度 +12 展开 理由
swatlyh + 6 + 5 千点万点,不如微元素指点。
龙哥Longer... + 8 + 3 这就是大佬的世界嘛
asx24 + 5 + 4 这就很元素了

查看全部评分

本帖被以下画板推荐:

微信公众号:Game艺视界
使用道具 <
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表