Shader "Hidden/Universal Render Pipeline/StencilDeferred" { Properties { _StencilRef ("StencilRef", Int) = 0 _StencilReadMask ("StencilReadMask", Int) = 0 _StencilWriteMask ("StencilWriteMask", Int) = 0 _LitPunctualStencilRef ("LitPunctualStencilWriteMask", Int) = 0 _LitPunctualStencilReadMask ("LitPunctualStencilReadMask", Int) = 0 _LitPunctualStencilWriteMask ("LitPunctualStencilWriteMask", Int) = 0 _SimpleLitPunctualStencilRef ("SimpleLitPunctualStencilWriteMask", Int) = 0 _SimpleLitPunctualStencilReadMask ("SimpleLitPunctualStencilReadMask", Int) = 0 _SimpleLitPunctualStencilWriteMask ("SimpleLitPunctualStencilWriteMask", Int) = 0 _LitDirStencilRef ("LitDirStencilRef", Int) = 0 _LitDirStencilReadMask ("LitDirStencilReadMask", Int) = 0 _LitDirStencilWriteMask ("LitDirStencilWriteMask", Int) = 0 _SimpleLitDirStencilRef ("SimpleLitDirStencilRef", Int) = 0 _SimpleLitDirStencilReadMask ("SimpleLitDirStencilReadMask", Int) = 0 _SimpleLitDirStencilWriteMask ("SimpleLitDirStencilWriteMask", Int) = 0 _ClearStencilRef ("ClearStencilRef", Int) = 0 _ClearStencilReadMask ("ClearStencilReadMask", Int) = 0 _ClearStencilWriteMask ("ClearStencilWriteMask", Int) = 0 } HLSLINCLUDE // _ADDITIONAL_LIGHT_SHADOWS is shader keyword globally enabled for a range of render-passes. // When rendering deferred lights, we need to set/unset this flag dynamically for each deferred // light, however there is no way to restore the value of the keyword, whch is needed by the // forward transparent pass. The workaround is to use a new shader keyword // _DEFERRED_ADDITIONAL_LIGHT_SHADOWS to set _ADDITIONAL_LIGHT_SHADOWS as a #define, so that // the "state" of the keyword itself is unchanged. #ifdef _DEFERRED_ADDITIONAL_LIGHT_SHADOWS #define _ADDITIONAL_LIGHT_SHADOWS 1 #endif #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Deferred.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" struct Attributes { float4 positionOS : POSITION; uint vertexID : SV_VertexID; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float4 positionCS : SV_POSITION; float3 screenUV : TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #if defined(_SPOT) float4 _SpotLightScale; float4 _SpotLightBias; float4 _SpotLightGuard; #endif Varyings Vertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_TRANSFER_INSTANCE_ID(input, output); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); float3 positionOS = input.positionOS.xyz; #if defined(_SPOT) // Spot lights have an outer angle than can be up to 180 degrees, in which case the shape // becomes a capped hemisphere. There is no affine transforms to handle the particular cone shape, // so instead we will adjust the vertices positions in the vertex shader to get the tighest fit. [flatten] if (any(positionOS.xyz)) { // The hemisphere becomes the rounded cap of the cone. positionOS.xyz = _SpotLightBias.xyz + _SpotLightScale.xyz * positionOS.xyz; positionOS.xyz = normalize(positionOS.xyz) * _SpotLightScale.w; // Slightly inflate the geometry to fit the analytic cone shape. // We want the outer rim to be expanded along xy axis only, while the rounded cap is extended along all axis. positionOS.xyz = (positionOS.xyz - float3(0, 0, _SpotLightGuard.w)) * _SpotLightGuard.xyz + float3(0, 0, _SpotLightGuard.w); } #endif #if defined(_DIRECTIONAL) || defined(_FOG) || defined(_CLEAR_STENCIL_PARTIAL) output.positionCS = float4(positionOS.xy, UNITY_RAW_FAR_CLIP_VALUE, 1.0); // Force triangle to be on zfar #else VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS.xyz); output.positionCS = vertexInput.positionCS; #endif output.screenUV = output.positionCS.xyw; #if UNITY_UV_STARTS_AT_TOP output.screenUV.xy = output.screenUV.xy * float2(0.5, -0.5) + 0.5 * output.screenUV.z; #else output.screenUV.xy = output.screenUV.xy * 0.5 + 0.5 * output.screenUV.z; #endif return output; } TEXTURE2D_X(_CameraDepthTexture); TEXTURE2D_X_HALF(_GBuffer0); TEXTURE2D_X_HALF(_GBuffer1); TEXTURE2D_X_HALF(_GBuffer2); #ifdef _DEFERRED_MIXED_LIGHTING TEXTURE2D_X_HALF(_GBuffer4); #endif float4x4 _ScreenToWorld[2]; SamplerState my_point_clamp_sampler; float3 _LightPosWS; half3 _LightColor; half4 _LightAttenuation; // .xy are used by DistanceAttenuation - .zw are used by AngleAttenuation *for SpotLights) half3 _LightDirection; // directional/spotLights support half4 _LightOcclusionProbInfo; int _LightFlags; int _ShadowLightIndex; half4 FragWhite(Varyings input) : SV_Target { return half4(1.0, 1.0, 1.0, 1.0); } half4 DeferredShading(Varyings input) : SV_Target { UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); // Using SAMPLE_TEXTURE2D is faster than using LOAD_TEXTURE2D on iOS platforms (5% faster shader). // Possible reason: HLSLcc upcasts Load() operation to float, which doesn't happen for Sample()? float2 screen_uv = (input.screenUV.xy / input.screenUV.z); float d = SAMPLE_TEXTURE2D_X_LOD(_CameraDepthTexture, my_point_clamp_sampler, screen_uv, 0).x; // raw depth value has UNITY_REVERSED_Z applied on most platforms. half4 gbuffer0 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer0, my_point_clamp_sampler, screen_uv, 0); half4 gbuffer1 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer1, my_point_clamp_sampler, screen_uv, 0); half4 gbuffer2 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer2, my_point_clamp_sampler, screen_uv, 0); #ifdef _DEFERRED_MIXED_LIGHTING half4 gbuffer4 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer4, my_point_clamp_sampler, screen_uv, 0); half4 shadowMask = gbuffer4; #else half4 shadowMask = 1.0; #endif uint materialFlags = UnpackMaterialFlags(gbuffer0.a); bool materialReceiveShadowsOff = (materialFlags & kMaterialFlagReceiveShadowsOff) != 0; #if SHADER_API_MOBILE || SHADER_API_SWITCH // Specular highlights are still silenced by setting specular to 0.0 during gbuffer pass and GPU timing is still reduced. bool materialSpecularHighlightsOff = false; #else bool materialSpecularHighlightsOff = (materialFlags & kMaterialFlagSpecularHighlightsOff); #endif #if defined(_DEFERRED_MIXED_LIGHTING) // If both lights and geometry are static, then no realtime lighting to perform for this combination. [branch] if ((_LightFlags & materialFlags) == kMaterialFlagSubtractiveMixedLighting) return half4(0.0, 0.0, 0.0, 0.0); // Cannot discard because stencil must be updated. #endif #if defined(USING_STEREO_MATRICES) int eyeIndex = unity_StereoEyeIndex; #else int eyeIndex = 0; #endif float4 posWS = mul(_ScreenToWorld[eyeIndex], float4(input.positionCS.xy, d, 1.0)); posWS.xyz *= rcp(posWS.w); InputData inputData = InputDataFromGbufferAndWorldPosition(gbuffer2, posWS.xyz); Light unityLight; #if defined(_DIRECTIONAL) unityLight.direction = _LightDirection; unityLight.color = _LightColor.rgb; unityLight.distanceAttenuation = 1.0; if (materialReceiveShadowsOff) unityLight.shadowAttenuation = 1.0; else { #if defined(MAIN_LIGHT_CALCULATE_SHADOWS) #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) float4 shadowCoord = float4(screen_uv, 0.0, 1.0); #else float4 shadowCoord = TransformWorldToShadowCoord(posWS.xyz); #endif unityLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, shadowMask, _MainLightOcclusionProbes); #elif defined(_DEFERRED_ADDITIONAL_LIGHT_SHADOWS) unityLight.shadowAttenuation = AdditionalLightShadow(_ShadowLightIndex, posWS.xyz, _LightDirection, shadowMask, _LightOcclusionProbInfo); #else unityLight.shadowAttenuation = 1.0; #endif } #else PunctualLightData light; light.posWS = _LightPosWS; light.radius2 = 0.0; // only used by tile-lights. light.color = float4(_LightColor, 0.0); light.attenuation = _LightAttenuation; light.spotDirection = _LightDirection; light.occlusionProbeInfo = _LightOcclusionProbInfo; light.flags = _LightFlags; unityLight = UnityLightFromPunctualLightDataAndWorldSpacePosition(light, posWS.xyz, shadowMask, _ShadowLightIndex, materialReceiveShadowsOff); #endif half3 color = 0.0.xxx; #if defined(_LIT) BRDFData brdfData = BRDFDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2); color = LightingPhysicallyBased(brdfData, unityLight, inputData.normalWS, inputData.viewDirectionWS, materialSpecularHighlightsOff); #elif defined(_SIMPLELIT) SurfaceData surfaceData = SurfaceDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2, kLightingSimpleLit); half3 attenuatedLightColor = unityLight.color * (unityLight.distanceAttenuation * unityLight.shadowAttenuation); half3 diffuseColor = LightingLambert(attenuatedLightColor, unityLight.direction, inputData.normalWS); half3 specularColor = LightingSpecular(attenuatedLightColor, unityLight.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, surfaceData.smoothness), surfaceData.smoothness); // TODO: if !defined(_SPECGLOSSMAP) && !defined(_SPECULAR_COLOR), force specularColor to 0 in gbuffer code color = diffuseColor * surfaceData.albedo + specularColor; #endif return half4(color, 0.0); } half4 FragFog(Varyings input) : SV_Target { float d = LOAD_TEXTURE2D_X(_CameraDepthTexture, input.positionCS.xy).x; float eye_z = LinearEyeDepth(d, _ZBufferParams); float clip_z = UNITY_MATRIX_P[2][2] * -eye_z + UNITY_MATRIX_P[2][3]; half fogFactor = ComputeFogFactor(clip_z); half fogIntensity = ComputeFogIntensity(fogFactor); return half4(unity_FogColor.rgb, fogIntensity); } ENDHLSL SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"} // 0 - Stencil pass Pass { Name "Stencil Volume" ZTest LEQual ZWrite Off ZClip false Cull Off ColorMask 0 Stencil { Ref [_StencilRef] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] CompFront NotEqual PassFront Keep ZFailFront Invert CompBack NotEqual PassBack Keep ZFailBack Invert } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile_vertex _ _SPOT #pragma vertex Vertex #pragma fragment FragWhite //#pragma enable_d3d11_debug_symbols ENDHLSL } // 1 - Deferred Punctual Light (Lit) Pass { Name "Deferred Punctual Light (Lit)" ZTest GEqual ZWrite Off ZClip false Cull Front Blend One One, Zero One BlendOp Add, Add Stencil { Ref [_LitPunctualStencilRef] ReadMask [_LitPunctualStencilReadMask] WriteMask [_LitPunctualStencilWriteMask] Comp Equal Pass Zero Fail Keep ZFail Keep } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _POINT _SPOT #pragma multi_compile_fragment _LIT #pragma multi_compile_fragment _ADDITIONAL_LIGHTS #pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING #pragma vertex Vertex #pragma fragment DeferredShading //#pragma enable_d3d11_debug_symbols ENDHLSL } // 2 - Deferred Punctual Light (SimpleLit) Pass { Name "Deferred Punctual Light (SimpleLit)" ZTest GEqual ZWrite Off ZClip false Cull Front Blend One One, Zero One BlendOp Add, Add Stencil { Ref [_SimpleLitPunctualStencilRef] ReadMask [_SimpleLitPunctualStencilReadMask] WriteMask [_SimpleLitPunctualStencilWriteMask] CompBack Equal PassBack Zero FailBack Keep ZFailBack Keep } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _POINT _SPOT #pragma multi_compile_fragment _SIMPLELIT #pragma multi_compile_fragment _ADDITIONAL_LIGHTS #pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING #pragma vertex Vertex #pragma fragment DeferredShading //#pragma enable_d3d11_debug_symbols ENDHLSL } // 3 - Directional Light (Lit) Pass { Name "Deferred Directional Light (Lit)" ZTest NotEqual ZWrite Off Cull Off Blend One One, Zero One BlendOp Add, Add Stencil { Ref [_LitDirStencilRef] ReadMask [_LitDirStencilReadMask] WriteMask [_LitDirStencilWriteMask] Comp Equal Pass Keep Fail Keep ZFail Keep } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _DIRECTIONAL #pragma multi_compile_fragment _LIT #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ADDITIONAL_LIGHTS #pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING #pragma vertex Vertex #pragma fragment DeferredShading //#pragma enable_d3d11_debug_symbols ENDHLSL } // 4 - Directional Light (SimpleLit) Pass { Name "Deferred Directional Light (SimpleLit)" ZTest NotEqual ZWrite Off Cull Off Blend One One, Zero One BlendOp Add, Add Stencil { Ref [_SimpleLitDirStencilRef] ReadMask [_SimpleLitDirStencilReadMask] WriteMask [_SimpleLitDirStencilWriteMask] Comp Equal Pass Keep Fail Keep ZFail Keep } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _DIRECTIONAL #pragma multi_compile_fragment _SIMPLELIT #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ADDITIONAL_LIGHTS #pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING #pragma vertex Vertex #pragma fragment DeferredShading //#pragma enable_d3d11_debug_symbols ENDHLSL } // 5 - Legacy fog Pass { Name "Fog" ZTest NotEqual ZWrite Off Cull Off Blend OneMinusSrcAlpha SrcAlpha, Zero One BlendOp Add, Add HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _FOG #pragma multi_compile FOG_LINEAR FOG_EXP FOG_EXP2 #pragma vertex Vertex #pragma fragment FragFog //#pragma enable_d3d11_debug_symbols ENDHLSL } // 6 - Clear stencil partial Pass { Name "ClearStencilPartial" ColorMask 0 ZTest NotEqual ZWrite Off Cull Off Stencil { Ref [_ClearStencilRef] ReadMask [_ClearStencilReadMask] WriteMask [_ClearStencilWriteMask] Comp NotEqual Pass Zero Fail Keep ZFail Keep } HLSLPROGRAM #pragma exclude_renderers gles #pragma multi_compile _CLEAR_STENCIL_PARTIAL #pragma vertex Vertex #pragma fragment FragWhite ENDHLSL } } FallBack "Hidden/Universal Render Pipeline/FallbackError" }