#ifndef UNIVERSAL_COPY_DEPTH_PASS_INCLUDED #define UNIVERSAL_COPY_DEPTH_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #if defined(_DEPTH_MSAA_2) #define MSAA_SAMPLES 2 #elif defined(_DEPTH_MSAA_4) #define MSAA_SAMPLES 4 #elif defined(_DEPTH_MSAA_8) #define MSAA_SAMPLES 8 #else #define MSAA_SAMPLES 1 #endif struct Attributes { #if _USE_DRAW_PROCEDURAL uint vertexID : SV_VertexID; #else float4 positionHCS : POSITION; float2 uv : TEXCOORD0; #endif UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; UNITY_VERTEX_OUTPUT_STEREO }; Varyings vert(Attributes input) { Varyings output; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); // Note: CopyDepth pass is setup with a mesh already in CS // Therefore, we can just output vertex position // We need to handle y-flip in a way that all existing shaders using _ProjectionParams.x work. // Otherwise we get flipping issues like this one (case https://issuetracker.unity3d.com/issues/lwrp-depth-texture-flipy) // Unity flips projection matrix in non-OpenGL platforms and when rendering to a render texture. // If URP is rendering to RT: // - Source Depth is upside down. We need to copy depth by using a shader that has flipped matrix as well so we have same orientaiton for source and copy depth. // - This also guarantess to be standard across if we are using a depth prepass. // - When shaders (including shader graph) render objects that sample depth they adjust uv sign with _ProjectionParams.x. (https://docs.unity3d.com/Manual/SL-PlatformDifferences.html) // - All good. // If URP is NOT rendering to RT neither rendering with OpenGL: // - Source Depth is NOT fliped. We CANNOT flip when copying depth and don't flip when sampling. (ProjectionParams.x == 1) #if _USE_DRAW_PROCEDURAL output.positionCS = GetQuadVertexPosition(input.vertexID); output.positionCS.xy = output.positionCS.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f); //convert to -1..1 output.uv = GetQuadTexCoord(input.vertexID); #else output.positionCS = float4(input.positionHCS.xyz, 1.0); output.uv = input.uv; #endif output.positionCS.y *= _ScaleBiasRt.x; return output; } #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) #define DEPTH_TEXTURE_MS(name, samples) Texture2DMSArray name #define DEPTH_TEXTURE(name) TEXTURE2D_ARRAY_FLOAT(name) #define LOAD(uv, sampleIndex) LOAD_TEXTURE2D_ARRAY_MSAA(_CameraDepthAttachment, uv, unity_StereoEyeIndex, sampleIndex) #define SAMPLE(uv) SAMPLE_TEXTURE2D_ARRAY(_CameraDepthAttachment, sampler_CameraDepthAttachment, uv, unity_StereoEyeIndex).r #else #define DEPTH_TEXTURE_MS(name, samples) Texture2DMS name #define DEPTH_TEXTURE(name) TEXTURE2D_FLOAT(name) #define LOAD(uv, sampleIndex) LOAD_TEXTURE2D_MSAA(_CameraDepthAttachment, uv, sampleIndex) #define SAMPLE(uv) SAMPLE_DEPTH_TEXTURE(_CameraDepthAttachment, sampler_CameraDepthAttachment, uv) #endif #if MSAA_SAMPLES == 1 DEPTH_TEXTURE(_CameraDepthAttachment); SAMPLER(sampler_CameraDepthAttachment); #else DEPTH_TEXTURE_MS(_CameraDepthAttachment, MSAA_SAMPLES); float4 _CameraDepthAttachment_TexelSize; #endif #if UNITY_REVERSED_Z #define DEPTH_DEFAULT_VALUE 1.0 #define DEPTH_OP min #else #define DEPTH_DEFAULT_VALUE 0.0 #define DEPTH_OP max #endif float SampleDepth(float2 uv) { #if MSAA_SAMPLES == 1 return SAMPLE(uv); #else int2 coord = int2(uv * _CameraDepthAttachment_TexelSize.zw); float outDepth = DEPTH_DEFAULT_VALUE; UNITY_UNROLL for (int i = 0; i < MSAA_SAMPLES; ++i) outDepth = DEPTH_OP(LOAD(coord, i), outDepth); return outDepth; #endif } float frag(Varyings input) : SV_Depth { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); return SampleDepth(input.uv); } #endif