using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class PixelateFeature : ScriptableRendererFeature { public class PixelatePass : ScriptableRenderPass { private static readonly string ProfilerTag = "PixelateEffect"; private static readonly int PixelateStrengthXID = Shader.PropertyToID("_PixelateStrengthX"); private static readonly int PixelateStrengthYID = Shader.PropertyToID("_PixelateStrengthY"); private static readonly int SourceTextureID = Shader.PropertyToID("_SourceTexture"); public Material pixelateMaterial; public float pixelateX = 64f; public float pixelateY = 64f; private RTHandle sourceRT; private RTHandle transientRT; public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { sourceRT = renderingData.cameraData.renderer.cameraColorTargetHandle; RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor; descriptor.depthBufferBits = 0; RenderingUtils.ReAllocateIfNeeded(ref transientRT, descriptor, name: "_PixelateTransientRT"); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (pixelateMaterial == null) return; CommandBuffer cmd = CommandBufferPool.Get(ProfilerTag); pixelateMaterial.SetFloat(PixelateStrengthXID, pixelateX); pixelateMaterial.SetFloat(PixelateStrengthYID, pixelateY); cmd.SetGlobalTexture(SourceTextureID, sourceRT); cmd.SetRenderTarget(transientRT, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cmd.DrawProcedural(Matrix4x4.identity, pixelateMaterial, 0, MeshTopology.Triangles, 3); cmd.SetGlobalTexture(SourceTextureID, transientRT); cmd.SetRenderTarget(sourceRT, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cmd.DrawProcedural(Matrix4x4.identity, pixelateMaterial, 0, MeshTopology.Triangles, 3); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } public void UpdateConfig(float x, float y) { pixelateX = x; pixelateY = y; } } [System.Serializable] public class PixelateSettings { [SerializeField] private Shader pixelateShader; private Material pixelateMaterial; public Material PixelateMaterial { get { if (pixelateMaterial == null && pixelateShader != null) { pixelateMaterial = new Material(pixelateShader) { hideFlags = HideFlags.HideAndDontSave }; } return pixelateMaterial; } } [Min(2)] public float pixelateStrengthX = 64f; [Min(2)] public float pixelateStrengthY = 64f; public RenderPassEvent passEvent = RenderPassEvent.AfterRenderingTransparents; } public PixelateSettings settings = new(); public PixelatePass pixelatePass; public override void Create() { pixelatePass = new PixelatePass { renderPassEvent = settings.passEvent, pixelateMaterial = settings.PixelateMaterial, pixelateX = settings.pixelateStrengthX, pixelateY = settings.pixelateStrengthY }; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(pixelatePass); } }