Search Unity

Passing info to Post Process stack in Deferred

Discussion in 'Shaders' started by Deleted User, Jun 17, 2019.

  1. Deleted User

    Deleted User

    Guest

    Hello eveyone,

    we are writing a custom effect in the PostProcess Stack V2, and we are using the Deferred rendering pipeline.

    We are looking for a way to pass extra info (we need just a single 8 bit channel) from a shader to a separate Render Target that the Post Process can use.

    Do you have any ideas?
    Thanks
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Unity's deferred pipeline only has a single 2 bit channel left free, the alpha of the Normal GBuffer (it uses the format ARGB2101010), and it's not possible to add additional custom render targets to the built in deferred pass.
    https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

    The options for getting extra data to the post processing stack are as follows:

    Use a replacement shader pass or command buffers to render out your scene to an R8.
    Replacement shaders are a little confusing at first, but basically it's a single shader with multiple passes. Each pass has a uniquely named tag. For example, Unity's CameraDepthNormalTexture is generated uses a replacement shader pass when using the forward rendering path. Almost all built in shaders have a "RenderType" tag, like "Opaque", "TransparentCutout" or "Transparent". The replacement shader has matching passes for each of these types (excluding ones it doesn't want, like "Transparent"). You just need to write your own replacement shader that uses these same tags, or includes new ones if needed.
    https://docs.unity3d.com/Manual/SL-ShaderReplacement.html

    The command buffer version is a little bit more involved, as you would have to manually render every object you want to show up in your final buffer, but would give additional control over how you render them.

    You could then set the render target as a global texture using Shader.SetGlobalTexture(), or set it on the material in your post processing script.


    Modify the deferred pipeline to use Metallic through the whole chain.
    This is a bit more involved, but if you do not use any deferred shaders that use the "Standard (Specular setup)", recently renamed the "Autodesk Interactive" or something shader, then you could change the built in shaders to write out their metallic value to the Specular gbuffer, leaving two of the channels free. This can be done by modifying the shader code in the Editor folder (though that's a little sketchy), or putting a new "Standard" shader in your project and updating all of your materials to use that one instead of the original. Any custom Surface shaders would also have to be modified to not use the built in Standard shading model code. You'd also have to change the deferred shading shader to calculate the appropriate specular color in each light. This is a lot more optimized than using the replacement shader pass, but it doesn't support getting custom data from transparent objects as those still render using the forward path. So if you need that you'd need to use something like a replacement shader pass or command buffers, at least to get the data from the transparent objects, and combine the data rendered out from the gbuffer and that new texture.
     
  3. Deleted User

    Deleted User

    Guest

    Ok as I feared there is no easy way to add render targets...

    Thanks for your reply!