Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Upgrading Shader...

Discussion in 'High Definition Render Pipeline' started by stu_pidd_cow, Jan 31, 2020.

  1. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    I'm trying to upgrade a postprocessing shader that worked in legacy, but there seems to be some missing shader functions. In particular, I need these:

    • UnityStereoTransformScreenSpaceTex(float uv)
    • Linear01Depth(float depth)
    • SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, texcoord)
    SAMPLE_DEPTH_TEXTURE() seems to exist, but the parameters seem to have changed?

    There are also the new TEXTURE2D_X() and LOAD_TEXTURE2D_X() functions. Does anyone know what these are doing different from a the old tex2D() functions?
     
  2. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    Sorry to bump.
    No depth-related post processing is possible without theses functions, so surely other people are having issues with this?
     
  3. Phantom_X

    Phantom_X

    Joined:
    Jul 11, 2013
    Posts:
    268
    hey,
    inside ShaderVariables.hlsl you have this function that can help you to sample the depth

    Code (CSharp):
    1.  
    2. float LoadCameraDepth(uint2 pixelCoords)
    3. {
    4.     return LOAD_TEXTURE2D_X_LOD(_CameraDepthTexture, pixelCoords, 0).r;
    5. }
    6.  
    also note that they are multiplying the uv by the screen size like so

    Code (CSharp):
    1. float SampleCameraDepth(float2 uv)
    2. {
    3.     return LoadCameraDepth(uint2(uv * _ScreenSize.xy));
    4. }
     
  4. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    Thanks for the reply. The ShaderVariables.hlsl is a good resource for a lot of the missing things. I thought I'd share some of my findings here (since there doesn't seem to be any documentation for this elsewhere:mad:).

    unity_CameraInvProjection has changed into _InvProjMatrix (you can find a bunch of other camera matrices in ShaderVariables.hlsl).

    The _X on TEXTURE2D_X means that it is a screen texture that is capable of being different for each eye (in VR). For this reason, all your screen texture functions should have _X on the end (such as TEXTURE2D_X(tex) and LOAD_TEXTURE2D_X(tex, uv)).

    You usual texture will just use TEXTURE2D, TEXTURE2D_FLOAT, etc. To sample these, you must specify a sampler. You can do that like this:
    Code (CSharp):
    1.  
    2. // declare
    3. TEXTURE2D(_MainTex);
    4. SAMPLER(sampler_MainTex);
    5.  
    6. // use
    7. float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
    8.  
    Linear01Depth doesn't exist, and there doesn't seem to be a replacement, however it is quite easy to replace it with your own:
    Code (CSharp):
    1. inline float Linear01Depth( float z )
    2. {
    3.     return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
    4. }
    UnityStereoTransformScreenSpaceTex(uv) no longer exists. You can use UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input) instead.

    I have also noticed some other things which I think are bugs but, once again, it might just be that these things haven't been documented:
    • Custom post processing won't work if your CustomPostProcessVolumeComponent class is in a namespace. This makes it not very asset-friendly.
    • material.EnableKeyword() doesn't seem to work with post processing at all. This is a major deal breaker and is blocking me for achieving what I need.
    Does anyone know how to solve these issues?
     
    Lynxed, grizzly, Tommy4421 and 2 others like this.
  5. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    Sorry to bump again, but has anyone been able to use material/shader keywords in the new post processing?
     
  6. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    Is there any documentation for this new API and macros?
    @stu_pidd_cow is this keywords switching problem fixed? I never experienced keyword problems before.
     
  7. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    851
    @stu_pidd_cow
    Keywords shouldn't cause any problem, at least I haven't had since last August or so when I converted my post effects to HDRP.
    In C#: (this is just from my code...)
    Code (CSharp):
    1. m_Material.EnableKeyword("ADJUST_CONTRAST");
    2. m_Material.DisableKeyword("ADJUST_CONTRAST");
    Then in shader:
    Code (CSharp):
    1. #pragma multi_compile __ ADJUST_CONTRAST
    If I remember correctly I had to use that double underscore for some reason? Maybe for toggling on and off to work? But don't quote me on that, I need to test it as I've forgotten why. But I'm sure toggles work as I use tens of those in many effects.

    Then the actual use case:
    Code (CSharp):
    1. #ifdef ADJUST_CONTRAST
    2.    color.rgb = AdjustContrast(color.rgb, _Contrast);
    3. #endif
    This thread also has good information about post processing related things:
    https://forum.unity.com/threads/custom-post-processing-effects-with-new-hdrp-workflow.689317/

    I posted there months ago some info about depth, normals and motion vectors. (And there's other good info too, of course.)
     
    Last edited: Mar 6, 2020
  8. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    851
    @Lynxed it's best to just dig into the code... I used a text editor to seach the files and just took shots in the dark with some words I thought might be there like depth, normals and so on :). There's plenty of code that gives good pointers but it's really disturbing that there's no documentation.
     
  9. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    I'm following keijiro's Kino HDRP custom postprocess examples and trying to use TEXTURE2D_X as they do is, but i get shader error: unrecognized identifier 'TEXTURE2D_ARRAY' at line 19 (on d3d11).

    This shader is not working:
    Code (CSharp):
    1. Shader "ForOfWar/FogOfWarPostProcessShader"
    2. {
    3.  
    4.         SubShader
    5.         {
    6.  
    7.             //0 - Final Post Process Pass
    8.             Pass
    9.             {
    10.                 HLSLPROGRAM
    11.  
    12.                 #pragma vertex Vertex
    13.                 #pragma fragment Fragment                      
    14.  
    15.                 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    16.                 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    17.                 #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
    18.  
    19.                 TEXTURE2D_X _MainTex;
    20.                 TEXTURE2D_X _FowMeshMap;
    21.  
    22.  
    23.                 float3 _WorldSpaceCameraMainPos;
    24.                 float3 _OriginPosition;
    25.                 float4x4 _ClipToWorld;
    26.  
    27.                 struct Attributes
    28.                 {
    29.                     uint vertexID : SV_VertexID;
    30.                     float2 uv   : TEXCOORD0;
    31.                     UNITY_VERTEX_INPUT_INSTANCE_ID
    32.                 };
    33.  
    34.                 struct Varyings
    35.                 {
    36.                     float4 positionCS : SV_POSITION;
    37.                     float2 uv   : TEXCOORD0;
    38.                     float3 worldDir: TEXCOORD1;
    39.                     UNITY_VERTEX_OUTPUT_STEREO
    40.                 };
    41.  
    42.  
    43.                 Varyings Vertex(Attributes input)
    44.                 {
    45.                     Varyings output;
    46.                     UNITY_SETUP_INSTANCE_ID(input);
    47.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    48.                     output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);              
    49.                     output.uv = input.uv;
    50.                     output.worldDir = (mul(_ClipToWorld, float4((output.uv * 2) - 1, 0.0, 1.0)) - _WorldSpaceCameraMainPos);
    51.                     return output;
    52.                 }
    53.  
    54.                 float LinearEyeDepth(float z)
    55.                 {
    56.                     return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);
    57.                 }
    58.  
    59.                 float4 Fragment(Varyings i) : SV_Target
    60.                 {
    61.                     uint2 pixelCoords = i.uv * _ScreenSize.xy;
    62.  
    63.                     half4 col = LOAD_TEXTURE2D_X(_MainTex, pixelCoords);
    64.                     return col;
    65.  
    66.  
    67.                 }
    68.  
    69.                 ENDHLSL
    70.             }
    71.         }
    72. }
    I don't need TextureArrays in my PostProcessing in the first place, because it's not a VR project. But i can't just pass a RenderTexture from custom PostProcessing now. It's RTHandle object with Texture2DArray inside. What am i doing wrong and where to look? It's very frustrating! Is there a way to pass just one screen source texture in the post processing shader like it used to be?
     
    Last edited: Mar 6, 2020
  10. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    851
    @Lynxed: If you compare how that TEXTURE2D_X is used in the HDRP, I think it's not like it's a value type but a method, so you pass that texture as a parameter, like this:
    Code (CSharp):
    1. TEXTURE2D_X(_InputTexture);
    Did you try to cut'n'paste old Post-processing Stack v2 thing and make it work? It looks like that at the moment, as there's quite a few things wrong.

    That method called Vertex that takes the Varyings struct in is your vertex program, but you also got that that old style looking vert there?

    And quite a few other things that look like they're a bit sideways to my eye.
     
    Last edited: Mar 6, 2020
    Lynxed likes this.
  11. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    Thank you! I feel so dumb i did not see it's a method!
     
  12. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    The keywords issue was a problem in my code.
    I have submitted a bug report about the namespace issue to unity, and they have sait that they can reproduce, so hopefully it will be rectified soon.
     
  13. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    I'm trying to get world position from depth, learning from this https://github.com/keijiro/DepthInverseProjection
    Non of that code is working out of the box in 2019.3. I made the legacy pr works in this example by replacing paths:

    #include "PostProcessing/Shaders/StdLib.hlsl"
    to the following:
    #include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"

    For HDRP custom post process, as @stu_pidd_cow said, i replaced unity_CameraInvProjection with _InvProjMatrix, but i'm getting absolutely different results.

    I'm trying to get this (worldPos.xz visualuzed, legacy RP):
    n1Sih08nIh.gif

    but with HDRP i get this:
    0Vgjv7hTrc.gif

    notice, how axis weirdly rotates with the camera.

    My Custom PostProcess Render method looks like this:

    Code (CSharp):
    1.     public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination)
    2.     {
    3.         if (m_Material == null)
    4.             return;
    5.    
    6.         m_Material.SetTexture("_MainTex", source);
    7.         m_Material.SetFloat("_Opacity", intensity.value);
    8.         m_Material.SetMatrix("_InverseView", camera.camera.cameraToWorldMatrix);
    9.         m_Material.EnableKeyword("EXCLUDE_FAR_PLANE");
    10.         HDUtils.DrawFullScreen(cmd, m_Material, destination, shaderPassId: 1);
    11.     }
    It's pretty much a copy of what keijiro is doing in hos PPSv2 version of this, so nothing different here.
    Can someone please help?
     
  14. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    So, if i understand correctly, unity_CameraInvProjection is NOT _InvProjMatrix,
    Right now I had to make my own with
    Code (CSharp):
    1. m_Material.SetMatrix("_InvCamProjMatrix", camera.camera.projectionMatrix.inverse);  
    that i set every time in post process Render() method.
    Now it's working, but i'm sure HDRP has this matrix somewhere.
     
  15. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,480
    Are you using absolute world space? In HDRP the rendering is camera relative.
     
  16. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    83
    Didn't know that was a thing. Thank you, i'll dig about this more.
     
    hippocoder likes this.
  17. stu_pidd_cow

    stu_pidd_cow

    Joined:
    Aug 4, 2014
    Posts:
    142
    Some more things that I have found. Once again, I'm not sure if these are bugs or if they are intentional, but they are definitely not documented anywhere.
    • unity_CameraInvProjection no longer exists. It seems like _InvProjMatrix is meant to be the replacement but, whatever is in it, it seems to be wrong. If you pass in your own matrix using camera.projectionMatrix.inverse you will get a very different (yet correct) value.
    • unity_OrthoParams.xy does not give the same values that it once did. You can get the correct values by doing unity_OrthoParams.xy / 2.

    I have finally got my shader to do what I want, but I would like to express how pathetic it has been unity would release HDRP as an "out of preview" package, claiming that custom shaders and custom post processing is now supported, when it is very obvious that it is quite the opposite. A feature does not exist without proper documentation. The official documentation should not consist of telling developers to just "look through the code". There are thousands of lines of code over dozens of source files. And, as I have demonstrated in this thread, the features are either buggy, inconsistent and/or misleading. As an asset store publisher, this has been a nightmarish scenario that has cost me far too much time and has even cost me money in asset sales and negative reviews. As a developer with well over 10 years experience, I have never witnessed such nonexistant support from a large company such as unity. I'm not sure how sustainable this is for unity, but this is not sustainable for me as an asset publisher.

    Now I'm moving onto to URP, which has been out of preview for almost a year now, and has just dropped support for the PPSv2 without providing any alternative for custom PP. How much worse can it get, right? /rant
     
unityunity