GameTech/URP 渲染实战

案例 9.4菲涅尔:F0 扫描与掠射高光入门

目标:先用 F(𝐧·𝐯) 看不同 F0 的“边缘变亮”;再用直接光的镜面项,看 F(𝐯·𝐡) 如何让逆光的高光变强。

图 9-15输出 F(n·v),从左到右 F0 = 0.02(水)、0.04(塑料)、0.17(钻石)、金、银。电介质中心很暗、边缘一圈白;金属整体就很亮,边缘也趋于白色。

第二组实验换一个角度。把案例 9.1 的 Shader 设为 Specular 模式(D·G·F/(4𝐧·𝐥𝐧·𝐯),再乘 πc𝐧·𝐥),材质是 F0 = 0.04 的光滑电介质地板。相机仰角从 70° 降到 12°,灯始终放在相机的镜面方向上,让高光正好落在画面中央:

Assets/Cookbook/Ch09/Editor/Ch09Shots.cs(节选:fresnelshot)
[BookShot("ch09-fresnel-angle", W = 420, H = 300, Panels = 3)]
static void FresnelAngle(Shot s)
{
    // 一块光滑的电介质地板,相机仰角从高到低;灯放在相机的镜面方向上,让高光正好落在画面中央。
    // 高光中心处 v·h = sin(仰角):70° → 0.94,35° → 0.57,12° → 0.21
    float e = new[] { 70f, 35f, 12f }[s.Panel];
    var m = Terms(s, 4, 0.35f);
    m.SetVector("_F0", V(0.04f));
    m.SetFloat("_Display", 1); m.SetFloat("_Exposure", 1.0f);
    s.Background(new Color(0.16f, 0.17f, 0.19f));
    s.Grid(m, Vector3.zero, 40f, 8);
    float r = e * Mathf.Deg2Rad;
    s.LookAt(new Vector3(0, 6 * Mathf.Sin(r), -6 * Mathf.Cos(r)), Vector3.zero, 40);
    s.SunDir(e, 180, 1f);
    s.Sun.shadows = LightShadows.None;
}
图 9-16同一块 F0 = 0.04 的地板,只改观察仰角:70°、35°、12°。高光中心处 v·h 分别约为 0.94、0.57、0.21,对应 Schlick 的 F 约为 0.040、0.054、0.33。最后一张就是“夕阳下的路面眩光”。

F 从 0.04 涨到 0.33,增大了 8 倍多;同时 V 项在掠射时也变大(分母里的 𝐧·𝐯 变小),D 的投影被拉长成竖条。三者叠加,就是开车时看到的那条刺眼的反光带。如果把 F 换成常数 0.04,第三张图会暗淡得多——这是 Blinn-Phong 永远做不出来的效果。