105 lines
3.9 KiB
C#
Raw Normal View History

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