add soft PlanarScreenShadow

This commit is contained in:
StarBeats 2025-07-20 17:26:12 +08:00
parent 58a65fd1b2
commit e9583e6fdc
17 changed files with 713 additions and 33 deletions

View File

@ -4667,6 +4667,14 @@ PrefabInstance:
propertyPath: CameraManager propertyPath: CameraManager
value: value:
objectReference: {fileID: 2012500279} objectReference: {fileID: 2012500279}
- target: {fileID: 4708105552671890492, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
propertyPath: m_Layer
value: 13
objectReference: {fileID: 0}
- target: {fileID: 4708105552671890492, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5542111180780342640, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3} - target: {fileID: 5542111180780342640, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
propertyPath: near clip plane propertyPath: near clip plane
value: 0.2 value: 0.2

View File

@ -52,6 +52,9 @@
}, },
{ {
"m_Id": "88da0599e9d94034811c72283049022d" "m_Id": "88da0599e9d94034811c72283049022d"
},
{
"m_Id": "d68fe775c2244281aaaf884b54f7550e"
} }
], ],
"m_Dropdowns": [], "m_Dropdowns": [],
@ -5314,8 +5317,8 @@
"m_ObjectId": "57babe972b6b4f82913b0f9611d0db56", "m_ObjectId": "57babe972b6b4f82913b0f9611d0db56",
"m_Title": "Sand Normal Unpack", "m_Title": "Sand Normal Unpack",
"m_Position": { "m_Position": {
"x": 1625.9998779296875, "x": 1626.0003662109375,
"y": 521.0001220703125 "y": 521.0
} }
} }
@ -5522,7 +5525,7 @@
"m_ObjectId": "5d0be58100c74d1580b95814654e3dba", "m_ObjectId": "5d0be58100c74d1580b95814654e3dba",
"m_Title": "Sand Color Ramp & pack Color+Smoothness", "m_Title": "Sand Color Ramp & pack Color+Smoothness",
"m_Position": { "m_Position": {
"x": 1477.9998779296875, "x": 1478.0001220703125,
"y": 295.0 "y": 295.0
} }
} }
@ -5921,8 +5924,8 @@
"m_ObjectId": "68757db7797640349d4c8ed3c2186f5b", "m_ObjectId": "68757db7797640349d4c8ed3c2186f5b",
"m_Title": "Gravels textures sample", "m_Title": "Gravels textures sample",
"m_Position": { "m_Position": {
"x": 1723.0, "x": 1723.0001220703125,
"y": -632.0 "y": -632.0000610351563
} }
} }
@ -5995,7 +5998,7 @@
"m_ObjectId": "71f3e8e98fc245bb86e4724c9cd07690", "m_ObjectId": "71f3e8e98fc245bb86e4724c9cd07690",
"m_Title": "Sand Footsteps", "m_Title": "Sand Footsteps",
"m_Position": { "m_Position": {
"x": 828.0001220703125, "x": 828.0001831054688,
"y": 452.0 "y": 452.0
} }
} }
@ -6270,8 +6273,8 @@
"m_ObjectId": "7b17344c163a452c9f42669137517050", "m_ObjectId": "7b17344c163a452c9f42669137517050",
"m_Title": "Sands Heights (R: Smooth, G: Harsh, B:Footsteps)", "m_Title": "Sands Heights (R: Smooth, G: Harsh, B:Footsteps)",
"m_Position": { "m_Position": {
"x": -398.00006103515627, "x": -398.0,
"y": 1061.0 "y": 1061.000244140625
} }
} }
@ -8292,7 +8295,7 @@
"m_ObjectId": "aedc4a1ea6fd47c6b29d08142b8e7496", "m_ObjectId": "aedc4a1ea6fd47c6b29d08142b8e7496",
"m_Title": "Gravels Wetness", "m_Title": "Gravels Wetness",
"m_Position": { "m_Position": {
"x": 2710.0, "x": 2710.000244140625,
"y": -634.0 "y": -634.0
} }
} }
@ -9214,6 +9217,9 @@
}, },
{ {
"m_Id": "88da0599e9d94034811c72283049022d" "m_Id": "88da0599e9d94034811c72283049022d"
},
{
"m_Id": "d68fe775c2244281aaaf884b54f7550e"
} }
] ]
} }
@ -9269,7 +9275,7 @@
"m_ObjectId": "c8c4cd8384354517bd21fdc741a20c9b", "m_ObjectId": "c8c4cd8384354517bd21fdc741a20c9b",
"m_Title": "Sand Harsh", "m_Title": "Sand Harsh",
"m_Position": { "m_Position": {
"x": 242.00001525878907, "x": 242.0,
"y": 452.0 "y": 452.0
} }
} }
@ -9437,8 +9443,8 @@
"m_ObjectId": "cecd406a7faa4c75bd0b5a6a4377d8e1", "m_ObjectId": "cecd406a7faa4c75bd0b5a6a4377d8e1",
"m_Title": "Vertex Color A : normal intensity", "m_Title": "Vertex Color A : normal intensity",
"m_Position": { "m_Position": {
"x": -637.0000610351563, "x": -637.0,
"y": 427.0 "y": 427.0000305175781
} }
} }
@ -9671,6 +9677,31 @@
"m_Labels": [] "m_Labels": []
} }
{
"m_SGVersion": 1,
"m_Type": "UnityEditor.ShaderGraph.ShaderKeyword",
"m_ObjectId": "d68fe775c2244281aaaf884b54f7550e",
"m_Guid": {
"m_GuidSerialized": "30932fa6-64db-4c78-9c9f-56fbb3e86f62"
},
"m_Name": "PLANAR_SHADOW",
"m_DefaultRefNameVersion": 1,
"m_RefNameGeneratedByDisplayName": "PLANAR_SHADOW",
"m_DefaultReferenceName": "_PLANAR_SHADOW",
"m_OverrideReferenceName": "PLANAR_SHADOW",
"m_GeneratePropertyBlock": true,
"m_UseCustomSlotLabel": false,
"m_CustomSlotLabel": "",
"m_DismissedVersion": 0,
"m_KeywordType": 0,
"m_KeywordDefinition": 1,
"m_KeywordScope": 1,
"m_KeywordStages": 2,
"m_Entries": [],
"m_Value": 0,
"m_IsEditable": true
}
{ {
"m_SGVersion": 0, "m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot",

View File

@ -52,7 +52,7 @@ MonoBehaviour:
m_Cascade2Split: 0.25 m_Cascade2Split: 0.25
m_Cascade3Split: {x: 0.1, y: 0.3} m_Cascade3Split: {x: 0.1, y: 0.3}
m_Cascade4Split: {x: 0.049999993, y: 0.14999999, z: 0.5} m_Cascade4Split: {x: 0.049999993, y: 0.14999999, z: 0.5}
m_CascadeShadowOffset: {x: 0, y: 0, z: 4.4} m_CascadeShadowOffset: {x: 0, y: 0, z: 0}
enableShadowOffset: 1 enableShadowOffset: 1
m_CascadeBorder: 0.48867315 m_CascadeBorder: 0.48867315
m_ShadowDepthBias: 1 m_ShadowDepthBias: 1

View File

@ -108,6 +108,29 @@ MonoBehaviour:
cutoffThreshold: 0.2 cutoffThreshold: 0.2
binaryValue: 0.9 binaryValue: 0.9
flags: 13 flags: 13
--- !u!114 &-5418649131825517062
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b5a3747493cb37e4aa9909e94ba4739d, type: 3}
m_Name: PlanarScreenShadow
m_EditorClassIdentifier:
m_Active: 0
settings:
PlanarShadowMat: {fileID: 2100000, guid: ce6debd28bc41e144a6cf99005cf820e, type: 2}
planarShadowColor: {r: 0, g: 0, b: 0, a: 1}
castPlaneOffset: -1
castPlaneNormal: {x: 0, y: 1, z: 0}
shadowResolution: 256
softQuality: 32
softScaleByDistance: 2.32
softGradientDistance: 15
minSoft: 1
--- !u!114 &-4454652084718109581 --- !u!114 &-4454652084718109581
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -313,7 +336,8 @@ MonoBehaviour:
- {fileID: -1629415145513658388} - {fileID: -1629415145513658388}
- {fileID: 7541218312462517771} - {fileID: 7541218312462517771}
- {fileID: 5808157236138506604} - {fileID: 5808157236138506604}
m_RendererFeatureMap: bc3f630842f2e70dd6a559c442a94bfd4529d15534f2d3de228858dca8d12222716523fbf3439fdb7a327b7bff4bdd446ac59dfa966ffa88ca6373cd5da9013d6cff55ca297e5e908a7b3653203b82383b2141bb05fbe69aec5704e48e2763e90bc6ff9f19caa7686c79a6bb3bb89a50 - {fileID: -5418649131825517062}
m_RendererFeatureMap: bc3f630842f2e70dd6a559c442a94bfd4529d15534f2d3de228858dca8d12222716523fbf3439fdb7a327b7bff4bdd446ac59dfa966ffa88ca6373cd5da9013d6cff55ca297e5e908a7b3653203b82383b2141bb05fbe69aec5704e48e2763e90bc6ff9f19caa7686c79a6bb3bb89a50faad0fe75217cdb4
m_UseNativeRenderPass: 0 m_UseNativeRenderPass: 0
postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2}
shaders: shaders:
@ -540,7 +564,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: eab40a9966087544f860c63893896a09, type: 3} m_Script: {fileID: 11500000, guid: eab40a9966087544f860c63893896a09, type: 3}
m_Name: SoftShadowMask m_Name: SoftShadowMask
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Active: 1 m_Active: 0
settings: settings:
BlurMask: 1 BlurMask: 1
MaskMat: {fileID: 2100000, guid: 1368366248809f24e9a110be3075d1b8, type: 2} MaskMat: {fileID: 2100000, guid: 1368366248809f24e9a110be3075d1b8, type: 2}

View File

@ -0,0 +1,330 @@
using System;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RendererUtils;
using UnityEngine.Rendering.Universal;
namespace X.Rendering.Feature
{
[DisallowMultipleRendererFeature("PlanarScreenShadow")]
public class PlanarScreenShadow : ScriptableRendererFeature
{
public enum SoftQuality
{
None = 0,
Low = 10,
Medium = 16,
High = 32,
}
public enum ShadowResolution
{
_256 = 256,
_512 = 512,
_768 = 768,
_1024 = 1024,
}
[Serializable]
private class Settings
{
public Material PlanarShadowMat;
public Color planarShadowColor = Color.grey;
public float castPlaneOffset = 0;
public Vector3 castPlaneNormal = Vector3.up;
public ShadowResolution shadowResolution = ShadowResolution._512;
public SoftQuality softQuality = SoftQuality.Medium;
public float softScaleByDistance = 1.0f;
public float softGradientDistance = 15f;
[Range(0.0f, 1.0f)]
public float minSoft = 0.1f;
}
[SerializeField]
private Settings settings = new();
PlanarShadowRenderPass pnanarShaowPass;
/// <inheritdoc/>
public override void Create()
{
pnanarShaowPass = new PlanarShadowRenderPass(settings);
pnanarShaowPass.renderPassEvent = RenderPassEvent.BeforeRenderingOpaques;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(pnanarShaowPass);
}
class PlanarShadowRenderPass : ScriptableRenderPass
{
private RTHandle planarShadowRT;
private RTHandle shadowDistanceTempTarget;
private RTHandle shadowDistanceTarget;
private RTHandle softShadowRenderTarget;
private Settings settings;
private ShaderTagId[] planarShadowShaderIds = new ShaderTagId[] { new ShaderTagId("PlanarShadow") , new ShaderTagId("UniversalForward") };
private ProfilingSampler profiler;
static GlobalKeyword planarShadowKeyword;
static GlobalKeyword lowSoftQuality;
static GlobalKeyword mediumSoftQuality;
static GlobalKeyword highSoftQuality;
static Vector4[] lowSoftOperator;
static Vector4[] mediumSoftOperator;
static Vector4[] highSoftOperator;
static readonly int playerLayer = LayerMask.NameToLayer("Player");
public PlanarShadowRenderPass(Settings settings)
{
this.settings = settings;
InitOperators();
planarShadowKeyword = GlobalKeyword.Create("PLANAR_SHADOW");
lowSoftQuality = GlobalKeyword.Create("LOW_SOFT_QUALITY");
mediumSoftQuality = GlobalKeyword.Create("MEDIUM_SOFT_QUALITY");
highSoftQuality = GlobalKeyword.Create("HIGH_SOFT_QUALITY");
profiler = new(nameof(PlanarShadowRenderPass));
}
private static void InitOperators()
{
lowSoftOperator = new Vector4[32]
{
new Vector4(-0.7449182f, -0.3948351f, 0.05994137f, 0f),
new Vector4(0.04522014f, -0.7452399f, 0.08145966f, 0f),
new Vector4(0.5859449f, -0.3042229f, 0.1038759f, 0f),
new Vector4(0.2801918f, 0.1988664f, 0.1961446f, 0f),
new Vector4(0.8921295f, 0.231646f, 0.04541548f, 0f),
new Vector4(-0.2148036f, -0.2805325f, 0.1935014f, 0f),
new Vector4(-0.3599106f, 0.2223929f, 0.1736383f, 0f),
new Vector4(-0.8255251f, 0.4714117f, 0.04075267f, 0f),
new Vector4(0.1672432f, 0.8953505f, 0.0472625f, 0f),
new Vector4(-0.3843737f, 0.7612128f, 0.05800831f, 0f),
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,};
mediumSoftOperator = new Vector4[32]
{
new Vector4(-0.573014f, -0.3037193f, 0.07195906f, 0f),
new Vector4(0.03478467f, -0.5732615f, 0.08628026f, 0f),
new Vector4(-0.4175899f, -0.7260013f, 0.04103231f, 0f),
new Vector4(-0.2290866f, -0.06732111f, 0.1488967f, 0f),
new Vector4(0.2787023f, -0.9224322f, 0.02605386f, 0f),
new Vector4(0.4750609f, 0.0006364584f, 0.1062624f, 0f),
new Vector4(-0.8097122f, 0.1471269f, 0.04306531f, 0f),
new Vector4(-0.6714117f, 0.6465726f, 0.0293584f, 0f),
new Vector4(-0.0459074f, 0.6448682f, 0.07233827f, 0f),
new Vector4(-0.413441f, 0.2941564f, 0.0997189f, 0f),
new Vector4(0.596337f, -0.5908241f, 0.04076795f, 0f),
new Vector4(0.8953905f, 0.02900922f, 0.03352015f, 0f),
new Vector4(0.6646501f, 0.5270658f, 0.03957359f, 0f),
new Vector4(0.2487512f, 0.3517451f, 0.1151315f, 0f),
new Vector4(-0.9710876f, -0.2296215f, 0.0227782f, 0f),
new Vector4(0.1961836f, 0.9729925f, 0.02326321f, 0f),
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,Vector4.zero,
Vector4.zero};
highSoftOperator = new Vector4[32]
{new Vector4(0.4153066f, -0.0570948f, 0.06091154f, 0f),
new Vector4(0.1744031f, 0.1689546f, 0.07693625f, 0f),
new Vector4(0.1248782f, -0.3793401f, 0.06292317f, 0f),
new Vector4(0.377597f, -0.5691307f, 0.03405317f, 0f),
new Vector4(-0.2083057f, -0.1873559f, 0.07398886f, 0f),
new Vector4(0.5849795f, -0.7913114f, 0.0124803f, 0f),
new Vector4(-0.5503789f, -0.6051685f, 0.02270556f, 0f),
new Vector4(0.5012408f, 0.3336388f, 0.04192101f, 0f),
new Vector4(0.02808845f, -0.6995828f, 0.03247567f, 0f),
new Vector4(-0.263142f, -0.4866776f, 0.04693219f, 0f),
new Vector4(0.2714973f, 0.5782288f, 0.03827445f, 0f),
new Vector4(0.6123171f, 0.6595281f, 0.0171343f, 0f),
new Vector4(-0.6475288f, -0.1612791f, 0.03552699f, 0f),
new Vector4(0.4024244f, 0.8707167f, 0.01374556f, 0f),
new Vector4(-0.1119028f, 0.6489825f, 0.03636114f, 0f),
new Vector4(-0.02142411f, 0.9497761f, 0.01423686f, 0f),
new Vector4(-0.2120009f, 0.3269744f, 0.06389162f, 0f),
new Vector4(-0.5039293f, 0.1003278f, 0.05105383f, 0f),
new Vector4(0.8276886f, 0.4618528f, 0.01435572f, 0f),
new Vector4(0.8411248f, -0.5285234f, 0.0120281f, 0f),
new Vector4(-0.3644551f, 0.790384f, 0.0190265f, 0f),
new Vector4(0.306049f, -0.8608109f, 0.01630674f, 0f),
new Vector4(-0.7063691f, 0.6909254f, 0.01228318f, 0f),
new Vector4(0.9388323f, -0.01849926f, 0.01484117f, 0f),
new Vector4(0.6864765f, 0.1109735f, 0.03290983f, 0f),
new Vector4(0.638592f, -0.3184139f, 0.03126587f, 0f),
new Vector4(-0.07949254f, -0.9821419f, 0.01241689f, 0f),
new Vector4(-0.4160894f, -0.9045444f, 0.01192026f, 0f),
new Vector4(-0.7837164f, 0.1824391f, 0.02371033f, 0f),
new Vector4(-0.8274034f, -0.4524156f, 0.01461939f, 0f),
new Vector4(-0.9582478f, -0.1421478f, 0.01325019f, 0f),
new Vector4(-0.4291434f, 0.5112085f, 0.03551322f, 0f),
};
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
Profiler.BeginSample("Planar Screen Shadow Setup");
RecreateRenderTexture(renderingData);
Profiler.EndSample();
}
private void RecreateRenderTexture(RenderingData renderingData)
{
Vector2Int sourceRTSize = new Vector2Int(renderingData.cameraData.scaledWidth, renderingData.cameraData.scaledHeight);
int shadowResolution = (int)settings.shadowResolution;
int resolutionWidth = shadowResolution;
int resolutionHeight = shadowResolution;
if (sourceRTSize.x > sourceRTSize.y)
resolutionWidth = Mathf.RoundToInt(shadowResolution * ((float)sourceRTSize.x / (float)sourceRTSize.y));
else
resolutionHeight = Mathf.RoundToInt(shadowResolution * ((float)sourceRTSize.y / (float)sourceRTSize.x));
if (resolutionWidth == 0 || resolutionHeight == 0)
return;
var shadowMapDesc = new RenderTextureDescriptor();
shadowMapDesc.width = resolutionWidth;
shadowMapDesc.height = resolutionHeight;
shadowMapDesc.depthBufferBits = 0;
shadowMapDesc.msaaSamples = 1;
shadowMapDesc.useMipMap = false;
shadowMapDesc.autoGenerateMips = false;
shadowMapDesc.dimension = TextureDimension.Tex2D;
shadowMapDesc.graphicsFormat = RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8G8_UNorm, FormatUsage.Linear | FormatUsage.Render)
? GraphicsFormat.R8G8_UNorm
: GraphicsFormat.B8G8R8A8_UNorm;
SoftQuality softQuality = settings.softQuality;
FilterMode filterMode = softQuality == SoftQuality.None ? FilterMode.Bilinear : FilterMode.Point;
RenderingUtils.ReAllocateIfNeeded(ref planarShadowRT, shadowMapDesc, filterMode, TextureWrapMode.Clamp, name: "_PlanarShadowMap");
int disMapSize = 64;
int disMapHeight = disMapSize;
int disMapWidth = disMapSize;
if (sourceRTSize.x > sourceRTSize.y)
disMapWidth = Mathf.RoundToInt(disMapSize * ((float)sourceRTSize.x / (float)sourceRTSize.y));
else
disMapHeight = Mathf.RoundToInt(disMapSize * ((float)sourceRTSize.y / (float)sourceRTSize.x));
var distanceMapDesc = shadowMapDesc;
distanceMapDesc.graphicsFormat = RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8_UNorm, FormatUsage.Linear | FormatUsage.Render)
? GraphicsFormat.R8_UNorm
: GraphicsFormat.B8G8R8A8_UNorm;
distanceMapDesc.width = disMapWidth;
distanceMapDesc.height = disMapHeight;
RenderingUtils.ReAllocateIfNeeded(ref shadowDistanceTempTarget, distanceMapDesc, FilterMode.Point, TextureWrapMode.Clamp);
RenderingUtils.ReAllocateIfNeeded(ref shadowDistanceTarget, distanceMapDesc, FilterMode.Bilinear, TextureWrapMode.Clamp);
var softMapDesc = shadowMapDesc;
softMapDesc.graphicsFormat = RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8_UNorm, FormatUsage.Linear | FormatUsage.Render)
? GraphicsFormat.R8_UNorm
: GraphicsFormat.B8G8R8A8_UNorm;
RenderingUtils.ReAllocateIfNeeded(ref softShadowRenderTarget, softMapDesc,
FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_SoftPlanarShadowMap");
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cameraData = renderingData.cameraData;
var cmd = renderingData.commandBuffer;
using var scp = new ProfilingScope(cmd, profiler);
float castPlaneOffset = settings.castPlaneOffset;
Vector3 castPlaneNormal = settings.castPlaneNormal;
ShadowResolution shadowResolution = settings.shadowResolution;
SoftQuality softQuality = settings.softQuality;
float softScaleByDistance = settings.softScaleByDistance;
float softGradientDistance = settings.softGradientDistance;
float minSoft = settings.minSoft;
var rendererListDesc = new RendererListDesc(planarShadowShaderIds, renderingData.cullResults, cameraData.camera)
{
renderQueueRange = RenderQueueRange.all,
sortingCriteria = SortingCriteria.OptimizeStateChanges,
rendererConfiguration = renderingData.perObjectData,
overrideMaterial = settings.PlanarShadowMat,
overrideMaterialPassIndex = 3,
layerMask = 1 << playerLayer,
};
RendererList rendererList = context.CreateRendererList(rendererListDesc);
Vector3 planeNormal = castPlaneNormal.normalized;
Vector4 shadowCasterPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, castPlaneOffset);
cmd.BeginSample("PlanarShadow");
cmd.SetGlobalVector("_PlanarShadowCastPlane", shadowCasterPlane);
cmd.SetGlobalFloat("_MinSoft", Mathf.Clamp01(minSoft));
cmd.SetGlobalFloat("_PlanarShadowMaxSoftDistance", softGradientDistance);
cmd.SetViewProjectionMatrices(cameraData.camera.worldToCameraMatrix, cameraData.camera.projectionMatrix);
cmd.SetRenderTarget(planarShadowRT, loadAction: RenderBufferLoadAction.DontCare, storeAction: RenderBufferStoreAction.Store);
cmd.ClearRenderTarget(false, true, Color.clear);
cmd.DrawRendererList(rendererList);
cmd.EndSample("PlanarShadow");
if (softQuality != SoftQuality.None)
{
cmd.BeginSample("BlurShadow");
VisibleLight mainLight = renderingData.lightData.visibleLights[renderingData.lightData.mainLightIndex];
Vector3 lightDirection = -mainLight.localToWorldMatrix.GetColumn(2);
lightDirection.y = 0;
Vector3 pixelOffset = cameraData.camera.WorldToScreenPoint(Vector3.zero) - cameraData.camera.WorldToScreenPoint(lightDirection);
pixelOffset.z = 0;
pixelOffset = pixelOffset.normalized;
Vector4 shadowScreenVDir = new Vector4(pixelOffset.x, pixelOffset.y, 0, 0);
Vector4 shadowScreenHDir = new Vector4(pixelOffset.x, -pixelOffset.y, 0, 0);
int disMapWidth = shadowDistanceTempTarget.rt.width;
int disMapHeight = shadowDistanceTempTarget.rt.height;
cmd.SetGlobalVector("_ShadowScreenHDir", shadowScreenHDir);
cmd.SetGlobalVector("_ShadowScreenVDir", shadowScreenVDir);
cmd.SetGlobalVector("_EdgeMapTexelSize", new Vector4(1.0f / disMapWidth, 1.0f / disMapHeight, disMapWidth, disMapHeight));
cmd.SetGlobalTexture("_SourceTex", planarShadowRT);
cmd.SetRenderTarget(shadowDistanceTempTarget, loadAction: RenderBufferLoadAction.DontCare, storeAction: RenderBufferStoreAction.Store);
cmd.DrawProcedural(Matrix4x4.identity, settings.PlanarShadowMat, 1, MeshTopology.Triangles, 3);
cmd.SetGlobalTexture("_SourceTex", shadowDistanceTempTarget);
cmd.SetRenderTarget(shadowDistanceTarget, loadAction: RenderBufferLoadAction.DontCare, storeAction: RenderBufferStoreAction.Store);
cmd.DrawProcedural(Matrix4x4.identity, settings.PlanarShadowMat, 0, MeshTopology.Triangles, 3);
Vector4[] possionOperator = lowSoftOperator;
if (softQuality == SoftQuality.Medium)
possionOperator = mediumSoftOperator;
if (softQuality == SoftQuality.High)
possionOperator = highSoftOperator;
cmd.DisableKeyword(lowSoftQuality);
cmd.DisableKeyword(mediumSoftQuality);
cmd.DisableKeyword(highSoftQuality);
if (softQuality == SoftQuality.Low)
cmd.EnableKeyword(lowSoftQuality);
if (softQuality == SoftQuality.Medium)
cmd.EnableKeyword(mediumSoftQuality);
if (softQuality == SoftQuality.High)
cmd.EnableKeyword(highSoftQuality);
cmd.SetGlobalFloat("_SoftScaleByDistance", softScaleByDistance * (float)shadowResolution / 256f);
cmd.SetGlobalTexture("_DistanceTex", shadowDistanceTarget);
cmd.SetGlobalVectorArray(Shader.PropertyToID("_PossionOperator"), possionOperator);
cmd.SetGlobalTexture("_SourceTex", planarShadowRT);
cmd.SetRenderTarget(softShadowRenderTarget, loadAction: RenderBufferLoadAction.DontCare, storeAction: RenderBufferStoreAction.Store);
cmd.DrawProcedural(Matrix4x4.identity, settings.PlanarShadowMat, 2, MeshTopology.Triangles, 3);
cmd.EndSample("BlurShadow");
}
cmd.EnableKeyword(planarShadowKeyword);
cmd.SetGlobalColor("_PlanarShadowColor", settings.planarShadowColor);
cmd.SetGlobalTexture("_PlanarShadowMap", softQuality == SoftQuality.None ? planarShadowRT : softShadowRenderTarget);
}
public override void OnFinishCameraStackRendering(CommandBuffer cmd)
{
cmd.DisableKeyword(planarShadowKeyword);
base.OnFinishCameraStackRendering(cmd);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b5a3747493cb37e4aa9909e94ba4739d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,216 @@
Shader "Unlit/PlanarShadow"
{
SubShader
{
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#ifdef LOW_SOFT_QUALITY
#define OPERATOR_SIZE 10
#elif defined(MEDIUM_SOFT_QUALITY)
#define OPERATOR_SIZE 16
#else
#define OPERATOR_SIZE 32
#endif
struct Varyings
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
TEXTURE2D(_SourceTex);
SAMPLER(sampler_SourceTex);
TEXTURE2D(_DistanceTex);
SAMPLER(sampler_DistanceTex);
SAMPLER(sampler_LinearClamp);
float4 _PossionOperator[32];
float4 _EdgeMapTexelSize;
float4 _SourceTex_TexelSize;
float2 _ShadowScreenHDir;
float2 _ShadowScreenVDir;
float _MinSoft;
float _SoftScaleByDistance;
Varyings FullScreenVert(uint vertexID: SV_VertexID)
{
Varyings o;
o.vertex = GetFullScreenTriangleVertexPosition(vertexID);
o.uv = GetFullScreenTriangleTexCoord(vertexID);
return o;
}
half4 buildSoftEdgeVFrag(Varyings input) : SV_Target
{
half2 uv = input.uv;
half2 uvStep = _EdgeMapTexelSize.xy * _ShadowScreenVDir * 0.6f;
UNITY_UNROLL
for(int i = 0;i<4;i++)
{
half dis = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv - i * uvStep).r;
if(dis > 0)
return dis;
}
return 0;
}
half4 buildSoftEdgeHFrag(Varyings input) : SV_Target
{
half2 uv = input.uv;
half2 uvStep = _SourceTex_TexelSize.xy * _ShadowScreenHDir* 0.6f;
UNITY_UNROLL
for(int i = 0; i < 6; i++)
{
half dis = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv - i * uvStep).r;
half dis2 = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv + i * uvStep).r;
if(dis > 0)
return dis;
if(dis2 > 0)
return dis2;
}
return 0;
}
half4 CircleVisiualFrag(Varyings input) : SV_Target
{
half2 uv = input.uv;
half blurSize = SAMPLE_TEXTURE2D(_DistanceTex, sampler_DistanceTex, uv).r;
half2 uvStep = _SourceTex_TexelSize.xy * (_MinSoft + (1 - _MinSoft) * blurSize) * _SoftScaleByDistance;
half col = 0;
if(blurSize == 0)
return SAMPLE_TEXTURE2D(_SourceTex, sampler_LinearClamp, uv).g;
UNITY_UNROLL
for(int i = 0; i < OPERATOR_SIZE;i++)
{
col += SAMPLE_TEXTURE2D(_SourceTex, sampler_LinearClamp, uv + uvStep * _PossionOperator[i].xy).g * _PossionOperator[i].z;
}
return half4(col.rrr,1);
}
ENDHLSL
Pass
{
Name "BlurV"
HLSLPROGRAM
#pragma vertex FullScreenVert
#pragma fragment buildSoftEdgeVFrag
ENDHLSL
}
Pass
{
Name "BlurH"
HLSLPROGRAM
#pragma vertex FullScreenVert
#pragma fragment buildSoftEdgeHFrag
ENDHLSL
}
Pass
{
Name "CircleVisiual"
HLSLPROGRAM
#pragma multi_compile _ LOW_SOFT_QUALITY MEDIUM_SOFT_QUALITY
#pragma vertex FullScreenVert
#pragma fragment CircleVisiualFrag
ENDHLSL
}
Pass
{
Tags { "LightMode" = "PlanarShadow" }
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#pragma enable_d3d11_debug_symbols
#pragma shader_feature_local TRANSPARENT_SHADOW_CASTER
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
float4 _PlanarShadowCastPlane;
float _PlanarShadowMaxSoftDistance;
half4 _PlanarShadowColor;
TEXTURE2D(_PlanarShadowMap);
SAMPLER(sampler_PlanarShadowMap);
void CastVertexToPlane(float3 oriPositionWS, float3 lightDirection, out float3 positionWS, out float shadowSoftScale, float objtY)
{
float3 planeNor = _PlanarShadowCastPlane.xyz;
float w = _PlanarShadowCastPlane.w + objtY;
// https://zhuanlan.zhihu.com/p/42781261
float castDistance = (w - dot(oriPositionWS.xyz, planeNor)) / dot(lightDirection, planeNor);
positionWS = oriPositionWS.xyz + castDistance * lightDirection;
shadowSoftScale = max(0, castDistance / _PlanarShadowMaxSoftDistance);
}
half3 GetPlanarScreenShadowAttenuation(float2 screenUV)
{
#ifdef PLANAR_SHADOW
half attenutaion = SAMPLE_TEXTURE2D(_PlanarShadowMap, sampler_PlanarShadowMap, screenUV).r;
return lerp(1, _PlanarShadowColor, attenutaion);
#else
return 1;
#endif
}
struct attribute
{
float4 vertex : POSITION;
float2 uv : TEXCOORD;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float softValue : TEXCOORD1;
};
sampler2D _MainTexture;
v2f vert (attribute v)
{
v2f o;
float4 worldPos = mul(UNITY_MATRIX_M, v.vertex);
float3 lightDir = -_MainLightPosition.xyz;
float y = UNITY_MATRIX_M[1][3];
float3 castPosWS;
float softValue;
CastVertexToPlane(worldPos.xyz, lightDir, castPosWS, softValue, y);
o.softValue = softValue;
o.vertex = mul(UNITY_MATRIX_VP, float4(castPosWS, 1));
o.uv = v.uv;
return o;
}
half4 frag (v2f i) : SV_Target
{
#ifdef TRANSPARENT_SHADOW_CASTER
float4 col = tex2D(_MainTexture, i.uv);
#else
float4 col = 1;
#endif
return half4(i.softValue,col.a,0, 0);
}
ENDHLSL
}
}
}

View File

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

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_PlanarShadow
m_Shader: {fileID: 4800000, guid: 4c79b39ee25d0e04ea7d02ed858ff14b, 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: ce6debd28bc41e144a6cf99005cf820e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,7 +3,6 @@ using Unity.Mathematics;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal; using UnityEngine.Rendering.Universal;
using static UnityEngine.Rendering.Universal.UniversalRenderPipeline.Profiling.Pipeline;
namespace X.Rendering.Feature namespace X.Rendering.Feature
{ {

View File

@ -298,7 +298,10 @@ half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData)
inputData.normalWS, inputData.viewDirectionWS, inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff); surfaceData.clearCoatMask, specularHighlightsOff);
} }
#if defined(PLANAR_SHADOW)
lightingData.mainLightColor *= GetPlanarScreenShadowAttenuation(inputData.normalizedScreenSpaceUV);
#endif
#if defined(_ADDITIONAL_LIGHTS) #if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount(); uint pixelLightCount = GetAdditionalLightsCount();

View File

@ -121,6 +121,17 @@ struct ShadowSamplingData
half softShadowQuality; half softShadowQuality;
}; };
#ifdef PLANAR_SHADOW
half4 _PlanarShadowColor;
TEXTURE2D(_PlanarShadowMap);
SAMPLER(sampler_PlanarShadowMap);
half3 GetPlanarScreenShadowAttenuation(float2 screenUV)
{
half attenutaion = SAMPLE_TEXTURE2D(_PlanarShadowMap, sampler_PlanarShadowMap, screenUV).r;
return lerp(1, _PlanarShadowColor, attenutaion);
}
#endif
ShadowSamplingData GetMainLightShadowSamplingData() ShadowSamplingData GetMainLightShadowSamplingData()
{ {
ShadowSamplingData shadowSamplingData; ShadowSamplingData shadowSamplingData;
@ -620,5 +631,4 @@ half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS)
{ {
return AdditionalLightRealtimeShadow(lightIndex, positionWS, half3(1, 0, 0)); return AdditionalLightRealtimeShadow(lightIndex, positionWS, half3(1, 0, 0));
} }
#endif #endif

View File

@ -136,6 +136,7 @@ Shader "Universal Render Pipeline/Lit"
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #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 _ _SCREEN_SPACE_SHADOW_LOW_RESOLUTION_PCF
#pragma multi_compile_fragment _ _SOFTSHADOW_MASK #pragma multi_compile_fragment _ _SOFTSHADOW_MASK
#pragma multi_compile_fragment _ PLANAR_SHADOW
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS

View File

@ -3,18 +3,18 @@
"com.unity.burst": "1.8.19", "com.unity.burst": "1.8.19",
"com.unity.cinemachine": "2.10.3", "com.unity.cinemachine": "2.10.3",
"com.unity.collab-proxy": "2.7.1", "com.unity.collab-proxy": "2.7.1",
"com.unity.ide.rider": "3.0.34", "com.unity.ide.rider": "3.0.35",
"com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.visualstudio": "2.0.22",
"com.unity.ide.vscode": "1.2.5", "com.unity.ide.vscode": "1.2.5",
"com.unity.inputsystem": "1.11.2", "com.unity.inputsystem": "1.14.0",
"com.unity.learn.iet-framework": "3.1.3", "com.unity.learn.iet-framework": "3.1.3",
"com.unity.memoryprofiler": "1.1.4", "com.unity.memoryprofiler": "1.1.6",
"com.unity.recorder": "4.0.3", "com.unity.recorder": "4.0.3",
"com.unity.render-pipelines.universal": "14.0.12", "com.unity.render-pipelines.universal": "14.0.12",
"com.unity.splines": "2.7.2", "com.unity.splines": "2.8.0",
"com.unity.test-framework": "1.1.33", "com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.7", "com.unity.textmeshpro": "3.0.7",
"com.unity.timeline": "1.7.6", "com.unity.timeline": "1.7.7",
"com.unity.ugui": "1.0.0", "com.unity.ugui": "1.0.0",
"com.unity.modules.ai": "1.0.0", "com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0", "com.unity.modules.androidjni": "1.0.0",

View File

@ -51,7 +51,7 @@
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
"com.unity.ide.rider": { "com.unity.ide.rider": {
"version": "3.0.34", "version": "3.0.35",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
@ -76,7 +76,7 @@
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
"com.unity.inputsystem": { "com.unity.inputsystem": {
"version": "1.11.2", "version": "1.14.0",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
@ -102,15 +102,15 @@
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
"com.unity.memoryprofiler": { "com.unity.memoryprofiler": {
"version": "1.1.4", "version": "1.1.6",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
"com.unity.burst": "1.8.0", "com.unity.editorcoroutines": "1.0.0",
"com.unity.collections": "1.2.3", "com.unity.collections": "1.2.3",
"com.unity.mathematics": "1.2.1", "com.unity.mathematics": "1.2.1",
"com.unity.profiling.core": "1.0.0", "com.unity.burst": "1.8.0",
"com.unity.editorcoroutines": "1.0.0" "com.unity.profiling.core": "1.0.0"
}, },
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
@ -186,12 +186,13 @@
} }
}, },
"com.unity.splines": { "com.unity.splines": {
"version": "2.7.2", "version": "2.8.0",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
"com.unity.settings-manager": "1.0.3",
"com.unity.mathematics": "1.2.1", "com.unity.mathematics": "1.2.1",
"com.unity.settings-manager": "1.0.3" "com.unity.modules.imgui": "1.0.0"
}, },
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
@ -216,7 +217,7 @@
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
"com.unity.timeline": { "com.unity.timeline": {
"version": "1.7.6", "version": "1.7.7",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {

View File

@ -22,7 +22,7 @@ TagManager:
- Occluder - Occluder
- Camera - Camera
- MainCameraOnly - MainCameraOnly
- - Player
- -
- -
- -