105 lines
3.9 KiB
C#
105 lines
3.9 KiB
C#
using System;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
namespace X.Rendering.Feature
|
|
{
|
|
public class SoftShadowMask : ScriptableRendererFeature
|
|
{
|
|
[Serializable]
|
|
private class Settings
|
|
{
|
|
public bool BlurMask = false;
|
|
public bool Use16Samples = true;
|
|
public Material MaskMat = null;
|
|
public Material BlurMat = null;
|
|
}
|
|
|
|
[SerializeField]
|
|
private Settings settings = new();
|
|
SoftShadowMaskPass shadowMaskPass;
|
|
|
|
public override void Create()
|
|
{
|
|
shadowMaskPass = new(settings);
|
|
}
|
|
|
|
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
|
{
|
|
renderer.EnqueuePass(shadowMaskPass);
|
|
}
|
|
|
|
|
|
class SoftShadowMaskPass : ScriptableRenderPass
|
|
{
|
|
internal static readonly int SoftShadowMaskTextureId = Shader.PropertyToID("_SoftShadowMaskTexture");
|
|
internal static readonly GlobalKeyword softShadowMaskKeyword = GlobalKeyword.Create("_SOFTSHADOW_MASK");
|
|
|
|
private Settings settings;
|
|
private ProfilingSampler profiler;
|
|
Vector4[] offset16Array = new Vector4[8];
|
|
Vector4[] offset5Array = new Vector4[2];
|
|
RTHandle softShadowMask;
|
|
|
|
public SoftShadowMaskPass(Settings settings)
|
|
{
|
|
this.settings = settings;
|
|
renderPassEvent = RenderPassEvent.AfterRenderingPrePasses;
|
|
profiler = new(nameof(SoftShadowMaskPass));
|
|
}
|
|
|
|
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
|
{
|
|
var cmd = renderingData.commandBuffer;
|
|
using var scp = new ProfilingScope(cmd, profiler);
|
|
cmd.EnableKeyword(softShadowMaskKeyword);
|
|
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);
|
|
}
|
|
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()
|
|
{
|
|
bindMS = false,
|
|
colorFormat = RenderTextureFormat.R8,
|
|
width = w / 4,
|
|
height = h / 4,
|
|
enableRandomWrite = false,
|
|
depthBufferBits = 0,
|
|
dimension = TextureDimension.Tex2D,
|
|
msaaSamples = 1,
|
|
});
|
|
cmd.SetRenderTarget(softShadowMask);
|
|
cmd.DrawProcedural(Matrix4x4.identity, settings.MaskMat, 0, MeshTopology.Triangles, 3);
|
|
cmd.SetGlobalTexture(SoftShadowMaskTextureId, softShadowMask);
|
|
}
|
|
|
|
public override void OnFinishCameraStackRendering(CommandBuffer cmd)
|
|
{
|
|
base.OnFinishCameraStackRendering(cmd);
|
|
cmd.DisableKeyword(softShadowMaskKeyword);
|
|
}
|
|
}
|
|
}
|
|
}
|