From 9852662f7dd932e2aeb1b7ef726672af8f7212e9 Mon Sep 17 00:00:00 2001 From: StarBeats <977663818@qq.com> Date: Thu, 17 Jul 2025 17:21:42 +0800 Subject: [PATCH] soft shadow mask --- Assets/Settings/Mobile/Mobile_High.asset | 2 +- .../Mobile/Mobile_High_Renderer.asset | 13 +- .../XRenderFeatures/Shaders/Blur.shader | 91 +++++ .../XRenderFeatures/Shaders/Blur.shader.meta | 9 + .../Shaders/SoftShadowMask.shader | 32 +- .../XRenderFeatures/Shaders/Unlit_Blur.mat | 29 ++ .../Shaders/Unlit_Blur.mat.meta | 8 + .../Runtime/XRenderFeatures/SoftShadowMask.cs | 71 ++-- .../ShaderLibrary/Lighting.hlsl | 17 + .../ShaderLibrary/RealtimeLights.hlsl | 15 +- .../ShaderLibrary/Shadows.hlsl | 327 +++++++++++------- .../Shaders/Lit.shader | 3 +- .../Shaders/LitForwardPass.hlsl | 1 + 13 files changed, 429 insertions(+), 189 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader.meta create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat.meta diff --git a/Assets/Settings/Mobile/Mobile_High.asset b/Assets/Settings/Mobile/Mobile_High.asset index edfb3e1..0bb53fa 100644 --- a/Assets/Settings/Mobile/Mobile_High.asset +++ b/Assets/Settings/Mobile/Mobile_High.asset @@ -38,7 +38,7 @@ MonoBehaviour: m_MainLightRenderingMode: 1 m_MainLightShadowsSupported: 1 m_MainLightShadowmapResolution: 2048 - m_AdditionalLightsRenderingMode: 1 + m_AdditionalLightsRenderingMode: 2 m_AdditionalLightsPerObjectLimit: 4 m_AdditionalLightShadowsSupported: 1 m_AdditionalLightsShadowmapResolution: 2048 diff --git a/Assets/Settings/Mobile/Mobile_High_Renderer.asset b/Assets/Settings/Mobile/Mobile_High_Renderer.asset index 727358c..bd04aff 100644 --- a/Assets/Settings/Mobile/Mobile_High_Renderer.asset +++ b/Assets/Settings/Mobile/Mobile_High_Renderer.asset @@ -347,7 +347,7 @@ MonoBehaviour: zFailOperation: 0 m_ShadowTransparentReceive: 0 m_RenderingMode: 2 - m_DepthPrimingMode: 0 + m_DepthPrimingMode: 2 m_CopyDepthMode: 1 m_AccurateGbufferNormals: 0 m_IntermediateTextureMode: 0 @@ -542,10 +542,11 @@ MonoBehaviour: m_EditorClassIdentifier: m_Active: 1 settings: - BlurMask: 0 - Use16Samples: 0 + BlurMask: 1 MaskMat: {fileID: 2100000, guid: 1368366248809f24e9a110be3075d1b8, type: 2} - BlurMat: {fileID: 0} + BlurMat: {fileID: 2100000, guid: 0487cfddca141924d8a1736f6c0b9b7b, type: 2} + BlurIterations: 3 + BlurSpread: 0.15 --- !u!114 &6334271670068977784 MonoBehaviour: m_ObjectHideFlags: 0 @@ -571,8 +572,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: e32e72b6a3f58a24c9033e2b9275eea0, type: 3} m_Name: ScreenSpaceShadows m_EditorClassIdentifier: - m_Active: 1 + m_Active: 0 m_Shader: {fileID: 4800000, guid: 0f854b35a0cf61a429bd5dcfea30eddd, type: 3} m_Settings: UseLowResolution: 1 - UseLowResolutionPCF: 0 + UseLowResolutionPCF: 1 diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader new file mode 100644 index 0000000..ea9c478 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader @@ -0,0 +1,91 @@ +Shader "Unlit/Blur" +{ + + SubShader + { + ZTest Always Cull Off ZWrite Off + + HLSLINCLUDE + + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + sampler2D _MainTex; + half4 _MainTex_TexelSize; + float _BlurSize; + + struct v2f { + float4 pos : SV_POSITION; + half2 uv[5]: TEXCOORD0; + }; + + //垂直方向的模糊 + v2f vertBlurVertical(uint vertexID: SV_VertexID) + { + v2f o; + o.pos = GetFullScreenTriangleVertexPosition(vertexID); + + half2 uv = GetFullScreenTriangleTexCoord(vertexID); + + o.uv[0] = uv; + o.uv[1] = uv + float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize; + o.uv[2] = uv - float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize; + o.uv[3] = uv + float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize; + o.uv[4] = uv - float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize; + + return o; + } + //水平方向的模糊 + v2f vertBlurHorizontal(uint vertexID: SV_VertexID) + { + v2f o; + o.pos = GetFullScreenTriangleVertexPosition(vertexID); + + half2 uv = GetFullScreenTriangleTexCoord(vertexID); + + o.uv[0] = uv; + o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize; + o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize; + o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize; + o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize; + + return o; + } + + half4 fragBlur(v2f i) : SV_Target { + float weight[3] = {0.4026, 0.2442, 0.0545}; + + half3 sum = tex2D(_MainTex, i.uv[0]).rgb * weight[0]; + + for (int it = 1; it < 3; it++) { + sum += tex2D(_MainTex, i.uv[it*2-1]).rgb * weight[it]; + sum += tex2D(_MainTex, i.uv[it*2]).rgb * weight[it]; + } + + return half4(sum, 1.0); + } + + ENDHLSL + Pass + { + NAME "GAUSSIAN_BLUR_VERTICAL" + + HLSLPROGRAM + + #pragma vertex vertBlurVertical + #pragma fragment fragBlur + + ENDHLSL + } + + Pass + { + NAME "GAUSSIAN_BLUR_HORIZONTAL" + + HLSLPROGRAM + + #pragma vertex vertBlurHorizontal + #pragma fragment fragBlur + + ENDHLSL + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader.meta b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader.meta new file mode 100644 index 0000000..016abdc --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Blur.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ac5e0807b54a94e4a9d8093afd986e43 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/SoftShadowMask.shader b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/SoftShadowMask.shader index 59a3170..3938179 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/SoftShadowMask.shader +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/SoftShadowMask.shader @@ -20,7 +20,6 @@ Shader "Unlit/SoftShadowMask" #pragma multi_compile _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE - #pragma multi_compile_fragment _ _Use16Samples struct Varyings { @@ -36,12 +35,8 @@ Shader "Unlit/SoftShadowMask" return o; } - #ifdef _Use16Samples - float4 _Offset16[8]; - #else float4 _Offset5[2]; - #endif - + float4 _MaskSizeAndInvRenderSize; half GetDepth(float2 uv) { #if UNITY_REVERSED_Z @@ -66,31 +61,17 @@ Shader "Unlit/SoftShadowMask" return 1; } - half shadow = SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_LinearClampCompare, - coords.xyz); - #ifdef _Use16Samples - for (int i = 0; i < 8; ++i) - { - uv = input.uv+ _Offset16[i].xy; - wpos = ComputeWorldSpacePosition(uv, GetDepth(uv), unity_MatrixInvVP); - coords = TransformWorldToShadowCoord(wpos); - shadow += BEYOND_SHADOW_FAR(coords) ? 1 : SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_LinearClampCompare,coords.xyz); - - uv = input.uv+ _Offset16[i].zw; - wpos = ComputeWorldSpacePosition(uv, GetDepth(uv), unity_MatrixInvVP); - coords = TransformWorldToShadowCoord(wpos); - shadow += BEYOND_SHADOW_FAR(coords) ? 1 : SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_LinearClampCompare, coords.xyz ); - } - #else + half shadow = 0; + float2 uv0 = input.uv; for (int i = 0; i < 2; ++i) { - uv = input.uv + _Offset5[i].xy; + uv = uv0 + _Offset5[i].xy; wpos = ComputeWorldSpacePosition(uv, GetDepth(uv), unity_MatrixInvVP); coords = TransformWorldToShadowCoord(wpos); shadow += BEYOND_SHADOW_FAR(coords) ? 1 : SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_LinearClampCompare, coords.xyz); - uv = input.uv + _Offset5[i].zw; + uv = uv0 + _Offset5[i].zw; wpos = ComputeWorldSpacePosition(uv, GetDepth(uv), unity_MatrixInvVP); coords = TransformWorldToShadowCoord(wpos); @@ -98,8 +79,7 @@ Shader "Unlit/SoftShadowMask" coords.xyz); } - shadow *= 0.2f; - #endif + shadow *= 0.25f; return shadow; } diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat new file mode 100644 index 0000000..f825922 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Unlit_Blur + m_Shader: {fileID: 4800000, guid: ac5e0807b54a94e4a9d8093afd986e43, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: [] + m_Colors: [] + m_BuildTextureStacks: [] diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat.meta b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat.meta new file mode 100644 index 0000000..7acacff --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/Shaders/Unlit_Blur.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0487cfddca141924d8a1736f6c0b9b7b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/SoftShadowMask.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/SoftShadowMask.cs index a7c4bda..7f46d37 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/SoftShadowMask.cs +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/XRenderFeatures/SoftShadowMask.cs @@ -3,6 +3,7 @@ using Unity.Mathematics; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; +using static UnityEngine.Rendering.Universal.UniversalRenderPipeline.Profiling.Pipeline; namespace X.Rendering.Feature { @@ -12,9 +13,10 @@ namespace X.Rendering.Feature private class Settings { public bool BlurMask = false; - public bool Use16Samples = true; public Material MaskMat = null; public Material BlurMat = null; + public int BlurIterations = 3; + public float BlurSpread = 0.6f; } [SerializeField] @@ -39,10 +41,10 @@ namespace X.Rendering.Feature private Settings settings; private ProfilingSampler profiler; - Vector4[] offset16Array = new Vector4[8]; - Vector4[] offset5Array = new Vector4[2]; + Vector4[] offsetArray = new Vector4[4]; RTHandle softShadowMask; - + RTHandle buffer0; + RTHandle buffer1; public SoftShadowMaskPass(Settings settings) { this.settings = settings; @@ -58,40 +60,55 @@ namespace X.Rendering.Feature var w = renderingData.cameraData.cameraTargetDescriptor.width; var h = renderingData.cameraData.cameraTargetDescriptor.height; float2 wh = new float2 { x = w, y = h }; - if (settings.Use16Samples) { - cmd.EnableShaderKeyword("_Use16Samples"); - for (int i = 0; i < 8; ++i) - { - - } - cmd.SetGlobalVectorArray("_Offset16", offset16Array); + offsetArray[0] = new float4(new float2(-1, 1) / wh, new float2(1, 1) / wh); + offsetArray[1] = new float4(new float2(-1, -1) / wh, new float2(1, -1) / wh); + offsetArray[2] = new float4(new float2(-2, -2) / wh, new float2(2, 2) / wh); + offsetArray[3] = new float4(new float2(-2, 2) / wh, new float2(2, -2) / wh); + cmd.SetGlobalVectorArray("_Offset5", offsetArray); } - else - { - cmd.DisableShaderKeyword("_Use16Samples"); - for (int i = 0; i < 2; ++i) - { - - offset5Array[i] = new float4(new float2(-1, 1) / wh, new float2(1, 1) / wh); - offset5Array[i] = new float4(new float2(-1, -1) / wh, new float2(1, -1) / wh); - } - cmd.SetGlobalVectorArray("_Offset5", offset5Array); - } - RenderingUtils.ReAllocateIfNeeded(ref softShadowMask, new RenderTextureDescriptor() + cmd.SetGlobalVector("_MaskSizeAndInvRenderSize", new Vector4(w / 4, h / 4, 1f / w, 1f / h)); + var desc = new RenderTextureDescriptor() { bindMS = false, colorFormat = RenderTextureFormat.R8, width = w / 4, height = h / 4, enableRandomWrite = false, - depthBufferBits = 0, - dimension = TextureDimension.Tex2D, + depthBufferBits = 0, + dimension = TextureDimension.Tex2D, msaaSamples = 1, - }); + }; + RenderingUtils.ReAllocateIfNeeded(ref softShadowMask, desc); + cmd.SetGlobalTexture("_CameraDepthTexture", renderingData.cameraData.renderer.cameraDepthTargetHandle); cmd.SetRenderTarget(softShadowMask); cmd.DrawProcedural(Matrix4x4.identity, settings.MaskMat, 0, MeshTopology.Triangles, 3); - cmd.SetGlobalTexture(SoftShadowMaskTextureId, softShadowMask); + if (settings.BlurMask) + { + cmd.BeginSample("SoftShadowMask Blur"); + //desc.memoryless = RenderTextureMemoryless.Color; + RenderingUtils.ReAllocateIfNeeded(ref buffer0, desc, name: "buffer0"); + RenderingUtils.ReAllocateIfNeeded(ref buffer1, desc, name: "buffer1"); + + cmd.SetGlobalTexture("_MainTex", softShadowMask); + for (int i = 0; i < settings.BlurIterations; i++) + { + settings.BlurMat.SetFloat("_BlurSize", i * settings.BlurSpread); + cmd.SetRenderTarget(buffer0); + cmd.DrawProcedural(Matrix4x4.identity, settings.BlurMat, 0, MeshTopology.Triangles, 3); + cmd.SetGlobalTexture("_MainTex", buffer0); + + cmd.SetRenderTarget(buffer1); + cmd.DrawProcedural(Matrix4x4.identity, settings.BlurMat, 1, MeshTopology.Triangles, 3); + cmd.SetGlobalTexture("_MainTex", buffer1); + } + cmd.EndSample("SoftShadowMask Blur"); + cmd.SetGlobalTexture(SoftShadowMaskTextureId, buffer1); + } + else + { + cmd.SetGlobalTexture(SoftShadowMaskTextureId, softShadowMask); + } } public override void OnFinishCameraStackRendering(CommandBuffer cmd) diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Lighting.hlsl b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Lighting.hlsl index b91d666..484a6ed 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Lighting.hlsl +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Lighting.hlsl @@ -338,6 +338,23 @@ half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData) lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse; #endif +// #if defined(_SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF) +// half realtimeShadow = half(SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_PointClamp, inputData.normalizedScreenSpaceUV.xy).x); +// UNITY_BRANCH +// if(abs(realtimeShadow - 0.5) < 0.499) +// { +// return float4(1, 0, 0, 1); +// } +// #endif +// #if defined(_SOFTSHADOW_MASK) +// half realtimeShadow = half(SAMPLE_TEXTURE2D(_SoftShadowMaskTexture, sampler_PointClamp, inputData.normalizedScreenSpaceUV.xy).x); +// UNITY_BRANCH +// if(abs(realtimeShadow - 0.5) < 0.499) +// { +// return float4(1, 0, 0, 1); +// } +// #endif + #if REAL_IS_HALF // Clamp any half.inf+ to HALF_MAX return min(CalculateFinalColor(lightingData, surfaceData.alpha), HALF_MAX); diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/RealtimeLights.hlsl b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/RealtimeLights.hlsl index 076b234..818bf5f 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/RealtimeLights.hlsl +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/RealtimeLights.hlsl @@ -122,6 +122,19 @@ Light GetMainLight(float4 shadowCoord) return light; } +Light GetMainLight(float4 shadowCoord, float2 screenUV, float3 positionWS, half4 shadowMask) +{ + Light light = GetMainLight(); + light.shadowAttenuation = MainLightShadow(shadowCoord, screenUV, positionWS, shadowMask, _MainLightOcclusionProbes); + + #if defined(_LIGHT_COOKIES) + real3 cookieColor = SampleMainLightCookie(positionWS); + light.color *= cookieColor; + #endif + + return light; +} + Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask) { Light light = GetMainLight(); @@ -137,7 +150,7 @@ Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask) Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor) { - Light light = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask); + Light light = GetMainLight(inputData.shadowCoord, inputData.normalizedScreenSpaceUV, inputData.positionWS, shadowMask); #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Shadows.hlsl b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Shadows.hlsl index e8c9d6b..2a75d57 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Shadows.hlsl +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/ShaderLibrary/Shadows.hlsl @@ -10,17 +10,17 @@ #define MAX_SHADOW_CASCADES 4 #if !defined(_RECEIVE_SHADOWS_OFF) - #if defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN) +#if defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN) #define MAIN_LIGHT_CALCULATE_SHADOWS - #if defined(_MAIN_LIGHT_SHADOWS) || (defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)) +#if defined(_MAIN_LIGHT_SHADOWS) || (defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)) #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR - #endif - #endif +#endif +#endif - #if defined(_ADDITIONAL_LIGHT_SHADOWS) +#if defined(_ADDITIONAL_LIGHT_SHADOWS) #define ADDITIONAL_LIGHT_CALCULATE_SHADOWS - #endif +#endif #endif #if defined(UNITY_DOTS_INSTANCING_ENABLED) @@ -36,7 +36,7 @@ #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON) #define SAMPLE_SHADOWMASK(uv) SAMPLE_TEXTURE2D_LIGHTMAP(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, uv SHADOWMASK_SAMPLE_EXTRA_ARGS); #elif !defined (LIGHTMAP_ON) - #define SAMPLE_SHADOWMASK(uv) unity_ProbesOcclusion; +#define SAMPLE_SHADOWMASK(uv) unity_ProbesOcclusion; #else #define SAMPLE_SHADOWMASK(uv) half4(1, 1, 1, 1); #endif @@ -49,6 +49,7 @@ SCREENSPACE_TEXTURE(_ScreenSpaceShadowmapTexture); +TEXTURE2D(_SoftShadowMaskTexture); TEXTURE2D_SHADOW(_MainLightShadowmapTexture); TEXTURE2D_SHADOW(_AdditionalLightsShadowmapTexture); SAMPLER_CMP(sampler_LinearClampCompare); @@ -56,48 +57,50 @@ SAMPLER_CMP(sampler_LinearClampCompare); // GLES3 causes a performance regression in some devices when using CBUFFER. #ifndef SHADER_API_GLES3 CBUFFER_START(LightShadows) -#endif + #endif -// Last cascade is initialized with a no-op matrix. It always transforms -// shadow coord to half3(0, 0, NEAR_PLANE). We use this trick to avoid -// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES -float4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1]; -float4 _CascadeShadowSplitSpheres0; -float4 _CascadeShadowSplitSpheres1; -float4 _CascadeShadowSplitSpheres2; -float4 _CascadeShadowSplitSpheres3; -float4 _CascadeShadowSplitSphereRadii; + // Last cascade is initialized with a no-op matrix. It always transforms + // shadow coord to half3(0, 0, NEAR_PLANE). We use this trick to avoid + // branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES + float4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1]; + float4 _CascadeShadowSplitSpheres0; + float4 _CascadeShadowSplitSpheres1; + float4 _CascadeShadowSplitSpheres2; + float4 _CascadeShadowSplitSpheres3; + float4 _CascadeShadowSplitSphereRadii; -float4 _MainLightShadowOffset0; // xy: offset0, zw: offset1 -float4 _MainLightShadowOffset1; // xy: offset2, zw: offset3 -float4 _MainLightShadowParams; // (x: shadowStrength, y: >= 1.0 if soft shadows, 0.0 otherwise, z: main light fade scale, w: main light fade bias) -float4 _MainLightShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) + float4 _MainLightShadowOffset0; // xy: offset0, zw: offset1 + float4 _MainLightShadowOffset1; // xy: offset2, zw: offset3 + float4 _MainLightShadowParams; + // (x: shadowStrength, y: >= 1.0 if soft shadows, 0.0 otherwise, z: main light fade scale, w: main light fade bias) + float4 _MainLightShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) -float4 _AdditionalShadowOffset0; // xy: offset0, zw: offset1 -float4 _AdditionalShadowOffset1; // xy: offset2, zw: offset3 -float4 _AdditionalShadowFadeParams; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0) -float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) + float4 _AdditionalShadowOffset0; // xy: offset0, zw: offset1 + float4 _AdditionalShadowOffset1; // xy: offset2, zw: offset3 + float4 _AdditionalShadowFadeParams; + // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0) + float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) -#if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) -#if !USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA + #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) + #if !USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA // Point lights can use 6 shadow slices. Some mobile GPUs performance decrease drastically with uniform // blocks bigger than 8kb while others have a 64kb max uniform block size. This number ensures size of buffer // AdditionalLightShadows stays reasonable. It also avoids shader compilation errors on SHADER_API_GLES30 // devices where max number of uniforms per shader GL_MAX_FRAGMENT_UNIFORM_VECTORS is low (224) float4 _AdditionalShadowParams[MAX_VISIBLE_LIGHTS]; // Per-light data float4x4 _AdditionalLightsWorldToShadow[MAX_VISIBLE_LIGHTS]; // Per-shadow-slice-data -#endif -#endif + #endif + #endif -#ifndef SHADER_API_GLES3 + #ifndef SHADER_API_GLES3 CBUFFER_END #endif #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) - #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA +#if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA StructuredBuffer _AdditionalShadowParams_SSBO; // Per-light data - TODO: test if splitting _AdditionalShadowParams_SSBO[lightIndex].w into a separate StructuredBuffer buffer is faster StructuredBuffer _AdditionalLightsWorldToShadow_SSBO; // Per-shadow-slice-data - A shadow casting light can have 6 shadow slices (if it's a point light) - #endif +#endif #endif float4 _ShadowBias; // x: depth bias, y: normal bias @@ -167,14 +170,14 @@ half4 GetMainLightShadowParams() half4 GetAdditionalLightShadowParams(int lightIndex) { #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) - #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA + #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA return _AdditionalShadowParams_SSBO[lightIndex]; - #else - return _AdditionalShadowParams[lightIndex]; - #endif #else - // Same defaults as set in AdditionalLightsShadowCasterPass.cs - return half4(0, 0, 0, -1); + return _AdditionalShadowParams[lightIndex]; + #endif + #else + // Same defaults as set in AdditionalLightsShadowCasterPass.cs + return half4(0, 0, 0, -1); #endif } @@ -185,92 +188,125 @@ half SampleScreenSpaceShadowmap(float4 shadowCoord) // The stereo transform has to happen after the manual perspective divide shadowCoord.xy = UnityStereoTransformScreenSpaceTex(shadowCoord.xy); -#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) + #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) half attenuation = SAMPLE_TEXTURE2D_ARRAY(_ScreenSpaceShadowmapTexture, sampler_PointClamp, shadowCoord.xy, unity_StereoEyeIndex).x; -#else -#if defined(_SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF) - // mip 可能造成更多 PCF - half attenuation = half(SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_PointClamp, float3(shadowCoord.xy, 2)).x); -#else + #else half attenuation = half(SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_PointClamp, shadowCoord.xy).x); -#endif -#endif + #endif return attenuation; } -real SampleShadowmapFilteredLowQuality(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +real SampleShadowmapFilteredLowQuality( + TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) { // 4-tap hardware comparison real4 attenuation4; - attenuation4.x = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + float3(samplingData.shadowOffset0.xy, 0))); - attenuation4.y = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + float3(samplingData.shadowOffset0.zw, 0))); - attenuation4.z = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + float3(samplingData.shadowOffset1.xy, 0))); - attenuation4.w = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + float3(samplingData.shadowOffset1.zw, 0))); + attenuation4.x = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + shadowCoord.xyz + float3(samplingData.shadowOffset0.xy, 0))); + attenuation4.y = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + shadowCoord.xyz + float3(samplingData.shadowOffset0.zw, 0))); + attenuation4.z = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + shadowCoord.xyz + float3(samplingData.shadowOffset1.xy, 0))); + attenuation4.w = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + shadowCoord.xyz + float3(samplingData.shadowOffset1.zw, 0))); return dot(attenuation4, real(0.25)); } -real SampleShadowmapFilteredMediumQuality(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +real SampleShadowmapFilteredMediumQuality( + TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) { real fetchesWeights[9]; real2 fetchesUV[9]; SampleShadow_ComputeSamples_Tent_5x5(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV); - return fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z)) - + fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z)) - + fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z)) - + fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z)) - + fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z)) - + fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z)) - + fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z)) - + fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z)) - + fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z)); + return fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[0].xy, shadowCoord.z)) + + fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[1].xy, shadowCoord.z)) + + fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[2].xy, shadowCoord.z)) + + fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[3].xy, shadowCoord.z)) + + fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[4].xy, shadowCoord.z)) + + fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[5].xy, shadowCoord.z)) + + fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[6].xy, shadowCoord.z)) + + fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[7].xy, shadowCoord.z)) + + fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[8].xy, shadowCoord.z)); } -real SampleShadowmapFilteredHighQuality(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +real SampleShadowmapFilteredHighQuality( + TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) { real fetchesWeights[16]; real2 fetchesUV[16]; SampleShadow_ComputeSamples_Tent_7x7(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV); - return fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z)) - + fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z)) - + fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z)) - + fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z)) - + fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z)) - + fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z)) - + fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z)) - + fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z)) - + fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z)) - + fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[9].xy, shadowCoord.z)) - + fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[10].xy, shadowCoord.z)) - + fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[11].xy, shadowCoord.z)) - + fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[12].xy, shadowCoord.z)) - + fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[13].xy, shadowCoord.z)) - + fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[14].xy, shadowCoord.z)) - + fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z)); + return fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[0].xy, shadowCoord.z)) + + fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[1].xy, shadowCoord.z)) + + fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[2].xy, shadowCoord.z)) + + fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[3].xy, shadowCoord.z)) + + fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[4].xy, shadowCoord.z)) + + fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[5].xy, shadowCoord.z)) + + fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[6].xy, shadowCoord.z)) + + fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[7].xy, shadowCoord.z)) + + fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[8].xy, shadowCoord.z)) + + fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[9].xy, shadowCoord.z)) + + fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[10].xy, shadowCoord.z)) + + fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[11].xy, shadowCoord.z)) + + fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[12].xy, shadowCoord.z)) + + fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[13].xy, shadowCoord.z)) + + fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[14].xy, shadowCoord.z)) + + fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, + float3(fetchesUV[15].xy, shadowCoord.z)); } -real SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +real SampleShadowmapFiltered( + TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) { real attenuation = real(1.0); if (samplingData.softShadowQuality == SOFT_SHADOW_QUALITY_LOW) { - attenuation = SampleShadowmapFilteredLowQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + attenuation = SampleShadowmapFilteredLowQuality( + TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); } - else if(samplingData.softShadowQuality == SOFT_SHADOW_QUALITY_MEDIUM) + else if (samplingData.softShadowQuality == SOFT_SHADOW_QUALITY_MEDIUM) { - attenuation = SampleShadowmapFilteredMediumQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + attenuation = SampleShadowmapFilteredMediumQuality( + TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); } else // SOFT_SHADOW_QUALITY_HIGH { - attenuation = SampleShadowmapFilteredHighQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + attenuation = SampleShadowmapFilteredHighQuality( + TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); } return attenuation; } -real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, half4 shadowParams, bool isPerspectiveProjection = true) +real SampleShadowmap( + TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, + half4 shadowParams, bool isPerspectiveProjection = true) { // Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time if (isPerspectiveProjection) @@ -296,7 +332,7 @@ real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); } #else - attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); + attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); #endif attenuation = LerpWhiteTo(attenuation, shadowStrength); @@ -312,7 +348,8 @@ half ComputeCascadeIndex(float3 positionWS) float3 fromCenter1 = positionWS - _CascadeShadowSplitSpheres1.xyz; float3 fromCenter2 = positionWS - _CascadeShadowSplitSpheres2.xyz; float3 fromCenter3 = positionWS - _CascadeShadowSplitSpheres3.xyz; - float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3)); + float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), + dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3)); half4 weights = half4(distances2 < _CascadeShadowSplitSphereRadii); weights.yzw = saturate(weights.yzw - weights.xyz); @@ -322,11 +359,11 @@ half ComputeCascadeIndex(float3 positionWS) float4 TransformWorldToShadowCoord(float3 positionWS) { -#ifdef _MAIN_LIGHT_SHADOWS_CASCADE + #ifdef _MAIN_LIGHT_SHADOWS_CASCADE half cascadeIndex = ComputeCascadeIndex(positionWS); -#else + #else half cascadeIndex = half(0.0); -#endif + #endif float4 shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0)); @@ -336,8 +373,8 @@ float4 TransformWorldToShadowCoord(float3 positionWS) half MainLightRealtimeShadow(float4 shadowCoord) { #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) - return half(1.0); - #elif defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) + return half(1.0); + #elif ( defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)) float attenuation = SampleScreenSpaceShadowmap(shadowCoord); return attenuation; #else @@ -370,15 +407,15 @@ half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 ligh shadowSliceIndex += cubemapFaceId; } - #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA + #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA float4 shadowCoord = mul(_AdditionalLightsWorldToShadow_SSBO[shadowSliceIndex], float4(positionWS, 1.0)); - #else + #else float4 shadowCoord = mul(_AdditionalLightsWorldToShadow[shadowSliceIndex], float4(positionWS, 1.0)); - #endif + #endif return SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, true); #else - return half(1.0); + return half(1.0); #endif } @@ -400,17 +437,17 @@ half GetAdditionalLightShadowFade(float3 positionWS) float fade = saturate(distanceCamToPixel2 * float(_AdditionalShadowFadeParams.x) + float(_AdditionalShadowFadeParams.y)); return half(fade); #else - return half(1.0); + return half(1.0); #endif } half MixRealtimeAndBakedShadows(half realtimeShadow, half bakedShadow, half shadowFade) { -#if defined(LIGHTMAP_SHADOW_MIXING) + #if defined(LIGHTMAP_SHADOW_MIXING) return min(lerp(realtimeShadow, 1, shadowFade), bakedShadow); -#else + #else return lerp(realtimeShadow, bakedShadow, shadowFade); -#endif + #endif } half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels) @@ -423,61 +460,94 @@ half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels) return bakedShadow; } -half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels) +half MainLightShadow(float4 shadowCoord, float2 screenUV, float3 positionWS, half4 shadowMask, + half4 occlusionProbeChannels) { - half realtimeShadow = MainLightRealtimeShadow(shadowCoord); - #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && defined(_SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF) + #if defined(_SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF) + // mip 可能造成更多 PCF + half realtimeShadow = half(SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_PointClamp, float3(screenUV.xy, 2)).x); UNITY_BRANCH if(abs(realtimeShadow - 0.5) < 0.499) { - float4 shadowCoord1 = TransformWorldToShadowCoord(positionWS); ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData(); half4 shadowParams = GetMainLightShadowParams(); - realtimeShadow = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord1, shadowSamplingData, shadowParams, false); + realtimeShadow = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, false); } + + #elif defined(_SOFTSHADOW_MASK) + half realtimeShadow = half(SAMPLE_TEXTURE2D(_SoftShadowMaskTexture, sampler_PointClamp, screenUV.xy).x); + UNITY_BRANCH + if(abs(realtimeShadow - 0.5) < 0.499) + { + ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData(); + half4 shadowParams = GetMainLightShadowParams(); + realtimeShadow = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, false); + } + #else + half realtimeShadow = MainLightRealtimeShadow(shadowCoord); #endif -#ifdef CALCULATE_BAKED_SHADOWS + #ifdef CALCULATE_BAKED_SHADOWS half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels); -#else + #else half bakedShadow = half(1.0); -#endif + #endif -#ifdef MAIN_LIGHT_CALCULATE_SHADOWS + #ifdef MAIN_LIGHT_CALCULATE_SHADOWS half shadowFade = GetMainLightShadowFade(positionWS); -#else + #else half shadowFade = half(1.0); -#endif + #endif return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); } -half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels) +half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels) +{ + half realtimeShadow = MainLightRealtimeShadow(shadowCoord); + + #ifdef CALCULATE_BAKED_SHADOWS + half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels); + #else + half bakedShadow = half(1.0); + #endif + + #ifdef MAIN_LIGHT_CALCULATE_SHADOWS + half shadowFade = GetMainLightShadowFade(positionWS); + #else + half shadowFade = half(1.0); + #endif + + return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); +} + +half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, + half4 occlusionProbeChannels) { half realtimeShadow = AdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection); -#ifdef CALCULATE_BAKED_SHADOWS + #ifdef CALCULATE_BAKED_SHADOWS half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels); -#else + #else half bakedShadow = half(1.0); -#endif + #endif -#ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS + #ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS half shadowFade = GetAdditionalLightShadowFade(positionWS); -#else + #else half shadowFade = half(1.0); -#endif + #endif return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); } float4 GetShadowCoord(VertexPositionInputs vertexInput) { -#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) + #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) return ComputeScreenPos(vertexInput.positionCS); -#else + #else return TransformWorldToShadowCoord(vertexInput.positionWS); -#endif + #endif } float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection) @@ -525,21 +595,24 @@ half GetMainLightShadowStrength() half GetAdditionalLightShadowStrenth(int lightIndex) { #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) - #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA + #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA return _AdditionalShadowParams_SSBO[lightIndex].x; - #else - return _AdditionalShadowParams[lightIndex].x; - #endif #else - return half(1.0); + return _AdditionalShadowParams[lightIndex].x; + #endif + #else + return half(1.0); #endif } // Deprecated: Use SampleShadowmap that takes shadowParams instead of strength. -real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, half shadowStrength, bool isPerspectiveProjection = true) +real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), + ShadowSamplingData samplingData, half shadowStrength, bool isPerspectiveProjection = true) { half4 shadowParams = half4(shadowStrength, 1.0, 0.0, 0.0); - return SampleShadowmap(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, shadowParams, isPerspectiveProjection); + return SampleShadowmap( + TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, shadowParams, + isPerspectiveProjection); } // Deprecated: Use AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) in Shadows.hlsl instead, as it supports Point Light shadows diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/Lit.shader index 9e4a8bf..d241d1d 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/Lit.shader @@ -135,6 +135,7 @@ Shader "Universal Render Pipeline/Lit" // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ _SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF + #pragma multi_compile_fragment _ _SOFTSHADOW_MASK #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS @@ -168,7 +169,7 @@ Shader "Universal Render Pipeline/Lit" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" #pragma multi_compile_vertex _ ENABLE_VS_SKINNING - +#pragma enable_d3d11_debug_symbols #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl" ENDHLSL diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/LitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/LitForwardPass.hlsl index ba3d38a..3368d64 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/LitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Shaders/LitForwardPass.hlsl @@ -232,6 +232,7 @@ void LitPassFragment( #endif half4 color = UniversalFragmentPBR(inputData, surfaceData); + color.rgb = MixFog(color.rgb, inputData.fogCoord); color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent(_Surface));