Modify Gbuffer Layout / Add RenderTarget

I’ve posted this on the forum already (http://forum.unity3d.com/threads/add-new-rendertarget-to-gbuffer.417650/), but I know realize that this might be a better place for this question.

Premise:

As specified in the API documentation the current default GBuffer layout in Unity is:

  • RT0, ARGB32 format: Diffuse color (RGB), occlusion (A).
  • RT1, ARGB32 format: Specular color (RGB), roughness (A).
  • RT2, ARGB2101010 format: World space normal (RGB), unused (A).
  • RT3, ARGB2101010 (non-HDR) or ARGBHalf (HDR) format: Emission + lighting + lightmaps + reflection probes buffer.
  • Depth+Stencil buffer.

If I’m correct, the engine renders to this textures using the Standard shader, which (in a deferred rendering setup) invokes the vertDeferred and fragDeferred functions defined inside UnityStandardCore.cginc .

In particular fragDeferred has the following signature:

void fragDeferred (
    VertexOutputDeferred i,
    out half4 outDiffuse : SV_Target0, //RT0: diffuse color (rgb), occlusion (a)
    out half4 outSpecSmoothness : SV_Target1, //RT1: spec color (rgb), smoothness (a)
    out half4 outNormal : SV_Target2, //RT2: normal (rgb), unused, very low precision (a)
    out half4 outEmission : SV_Target3 //RT3: emission (rgb), --unused-- (a)
);

My Current Progress:

From my new StandardCustom.shader, (mostly similar to Unity’s Standard.shader) I’m now including my own version of UnityStandardCore.cginc, called UnityStandardCustomCore.cginc.

UnityStandardCustomCore.cginc adds a new RenderTarget to fragDeferred, changing its signature has follows:

void fragDeferred (
    VertexOutputDeferred i,
    out half4 outDiffuse : SV_Target0, //RT0: diffuse color (rgb), occlusion (a)
    out half4 outSpecSmoothness : SV_Target1, //RT1: spec color (rgb), smoothness (a)
    out half4 outNormal : SV_Target2, //RT2: normal (rgb), unused, very low precision (a)
    out half4 outEmission : SV_Target3 //RT3: emission (rgb), --unused-- (a)
    out half4 customRT: SV_Target4 //RT4: my custom RT
);

Question:

Although the shaders are now ready to handle an additional RenderTarget, I’m not sure how to “feed” them one. Does anyone know how to achieve this?

Summary:

  1. I want to add an additional RenderTarget to the GBuffer
  2. I’ve rewritten Unity’s shaders to handle an additional RT
  3. I don’t know how modify Unity’s Gbuffer setup so that I can provide to the shaders an additional RenderTexture

Anyway knows how to help me? Thanks in advance.

MRT only supports 4 render targets. It’s a hardware limit…

DX11 RWTexture2D<> or RWStructuredBuffer<> may be used as additional render targets, but the performance can be a problem. In fact, more render targets might not be practical.

Maybe you can try change the gbuffer layout, compress some components? Say, use baseColor+metallic+roughness. This will save two channels…or use interlacing trick on baseColor(diffuseColor) to save one more channel?

Hi @Zarenityx ,

did you manage to read from your additional render target? I want to try the same thing but will just start working on it. Or did you end up with another approach?
Thanks