Search Unity

Stencil and deferred rendering

Discussion in 'Shaders' started by AviB, Jan 5, 2020.

  1. AviB

    AviB

    Joined:
    Jan 28, 2014
    Posts:
    22
    Hi,

    I want to use multiple lighting technique in Unity using deferred rendering.
    I'm trying to use the stencil to mask the relevant pixels and apply the shading technique.
    I'm overriding the Internal-DeferredShading shader, but for some reason, I don't get any influence while trying using the stencil.

    Another Issue Is related to the pass count, adding more passes does not seems to work
    (Each pass should represent different shading technique).

    Will be happy to learn what I'm doing wrong, and what is the correct way to use multiple shading techniques in Unity deferred shading.


    Thank you
     
    unity_S1kRM0X9T9nLaA likes this.
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Unity already uses the stencil buffer to support light layer masking. Over the last few years they’ve disabled more and more of user defined stencil settings during deferred rendering to where currently any stencil setting you define on a deferred related shader is ignored.

    The internal deferred shading shader probably only ever uses the first pass because they never considered anyone wanting multiple passes.

    Basically, you out of luck here, you can’t do what you’re looking to do with stencils and multiple passes.

    The way to do this is to render to one of the unused gbuffer channels to store the lighting technique index you want to use, and use an if condition in the internal deferred shading shader. Technically only the alpha of the normal gbuffer is free, and that’s a 2 bit channel, so you can store 0.0, 0.33, 0.67, and 1.0. If you need more than 4 values you can modify the contents of the gbuffers to your liking, either universally (assuming you replace all of the Standard shaders in your game), or when that alpha channel is set. Another alternative hack is render to the alpha of the emissive gbuffer and copy that channel to a new texture with a command buffer before the deferred shading is done. It’s the render texture the deferred shading is rendering to, so if you don’t make a copy you can’t read from it.
     
    mmlp and dCalle like this.
  3. AviB

    AviB

    Joined:
    Jan 28, 2014
    Posts:
    22
    Thank you very much for your answer.
    Unfortunately, I am already doing it this way ( Option 1) . It is not the optimal solution, so I hoped there is something else I can do.
    I haven't played with the HDRP yet, is this problem exists there as well?
     
  4. AviB

    AviB

    Joined:
    Jan 28, 2014
    Posts:
    22
    Found the answer to my second question :(

    https://docs.unity3d.com/Packages/c....9/manual/Forward-And-Deferred-Rendering.html

    "HDRP enforces Forward rendering for the following types of Shaders:
    • Fabric
    • Hair
    • AxF
    • StackLit
    • Unlit
    • Lit shader with a Transparent Surface Type
    If you set the Lit Shader Mode to Deferred in your HDRP Asset, HDRP uses deferred rendering to render all Materials that use an Opaque Lit Material."

    Also tryed to hook with the shader keywords, but did not get to far...

    It looks like the deferred shading lighting stage is black box with no way to add some custom data along the way.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Yes, the built in deferred rendering path is a black box. That's in part why Unity created the Scriptable Render Pipeline that the HDRP is built on. You can write your own renderer that does whatever you want it to do. In the case of the HDRP it's aiming at being a modern, high end renderer like that you would find in other big budget AAA titles. What that means is it's also a very complex renderer. By comparison the built in deferred rendering path is far more simple and straight forward, so it's more enviable to be able to modify in that respect, but it isn't an option.

    The URP on the other hand looks to be getting a deferred option, which will most likely work much more like the built in deferred renderer, which means that should be a much easier place to start.