URP 渲染实战 / 第 9 章 PBR 理论 / 案例 9.8
案例 9.8同一个金球,两种工作流入门
目标:用 URP 自带的 Lit 验证两种工作流在“合法”参数下完全等价,并展示镜面工作流独有的自由度。
Assets/Cookbook/Ch09/Editor/Ch09Shots.cs(节选:workflow)
[BookShot("ch09-workflow", W = 420, H = 320, Panels = 3)] static void Workflow(Shot s) { s.Floor(); Material m; if (s.Panel == 0) { m = s.Lit(new Color(1f, 0.78f, 0.34f), 1f, 0.75f); // 金属度工作流:金属 = 1,底色即 F0 } else { m = s.Lit(Color.black, 0f, 0.75f); m.SetFloat("_WorkflowMode", 0); m.EnableKeyword("_SPECULAR_SETUP"); // 脚本建的材质不会跑 ShaderGUI,关键字要自己开 if (s.Panel == 1) m.SetColor("_SpecColor", new Color(1f, 0.78f, 0.34f)); // 镜面工作流:漫反射黑、镜面色 = 同样的金色 else { m.SetColor("_BaseColor", new Color(0.7f, 0.08f, 0.06f)); m.SetColor("_SpecColor", new Color(0.25f, 0.45f, 0.75f)); // 红色漫反射 + 蓝色高光:金属度工作流表达不了 } } s.Sphere(m, new Vector3(0, 0.75f, 0), 1.5f); s.LookAt(new Vector3(0, 1.35f, -4.0f), new Vector3(0, 0.7f, 0), 32); }

常见坑用脚本
new Material(Shader.Find("Universal Render Pipeline/Lit")) 创建材质时,材质面板(ShaderGUI)不会运行,所以面板上切换工作流、勾选法线贴图时自动设置的关键字都不会被设置。要切到镜面工作流,必须自己 EnableKeyword("_SPECULAR_SETUP");用了法线贴图要开 _NORMALMAP。忘了这一步,参数填了也没用。粗糙度:Smoothness、感知粗糙度与 α
同一个“粗糙度”在不同地方有三种写法,读源码时一定要分清:
- Smoothness(光滑度):材质面板上的滑条,Unity 的习惯,1 表示镜面。
- 感知粗糙度(perceptualRoughness):大多数 DCC 工具(Substance、Blender)里的 Roughness 就是它。
- α(URP 源码里叫
roughness):真正代入 GGX、Smith 公式的量。GGX 公式里实际出现的又是 ,URP 叫它roughness2。
为什么要平方?Burley 在 Disney 报告里指出,如果直接把滑条线性映射到 ,滑条的前半段( 从 0 到 0.5)高光就已经很糊了,后半段几乎看不出变化。平方之后,滑条每走一步,人眼感受到的变化大致均匀,所以叫“感知”粗糙度。
在 half 精度下, 太小会导致 下溢成 0,GGX 变成除零。URP 在 InitializeBRDFData 里用 HALF_MIN_SQRT()和 HALF_MIN()分别给 和 设了下限,自己写 Shader 时也要做类似的钳制。