Search Unity

Resolved Converting Custom shader into URP compatible shader

Discussion in 'Universal Render Pipeline' started by r-irfan, Mar 20, 2021.

  1. r-irfan

    r-irfan

    Joined:
    Feb 20, 2020
    Posts:
    3
    Hi, I am using a custom shader "Barrel distortion.shader" from github Repo :jondyne / ARcore mobileVRHeadset, working perfectly in Legacy Rendering Pipeline.

    Now I am using URP. Started learning shader programming from yesterday. I am trying to rewrite it in HLSL to make it compatible with URP.

    Here's the custom shader I am using in Legacy rendering pipeline:
    Code (CSharp):
    1. Shader "Yaturu/Barrel Distortion"
    2. {
    3.     Properties{
    4.         _MainTex("", 2D) = "white" {}
    5.  
    6.         _FOV("FOV", Range(1, 2)) = 1.0
    7.         _Alpha("Alpha", Float) = 1.0
    8.     }
    9.  
    10.     SubShader{
    11.         ZWrite Off
    12.  
    13.         Pass{
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.             #include "UnityCG.cginc"
    18.  
    19.             struct v2f {
    20.                 float4 pos : POSITION;
    21.                 float2 uv : TEXCOORD0;
    22.             };
    23.  
    24.             // Default Vertex Shader
    25.             v2f vert(appdata_img v) {
    26.                 v2f o;
    27.                 o.pos = UnityObjectToClipPos(v.vertex);
    28.                 o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy);
    29.                 return o;
    30.             }
    31.  
    32.             // Parameters
    33.             sampler2D _MainTex;
    34.             float _FOV;
    35.  
    36.             // Alpha is the ratio of pixel density: width to height
    37.             float _Alpha;
    38.  
    39.             uniform float4x4 _UnityDisplayTransform;
    40.  
    41.             // Fragment Shader: Remap the texture coordinates to combine
    42.             // barrel distortion and disparity video display
    43.             fixed4 frag(v2f i) : COLOR {
    44.                 float2 uv1, uv2, uv3;
    45.                 float t1, t2;
    46.                 float offset;
    47.  
    48.                 // uv1 is the remap of left and right screen to a full screen
    49.                 uv1 = i.uv - 0.5;
    50.                 uv1.x = uv1.x * 2 - 0.5 + step(i.uv.x, 0.5);
    51.  
    52.                 t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y);
    53.                 t2 = 1.0 / (t1 * tan(_FOV * 0.5));
    54.  
    55.                 // uv2 is the remap of side screen with barrel distortion
    56.                 uv2 = uv1 * t2 + 0.5;
    57.  
    58.                 // black color for out-of-range pixels
    59.                 if (uv2.x >= 1.5 || uv2.y >= 1.0 || uv2.x <= -0.5 || uv2.y <= 0.0) {
    60.                     return fixed4(0, 0, 0, 1);
    61.                 } else {
    62.                     offset = 0.5 - _Alpha * 0.5;
    63.                     // uv3 is the remap of image texture
    64.                     uv3 = uv2;
    65.                     uv3.x = uv2.x * _Alpha + offset;
    66.  
    67.                     return tex2D(_MainTex, uv3);
    68.                 }
    69.             }
    70.             ENDCG
    71.         }
    72.     }
    73.     FallBack "Diffuse"
    74. }
    75.  
    This is the rewritten shader in HLSL with my one day shader programming learning knowledge with the help of available online documentation:

    Code (CSharp):
    1. Shader "Custom/StereoURP"
    2. {
    3.     Properties{
    4.         _MainTex("", 2D) = "white" {}
    5.  
    6.         _FOV("FOV", Range(1, 2)) = 1.0
    7.         _Alpha("Alpha", Float) = 1.0
    8.     }
    9.  
    10.     SubShader{
    11.         ZWrite Off
    12.  
    13.         // SubShader Tags define when and under which conditions a SubShader block or
    14.         // a pass is executed.
    15.         Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalRenderPipeline" }
    16.  
    17.         Pass{
    18.             // The HLSL code block. Unity SRP uses the HLSL language.
    19.             HLSLPROGRAM
    20.             #pragma vertex vert
    21.             #pragma fragment frag
    22.  
    23.          
    24.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    25.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
    26.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
    27.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
    28.          
    29.  
    30.  
    31.             struct v2f {
    32.                 float4 pos : POSITION;
    33.                 float2 uv : TEXCOORD0;
    34.             };
    35.  
    36.  
    37.             struct appdata_img {
    38.                 float4 vertex : POSITION;
    39.                 half2 texcoord : TEXCOORD0;
    40.             };
    41.  
    42.             float4 ObjectToClipPos(float3 pos)
    43.             {
    44.                 return mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, float4 (pos, 1)));
    45.             }
    46.  
    47.             float2 MultiplyUV(float4x4 mat, float2 inUV) {
    48.                 float4 temp = float4 (inUV.x, inUV.y, 0, 0);
    49.                 temp = mul(mat, temp);
    50.                 return temp.xy;
    51.             }
    52.          
    53.  
    54.             // Default Vertex Shader
    55.             v2f vert(appdata_img v) {
    56.                 v2f o;
    57.                 o.pos = TransformWorldToHClip(v.vertex);
    58.                 //o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    59.                 o.uv = MultiplyUV(float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), v.texcoord.xy);
    60.                 return o;
    61.             }
    62.  
    63.             // Parameters
    64.             sampler2D _MainTex;
    65.             float _FOV;
    66.  
    67.             // Alpha is the ratio of pixel density: width to height
    68.             float _Alpha;
    69.  
    70.             uniform float4x4 _UnityDisplayTransform;
    71.  
    72.             // Fragment Shader: Remap the texture coordinates to combine
    73.             // barrel distortion and disparity video display
    74.             fixed4 frag(v2f i) : COLOR {
    75.                 float2 uv1, uv2, uv3;
    76.                 float t1, t2;
    77.                 float offset;
    78.  
    79.                 // uv1 is the remap of left and right screen to a full screen
    80.                 uv1 = i.uv - 0.5;
    81.                 uv1.x = uv1.x * 2 - 0.5 + step(i.uv.x, 0.5);
    82.  
    83.                 t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y);
    84.                 t2 = 1.0 / (t1 * tan(_FOV * 0.5));
    85.  
    86.                 // uv2 is the remap of side screen with barrel distortion
    87.                 uv2 = uv1 * t2 + 0.5;
    88.  
    89.                 // black color for out-of-range pixels
    90.                 if (uv2.x >= 1.5 || uv2.y >= 1.0 || uv2.x <= -0.5 || uv2.y <= 0.0) {
    91.                     return fixed4(0, 0, 0, 1);
    92.  
    93.                 } else {
    94.                     offset = 0.5 - _Alpha * 0.5;
    95.                     // uv3 is the remap of image texture
    96.                     uv3 = uv2;
    97.                     uv3.x = uv2.x * _Alpha + offset;
    98.  
    99.                     return tex2D(_MainTex, uv3);
    100.                 }
    101.             }
    102.                 ENDHLSL
    103.         }
    104.     }
    105.     FallBack "Diffuse"
    106. }
    107.  
    108.  

    Showing 2 Errors :
    1. unrecognized identifier 'fixed4' at line 73
    2. 'TransformWorldToHClip': implicit truncation of vector type at line 56

    I appreciate any tips or pointer to make changes in code for fixing errors and making it compatible with URP.

    Thanks in advance.
     
    Last edited: Mar 20, 2021
    ChristopherKerr likes this.
  2. Ragueel

    Ragueel

    Joined:
    Jun 2, 2018
    Posts:
    39
    For the first, you can try to change it to float4 or half4, but I am not sure if it will help. Also, change COLOR to SV_TARGET

    For the second you have to specify which variables you will use.
    Change it to v.vertex.xyz
     
    ChristopherKerr and r-irfan like this.
  3. r-irfan

    r-irfan

    Joined:
    Feb 20, 2020
    Posts:
    3
    Thanks a lot Ragueel, By changing the shader as you mentioned, it worked. Disparity video and Barrel distortion are now applied to the screen.

    I found a new issue after applying the shader, the output is inverted horizontally. I observed it when I changed the cube position, from 0 meters to 0.5f in X-axis, cube moved to left side in game view. What changes do I need to make output appear correct.
     
  4. r-irfan

    r-irfan

    Joined:
    Feb 20, 2020
    Posts:
    3
    I flipped the output horizontally using "uv.x = 1.0 - uv.x;" before returning the texture in the shader.