unity-反射探针ReflectionProbe

作用是使物体可以反射周围的情况.


前篇

Reflection Probe 是可以 实时或烘焙 的方式生成 cubemap, 在 PBR 的 间接光 (IBL) 的 高光项 时, 去采样这个 cubemap.

如果使用默认的 pbr shader (standard) 的话, 就是使用这种方式去表达间接光, 实时的性能消耗太高, 实际生成环境是不可能用的, 自己去自定义 IBL 的 shader, 然后烘焙一个 cubemap 来采样.

参考总结: unity-shader-基于图像的光照IBL.md

参考测试工程 ReflectionProbe.unity


standard 代码分析

  1. UnityShaderVariables.cginc 文件中, 定义了这个 cubemap 相关参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // ----------------------------------------------------------------------------
    // Reflection Probes

    UNITY_DECLARE_TEXCUBE(unity_SpecCube0);
    UNITY_DECLARE_TEXCUBE_NOSAMPLER(unity_SpecCube1);

    CBUFFER_START(UnityReflectionProbes)
    float4 unity_SpecCube0_BoxMax;
    float4 unity_SpecCube0_BoxMin;
    float4 unity_SpecCube0_ProbePosition;
    half4 unity_SpecCube0_HDR;

    float4 unity_SpecCube1_BoxMax;
    float4 unity_SpecCube1_BoxMin;
    float4 unity_SpecCube1_ProbePosition;
    half4 unity_SpecCube1_HDR;
    CBUFFER_END

    unity_SpecCube0 存储的是 场景 和 天空盒的反射探针数据, unity_SpecCube1 存储的离物体最近的反射探针的数据)

  2. 在 PBR 的 间接光 (IBL) 的 高光项 时, 就是去采样这个 cubemap. 在 UnityGlobalIllumination.cginc 文件中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
    {
    half3 specular;
    ...
    half3 env1 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0), data.probeHDR[1], glossIn);
    specular = lerp(env1, env0, blendLerp);
    ...
    return specular * occlusion;
    }

使用

实时方式

不需要 标记 需要反射的物体为 Reflection Probe Static

烘焙方式

需要 标记 需要反射的物体为 Reflection Probe Static