Search Unity

Discussion CommandBuffer methods don't run properly inside of render feature

Discussion in 'Universal Render Pipeline' started by weiner_monkey, May 10, 2023.

  1. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    Pulling my hair on this one, I have a render feature where I want to draw meshes in a custom order, so I'm running CommandBuffer.DrawRenderer(). Which works fine, but I cant set or change render targets. For example, adding this line in Execute():

    Code (CSharp):
    1. buffer.SetRenderTarget(new RenderTargetIdentifier[]{ BuiltinRenderTextureType.CameraTarget, _depthLUT }, BuiltinRenderTextureType.CameraTarget);
    does nothing. The shader fragment is writing to SVTarget0 and SVTarget1. But adding this line makes no difference. Even changing it to:

    Code (CSharp):
    1. buffer.SetRenderTarget(new RenderTargetIdentifier[]{ _depthLUT, _depthLUT }, BuiltinRenderTextureType.CameraTarget);
    does nothing, _depthLUT remains black and DrawRenderer works as normal, rendering to the screen. Any idea why this is happening? I'd like to render some stuff on a secondary texture.

    Unity 2021.3.15 LTS, URP 12.1.8
     
  2. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,266
    Try using the "ConfigureTarget" function, by overriding the Configure function in your render pass. By design, the render target must be set here.

    upload_2023-5-10_16-59-55.png
     

    Attached Files:

  3. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    289
    Out of interest, do you know where it says this in the documentation? I've heard it said before on the forums but I can't find the doc reference.

    OP:
    buffer.SetRenderTarget(int) and (RTHandle) work fine for me on 2019, 2020, 2021, and 2022, including the optional versions where depth is specified.

    e.g.
    Code (CSharp):
    1. buffer.SetRenderTarget(_OutlineObjectBuffer);
    2. context.ExecuteCommandBuffer(buffer);
    3. CommandBufferPool.Release(buffer);
    4. // make sure you execute the buffer before using context.DrawRenderers
    5. context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings);
     
  4. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    I have already tried that in a similar way:
    Code (CSharp):
    1. ConfigureTarget(new RenderTargetIdentifier[]{ BuiltinRenderTextureType.CameraTarget, _depthLUT });
    and also:
    Code (CSharp):
    1. ConfigureTarget(new RenderTargetIdentifier[]{ _depthLUT, BuiltinRenderTextureType.CameraTarget });
    where _depthLUT remained black and it just rendered to the camera target.

    However, when I tried:
    Code (CSharp):
    1. ConfigureTarget(_depthLUT,);
    It renders correctly to the _depthLUT target, without showing anything on the screen. So I'm not quite sure why this is happening. For info, this is what the frag shader that is used to render looks like:

    Code (CSharp):
    1.             struct PixelS
    2.             {
    3.                 float4 target0 : SV_Target0;
    4.                 float4 target1 : SV_Target1;
    5.             };
    6.            
    7.             PixelS SpriteFrag(v2f IN) : SV_Target
    8.             {
    9.                 PixelS val;
    10.                
    11.                 fixed4 c = tex2D(_Main, IN.texcoord);
    12.                 fixed4 d = tex2D(_Sec, IN.texcoord);
    13.              
    14.  
    15.                 val.target0 = c;
    16.                 val.target1 = d
    17.                
    18.                 return val;
    19.             }
    target0 shows as normal.
     
  5. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,266
    We've probably read the same forum posts :p To which I'm clenching in absence of any concrete explanation. The C# function summary does say the same thing. I believe If ConfigureTarget isn't used, URP assumes you're targeting the current camera color target, which may have some adverse effect. I suppose it doesn't hurt to be explicit.

    In the same pass where I was looking, I actually also use CommandBuffer.SetRenderTarget in the Execute function, and that works perfectly.

    The key may be to execute+clear the command buffer right after doing so for it to work (like you have as well).
     
    ElliotB likes this.
  6. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    Hmm not sure what could cause it then, such a pain. Can you share how you set up the _mrt array?
     
  7. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    Tried a multitude of combinations, it seems SetRenderTarget() works properly for a single color target, but when an array is given it always resets to the default single camera target, no matter what combinations. This seems like a bug.
     
    ElliotB likes this.
  8. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    289
    I can report it also works when setting a color target and a depth target (both RenderTargetIdentifier or RTHandles). I have not used the array functionality before though.
     
  9. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    Yes works with that as well, but not with color[]. I just tested in a fresh project and it doesnt work in that either
     
    ElliotB likes this.