Search Unity

Matrices in URP has different values from standard pipeline

Discussion in 'Shaders' started by kmedved, Nov 27, 2020.

  1. kmedved

    kmedved

    Joined:
    Aug 18, 2016
    Posts:
    189
    Hi! Converted shader from standard pipeline to URP and got an issue - seems that matrices 'UNITY_MATRIX_VP', 'unity_CameraToWorld' has different values:



    Shader before upgrade:
    Code (CSharp):
    1. Shader "GPUMan/ConeOfSightNew" {
    2.     Properties{
    3.         _Color("Color",Color) = (1,1,1,1)
    4.         _NonVisibleColor("Non Visible Color",Color) = (0,0,0,1)
    5.         _ViewAngle("Sight Angle", Range(0.01,90)) = 45
    6.         _AngleStrength("Angle Strength", Float) = 1
    7.         _ViewIntervals("Intervals", Range(0, 1)) = 0.0075
    8.         _ViewIntervalsStep("Intervals Step", Float) = 0.0025
    9.         _InnerCircleSize("InnerCircleSize", Range(0, 1)) = 0.05
    10.         _CircleStrength("CircleStrength", Float) = 70
    11.     }
    12.  
    13.         Subshader{
    14.             Tags
    15.             {
    16.                 "Queue" = "Transparent"
    17.             }
    18.             Pass {
    19.                 Blend SrcAlpha OneMinusSrcAlpha
    20.                 ZWrite Off
    21.  
    22.                 CGPROGRAM
    23.                 #pragma vertex vert
    24.                 #pragma fragment frag
    25.  
    26.                 #include "UnityCG.cginc"
    27.  
    28.                 struct v2f
    29.                 {
    30.                     float4 pos : SV_POSITION;
    31.                     float3 ray : TEXCOORD1;
    32.                     float4 screenUV : TEXCOORD2;
    33.                 };
    34.  
    35.                 sampler2D _ViewDepthTexture;
    36.                 sampler2D_float _CameraDepthTexture;
    37.  
    38.                 float4x4 _ViewSpaceMatrix;
    39.                 half _AngleStrength;
    40.                 half4 _Color;
    41.                 half4 _NonVisibleColor;
    42.                 half _ViewAngle;
    43.                 float _ViewIntervals;
    44.                 float _ViewIntervalsStep;
    45.                 half _InnerCircleSize;
    46.                 half _CircleStrength;
    47.  
    48.                 v2f vert(appdata_base v)
    49.                 {
    50.                     v2f o;
    51.                     o.pos = UnityObjectToClipPos(v.vertex);
    52.                     o.ray = UnityObjectToViewPos(v.vertex) * float3(1, 1, -1);
    53.                     o.screenUV = ComputeScreenPos(o.pos);
    54.                     return o;
    55.                 }
    56.  
    57.                 float getRadiusAlpha(float distFromCenter)
    58.                 {
    59.                     float innerCircleAlpha = saturate(distFromCenter - _InnerCircleSize);
    60.                     return max((0.5 - distFromCenter) * innerCircleAlpha  * _CircleStrength, 0);
    61.                 }
    62.  
    63.                 float getAngleAlpha(float2 pos)
    64.                 {
    65.                     const float PI = 3.14159;
    66.                     float sightAngleRadians = _ViewAngle / 2 * PI / 180;
    67.                     float2 npos = normalize(pos);
    68.                     float fwdDotPos = max(dot(float2(0, 1), npos), 0);
    69.                     float angle = acos(fwdDotPos);
    70.                     float angleF = angle / sightAngleRadians;
    71.                     return max(1.0 - pow(angleF, _AngleStrength), 0);
    72.                 }
    73.  
    74.                 float getObstacleAlpha(float4 worldPos)
    75.                 {
    76.                     const float BIAS = 0.0001;
    77.                     float4 posViewSpace = mul(_ViewSpaceMatrix, worldPos);
    78.                     float3 projCoords = posViewSpace.xyz / posViewSpace.w;    // ndc : -1 to 1
    79.                     projCoords = projCoords * 0.5 + 0.5; // 0 to 1
    80.                     float sampledDepth = (1.0 - SAMPLE_DEPTH_TEXTURE(_ViewDepthTexture, projCoords.xy));
    81.                     float depthDiff = (projCoords.z - BIAS) - sampledDepth;
    82.                     return saturate(depthDiff > 0 ? 0 : 1);
    83.                 }
    84.  
    85.                 half4 frag(v2f i) : COLOR
    86.                 {
    87.                     i.ray = i.ray * (_ProjectionParams.z / i.ray.z);  // farPlane / rayZ
    88.                  
    89.                     // 3D point reconstruction from depth texture
    90.                     float depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, i.screenUV);
    91.                     depth = Linear01Depth(depth);
    92.                     float4 vpos = float4(i.ray * depth, 1);
    93.                     float4 wpos = mul(unity_CameraToWorld, vpos);
    94.  
    95.                     // Discard point if is a vertical surface
    96.                     clip((dot(normalize(ddy(wpos)), float3(0, 1, 0)) > 0.45) ? -1 : 1);
    97.                     float3 opos = mul(unity_WorldToObject, wpos);
    98.                     opos.y = 0;
    99.  
    100.                     // Discard hit point if it is outside the box
    101.                     clip(float3(0.5, 0.5, 0.5) - abs(opos.xyz));
    102.  
    103.                     // Alpha calculation
    104.                     float2 pos2D = opos.xz;
    105.                     float distFromCenter = length(pos2D);
    106.                     float obstacleAlpha = getObstacleAlpha(wpos); // 0 if occluded, 1 if not
    107.                     float alpha = getRadiusAlpha(distFromCenter) * getAngleAlpha(pos2D);
    108.  
    109.                     // Cone stripes
    110.                     float intervals = _ViewIntervals > 0 ? (distFromCenter % _ViewIntervals) : 0;
    111.                     alpha *= step(_ViewIntervalsStep, intervals);
    112.  
    113.                     float4 col = obstacleAlpha > 0 ? _Color : _NonVisibleColor;
    114.                     return saturate(float4(col.rgb, alpha * col.a));
    115.                 }
    116.                 ENDCG
    117.             }
    118.     }
    119. }

    To make shader work I modified 'unity_CameraToWorld' matrix to default (non-URP) values.
    URP Shader:
    Code (CSharp):
    1. Shader "GPUMan/ConeOfSightNew"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color",Color) = (1,1,1,1)
    6.         _NonVisibleColor("Non Visible Color",Color) = (0,0,0,1)
    7.         _ViewAngle("Sight Angle", Range(0.01,90)) = 45
    8.         _AngleStrength("Angle Strength", Float) = 1
    9.         _ViewIntervals("Intervals", Range(0, 1)) = 0.0075
    10.         _ViewIntervalsStep("Intervals Step", Float) = 0.0025
    11.         _InnerCircleSize("InnerCircleSize", Range(0, 1)) = 0.05
    12.         _CircleStrength("CircleStrength", Float) = 70
    13.     }
    14.  
    15.     Subshader
    16.     {
    17.         Tags
    18.         {
    19.             "Queue" = "Transparent"
    20.             "RenderPipeline" = "UniversalPipeline"
    21.         }
    22.         Pass
    23.         {
    24.             Name "ForwardLit"
    25.             Tags{"LightMode" = "UniversalForward"}
    26.             Blend SrcAlpha OneMinusSrcAlpha
    27.             ZWrite Off
    28.  
    29.             HLSLPROGRAM
    30.  
    31.             #pragma vertex vert
    32.             #pragma fragment frag
    33.            
    34.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    35.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
    36.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    37.  
    38.             struct appdata_base
    39.             {
    40.                 float4 vertex : POSITION;
    41.                 float3 normal : NORMAL;
    42.                 float4 texcoord : TEXCOORD0;
    43.             };
    44.  
    45.             struct v2f
    46.             {
    47.                 float4 pos : SV_POSITION;
    48.                 float3 ray : TEXCOORD1;
    49.                 float4 screenUV : TEXCOORD2;
    50.             };
    51.  
    52.             TEXTURE2D(_ViewDepthTexture);
    53.             SAMPLER(sampler_ViewDepthTexture);
    54.  
    55.             float4x4 _ViewSpaceMatrix;
    56.             half _AngleStrength;
    57.             half4 _Color;
    58.             half4 _NonVisibleColor;
    59.             half _ViewAngle;
    60.             float _ViewIntervals;
    61.             float _ViewIntervalsStep;
    62.             half _InnerCircleSize;
    63.             half _CircleStrength;
    64.  
    65.             v2f vert(appdata_base v)
    66.             {
    67.                 v2f o = (v2f)0;
    68.                 o.pos = TransformObjectToHClip(v.vertex);
    69.                 o.ray = TransformWorldToView(TransformObjectToWorld(v.vertex)) * float3(1, 1, -1);
    70.                 o.screenUV = ComputeScreenPos(o.pos);
    71.                 return o;
    72.             }
    73.  
    74.             float getRadiusAlpha(float distFromCenter)
    75.             {
    76.                 float innerCircleAlpha = saturate(distFromCenter - _InnerCircleSize);
    77.                 return max((0.5 - distFromCenter) * innerCircleAlpha  * _CircleStrength, 0);
    78.             }
    79.  
    80.             float getAngleAlpha(float2 pos)
    81.             {
    82.                 float sightAngleRadians = _ViewAngle / 2 * PI / 180;
    83.                 float2 npos = normalize(pos);
    84.                 float fwdDotPos = max(dot(float2(0, 1), npos), 0);
    85.                 float angle = acos(fwdDotPos);
    86.                 float angleF = angle / sightAngleRadians;
    87.                 return max(1.0 - pow(angleF, _AngleStrength), 0);
    88.             }
    89.  
    90.             float getObstacleAlpha(float4 worldPos)
    91.             {
    92.                 const float BIAS = 0.0001;
    93.                 float4 posViewSpace = mul(_ViewSpaceMatrix, worldPos);
    94.                 float3 projCoords = posViewSpace.xyz / posViewSpace.w;    // ndc : -1 to 1
    95.                 projCoords = projCoords * 0.5 + 0.5; // 0 to 1
    96.                 float sampledDepth = (1.0 - SAMPLE_DEPTH_TEXTURE(_ViewDepthTexture, sampler_ViewDepthTexture, projCoords.xy));
    97.                 float depthDiff = (projCoords.z - BIAS) - sampledDepth;
    98.                 return saturate(depthDiff > 0 ? 0 : 1);
    99.             }
    100.  
    101.             half4 frag(v2f i) : COLOR
    102.             {
    103.                 i.ray = i.ray * (_ProjectionParams.z / i.ray.z);  // farPlane / rayZ
    104.                 float depth = SampleSceneDepth(i.screenUV);
    105.                 depth = Linear01Depth(depth, _ZBufferParams);
    106.  
    107.                 float4 vpos = float4(i.ray * depth, 1);
    108.                 float4x4 modified = unity_CameraToWorld;
    109.                 modified[0][2] *= -1;
    110.                 modified[1][2] *= -1;
    111.                 modified[2][2] *= -1;
    112.                 modified[3][2] *= -1;
    113.  
    114.                 float4 wpos = mul(modified, vpos);
    115.  
    116.                 // Discard point if is a vertical surface
    117.                 clip((dot(normalize(ddy(wpos)), float3(0, 1, 0)) > 0.45) ? -1 : 1);
    118.  
    119.                 float3 opos = mul(unity_WorldToObject, wpos);
    120.                 opos.y = 0;
    121.                 // Discard hit point if it is outside the box
    122.                 clip(float3(0.5, 0.5, 0.5) - abs(opos.xyz));
    123.  
    124.                 // Alpha calculation
    125.                 float2 pos2D = opos.xz;
    126.                 float distFromCenter = length(pos2D);
    127.                 float obstacleAlpha = getObstacleAlpha(wpos); // 0 if occluded, 1 if not
    128.                 float alpha = getRadiusAlpha(distFromCenter) * getAngleAlpha(pos2D);
    129.  
    130.                 // Cone stripes
    131.                 float intervals = _ViewIntervals > 0 ? (distFromCenter % _ViewIntervals) : 0;
    132.                 alpha *= step(_ViewIntervalsStep, intervals);
    133.  
    134.                 float4 col = obstacleAlpha > 0 ? _Color : _NonVisibleColor;
    135.                 return saturate(float4(col.rgb, alpha * col.a));
    136.             }
    137.             ENDHLSL
    138.         }
    139.     }
    140.     FallBack "Hidden/Universal Render Pipeline/FallbackError"
    141. }

    Why matrices has different values? How to convert shader propertly to make it work as in standard pipeline?
     
    Last edited: Nov 27, 2020