Files
Bombaleila/Assets/ThunderWire Studio/UHFPS/Content/Shaders/DualKawaseBlur/Runtime/DualKawaseBlurPass.cs
2026-03-03 05:27:03 +05:00

105 lines
4.0 KiB
C#

using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
using UnityEngine;
namespace UHFPS.Rendering
{
public class DualKawaseBlurPass : ScriptableRenderPass
{
internal struct Level
{
internal int down;
internal int up;
}
private static readonly int BlurOffset = Shader.PropertyToID("_Offset");
private const string PROFILER_TAG = "DualKawaseBlur";
internal Level[] m_Pyramid;
const int k_MaxPyramidSize = 16;
private readonly Material material;
public DualKawaseBlurPass(RenderPassEvent renderPassEvent, Material material)
{
this.renderPassEvent = renderPassEvent;
this.material = material;
m_Pyramid = new Level[k_MaxPyramidSize];
for (int i = 0; i < k_MaxPyramidSize; i++)
{
m_Pyramid[i] = new Level
{
down = Shader.PropertyToID("_BlurMipDown" + i),
up = Shader.PropertyToID("_BlurMipUp" + i)
};
}
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (material == null) return;
if (renderingData.cameraData.isSceneViewCamera) return;
if (!renderingData.cameraData.postProcessEnabled) return;
VolumeStack stack = VolumeManager.instance.stack;
DualKawaseBlur blurVolume = stack.GetComponent<DualKawaseBlur>();
if (blurVolume == null || !blurVolume.IsActive()) return;
var cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, new ProfilingSampler(PROFILER_TAG)))
{
Camera camera = renderingData.cameraData.camera;
int tw = (int)(camera.pixelWidth / blurVolume.RTDownScaling.value);
int th = (int)(camera.pixelHeight / blurVolume.RTDownScaling.value);
material.SetFloat(BlurOffset, Mathf.Sqrt(blurVolume.BlurRadius.value));
#if UNITY_2022_1_OR_NEWER
var cameraColor = renderingData.cameraData.renderer.cameraColorTargetHandle.rt;
#else
var cameraColor = renderingData.cameraData.renderer.cameraColorTarget;
#endif
// Downsample
RenderTargetIdentifier lastDown = cameraColor;
for (int i = 0; i < blurVolume.Iteration.value; i++)
{
int mipDown = m_Pyramid[i].down;
int mipUp = m_Pyramid[i].up;
cmd.GetTemporaryRT(mipDown, tw, th, 0, FilterMode.Bilinear);
cmd.GetTemporaryRT(mipUp, tw, th, 0, FilterMode.Bilinear);
cmd.Blit(lastDown, mipDown, material, 0);
lastDown = mipDown;
tw = Mathf.Max(tw / 2, 1);
th = Mathf.Max(th / 2, 1);
}
// Upsample
int lastUp = m_Pyramid[blurVolume.Iteration.value - 1].down;
for (int i = blurVolume.Iteration.value - 2; i >= 0; i--)
{
int mipUp = m_Pyramid[i].up;
cmd.Blit(lastUp, mipUp, material, 1);
lastUp = mipUp;
}
// Render blurred texture in blend pass
cmd.Blit(lastUp, cameraColor, material, 1);
// Cleanup
int originalLastUp = m_Pyramid[blurVolume.Iteration.value - 1].down;
for (int i = 0; i < blurVolume.Iteration.value; i++)
{
if (m_Pyramid[i].down != originalLastUp)
cmd.ReleaseTemporaryRT(m_Pyramid[i].down);
if (m_Pyramid[i].up != originalLastUp)
cmd.ReleaseTemporaryRT(m_Pyramid[i].up);
}
}
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
CommandBufferPool.Release(cmd);
}
}
}