URP中实现半透射材质
1 实现思路
1.1 Overview
- 我们不希望依赖于额外的深度图,以及模糊算法。因为这需要额外的内存占用与性能消耗
- 为了创建出可信的效果,在材质中行进的光线需要:
- 受到物体厚度的影响
- 其衰减效果能够受到视角的影响
- 计算简单
我们从简单的方向向量出发:
\[L_{Attenuation}(N\cdot L+V\cdot (-L))\]对于简单的形状(球体、立方体等)来说,这个式子可以模拟出基础的光线在物体内部的传播,因为它考虑到了光线radial diffusion的属性。
然而该方法未考虑厚度因素,对复杂模型视觉效果欠佳。要精确计算物体内部光传输,必须考量光线在物体内部传播的实际距离。虽然深度图能提供参考坐标系以计算光线从光源穿过物体到达像素的路径长度,但如前所述,我们需避免依赖额外深度图。
我们转而采用预计算物体局部厚度变化的贴图。如向Crytek《孤岛危机》的实时植被技术,美术师可通过纹理定义叶片厚度:暗色值表示不透明区域,亮色值表示半透明区域。该方案适用于树叶等半扁平表面,但在含有多样化半透明物体(如雕像)的场景中,手动标注模型各区域半透明属性是费力的流程。为此,我们采用法线反转的环境光遮蔽计算,通过离线烘焙存储为贴图。由于AO本质是计算表面点接收环境光的强度,反转法线后即可表征形体内部光传输强度,最终对形体内部所有光路进行均值化处理。
1.2 Computing Local Thickness
总结而言,在AO计算中反转表面法线,可近似模拟均质介质内部光线传播至表面出射点时的遮蔽程度。生成的倒色纹理呈现两种区域:白色半透明区与黑色不透明区。对于高精度曲面细分模型,该信息可存储在顶点色中(如Wii平台非寒霜引擎的某些实现)。最终光传输计算结果介于真实次表面散射与距离衰减之间:倒置AO提供光线收集的散射感,而单一距离值维持基础衰减特性。
1.3 What About Subsurface Scattering?
虽然我们的技术在模拟次表面散射的数学准确性上尚有差距,但由于局部厚度贴图支持彩色数值,仍能实现优质光传输效果。该彩色信息本质上表征了光线散射后表面”透射”的预计算颜色。这意味着只要大致知晓次表面散射带来的表面色彩变化,即可将其烘焙至该贴图。尽管数学层面不够严谨(远未达到[Hable09]等方案的精度),但只要能让表面呈现出次表面散射的视觉欺骗性,即可视为技术成功。
2 实现细节
2.1 Code
1
2
3
4
float3 adjustL = L + N * _Distortion;
float VdotNegateL = pow(saturate(dot(V, -adjustL)), _Power) * _Scale;
float3 translucency = lightAttenuation * (VdotNegateL + _Ambient) * _Thickness;
color.rgb += diffuseAlbedo * lightDiffuse * translucency;
2.2 Managing Data at Runtime
我们来分析一下上面这段代码中参数的作用
_Ambient
描述了从所有角度都可见的透射颜色,即允许光线穿透的最小恒定透光量,无论表面位于光源前方(前向透光性)或后方(后向透光性)均会生效。
_Power
针对视角相关后向透光性的幂衰减控制。虽然通常需要视角无关的效果,但该幂运算能通过视角依赖的方式打破光照连续性,破坏前/后向光照的均匀性,使渲染结果更具有机感。
_Distortion
第三个参数是扭曲值,用于根据表面法线对反转光源向量进行偏移。该因子模拟次表面光传输的畸变效应,增强效果有机感,甚至产生类菲涅尔现象。补充说明:无需对adjustL
向量归一化处理,因其与视线向量的点积结果被钳制在[0,1]区间,仅捕获背面透光(因使用-adjustL
反向向量),这正符合后向透光性的计算需求。
_Thickness
光传输由预先生成的局部厚度贴图进行调制,该贴图同时作用于前向透光与环境透光。此贴图会在物体”整体较厚”的区域对计算结果产生衰减作用。
_Scale
最终参数是直接透光性强度系数,该系数定义后向透光的穿光强度。该参数支持按光源独立调整,便于运行时微调效果。美术师可在材质层面设置核心反应参数(幂次/扭曲/环境光),再通过单系数全局控制各光源的透光强度。这种参数层级设计实现材质复用,跨场景应用时仅需调整单一强度值。