#URP Blitter error custom post process feature?

1 messages · Page 1 of 1 (latest)

woeful garden
#

Hello, I am trying to reimplement bloom as a custom feature and use the post process volume system so it works the same as the bloom from post processing with volumes. However URP seems to now create a blitter more than once causing an exception. I can't figure out why this happens. Is it a bug in URP

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace PostFX
{
    [Serializable, VolumeComponentMenu("PostFX/BloomV2")]
    [SupportedOnRenderPipeline(typeof(UniversalRenderPipeline))]
    public sealed partial class BloomV2 : VolumeComponent, IPostProcessComponent
    {
        /// <summary>
        /// Controls the strength of the bloom filter.
        /// </summary>
        [Tooltip("Strength of the bloom filter.")]
        public MinFloatParameter intensity = new MinFloatParameter(0.0f, 0.0f);

        public bool IsActive() => intensity.value > 0.0f;
    }
}

Exception: Blitter is already initialized. Please only initialize the blitter once or you will leak engine resources. If you need to re-initialize the blitter with different shaders destroy & recreate it.
UnityEngine.Rendering.Blitter.Initialize (UnityEngine.Shader blitPS, UnityEngine.Shader blitColorAndDepthPS) (at ./Library/PackageCache/com.unity.render-pipelines.core@84bf82d10e47/Runtime/Utilities/Blitter.cs:277)
UnityEngine.Rendering.Universal.UniversalRenderPipeline..ctor (UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset asset) (at ./Library/PackageCache/com.unity.render-pipelines.universal@fd0c0d56fb49/Runtime/UniversalRenderPipeline.cs:244)
UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset.CreatePipeline () (at ./Library/PackageCache/com.unity.render-pipelines.universal@fd0c0d56fb49/Runtime/Data/UniversalRenderPipelineAsset.cs:830)
UnityEngine.Rendering.RenderPipelineAsset.InternalCreatePipeline () (at <5fbef2e591e14a4c91f3c5e34508b853>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
#

The base class for the renderpass itself is below that bloom inherits, just copied from Unity's graphics repository where they are splitting post processing up in different passes.

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace PostFX
{
    internal abstract class PostFXPass : ScriptableRenderPass, IDisposable
    {
        VolumeStack m_VolumeStackOverride;

        public VolumeStack volumeStack
        {
            get
            {
                if (m_VolumeStackOverride == null)
                {
                    return VolumeManager.instance.stack;
                }
                else
                {
                    return m_VolumeStackOverride;
                }
            }
        }

        public VolumeStack volumeStackOverride
        {
            set { m_VolumeStackOverride = value; }
        }

        public abstract void Dispose();
    }
}
#
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

namespace PostFX
{
    internal sealed class BloomV2Pass : PostFXPass
    {
        public const int k_MAX_PYRAMID_LEVELS = 16;
        private Material m_BloomMaterial = default;
        private Material[] m_BloomUpsampleMaterial = default;
        private bool m_IsValid = false;

        internal BloomV2Pass(Shader shader)
        {
            m_BloomMaterial = PostFXUtilities.LoadShader(shader, passName);
            m_BloomUpsampleMaterial = new Material[k_MAX_PYRAMID_LEVELS];
            for (uint i = 0; i < k_MAX_PYRAMID_LEVELS; i++)
            {
                m_BloomUpsampleMaterial[i] = PostFXUtilities.LoadShader(shader, passName);
            }

            m_IsValid = m_BloomMaterial != null;
            for (uint i = 0; i < k_MAX_PYRAMID_LEVELS; i++)
            {
                m_IsValid &= m_BloomUpsampleMaterial[i] != null;
            }
        }

        public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
        {
            if (m_IsValid == false) { return; }

            BloomV2 bloom = volumeStack.GetComponent<BloomV2>();
            if (bloom.IsActive() == false) return;

            UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
            UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();

            var sourceTexture = resourceData.cameraColor;
            var sourceDescriptor = sourceTexture.GetDescriptor(renderGraph);
        }

        public override void Dispose()
        {
            if (m_BloomMaterial != null) CoreUtils.Destroy(m_BloomMaterial);
            for (uint i = 0; i < k_MAX_PYRAMID_LEVELS; i++)
            {
                if (m_BloomUpsampleMaterial[i] != null)
                    CoreUtils.Destroy(m_BloomUpsampleMaterial[i]);
            }
        }
    }
}
#

This is the only code i have the feature isn't finished yet but URP somehow complains now about a blitter being created while there is already one