Skip to content

Instantly share code, notes, and snippets.

@Kobusvdwalt
Created January 4, 2017 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kobusvdwalt/d74ad7013255d275a03817453dfbe28a to your computer and use it in GitHub Desktop.
Save Kobusvdwalt/d74ad7013255d275a03817453dfbe28a to your computer and use it in GitHub Desktop.
Shader "Hidden/PerfectEdge"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv[6] : TEXCOORD0;
float4 pos : SV_POSITION;
};
sampler2D _MainTex;
uniform float4 _MainTex_TexelSize;
sampler2D _CameraDepthNormalsTexture;
sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_ST;
v2f vert (appdata v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float2 uv = v.texcoord.xy;
o.uv[0] = uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1-uv.y;
#endif
o.uv[1] = uv;
half size = 1;
o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,1) * size, _MainTex_ST); // TR
o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,1) * size, _MainTex_ST); // TL
o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,-1) * size, _MainTex_ST); // BL
o.uv[5] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,-1) * size, _MainTex_ST); // BR
return o;
}
float GetSobel (float2 pos)
{
// Sobel calculation
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, pos));
float4 depthsDiag;
float4 depthsAxis;
float2 uvDist = 1 * _MainTex_TexelSize.xy;
depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos+uvDist, _CameraDepthTexture_ST))); // TR
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos+uvDist*float2(-1,1), _CameraDepthTexture_ST))); // TL
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos-uvDist*float2(-1,1), _CameraDepthTexture_ST))); // BR
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos-uvDist, _CameraDepthTexture_ST))); // BL
depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos+uvDist*float2(0,1), _CameraDepthTexture_ST))); // T
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos-uvDist*float2(1,0), _CameraDepthTexture_ST))); // L
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos+uvDist*float2(1,0), _CameraDepthTexture_ST))); // R
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(pos-uvDist*float2(0,1), _CameraDepthTexture_ST))); // B
float4 myDepths = depthsDiag;
depthsDiag -= centerDepth;
depthsAxis /= centerDepth;
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
const float4 VertDiagCoeff = float4(-1,1,-1,1);
const float4 HorizAxisCoeff = float4(1,0,0,-1);
const float4 VertAxisCoeff = float4(0,1,-1,0);
float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
float SobelX = dot(SobelH, float4(1,1,1,1));
float SobelY = dot(SobelV, float4(1,1,1,1));
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
Sobel = 1.0-pow(saturate(Sobel), 0.1);
return Sobel;
}
fixed4 frag (v2f i) : SV_Target
{
float SobelC = GetSobel(i.uv[1]);
float SobelTR = GetSobel(i.uv[2]);
float SobelTL = GetSobel(i.uv[3]);
float SobelBL = GetSobel(i.uv[4]);
float SobelBR = GetSobel(i.uv[5]);
float SobelAV = SobelTR + SobelTL + SobelBL + SobelBR;
SobelAV /= 4;
// Normals detection
float output = 1;
if (SobelC < 0.8)
{
if (abs(SobelAV - SobelC) > 0.01)
{
output *= 0;
}
}
half4 normalsC = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
half4 normalsBR = tex2D (_CameraDepthNormalsTexture, i.uv[4]);
half4 normalsBL = tex2D (_CameraDepthNormalsTexture, i.uv[5]);
half4 normalsTR = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
half4 normalsTL = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
float normalSensitivity = 3;
half2 diffBR = abs(normalsC.xy - normalsBR.xy) * normalSensitivity;
int isSameNormalBR = (diffBR.x + diffBR.y) * normalSensitivity < 0.1 ? 1 : 0;
half2 diffBL = abs(normalsC.xy - normalsBL.xy) * normalSensitivity;
int isSameNormalBL = (diffBL.x + diffBL.y) * normalSensitivity < 0.1 ? 1 : 0;
half2 diffTR = abs(normalsC.xy - normalsTR.xy) * normalSensitivity;
int isSameNormalTR = (diffTR.x + diffTR.y) * normalSensitivity < 0.1 ? 1 : 0;
half2 diffTL = abs(normalsC.xy - normalsTL.xy) * normalSensitivity;
int isSameNormalTL = (diffTL.x + diffTL.y) * normalSensitivity < 0.1 ? 1 : 0;
output *= isSameNormalBR * isSameNormalBL * isSameNormalTL * isSameNormalTR;
return output * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), 0, 0);
}
ENDCG
}
}
}
@Alex1234x
Copy link

Hello! Please help my for implement this shader in Unity!
Big Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment