Unity Shader 实战:从零掌握 PBR 基于物理的渲染
一、什么是 PBRPBRPhysically Based Rendering基于物理的渲染是现代游戏、影视行业的主流渲染方案。与传统的 Blinn-Phong 光照相比PBR 的核心区别在于对比项传统光照Blinn-PhongPBR材质参数高光颜色、高光强度艺术调整金属度、粗糙度物理可测量能量守恒❌ 无保证✅ 严格遵守跨光照一致性❌ 不同环境需重调✅ 任何光照下表现正确效果上限中等照片级真实感PBR 广泛应用于《赛博朋克2077》《艾尔登法环》《战神》等 AAA 大作以及 Unity、Unreal、Blender 等主流引擎的默认材质系统。一句话理解PBR 是用物理规律约束美术行为——只要参数符合现实材质在任何光照环境下都自然正确。二、PBR 的三大核心条件一个渲染系统要称得上 PBR必须同时满足以下三条① 微表面理论Microfacet Theory宏观上看起来光滑的表面微观上由无数朝向各异的**微小镜面微平面**组成。粗糙表面高 Roughness 光滑表面低 Roughness ↗↘↗↙↗↘↗↙ → → → → → → 微平面朝向分散 微平面近乎平行 → 高光模糊、分散 → 高光锐利、集中**粗糙度Roughness**参数控制微平面的分散程度Roughness 0完美镜面高光极小极亮Roughness 1完全漫反射无明显高光② 能量守恒Energy Conservation反射出去的光能 ≤ 接收到的光能不能无中生有。入射光 漫反射 镜面反射 吸收 1.0 kD kS 损耗实现方式hlsl复制float3 F FresnelSchlick(HdotV, F0); // 镜面反射比例 float3 kS F; float3 kD (1.0 - kS) * (1.0 - metallic); // 漫反射 1 - 镜面 // 金属材质无漫反射metallic1 → kD0③ 基于物理的 BRDF使用符合物理规律的双向反射分布函数描述光照交互详见下一章。三、核心数学Cook-Torrance BRDFBRDFBidirectional Reflectance Distribution Function双向反射分布函数定义了入射光在某观察方向上被反射的比例。PBR 中最常用的是Cook-Torrance BRDFD(h) · F(v,h) · G(l,v,h) fr(l, v) kD·------ ───────────────────── π 4·(n·l)·(n·v) 漫反射项Lambert 镜面反射项Cook-Torrance其中D、F、G三项各司其职3.1 D —— 法线分布函数GGX描述有多少微平面的法线朝向了半角向量 h决定高光形状。GGXTrowbridge-Reitz是当前工业标准hlsl复制float DistributionGGX(float NdotH, float roughness) { float a roughness * roughness; float a2 a * a; float NdotH2 NdotH * NdotH; float denom (NdotH2 * (a2 - 1.0) 1.0); return a2 / (PI * denom * denom); }为什么用 roughness²直接用 roughness 线性值时高光变化不自然平方后符合人眼感知的线性变化。GGX 相比老牌的 Beckmann 分布优势在于**长尾效应**高光边缘有更自然的渐隐非常接近真实金属质感。3.2 F —— 菲涅耳方程Fresnel描述不同入射角下镜面反射率的变化——观察角越斜反射越强。生活中随处可见菲涅耳效应正视水面看到水底侧视水面看到倒影。垂直观察grazing 0 掠射观察grazing 90° 反射率 ≈ F0基础值 反射率 → 1.0几乎全反射使用Schlick 近似高效计算hlsl复制float3 FresnelSchlick(float cosTheta, float3 F0) { return F0 (1.0 - F0) * pow(saturate(1.0 - cosTheta), 5.0); }F0基础反射率由材质决定非金属塑料、皮肤、木头F0 ≈float3(0.04, 0.04, 0.04)约 4%金属F0 Albedo 颜色金的 F0 是金黄色铁的 F0 是灰色hlsl复制// 金属工作流中 F0 的计算 float3 F0 lerp(float3(0.04, 0.04, 0.04), albedo, metallic);3.3 G —— 几何遮蔽函数Smith描述微平面之间的自遮挡和自阴影粗糙表面的微平面会互相遮挡导致能量损失。↓ 光线被相邻微平面遮挡 ↗↘↗↘↗↘↗↘ ←→←→←→←→ ← 部分出射光被阻挡几何遮蔽使用Smith Schlick-GGX组合hlsl复制float GeometrySchlickGGX(float NdotX, float roughness) { float r roughness 1.0; float k (r * r) / 8.0; // 直接光照用此 k 值 return NdotX / (NdotX * (1.0 - k) k); } float GeometrySmith(float NdotV, float NdotL, float roughness) { // 分别计算视线方向和光线方向的遮蔽相乘 return GeometrySchlickGGX(NdotV, roughness) * GeometrySchlickGGX(NdotL, roughness); }四、金属度/粗糙度工作流现代 PBR 流程统一使用Metallic-Roughness工作流一套贴图打天下贴图通道含义AlbedoBaseColorRGB固有色金属存储 F0非金属存储漫反射色MetallicR灰度金属度0 非金属1 金属RoughnessR灰度粗糙度0 完全光滑1 完全粗糙NormalRGB法线贴图增加表面细节AOR灰度环境遮蔽凹陷处变暗典型材质参数参考材质MetallicRoughnessF0黄金1.00.1(1.0, 0.77, 0.34)铁1.00.6(0.56, 0.57, 0.58)塑料光滑0.00.1(0.04, 0.04, 0.04)皮肤0.00.7(0.03, 0.03, 0.03)木头0.00.8(0.04, 0.04, 0.04)五、完整 Shader 实现URP5.1 Shader 属性声明hlsl复制Shader Custom/PBR { Properties { _AlbedoMap (Albedo, 2D) white {} _AlbedoColor (Albedo Color, Color) (1,1,1,1) _NormalMap (Normal Map, 2D) bump {} _MetallicMap (Metallic, 2D) black {} _Metallic (Metallic, Range(0,1)) 0 _RoughnessMap (Roughness, 2D) white {} _Roughness (Roughness, Range(0,1)) 0.5 _AOMap (AO Map, 2D) white {} } SubShader { Tags { RenderTypeOpaque RenderPipelineUniversalPipeline } Pass { Name ForwardLit Tags { LightModeUniversalForward } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE #include Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl #include Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl #define PI 3.141592653589795.2 D、F、G 三大函数hlsl复制// ── DGGX 法线分布函数 ────────────────────────── float D_GGX(float NdotH, float roughness) { float a roughness * roughness; float a2 a * a; float d (NdotH * NdotH * (a2 - 1.0) 1.0); return a2 / (PI * d * d); } // ── F菲涅耳Schlick 近似──────────────────── float3 F_Schlick(float cosTheta, float3 F0) { return F0 (1.0 - F0) * pow(saturate(1.0 - cosTheta), 5.0); } // ── G几何遮蔽Smith Schlick-GGX─────────── float G_SchlickGGX(float NdotX, float roughness) { float r roughness 1.0; float k (r * r) / 8.0; return NdotX / (NdotX * (1.0 - k) k); } float G_Smith(float NdotV, float NdotL, float roughness) { return G_SchlickGGX(NdotV, roughness) * G_SchlickGGX(NdotL, roughness); }5.3 顶点着色器hlsl复制struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float3 positionWS : TEXCOORD0; float3 normalWS : TEXCOORD1; float3 tangentWS : TEXCOORD2; float3 bitangentWS: TEXCOORD3; float2 uv : TEXCOORD4; }; Varyings vert(Attributes IN) { Varyings OUT; VertexPositionInputs posInputs GetVertexPositionInputs(IN.positionOS.xyz); VertexNormalInputs normInputs GetVertexNormalInputs(IN.normalOS, IN.tangentOS); OUT.positionCS posInputs.positionCS; OUT.positionWS posInputs.positionWS; OUT.normalWS normInputs.normalWS; OUT.tangentWS normInputs.tangentWS; OUT.bitangentWS normInputs.bitangentWS; OUT.uv TRANSFORM_TEX(IN.uv, _AlbedoMap); return OUT; }5.4 完整片元着色器hlsl复制六、法线贴图详解法线贴图是 PBR 材质中非常重要的一环它在不增加面数的情况下为模型表面添加细节。无法线贴图 有法线贴图 平滑光照无细节 凹凸感、划痕、纹理细节 ┌─────────────┐ ┌~~~~~─────~~~~~┐ │ │ │ 表面有起伏感 │ └─────────────┘ └~~~~~─────~~~~~┘法线贴图的 RGB 通道存储的是切线空间中的法线方向R → X左右偏移G → Y上下偏移注意 OpenGL/DX 方向差异B → Z深度通常偏蓝hlsl复制// URP 中解码法线贴图并变换到世界空间 float3 normalTS UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, uv)); float3x3 TBN float3x3(tangentWS, bitangentWS, normalWS); float3 N normalize(mul(normalTS, TBN));七、色调映射与 Gamma 校正PBR 计算在线性空间中进行但显示器是 Gamma 空间必须做两步处理步骤一色调映射Tone MappingHDR高动态范围光照值映射到 LDR0~1显示范围hlsl复制// Reinhard 色调映射简单实用 color color / (color 1.0); // ACES 色调映射更接近电影调色对比更强 float3 ACESToneMapping(float3 x) { float a 2.51, b 0.03, c 2.43, d 0.59, e 0.14; return saturate((x*(a*xb))/(x*(c*xd)e)); }步骤二Gamma 校正hlsl复制// 线性空间 → Gamma 2.2 空间用于显示器输出 color pow(max(color, 0), 1.0 / 2.2);注意如果你使用的是 URP 并开启了 HDR Post Processing色调映射和 Gamma 校正通常由后处理管线自动完成Shader 中无需手动处理。八、效果对比不同参数表现Roughness 变化效果Roughness: 0.0 0.2 0.5 0.8 1.0 ● ● ● ● ● (镜面) (抛光) (半哑) (磨砂) (粉笔) 小亮斑 略大亮斑 中等高光 模糊高光 几乎无高光Metallic 变化效果Metallic: 0.0 1.0 ● → ● (塑料) (金属) 高光白色 高光带颜色随 Albedo 有漫反射 无漫反射全镜面九、与 NPR 的组合半写实风格PBR 和 NPR 并非对立现代游戏常常混合使用游戏策略《原神》PBR 材质工作流 NPR 卡通光照 SDF 面部阴影《崩坏星穹铁道》PBR 底层 卡通描边 Ramp 阴影《蔚蓝档案》强 NPR 卡通 少量 PBR 金属质感混合方案核心思路用 PBR 工作流制作贴图保证材质物理正确替换光照计算部分为 NPR 卡通化处理保留 F0/菲涅耳让金属感真实十、推荐学习资源资源链接说明LearnOpenGL PBRlearnopengl.com最权威的 PBR 入门教程Unity 中文课堂learn.u3d.cn三节课掌握 PBR中文毛星云 PBR 白皮书知乎专栏深度 PBR 理论完全解析Substance 材质规范AdobeHelp工业级 PBR 材质制作指南小结本文系统讲解了 PBR 的完整知识体系✅三大核心条件微表面理论、能量守恒、物理 BRDF✅DFG 三项GGX 法线分布、Schlick 菲涅耳、Smith 几何遮蔽✅金属/粗糙度工作流F0 插值、贴图规范✅完整 URP Shader从顶点到片元的完整实现✅法线贴图TBN 矩阵变换✅色调映射 Gamma 校正Reinhard / ACESPBR 是现代渲染的基础理解它不仅能写出更好的 Shader也能与美术同学更高效地沟通材质制作规范。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2420261.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!