soft shadow mask
This commit is contained in:
parent
ec312c498e
commit
9852662f7d
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac5e0807b54a94e4a9d8093afd986e43
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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: []
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0487cfddca141924d8a1736f6c0b9b7b
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user