0
\$\begingroup\$

So I'm rendering a mesh to a render texture for an outline effect. In the HDRP pipeline UnityObjectToClipPos doesn't seem to work because when I try to merge the everything back together the outline is not in the correct position. Any ideas on how I render this mesh with the correct matrices?

FlatRender

Shader "Hidden/Shader/FlatRender"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            float4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return _Color;
            }
            ENDCG
        }
    }
}

Outline Post Processing

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)
    {
#if UNITY_EDITOR
        if(camera.camera.name == "SceneCamera")
        {
            cmd.CopyTexture(source, destination);
            return;
        }
#endif
            RenderTextureDescriptor silhouetteRTD = new RenderTextureDescriptor()
        {
            dimension = TextureDimension.Tex2D,
            width = camera.actualWidth,
            height = camera.actualHeight,

            depthBufferBits = 8,
            volumeDepth = 1,
            msaaSamples = (int)MSAASamples.None,

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

        cmd.SetRenderTarget(silhouetteTexture);
        cmd.ClearRenderTarget(false, true, Color.clear);
        cmd.SetProjectionMatrix(camera.camera.projectionMatrix);

        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))
            {
                cmd.DrawRenderer(obj.Renderer, m_FlatRender);
            }
        }

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

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

Example image of issue

enter image description here

\$\endgroup\$

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.