Search Unity

Question CustomPassSampleCameraColor returns black in AfterPostProcess injection point

Discussion in 'High Definition Render Pipeline' started by masak, Sep 4, 2021.

  1. masak

    masak

    Joined:
    Aug 14, 2011
    Posts:
    52
    Hello,

    I tried to sample camera color buffer like this sample.
    https://docs.unity3d.com/Packages/c...nition@10.6/manual/Custom-Pass-Scripting.html

    In BeforePostProcess and BeforeTransparent, this works. But not in AfterPostProcess.
    Screen becomes black.
    I want to know how to fix.
    Here is my test shader code
    Code (CSharp):
    1. Shader "Hidden/Darken"
    2. {
    3.     HLSLINCLUDE
    4.  
    5. #pragma vertex Vert
    6.  
    7. #pragma target 4.5
    8. #pragma only_renderers d3d11 playstation xboxone vulkan metal switch
    9.  
    10. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
    11.  
    12.  
    13.  
    14.     float4 FullScreenPass(Varyings varyings) : SV_Target
    15.     {
    16.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
    17.  
    18.         float depth = LoadCameraDepth(varyings.positionCS.xy);
    19.         PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
    20.         float4  color = float4(CustomPassSampleCameraColor(posInput.positionNDC.xy, 0), 1);
    21.  
    22.           return color;
    23.     }
    24.  
    25.         ENDHLSL
    26.  
    27.         SubShader
    28.     {
    29.         Pass
    30.         {
    31.             Name "Custom Pass 0"
    32.  
    33.             ZWrite Off
    34.             ZTest Always
    35.             Blend Off
    36.             Cull Off
    37.  
    38.             HLSLPROGRAM
    39.                 #pragma fragment FullScreenPass
    40.             ENDHLSL
    41.         }
    42.     }
    43.     Fallback Off
    44. }
     
  2. gebot3

    gebot3

    Joined:
    Apr 6, 2015
    Posts:
    4
    I have the same problem, if you try to sample _InputTexture, you can get an image affected with post-process, but the image sampled from _InputTexture is not affected by post-process that run with after post-process injection point.

    So if you use a custom post-process that run after unity post-process it may not be working properly
     
  3. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    265
    Hello,

    So, the fact that it works with the BeforePostProcess and BeforeTransparent injection points is because of a side effect of the code in HDRP.
    Most graphics API can't read and write to the same buffer at the same time, which is what you're doing in the code snippet you shared (read from camera color buffer with `CustomPassSampleCameraColor` and write to the same buffer by selecting the Camera Color as target buffer in the custom pass volume). Because of that limitation, you actually need to do a copy of the color buffer in a first pass and then read from the copy to write to the current color buffer.

    You can find examples of this in the custom pass repository (especially TIPS effect): https://github.com/alelievr/HDRP-Custom-Passes/blob/master/Assets/CustomPasses/TIPS/TIPS.cs#L122

    Lastly, I'd say that it works currently with the BeforePostProcess and BeforeTransparent injection points because the camera color buffer sampled in `CustomPassSampleCameraColor` is not the same as the one you're writing to. This is an implementation detail of HDRP and shouldn't be relied on because it can change in the future.
     
    Propagant and masak like this.