Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RenderGraph support Request #1

Open
AcidicVoid opened this issue Aug 6, 2024 · 2 comments
Open

RenderGraph support Request #1

AcidicVoid opened this issue Aug 6, 2024 · 2 comments

Comments

@AcidicVoid
Copy link

How to replicate:

  1. Add PixelationFx to Universal Renderer Data
  2. Create Volume, shouldn't matter if global or local
  3. Add a Volume Profile
  4. Add PixelationFx to the Volume Profile and
  5. Have a corresponding camera inside the volume, so the effect should be rendered

Problem:

The effect won't render, Unity shows the following warning:

The render pass VolFx.Pixelation+PassExecution does not have an implementation of the RecordRenderGraph method. Please implement this method, or consider turning on Compatibility Mode (RenderGraph disabled) in the menu Edit > Project Settings > Graphics > URP. Otherwise the render pass will have no effect. For more information, refer to https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest/index.html?subfolder=/manual/customizing-urp.html. UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
I don't want to turn on compatibility mode for various project-specific reasons.

@NullTale
Copy link
Owner

NullTale commented Aug 6, 2024

Emm, i'm do not support render graph

  • I don't mind if someone implement it, but it should be compatible with VolFx and not cause errors when compiling and in case if RenderGraph is not supported

@NullTale NullTale changed the title Missing implementation of RecordRenderGraph RenderGraph support Request Aug 6, 2024
@AcidicVoid
Copy link
Author

Oops.

Well, I've updated Pixelation.cs with the RenderGraph method to see if this fixes the issue.
Notice that this not well done, just a quickly made "dummy" implementation to prevent the, no precompiler commands added.

The effect still doesn't work. Any ideas what I could have missed?

Maybe it will help someone in the future.

Pixelation.cs:

#if !VOL_FX

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

//  Pixelation © NullTale - https://twitter.com/NullTale/
namespace VolFx
{
    public class Pixelation : ScriptableRendererFeature
    {
        protected static List<ShaderTagId> k_ShaderTags;
        
        public static int s_BlitTexId       = Shader.PropertyToID("_BlitTexture");
        public static int s_BlitScaleBiasId = Shader.PropertyToID("_BlitScaleBias");
        
        [Tooltip("When to execute")]
        public RenderPassEvent _event  = RenderPassEvent.BeforeRenderingPostProcessing;
        
        public PixelationPass _pass;
        
        [HideInInspector]
        public Shader _blitShader;

        [NonSerialized]
        public Material _blit;
        
        [NonSerialized]
        public PassExecution _execution;

        // =======================================================================
        public class PassExecution : ScriptableRenderPass
        {
            public  Pixelation   _owner;
            private RenderTarget _output;
            
            // =======================================================================
            public void Init()
            {
                renderPassEvent = _owner._event;
                
                _output = new RenderTarget().Allocate(_owner.name);
            }

            public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
            {
                string passName = "Copy To Debug Texture";
                using (var builder = renderGraph.AddRasterRenderPass<ContextContainer>(passName,
                    out var passData))
                {
                    UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();

                    UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
                    RenderTextureDescriptor desc = cameraData.cameraTargetDescriptor;
                    desc.msaaSamples = 1;
                    desc.depthBufferBits = 0;

                    TextureHandle destination =
                        UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc,
                            "CopyTexture", false);
                }
            }

            [Obsolete("Deprecated")]
            public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
            {
                _owner._pass.Validate();
                if (_owner._pass.IsActive == false)
                    return;
                
                // allocate stuff
                var cmd = CommandBufferPool.Get(_owner.name);
                ref var cameraData = ref renderingData.cameraData;
                ref var desc = ref cameraData.cameraTargetDescriptor;
                _output.Get(cmd, in desc);

                var source = _getCameraTex(ref renderingData);
                
                // draw post process chain
                _owner._pass.Invoke(cmd, source, _output.Handle, context, ref renderingData);
                _owner.Blit(cmd, _output.Handle, source);

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();
                CommandBufferPool.Release(cmd);

                // -----------------------------------------------------------------------
                RTHandle _getCameraTex(ref RenderingData renderingData)
                {
                    ref var cameraData = ref renderingData.cameraData;
#if UNITY_2022_1_OR_NEWER
                    return cameraData.renderer.cameraColorTargetHandle;
#else
                    return RTHandles.Alloc(cameraData.renderer.cameraColorTarget);
#endif
                }
            }

            public override void FrameCleanup(CommandBuffer cmd)
            {
                _output.Release(cmd);
                _output.Release(cmd);
                _owner._pass.Cleanup(cmd);
            }
        }
        
        // =======================================================================
        public void Blit(CommandBuffer cmd, RTHandle source, RTHandle destination)
        {
            cmd.SetGlobalVector(s_BlitScaleBiasId, new Vector4(1, 1, 0));
            cmd.SetGlobalTexture(s_BlitTexId, source);
            cmd.SetRenderTarget(destination, 0);
            cmd.DrawMesh(Utils.FullscreenMesh, Matrix4x4.identity, _blit, 0, 0);
        }
        
        public override void Create()
        {
#if UNITY_EDITOR
            _blitShader = Shader.Find("Hidden/Universal Render Pipeline/Blit");
            
            UnityEditor.EditorUtility.SetDirty(this);
#endif
            _blit      = new Material(_blitShader);
            _execution = new PassExecution() { _owner = this };
            _execution.Init();
            
            if (_pass != null)
                _pass._init();
            
            if (k_ShaderTags == null)
            {
                k_ShaderTags = new List<ShaderTagId>(new[]
                {
                    new ShaderTagId("SRPDefaultUnlit"),
                    new ShaderTagId("UniversalForward"),
                    new ShaderTagId("UniversalForwardOnly")
                });
            }
        }

        private void Reset()
        {
#if UNITY_EDITOR
            if (_pass != null)
            {
                UnityEditor.AssetDatabase.RemoveObjectFromAsset(_pass);
                UnityEditor.AssetDatabase.SaveAssets();
                _pass = null;
            }
#endif
        }

        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            if (renderingData.cameraData.cameraType != CameraType.Game)
                return;
#if UNITY_EDITOR
            if (_blit == null)
                _blit = new Material(_blitShader);
            
            if (_pass == null)
                return;
#endif
            renderer.EnqueuePass(_execution);
        }

        private void OnDestroy()
        {
#if UNITY_EDITOR
            if (_pass != null)
            {
                UnityEditor.AssetDatabase.RemoveObjectFromAsset(_pass);
                UnityEditor.AssetDatabase.SaveAssets();
                _pass = null;
            }
#endif
        }
    }
}
#endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants