Skip to content

Instantly share code, notes, and snippets.

@BrianAmadori
Last active August 7, 2023 22:46
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrianAmadori/72230debd937c45e92795a2200e2792c to your computer and use it in GitHub Desktop.
Save BrianAmadori/72230debd937c45e92795a2200e2792c to your computer and use it in GitHub Desktop.
Screen buffer based depth outline shader
//
// Screen space based depth outline. No post processing setup needed.
//
// - Enable Depth Buffer on URP settings.
// - Put any geometry with this shader (like a Quad) in front of geometry.
// - Voila.
//
// This shader is based on the work of Mirza Beig.
// https://github.com/MirzaBeig/Post-Processing-Wireframe-Outlines
//
Shader "Brian/URP/SS Depth Outline + Mask"
{
Properties
{
_MaskTex("Mask Texture", 2D) = "clear" {}
[HDR] _Color("Outline Color", Color) = (0.0, 0.0, 0.0, 0.0)
[Space(5)]
_LineWidth("Line Width", Range(0.0, 32.0)) = 4
_EdgeThreshold("Edge Threshold", Range(0.0, 0.0002)) = 0.0
}
SubShader
{
Tags
{
"RenderPipeline"="UniversalPipeline"
"RenderType"="Transparent"
"UniversalMaterialType" = "Unlit"
"Queue"="Transparent"
}
Cull Off
ZWrite Off
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 screen_uv : TEXCOORD0;
float2 mask_uv : TEXCOORD1;
float4 vertex : SV_POSITION;
};
sampler2D _MaskTex;
float4 _MaskTex_ST;
sampler2D _CameraDepthTexture;
float4 _Color;
float _LineWidth;
float _EdgeThreshold;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.screen_uv = (o.vertex.xy / o.vertex.w) * 0.5 + 0.5;
o.mask_uv = TRANSFORM_TEX(v.uv, _MaskTex);
#if UNITY_UV_STARTS_AT_TOP
o.screen_uv.y = 1.0 - o.screen_uv.y;
#endif
return o;
}
float4 averageDepthKernel(float2 uv)
{
float4 c = 0.0;
const int Q = 9;
float2 s = _LineWidth * ((1.0 / _ScreenParams.xy) / Q);
for (int y = -Q + 1; y < Q; y++)
{
for (int x = -Q + 1; x < Q; x++)
{
c += tex2D(_CameraDepthTexture, float4(uv + (float2(x, y) * s), 0.0, 0.0)).r;
}
}
return c / ((Q * 2 - 1) * (Q * 2 - 1));
}
float4 frag(v2f i) : SV_Target
{
float d = Linear01Depth(tex2D(_CameraDepthTexture, i.screen_uv));
float ad = Linear01Depth(averageDepthKernel(i.screen_uv));
float dt = d > ad - _EdgeThreshold;
float4 mask = tex2D(_MaskTex, i.mask_uv);
return float4(_Color.rgb, 1 - dt) * mask;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment