unity – How do I pass a temporary render texture generated by a command buffer to a material?


I’m working on an outline effect for my game. I want to do the render buffer based methods since the outlines are imo of much higher quality. I can render the selected objects into the buffer as expected. I now need to use that render texture in the next stage …. however, I can’t find a way to bind the temporary texture generated by the previous stage to the next step. The post processing effect is a work in progress, so I know it is not done yet. Want to visualize each step to make sure it works as expected.

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.HighDefinition;

[Serializable, VolumeComponentMenu("Post-processing/Custom/JumpFloodOutline")]
public sealed class JumpFloodOutline : CustomPostProcessVolumeComponent, IPostProcessComponent
{
    [Tooltip("Controls the thickness of the outline")]
    public ClampedFloatParameter Thickness = new ClampedFloatParameter(4.0f,0.0f,50.0f);
    
    [ColorUsage(true,true)]
    [Tooltip("Outline color")]
    public ColorParameter OutlineColor = new ColorParameter(Color.white,true,true,true);

    private Material m_FlatRender;
    //private Material m_BlurRender;
    private Material m_MergeOutline;
    private int silhouetteBufferID = Shader.PropertyToID("_SilhouetteBuffer");
    private int inputTextureID = Shader.PropertyToID("_InputTexture");
    private int colorID = Shader.PropertyToID("_Color");

    public bool IsActive()
    {
        return m_FlatRender != null && OutlineObjects.Count > 0 && Thickness.value > 0f && OutlineColor.value.a > 0.0f;
    }
    // Do not forget to add this post process in the Custom Post Process Orders list (Project Settings > HDRP Default Settings).
    public override CustomPostProcessInjectionPoint injectionPoint => CustomPostProcessInjectionPoint.BeforeTAA;

    const string kBlurShader = "Hidden/Shader/Blur";
    const string kFlatShader = "Hidden/Shader/FlatRender";
    const string kMergeShader = "Hidden/Shader/MergeOutline";

    public static List<OutlineObject> OutlineObjects = new List<OutlineObject>(); 

    private Material LoadMaterial(string shaderName)
    {
        var shader = Shader.Find(shaderName);
        if (shader != null)
        {
            return new Material(shader);
        }
        else
        {
            Debug.LogError($"Unable to find shader '{shaderName}'. Post Process Volume JumpFloodOutline is unable to load.");
            return null;
        }
    }

    public override void Setup()
    {
        m_FlatRender = LoadMaterial(kFlatShader);
        m_MergeOutline = LoadMaterial(kMergeShader);
    }

    public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination)
    {
        RenderTextureDescriptor silhouetteRTD = new RenderTextureDescriptor()
        {
            dimension = TextureDimension.Tex2D,
            width = camera.actualWidth,
            height = camera.actualHeight,

            depthBufferBits = 0,
            msaaSamples = 1,


            useMipMap = false,
            autoGenerateMips = false,
            colorFormat = RenderTextureFormat.ARGB32
        };
        //RenderTexture silhouetteTexture = RenderTexture.GetTemporary(silhouetteRTD);
        cmd.GetTemporaryRT(silhouetteBufferID, silhouetteRTD);
        cmd.SetRenderTarget(silhouetteBufferID);
        //cmd.SetRenderTarget(silhouetteTexture);
        cmd.ClearRenderTarget(false, true, Color.clear);

        m_FlatRender.SetColor(colorID, OutlineColor.value);
        for (int i = 0; i < OutlineObjects.Count; i++)
        {
            var obj = OutlineObjects[i];
            for (int m = 0; m < obj.Mesh.subMeshCount; m++)
            {
                cmd.DrawRenderer(obj.Renderer, m_FlatRender, m);
            }
        }

        m_MergeOutline.SetTexture("_InputTexture", source);
        cmd.SetGlobalTexture(silhouetteBufferID, silhouetteBufferID);
        cmd.Blit(silhouetteBufferID, destination,m_MergeOutline);


        cmd.ReleaseTemporaryRT(silhouetteBufferID);
    }

    public override void Cleanup()
    {
        CoreUtils.Destroy(m_FlatRender);
        CoreUtils.Destroy(m_MergeOutline);
    }
}



Source link

More To Explore

Share on facebook
Share on twitter
Share on linkedin
Share on email