Search Unity

Question HDRP: Reading from _ColorTextureMS inside CustomPass

Discussion in 'Shaders' started by fct509, Sep 22, 2020.

  1. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    I'm still new to what can be done with CustomPasses in HDRP, and I'm trying to read the pixel-fragment values from _ColorTextureMS.

    I was looking at the code found in https://github.com/Unity-Technologi...rPipeline/RenderPass/MSAA/ColorResolve.shader to see how they did this. I threw the code into a shader (using posInput.positionSS as a substitute for texCoord) that I'm passing to the FullScreenShaderPass, but when I pull the values, all I get are zero values resulting in a black screen.

    The shader is compiling with zero errors or warnings. I've set things to Forward Rendering. I've checked and the image is rendering with MSAA (at X4) when the CustomPass isn't enabled. I also make sure that there isn't any other kind of Anti-aliasing going on. I checked the Frame Debugger Window, and because of this, I know that the Custom Pass is running after the call to ResolveMSAAColor.

    Like I said, I'm still new to working with CustomPasses and the documentation that Unity has isn't really that helpful for people that want (or need) to learn this.

    Here's the shader so far. I haven't really done anything with what I'm values I'm pulling because I actually need to pull the values first.

    Code (HLSL):
    1.  
    2. Shader "FullScreen/AlterMSAA"
    3. {
    4.     HLSLINCLUDE
    5.  
    6.     #pragma vertex Vert
    7.  
    8.     #pragma target 4.5
    9.     #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
    10.  
    11.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
    12.  
    13.     // The PositionInputs struct allow you to retrieve a lot of useful information for your fullScreenShader:
    14.     // struct PositionInputs
    15.     // {
    16.     //     float3 positionWS;  // World space position (could be camera-relative)
    17.     //     float2 positionNDC; // Normalized screen coordinates within the viewport    : [0, 1) (with the half-pixel offset)
    18.     //     uint2  positionSS;  // Screen space pixel coordinates                       : [0, NumPixels)
    19.     //     uint2  tileCoord;   // Screen tile coordinates                              : [0, NumTiles)
    20.     //     float  deviceDepth; // Depth from the depth buffer                          : [0, 1] (typically reversed)
    21.     //     float  linearDepth; // View space Z coordinate                              : [Near, Far]
    22.     // };
    23.  
    24.     // To sample custom buffers, you have access to these functions:
    25.     // But be careful, on most platforms you can't sample to the bound color buffer. It means that you
    26.     // can't use the SampleCustomColor when the pass color buffer is set to custom (and same for camera the buffer).
    27.     // float4 SampleCustomColor(float2 uv);
    28.     // float4 LoadCustomColor(uint2 pixelCoords);
    29.     // float LoadCustomDepth(uint2 pixelCoords);
    30.     // float SampleCustomDepth(float2 uv);
    31.  
    32.     // There are also a lot of utility function you can use inside Common.hlsl and Color.hlsl,
    33.     // you can check them out in the source code of the core SRP package.
    34.  
    35.     TEXTURE2D_X_MSAA(float4, _ColorTextureMS);
    36.  
    37.     float4 LoadColorTextureMS(float2 pixelCoords, uint sampleIndex)
    38.     {
    39.         return LOAD_TEXTURE2D_X_MSAA(_ColorTextureMS, pixelCoords, sampleIndex);
    40.     }
    41.  
    42.     float4 FullScreenPass(Varyings varyings) : SV_Target
    43.     {
    44.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
    45.         float depth = LoadCameraDepth(varyings.positionCS.xy);
    46.         PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
    47.         float3 viewDirection = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
    48.         float4 color = float4(0.0, 0.0, 0.0, 0.0);
    49.  
    50.         // Load the camera color buffer at the mip 0 if we're not at the before rendering injection point
    51.         if (_CustomPassInjectionPoint != CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING)
    52.             color = float4(CustomPassLoadCameraColor(varyings.positionCS.xy, 0), 1);
    53.  
    54.         // Add your custom pass code here
    55.         int2 pixelCoords = int2(posInput.positionSS);
    56.         float4 msaa0 = FastTonemapInvert(FastTonemap(LoadColorTextureMS(pixelCoords, 0)));
    57.         float4 msaa1 = LoadColorTextureMS(pixelCoords, 1);
    58.         float4 msaa2 = LoadColorTextureMS(pixelCoords, 2);
    59.         float4 msaa3 = LoadColorTextureMS(pixelCoords, 3);
    60.  
    61.         return msaa1;
    62.  
    63.  
    64.         /*float4 msaaStuff = FastTonemapInvert((FastTonemap(LoadColorTextureMS(pixelCoords, 0))
    65.                                              + FastTonemap(LoadColorTextureMS(pixelCoords, 1))
    66.                                              + FastTonemap(LoadColorTextureMS(pixelCoords, 2))
    67.                                              + FastTonemap(LoadColorTextureMS(pixelCoords, 3))) * 0.25f);*/
    68.  
    69.  
    70.         // Fade value allow you to increase the strength of the effect while the camera gets closer to the custom pass volume
    71.        // float f = 1 - abs(_FadeValue * 2 - 1);
    72.  
    73.         //return float4(color.rg, 0.5, color.a);
    74.         //return float4(color.rgb + f, color.a);
    75.     }
    76.  
    77.     ENDHLSL
    78.  
    79.     SubShader
    80.     {
    81.         Pass
    82.         {
    83.             Name "Custom Pass 0"
    84.  
    85.             ZWrite Off
    86.             ZTest Always
    87.             Blend Off
    88.             Cull Off
    89.  
    90.             HLSLPROGRAM
    91.                 #pragma fragment FullScreenPass
    92.             ENDHLSL
    93.         }
    94.     }
    95.     Fallback Off
    96. }
    97.  
     
  2. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    So, I figured it out.

    It turns out that I had failed to set the MSAA RenderTexture. Even worse, it's a real pain to get my hands on said RenderTexture.

    1. Create a CustomPass that's designed to do nothing except to grab the MSAA RenderTexture.
    2. Run the MSAA GrabPass inside a Custom Pass Volume with an Injection Point of "After Opaque Depth And Normal" or "Before Transparent". It has to be one of those two, anything else will grab the non-MSAA-RenderTexture.
    3. Use the GetCameraBuffers(out RTHandle msaaColor, out RTHandle depth) method from CustomPass to get your hands on the RTHandles (I think the depth will also be MSAA, but I didn't check because I didn't need it).
    4. Get the RenderTexture from msaaColor.rt.
    You might need to do things a bit differently if you're targeting a Custom Texture instead of the Camera Texture, but for the camera's color buffer, this works just fine. Now, if you need to use the MSAA Color Render Texture at a different injection point, then I would advise you to stash it inside of a static attribute, but do be careful with changes to the MSAA level, those will invalidate the current MSAA Color Render Texture.

    Also, be careful when playing around with the clear flags; I was playing around with them and the GPU jumped to 100% usage and the Editor stopped responding. I had to shut down the Unity Editor from the Task Manager to get a handle on things.
     
    Tamago-Jam likes this.
  3. RyanKeable

    RyanKeable

    Joined:
    Oct 16, 2013
    Posts:
    62
    I've searched through many a forum and read many an article trying to find an applicable solution to HDR and MSAA resolving in the URP on VR.

    https://github.com/Unity-Technologi...rPipeline/RenderPass/MSAA/ColorResolve.shader

    Is exactly what I need to be integrated into the URP at the point where it draws renderers. Tonemapping each sample before the filter and then reversing that tonemap will fix AntiAliasing issues with HDR and MSAA. Just gotta wait for the support now I guess, I am not about to re-write the entire rendering system >.<