Skip to content

Instantly share code, notes, and snippets.

@hadashiA
Last active Jan 12, 2020
Embed
What would you like to do?
Shader "Hidden/Heipu/EdgeDetection"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off
ZWrite Off
ZTest Always
// Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
Pass
{
HLSLPROGRAM
#pragma vertex PassVertex
#pragma fragment PassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
// float3 viewSpaceDir : TEXCOORD1;
};
uniform TEXTURE2D(_MainTex);
uniform SAMPLER(sampler_MainTex);
uniform float4 _MainTex_TexelSize;
uniform TEXTURE2D(_DepthNormalTexture);
uniform SAMPLER(sampler_DepthNormalTexture);
uniform float4 _DepthNormalTexture_TexelSize;
uniform half _EdgeScaleFactor;
uniform half4 _EdgeColor;
uniform half _DepthThreshold;
uniform half _DepthNormalThreshold;
uniform half _DepthNormalThresholdScale;
uniform half _NormalThreshold;
// This matrix is populated in PostProcessOutline.cs.
uniform float4x4 _ClipToView;
Varyings PassVertex(Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
// OUT.viewSpaceDir = mul(_ClipToView, OUT.pos).xyz;
return output;
}
half4 PassFragment(Varyings input) : SV_Target
{
float halfScaleFloor = floor(_EdgeScaleFactor * 0.5);
float halfScaleCeil = ceil(_EdgeScaleFactor * 0.5);
float2 bottomLeftUV = input.uv - float2(_DepthNormalTexture_TexelSize.x, _DepthNormalTexture_TexelSize.y) * halfScaleFloor;
float2 topRightUV = input.uv + float2(_DepthNormalTexture_TexelSize.x, _DepthNormalTexture_TexelSize.y) * halfScaleCeil;
float2 bottomRightUV = input.uv + float2(_DepthNormalTexture_TexelSize.x * halfScaleCeil, -_DepthNormalTexture_TexelSize.y * halfScaleFloor);
float2 topLeftUV = input.uv + float2(-_DepthNormalTexture_TexelSize.x * halfScaleFloor, _DepthNormalTexture_TexelSize.y * halfScaleCeil);
half4 depthnormal0 = SAMPLE_TEXTURE2D(TEXTURE2D_ARGS(_DepthNormalTexture, sampler_DepthNormalTexture), bottomLeftUV);
half3 normal0 = depthnormal0.rgb;
half depth0 = depthnormal0.a;
half4 depthnormal1 = SAMPLE_TEXTURE2D(TEXTURE2D_ARGS(_DepthNormalTexture, sampler_DepthNormalTexture), topRightUV);
half3 normal1 = depthnormal1.rgb;
half depth1 = depthnormal1.a;
half4 depthnormal2 = SAMPLE_TEXTURE2D(TEXTURE2D_ARGS(_DepthNormalTexture, sampler_DepthNormalTexture), bottomRightUV);
half3 normal2 = depthnormal2.rgb;
half depth2 = depthnormal2.a;
half4 depthnormal3 = SAMPLE_TEXTURE2D(TEXTURE2D_ARGS(_DepthNormalTexture, sampler_DepthNormalTexture), topLeftUV);
half3 normal3 = depthnormal3.rgb;
half depth3 = depthnormal3.a;
half depthFiniteDifference0 = depth1 - depth0;
half depthFiniteDifference1 = depth3 - depth2;
half edgeDepth = sqrt(pow(depthFiniteDifference0, 2) + pow(depthFiniteDifference1, 2)) * 100;
// edgeDepth = step(_DepthThreshold, edgeDepth);
edgeDepth = edgeDepth > (_DepthThreshold * depth0) ? 1 : 0;
float3 normalFiniteDifference0 = normal1 - normal0;
float3 normalFiniteDifference1 = normal3 - normal2;
float edgeNormal = sqrt(
dot(normalFiniteDifference0, normalFiniteDifference0) +
dot(normalFiniteDifference1, normalFiniteDifference1));
edgeNormal = edgeNormal > _NormalThreshold ? 1 : 0;
half edge = max(edgeDepth, edgeNormal);
half4 edgeColor = half4(_EdgeColor.rgb, _EdgeColor.a * edge);
//
half4 c = SAMPLE_TEXTURE2D(TEXTURE2D_ARGS(_MainTex, sampler_MainTex), input.uv);
c.rgb *= (1 - edgeColor.a);
return depthnormal0;
}
ENDHLSL
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment