自定义光照烘焙和采样

在这里插入图片描述

一: 光照烘焙:

1.静态光照烘焙: 静态物体 烘焙 lightMap

所以需要对lightMap 采样

// 采样烘焙LightMap光照
float3 SampleLightMap(float2 lightMapUV)
{
    
    
    #if defined(LIGHTMAP_ON)
        return SampleSingleLightmap(TEXTURE2D_ARGS(unity_Lightmap,samplerunity_Lightmap),lightMapUV,float4(1.0,1.0,0.0,0.0),
        #if defined(UNITY_LIGHTMAP_FULL_HDR) 
            false,
        #else
            true,
        #endif
        float4(LIGHTMAP_HDR_MULTIPLIER,LIGHTMAP_HDR_EXPONENT,0.0,0.0)
           );
    #else
        return 0.0;
    #endif
}

2.动态物体烘焙: LightProbe
适用于灯光过渡区
所以需要对 LightProbe 采样


// 采样LightProbe球谐函数
float3 SampleLightProbe(Surface surfaceWS)
{
    
    
    #if defined(LIGHTMAP_ON)
        return 0.0;
    #else
        if(unity_ProbeVolumeParams.x)
        {
    
    
            return SampleProbeVolumeSH4(TEXTURE3D_ARGS(unity_ProbeVolumeSH,samplerunity_ProbeVolumeSH),surfaceWS.position,surfaceWS.normal,unity_ProbeVolumeWorldToObject,unity_ProbeVolumeParams.y,unity_ProbeVolumeParams.z,unity_ProbeVolumeMin.xyz,unity_ProbeVolumeSizeInv.xyz);
        }
        else
        {
    
    
            float4 coefficients[7];
            coefficients[0] = unity_SHAr;
            coefficients[1] = unity_SHAg;
            coefficients[2] = unity_SHAb;
            coefficients[3] = unity_SHBr;
            coefficients[4] = unity_SHBg;
            coefficients[5] = unity_SHBb;
            coefficients[6] = unity_SHC;
            return max(0.0,SampleSH9(coefficients,surfaceWS.normal));
        }
    #endif

}

3.漫反射出的间接光烘焙:
漫反射出的间接光照的烘焙!!!!(这个间接光是带有颜色的!!!!)
烘焙通过LightMode = Meta 的pass执行烘焙,当没有此pass的时候,unity默认是白色
在meta的Fragment 中的返回值,就是烘焙到贴图中效果
因此: 想要修改lightMap的效果,自定义MetaPass, 修改frag的返回值即可
例如: 红色的cube 漫反射到地面 是带有红色, 不用此通道 则被unity默认为白色

二.自发光烘焙:
同样是在MetaPass 中处理
自发光烘焙: 必须是静态


#ifndef CUSTOM_META_PASS_INCLUDE 
#define CUSTOM_META_PASS_INCLUDE

#include "../ShaderLibrary/Surface.hlsl"
#include "../ShaderLibrary/Shadows.hlsl"
#include "../ShaderLibrary/Light.hlsl"
#include "../ShaderLibrary/BRDF.hlsl"


struct Attributes
{
    
    
    float3 positionOS : POSITION;
    float2 baseUV : TEXCOORD0;
    float2 lightMapUV : TEXCOORD1;
};


struct Varings
{
    
    
    float4 positionCS : SV_POSITION;
    //  只是从vertex中 往 fragment中传递的参数, 除了命名体现的含义, 不需要GPU特定的命名
    // VAR_BASE_UV 只是标记接受的定义, 不需要GPU 的特别关注,所以后面的 VAR_LIGHT_MAP_UV;等也只是一个
    float2 baseUV : VAR_BASE_UV;
};

bool4 unity_MetaFragmentControl;

float unity_OneOverOutputBoost;
float unity_MaxOutputValue;

Varings MetaPassVertex(Attributes input)
{
    
    
    Varings output;
    input.positionOS.xy = input.lightMapUV * unity_LightmapST.xy + unity_LightmapST.zw;
    input.positionOS.z = input.positionOS.z > 0.0 ? FLT_MIN : 0.0;
    output.positionCS = TransformWorldToHClip(input.positionOS);
    output.baseUV = TransformBaseUV(input.baseUV);  
    return output;
}


float4 MetaPassFragment(Varings input):SV_TARGET
{
    
    
    float4 base = GetBase(input.baseUV);
    Surface surface;
    ZERO_INITIALIZE(Surface,surface);
    surface.color = base.rgb;
    surface.metallic = GetMetallic(input.baseUV);
    surface.smoothness = GetSmoothness(input.baseUV);
    BRDF brdf = GetBRDF(surface);
    float4 meta = 0.0;
    if(unity_MetaFragmentControl.x)
    {
    
    // 烘焙的 弹射后的间接光 的颜色设置
        meta = float4(brdf.diffuse,1.0);
        // brdf 的粗糙度降低一半的高光,也当作是间接反射的一部分
        meta.rgb += brdf.specular * brdf.roughness * 0.5;
        meta.rgb = min(PositivePow(meta.rgb,unity_OneOverOutputBoost),unity_MaxOutputValue);
    }
    else if (unity_MetaFragmentControl.y)
    {
    
    
        // 决定烘焙自发光的效果
        meta = float4(GetEmission(input.baseUV),1.0);
    }
    return meta;
}
#endif

在shaderGUI中 添加并且在 OnGUI调用BakedEmission():

    void BakedEmission()
    {
    
    
        EditorGUI.BeginChangeCheck();

        editor.LightmapEmissionProperty();
        if (EditorGUI.EndChangeCheck())
        {
    
    
            foreach (Material m in editor.targets)
            {
    
    
                m.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

            }
        }
    }

(四)多盏灯光:
因为shadowMask 图 只有4个通道, 每个通道存储一盏灯的数据,所以 最多存储四盏灯的数据。。
在采样shadowMask 的时候 对应灯光相应的通道的数据就是阴影遮罩数据 shadowMask

Guess you like

Origin blog.csdn.net/js0907/article/details/121036896