soft shadow mask

This commit is contained in:
StarBeats 2025-07-17 17:21:42 +08:00
parent ec312c498e
commit 9852662f7d
13 changed files with 429 additions and 189 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ac5e0807b54a94e4a9d8093afd986e43
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}

View File

@ -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: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0487cfddca141924d8a1736f6c0b9b7b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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,27 +60,15 @@ 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,
@ -88,10 +78,37 @@ namespace X.Rendering.Feature
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)

View File

@ -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);

View File

@ -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))

View File

@ -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<float4> _AdditionalShadowParams_SSBO; // Per-light data - TODO: test if splitting _AdditionalShadowParams_SSBO[lightIndex].w into a separate StructuredBuffer<int> buffer is faster
StructuredBuffer<float4x4> _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

View File

@ -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

View File

@ -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));