Search Unity

[HDRP] Custom render pass SetGlobalTexture issue

Discussion in 'High Definition Render Pipeline' started by b1gry4n, Aug 30, 2020.

  1. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146
    I am trying to render a buffer mask using a custom render pass and set a global shader texture to use this texture. I have been able to achieve the masking I want, but when I try to pass the texture to the shaders it doesnt seem to be showing up. Im not sure what i am doing wrong. I was able to achieve this in URP with a custom pass almost identical to the setup here minus the obvious differences in creating a custom pass between URP and HDRP. The only real difference I can see is I was using a temporary render texture in URP with GetTemporaryRT

    Here is the meat of my custom render pass.

    Code (CSharp):
    1.  protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
    2.     {
    3.         shaderTags = new ShaderTagId[3]
    4.         {
    5.             new ShaderTagId("Forward"),
    6.             new ShaderTagId("ForwardOnly"),
    7.             new ShaderTagId("")
    8.         };
    9.  
    10.         maskBuffer = RTHandles.Alloc(
    11.             Vector2.one, TextureXR.slices, dimension: TextureXR.dimension,
    12.             colorFormat: GraphicsFormat.R16G16B16A16_SFloat,
    13.             useDynamicScale: true, enableRandomWrite: true,name: "_MaskBuffer"
    14.         );
    15.  
    16.         maskDepthBuffer = RTHandles.Alloc(
    17.                  Vector2.one, TextureXR.slices, dimension: TextureXR.dimension,
    18.                  colorFormat: GraphicsFormat.R16_UInt, useDynamicScale: true,
    19.                  name: "_MaskBufferDepth", depthBufferBits: DepthBits.Depth16
    20.              );
    21.     }
    22.  
    23.  
    24. protected override void Execute(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult)
    25.     {
    26.         if (staticMaterial == null || dynamicMaterial == null || (!drawStatic && !drawDynamic))
    27.         {
    28.             return;
    29.         }
    30.  
    31.         //This is not working
    32.         //*****
    33.         cmd.SetGlobalTexture("_MaskBuffer", maskBuffer);
    34.         //I have also tried:
    35.         //cmd.SetGlobalTexture("_MaskBuffer", maskBuffer.nameID);
    36.         //cmd.SetGlobalTexture("_MaskBuffer", maskBuffer.rt);
    37.         //Shader.SetGlobalTexture("_MaskBuffer", maskBuffer);
    38.         //Shader.SetGlobalTexture("_MaskBuffer", maskBuffer.rt);
    39.         //*****
    40.  
    41.         CoreUtils.SetRenderTarget(cmd, maskBuffer, maskDepthBuffer, ClearFlag.All);  
    42.         if (drawStatic)
    43.         {
    44.             Render(renderContext, cmd, hdCamera, cullingResult, staticMask, staticMaterial);
    45.         }
    46.         if (drawDynamic)
    47.         {
    48.             Render(renderContext, cmd, hdCamera, cullingResult, dynamicMask, dynamicMaterial);
    49.         }
    50.         SetCameraRenderTarget(cmd);
    51.     }
    52.  
    53.  
    54. void Render(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult, LayerMask LayerMask, Material material)
    55.     {
    56.         var renstateBlock = new RenderStateBlock(RenderStateMask.Depth)
    57.         {
    58.             depthState = new DepthState(true, depthCompareFunction),
    59.             stencilState = new StencilState(false),
    60.         };
    61.  
    62.         var result = new RendererListDesc(shaderTags, cullingResult, hdCamera.camera)
    63.         {
    64.             rendererConfiguration = PerObjectData.None,
    65.             renderQueueRange = GetRenderQueueRange(renderQueueType),
    66.             sortingCriteria = Sorting,
    67.             excludeObjectMotionVectors = false,
    68.             overrideMaterial = material,
    69.             overrideMaterialPassIndex = (material != null) ? material.FindPass(overrideMaterialPassName) : 0,
    70.             stateBlock = renstateBlock,
    71.             layerMask = LayerMask,
    72.         };
    73.    
    74.         // Render objects into the custom buffer:
    75.         HDUtils.DrawRendererList(renderContext, cmd, RendererList.Create(result));
    76.     }

    Here is the result of this pass I would like to set as a global texture as seen via frame debugger



    Here is the shader and the custom function I am using to retrieve the texture.



    The expected result is for the render texture to appear on the cube, but as you can see it isnt. Im not sure what I am doing wrong.

     
  2. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,266
    SAMPLE_TEXTURE2D only works with Texture2D, so what you're shader is sampling is the default 16x16 gray texture.

    Use this instead:

    Code (CSharp):
    1. //Declaration
    2. TEXTURE2D_X(_MaskBuffer)
    3. //Sampling
    4. SAMPLE_TEXTURE2D_X(_MaskBuffer, sampler_MaskBuffer, uv)
    RenderTargets are in a texture array, because of stereo pass instanced support. So this macro has to be used, the rest is handled under the hood.
     
    jjbish likes this.
  3. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146

    Thanks, changing the hlsl in the custom node to the following solved the issue.

    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/TextureXR.hlsl"
    2. TEXTURE2D_X(_MaskBuffer);
    3. SAMPLER(sampler_MaskBuffer);
    4.  
    5. void ObjectMask_float(float2 In, out float4 Out)
    6. {
    7.     float4 samp = SAMPLE_TEXTURE2D_X(_MaskBuffer, sampler_MaskBuffer, In);
    8.     Out = samp;
    9. }
     
    jjbish and Egad_McDad like this.