122 lines
5.2 KiB
C#
122 lines
5.2 KiB
C#
using System;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
using static UnityEngine.Rendering.Universal.UniversalRenderPipeline.Profiling.Pipeline;
|
|
|
|
namespace X.Rendering.Feature
|
|
{
|
|
public class SoftShadowMask : ScriptableRendererFeature
|
|
{
|
|
[Serializable]
|
|
private class Settings
|
|
{
|
|
public bool BlurMask = false;
|
|
public Material MaskMat = null;
|
|
public Material BlurMat = null;
|
|
public int BlurIterations = 3;
|
|
public float BlurSpread = 0.6f;
|
|
}
|
|
|
|
[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[] offsetArray = new Vector4[4];
|
|
RTHandle softShadowMask;
|
|
RTHandle buffer0;
|
|
RTHandle buffer1;
|
|
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 };
|
|
{
|
|
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);
|
|
}
|
|
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,
|
|
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);
|
|
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)
|
|
{
|
|
base.OnFinishCameraStackRendering(cmd);
|
|
cmd.DisableKeyword(softShadowMaskKeyword);
|
|
}
|
|
}
|
|
}
|
|
}
|