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);
    [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);
            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 = 8,
            volumeDepth = 1,
            msaaSamples = 1,

            useMipMap = false,
            autoGenerateMips = false,
            colorFormat = RenderTextureFormat.ARGB32
        RenderTexture silhouetteTexture = RenderTexture.GetTemporary(silhouetteRTD);

        //cmd.GetTemporaryRT(silhouetteBufferID, silhouetteRTD);
        cmd.ClearRenderTarget(false, true, Color.clear);

        m_FlatRender.SetColor(colorID, OutlineColor.value);

        for (int i = 0; i < OutlineObjects.Count; i++)
            var obj = OutlineObjects[i];
            if (GeometryUtility.TestPlanesAABB(camera.frustum.planes, obj.Renderer.bounds))
                for (int m = 0; m < obj.Mesh.subMeshCount; m++)
                    cmd.DrawRenderer(obj.Renderer, m_FlatRender, m);

        m_MergeOutline.SetTexture("_InputTexture", source);
        m_MergeOutline.SetTexture("_OutlineTexture", silhouetteTexture);
        HDUtils.DrawFullScreen(cmd, m_MergeOutline, destination);

    public override void Cleanup()

Merge Shader

Shader "Hidden/Shader/MergeOutline"

#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"

        struct Attributes
        uint vertexID : SV_VertexID;

    struct Varyings
        float4 positionCS : SV_POSITION;
        float2 texcoord   : TEXCOORD0;

    Varyings Vert(Attributes input)
        Varyings output;
        output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
        output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
        return output;

    // List of properties to control your post process effect

    float4 CustomPostProcess(Varyings input) : SV_Target

        uint2 positionSS = input.texcoord * _ScreenSize.xy;
        float3 sourceColor = LOAD_TEXTURE2D_X(_InputTexture, positionSS).rgb;
        float4 outlineColor = LOAD_TEXTURE2D_X(_OutlineTexture, positionSS);
        float3 output = lerp(sourceColor,outlineColor.rgb, outlineColor.a);
        return float4(output,1);


            Name "MergeOutline"

            ZWrite Off
            ZTest Always
            Blend Off
            Cull Off

                #pragma fragment CustomPostProcess
                #pragma vertex Vert
    Fallback Off

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.