在URP中实现MRT

最后实现的结果

img

核心代码

  1. 在配置RT的时候将MRT绑定至当前RT
case GoRenderObjectsFeature.ECameraType.MRT:
    RenderTargetIdentifier[] renderTargetIdentifiers = new RenderTargetIdentifier[4];
    for (int i = 0; i < m_MRTDestinations.Length; i++)
    {
        //cameraTextureDescriptor.memoryless = RenderTextureMemoryless.Color;
        cameraTextureDescriptor.depthBufferBits = 0;
        cameraTextureDescriptor.colorFormat = RenderTextureFormat.ARGB32;
        cmd.GetTemporaryRT(m_MRTDestinations[i].id, cameraTextureDescriptor);
        renderTargetIdentifiers[i] = m_MRTDestinations[i].Identifier();
    }
    ConfigureClear(ClearFlag.Depth, m_ClearColor);
    ConfigureTarget(renderTargetIdentifiers, mCameraDepthTarget);
  1. 给shader添加MRTPass,并在ForwardLit.hlsl中实现相应Frag
Pass
{
    Name "GoMRT"
    Tags{"LightMode" = "GoMRT"}

    Blend[_SrcBlend][_DstBlend]
    ZWrite[_ZWrite]
    Cull[_Cull]

    HLSLPROGRAM
    // ... URP的各种宏等

    #pragma vertex LitPassVertex
    #pragma fragment LitPassFragmentMRT

    #include "LitInput.hlsl"
    #include "LitForwardPass.hlsl"
    ENDHLSL
}
void LitPassFragmentMRT(Varyings input, out half4 buf0 : SV_Target0, out half4 buf1 : SV_Target1, out half4 buf2 : SV_Target2, out half4 buf3 : SV_Target3)
{
    SurfaceData surfaceData;
    InitializeStandardLitSurfaceData(input.uv, surfaceData);
    InputData inputData;
    InitializeInputData(input, surfaceData.normalTS, inputData);

    buf0.rgb = surfaceData.albedo;
    buf0.a = surfaceData.metallic;
    buf1.rgb = inputData.normalWS;
    buf1.a = surfaceData.smoothness;
    buf2.rgb = inputData.bakedGI;
    buf2.a = 0;
    buf3.rgb = surfaceData.emission;
    buf3.a = 0;
}
void LitPassFragmentMRT(Varyings input, out half4 buf0 : SV_Target0, out half4 buf1 : SV_Target1, out half4 buf2 : SV_Target2, out half4 buf3 : SV_Target3)
{
    SurfaceData surfaceData;
    InitializeStandardLitSurfaceData(input.uv, surfaceData);
    InputData inputData;
    InitializeInputData(input, surfaceData.normalTS, inputData);

    buf0.rgb = surfaceData.albedo;
    buf0.a = surfaceData.metallic;
    buf1.rgb = inputData.normalWS;
    buf1.a = surfaceData.smoothness;
    buf2.rgb = inputData.bakedGI;
    buf2.a = 0;
    buf3.rgb = surfaceData.emission;
    buf3.a = 0;
}
  1. 将绘制好的GBuffer绑定至GlobalTexture
for (int i = 0; i < m_MRTDestinations.Length; i++)
{
    cmd.SetGlobalTexture("_GBuffer" + i, m_MRTDestinations[i].Identifier());
}
  1. 剩下就可以写一个全屏的Pass,拿到GBuffer玩耍啦