Search Unity

Command Buffer Camera target being swapped with other buffers

Discussion in 'Shaders' started by Dorodo, Jan 8, 2020.

  1. Dorodo

    Dorodo

    Joined:
    Mar 8, 2015
    Posts:
    44
    I'm trying to create an effect using the screenspace shadows generated during the pipeline via command buffers. The idea is to attach a light event to the directional light, fetch the texture, and set a globalTexture ID so I can access it in a shader without making a copy or doing blits. This is being done on the deferred lighting model.

    Technically, it works, as long as there's not an scene camera being rendered. When the scene view is active however, it looks like for some reason the two cameras are swapping the active target texture with each other, with the scene camera shadows being rendered on top of the game camera view and vice-versa:

    upload_2020-1-8_1-31-41.png


    The correct look should be this:

    upload_2020-1-8_1-50-44.png

    As a test, I've tried adding a conditional in my code in an attempt to make the scene camera ignore the command buffer entirely, but that doesn't seem to work. Here's my code so far:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Rendering;
    5.  
    6. public class CBVisualizer : MonoBehaviour
    7. {
    8.     CommandBuffer cb = null;
    9.  
    10.     private Light m_light;
    11.  
    12.     void OnEnable()
    13.     {
    14.         m_light = GetComponent<Light>();
    15.     }
    16.  
    17.     void CreateCB()
    18.     {
    19.         if (m_light && cb == null)
    20.         {
    21.             cb = new CommandBuffer();
    22.             cb.name = "GrabScrnSpcShadows";
    23.             cb.SetGlobalTexture("_mScreenSpaceShadows", BuiltinRenderTextureType.CurrentActive);
    24.             m_light.AddCommandBuffer(UnityEngine.Rendering.LightEvent.AfterScreenspaceMask, cb);
    25.         }
    26.     }
    27.  
    28.     private void OnRenderObject()
    29.     {
    30.         if (Camera.current != Camera.main)
    31.             return;
    32.  
    33.         CreateCB();
    34.     }
    35.  
    36.     void OnDisable()
    37.     {
    38.         if (m_light)
    39.         {
    40.             cb.Clear();
    41.             cb.SetGlobalTexture("_mScreenSpaceShadows", BuiltinRenderTextureType.None);
    42.             cb.ClearRenderTarget(true, true, Color.black);
    43.             m_light.RemoveCommandBuffer(UnityEngine.Rendering.LightEvent.AfterScreenspaceMask, cb);
    44.             Debug.Log("removed CB");
    45.         }
    46.     }
    47. }
    48.  
    Any ideas on how to mitigate this issue? I know this wouldn't affect a build, but it's a really jarring artifact and makes visualizing changes much more cubersome to do.
     
  2. CrazyGoG

    CrazyGoG

    Joined:
    Jul 19, 2013
    Posts:
    1
    You have to add another CommandBuffer to your camera.
    If in Deferred rendering, use CameraEvent.AfterLighting.
    It in Forward rendering, use CameraEvent.AfterForwardOpaque.
    Then, you need to Shader.GetGlobalTexture and Command.Blit every frame in OnPostRender