Search Unity

  1. We are looking for feedback on our SRP Rendering APIs through this Survey.
    Dismiss Notice
  2. Unity 2020.2 has been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

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:
    112
    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
unityunity