Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Problem reading texture for post-processing effect

Discussion in 'High Definition Render Pipeline' started by norilalatoli, Jun 20, 2020.

  1. norilalatoli

    norilalatoli

    Joined:
    Aug 9, 2018
    Posts:
    12
    I am making a post-processing effect for the screen. The idea is that a texture can blend its colors with the screen. For now, I am trying to interpolate between the texture colors and the screen colors. However, the texture seems to always output gray. I am not sure why.

    Ive attached low and maximum interpolations.

    Here is the shader code I have:
    Code (CSharp):
    1. Shader "Hidden/Shader/GrayScale"
    2. {
    3.     HLSLINCLUDE
    4.  
    5.     #pragma target 4.5
    6.     #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
    7.  
    8.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    9.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    10.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
    11.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
    12.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"
    13.  
    14.     struct Attributes
    15.     {
    16.         uint vertexID : SV_VertexID;
    17.         UNITY_VERTEX_INPUT_INSTANCE_ID
    18.     };
    19.  
    20.     struct Varyings
    21.     {
    22.         float4 positionCS : SV_POSITION;
    23.         float2 texcoord   : TEXCOORD0;
    24.         UNITY_VERTEX_OUTPUT_STEREO
    25.     };
    26.  
    27.     Varyings Vert(Attributes input)
    28.     {
    29.         Varyings output;
    30.         UNITY_SETUP_INSTANCE_ID(input);
    31.         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    32.         output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
    33.         output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
    34.         return output;
    35.     }
    36.  
    37.     // List of properties to control your post process effect
    38.     float _Intensity;
    39.     TEXTURE2D_X(_InputTexture);
    40.     TEXTURE2D_X(_MainTex);
    41.  
    42.     float4 _MainTex_TexelSize;  // saves texel size
    43.  
    44.     float4 CustomPostProcess(Varyings input) : SV_Target
    45.     {
    46.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
    47.  
    48.         uint2 positionSS = input.texcoord * _ScreenSize.xy;
    49.         uint2 positionOverlay = input.texcoord;  // gets position in overlay texture?
    50.  
    51.         float3 outColor = LOAD_TEXTURE2D_X(_InputTexture, positionSS).xyz;
    52.         float3 overlayColor = LOAD_TEXTURE2D_X(_MainTex, positionOverlay).xyz; // gets color from overlay texture?
    53.      
    54.         return float4(lerp(outColor, overlayColor, _Intensity), 1);
    55.     }
    56.  
    57.     ENDHLSL
    58.  
    59.     SubShader
    60.     {
    61.         Pass
    62.         {
    63.             Name "GrayScale"
    64.  
    65.             ZWrite Off
    66.             ZTest Always
    67.             Blend Off
    68.             Cull Off
    69.  
    70.             HLSLPROGRAM
    71.                 #pragma fragment CustomPostProcess
    72.                 #pragma vertex Vert
    73.             ENDHLSL
    74.         }
    75.     }
    76.     Fallback Off
    77. }
    78.  

    I do not know what I am doing wrong. Any help is appreciated. Especially if there was a way to do post processing effects with shadergraph.
     

    Attached Files:

    ModLunar likes this.
  2. GoGoGadget

    GoGoGadget

    Joined:
    Sep 23, 2013
    Posts:
    855
    Would also appreciate an answer to this. It seems texture setting/reading behaviour in HDRP post-processing is extremely poorly documented and doesn't work as it did in legacy RP.
     
    ModLunar likes this.
  3. norilalatoli

    norilalatoli

    Joined:
    Aug 9, 2018
    Posts:
    12
    I solved the problem. I had the same problem of everything about HDRP being poorly documented. So I needed a way to do my own research about both the shader and c# volume script.

    First, you can see what HDRP shader functions do one of the various include files at the top AND the 'switch.hlsl' file.

    Code (CSharp):
    1.     #pragma target 4.5
    2.     #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
    3.  
    4.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    5.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    6.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
    7.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
    8.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"
    In my case, I was trying to figure out what this meant:

    Code (CSharp):
    1. float3 outColor = LOAD_TEXTURE2D_X(_InputTexture, positionSS).xyz;
    Turns out that LOAD_TEXTURE2D (and most other capitalized text) are macros defined in the various include files. In the 'switch.hlsl' file (I find it by searching "switch" in all packages), it is defined as:

    Code (CSharp):
    1. #define LOAD_TEXTURE2D(textureName, unCoord2)                       textureName.Load(int3(unCoord2, 0))
    Which means that 'Load' is being called on a texture. This language is Direct X and there is lots of documentation on it.

    In terms of the main problem, you cant read the screen render texture (InputTexture) the same way you read another passed in texture. This is because 'Load' doesn't account for dimensions. You need to use 'Sample', or simply:

    Code (CSharp):
    1.         /* Get Texture Color At Screen Coordinates */
    2.         float4 colorMain = tex2D(_MainTex, input.texcoord);
    ---
    I've change the post-process effect function a bit, but here it is with the fixed behavior:

    Code (CSharp):
    1.     // List of properties to control your post process effect
    2.     float _Intensity;
    3.     float _CutoffAlpha;
    4.     int _Darken;
    5.     TEXTURE2D_X(_ScreenTex);
    6.     sampler2D _MainTex;
    7.     float2 _Tiling;
    8.     float2 _Offset;
    9.  
    10.     float4 CustomPostProcess(Varyings input) : SV_Target
    11.     {
    12.         /* Configure This Input For VR Compatibility */
    13.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
    14.      
    15.         /* Declare Screen Color */
    16.         float4 screenColor;
    17.  
    18.         /* Get Screen Color from Source Camera Render Texture At Screen Coordinates If Darken Disabled */
    19.         if (_Darken == 0)
    20.             screenColor = LOAD_TEXTURE2D_X(_ScreenTex, input.texcoord * _ScreenSize.xy);
    21.  
    22.         /* Else Simple Make The Screen Color Return Black */
    23.         else
    24.             screenColor = float4(0, 0, 0, 1);
    25.  
    26.         /* Get Texture Color At Screen Coordinates */
    27.         float4 colorMain = tex2D(_MainTex, input.texcoord);
    28.  
    29.         /* Get Interpolation Of Screen Color To Texture Color Based On Cutoff */
    30.         if (colorMain.w >= _CutoffAlpha)
    31.             colorMain = screenColor;
    32.      
    33.         /* Return Interpolation Of Screen Color To Texture Color Based On Intensity */
    34.         return lerp(screenColor, colorMain, _Intensity);
    35.     }
    Hope this helps!
     
  4. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    372
    Wow.. does that mean the default asset that's created when you right-click in your Project View and create an HDRP Post-Process Shader is invalid from the start??

    It uses LOAD_TEXTURE2D_X(...) by default.
    Either way, thanks so much, it'd make a huge difference if HDRP shaders were better documented.
    I don't understand why graphics programming documentation and language support in IDEs is such an issue :/