Unity URP管线Linear空间丝绸材质

效果展示

丝绸

简介

在 URP 中实现丝绸材质:各向异性 GGX + 织纹微法线 + Fuzz 边缘绒光的线性工作流实践

丝绸的真实感之所以难做,本质原因不在"颜色像不像",而在于它的高各向异性高光织物结构导致的微观法线扰动 、以及视角相关的绒毛散射(fuzz / sheen)。传统的金属度/粗糙度 PBR 模型偏向各向同性(isotropic)表面,直接用在丝绸上通常会得到"塑料布"的观感:高光不成条带、缺乏经纬纹理的闪烁(glint),更没有丝织物特有的柔和边缘亮。

本文基于一个 URP ForwardLit 自定义 Shader(Custom/SilkPBR_Linear),拆解其核心结构:各向异性 GGX BRDFThread Map 驱动的织纹微结构Roughness 变异与闪烁增强 、以及 Fuzz 对镜面项的抑制 ,并重点讨论线性/伽马空间处理对最终外观与能量一致性的影响。

总体
图中渲染的是各向异性高光,呈环形,在头发渲染中又称为"天使环",这里使用的光照模型是Kajiya-Kay Model。在很多游戏中,头发渲染都使用了Kajiya-Kay Model
结构:在 URP Forward Pass 里手写 PBR

该 Shader 使用 URP 的 Core.hlsl / Lighting.hlsl / GlobalIllumination.hlsl,但并没有直接调用 URP 的 UniversalFragmentPBR,而是自己计算:

  • 主光/附加光的直接光照(Direct)
  • SH 的漫反射环境光(Diffuse GI)
  • Reflection Probe 的镜面环境反射(Specular GI)
  • AO 在 GI 混合阶段进行整体调制

这类结构的好处是:你可以对丝绸这种"非标准材质"插入更多艺术/物理混合项(如 thread glint、fuzz 权重等),而不受标准 Lit 限制。

核心算法

  • BaseMap + BaseColor:基础反照率(漫反射颜色)。
  • NormalMap + NormalScale:法线扰动(宏观形状起伏)。
  • RoughnessMap(R) + Roughness:感知粗糙度(perceptual roughness)。
  • ThreadMap(RGB):织纹结构图(既用来"改变粗糙度",也用来"做高光 glint"与"微法线扰动")。
  • OcclusionMap(R) + Occlusion:AO 乘到 GI(间接光)上。
  • Specular + SpecTint:镜面 F0 的强度与颜色(丝绸会偏有色高光)。
  • Aniso + AnisoRotation:各向异性强度与方向旋转(决定高光拉伸方向)。
  • FuzzMap(R) + FuzzStrength :绒毛遮罩,主要用来削弱镜面(布料的"雾化/绒感")。
核心 BRDF:各向异性 GGX(Anisotropic GGX)
复制代码
float D_GGX_Aniso(float3 N, float3 H, float3 T, float3 B, float ax, float ay)
{
    float NoH = saturate(dot(N, H));
    float ToH = dot(T, H);
    float BoH = dot(B, H);
    float denom = (ToH*ToH)/(ax*ax) + (BoH*BoH)/(ay*ay) + NoH*NoH;
    return 1.0 / (PI * ax * ay * denom * denom + 1e-6);
}

这里的 ax/ay 本质是在切线 T 与副切线 B 两个方向上使用不同的粗糙度,从而把高光"拉长"。

aspect = sqrt(1 - 0.9 * abs(aniso)) 用于把标量粗糙度 alpha 拆成 ax/ay,并允许 aniso < 0 时交换轴向(把条纹方向旋转 90°),这在"经纬交错"的丝织物调参时很实用。

它用的是各向异性版本的微表面模型:

  • 法线分布函数 D: D_GGX_Aniso(N,H,T,B, ax, ay)
    用切线 T/副切线 B 两个方向不同的粗糙度(ax, ay)让高光沿某方向拉长。
  • 几何遮蔽项 G: G_Smith_Aniso(...)
    Smith 形式的各向异性遮蔽。
  • 菲涅尔 F: F_Schlick_coat(F0, VoH)
    Schlick 近似:F = F0 + (1-F0)*(1-VoH)^5

镜面项大体是:

复制代码
float3 spec = (D * G) * F / max(1e-4, 4.0 * NoV * NoL) * NoL;
各向异性参数如何来?
复制代码
先把 roughness 转成 alpha = perceptualRoughness^2
用 _Aniso 计算一个 aspect,再得到:
ax = alpha / aspect
ay = alpha * aspect
_AnisoRotation 会旋转 T/B,用来控制"丝绸高光走向"。
织纹 ThreadMap:做了三件事(这就是"丝绸味道"的关键)
A. 织纹驱动粗糙度变化(让明暗更"布料")
复制代码
threadH = average(threadRGB)
roughVar = (threadH*2-1) * _ThreadRoughnessVar
perceptualRoughness = roughMap*_Roughness + roughVar

效果:织纹亮/暗会让局部更光滑/更粗糙,形成织物不均匀反射

B. 织纹导向的"glint"闪点增强(丝绸常见的亮丝)
复制代码
glint = pow(threadH, 6)
spec *= (1 + glint * _ThreadDirStrength)

效果:threadH 高的地方高光更"闪"、更集中,模拟丝线反射。

C. 用 thread 的屏幕导数做"微法线扰动"(假装有细小凹凸)
复制代码
dhdx = ddx(threadH); dhdy = ddy(threadH);
N = normalize(N + (-dhdx*T0 - dhdy*B0) * microStrength);

这一步很关键:它不是普通 normal map,而是把 threadH 当高度,用屏幕空间导数近似高度场梯度,给法线增加微小扰动,让高光更碎、更像纤维织纹。

绒毛 Fuzz:主要在"压镜面",让布料更柔
复制代码
fuzzMask = fuzzTex * fuzzStrength
specWeight = lerp(1, 0 or 0.75, fuzzMask)
spec *= specWeight
  • 主光:lerp(1, 0, fuzzMask)(压得更狠)
  • 附加光/环境反射:lerp(1, 0.75, fuzzMask)(压得没那么狠)

直观结果:越"绒"的区域镜面越少、越像布面泛白/柔和。

光照合成:主光 + 多灯 + GI(SH漫反射 + 环境镜面)
  • 直射光 :对每个灯计算
    • 漫反射:diff = (1-F) * albedo/PI * NoL
    • 镜面:各向异性 GGX spec,再叠加 glint、silkSpecBoost、再被 fuzz 抑制
  • 间接漫反射SampleSH(N) * albedo
  • 间接镜面GlossyEnvironmentReflection(R, perceptualRoughness) 再乘 Schlick(F0, NoV)
  • AO:只乘到间接项(diffuseGI+specGI)上

申明

因涉及知识版权等原因,无法上传源材质 请凉解!!!

相关推荐
格林威21 分钟前
Baumer相机玻璃制品裂纹自动检测:提高透明材质检测精度的 6 个关键步骤,附 OpenCV+Halcon 实战代码!
人工智能·opencv·视觉检测·材质·工业相机·sdk开发·堡盟相机
心疼你的一切1 小时前
Unity异步编程神器:Unitask库深度解析(功能+实战案例+API全指南)
深度学习·unity·c#·游戏引擎·unitask
呆呆敲代码的小Y3 小时前
【Unity 实用工具篇】 | Book Page Curl 快速实现翻书效果
游戏·unity·游戏引擎·u3d·免费游戏·翻书插件
AC梦16 小时前
unity中如何将UI上的字高清显示
ui·unity
top_designer1 天前
Materialize:手绘地表太假?“PBR 纹理炼金术” 5分钟生成次世代材质
游戏·3d·aigc·材质·设计师·游戏美术·pbr
小贺儿开发1 天前
Unity3D 智慧城市管理平台
数据库·人工智能·unity·智慧城市·数据可视化
June bug2 天前
【领域知识】休闲游戏一次发版全流程:Google Play + Apple App Store
unity
星夜泊客2 天前
C# 基础:为什么类可以在静态方法中创建自己的实例?
开发语言·经验分享·笔记·unity·c#·游戏引擎
dzj20212 天前
PointerEnter、PointerExit、PointerDown、PointerUp——鼠标点击物体,则开始旋转,鼠标离开或者松开物体,则停止旋转
unity·pointerdown·pointerup
心前阳光2 天前
Unity 模拟父子关系
android·unity·游戏引擎