Created
January 4, 2017 16:30
-
-
Save Kobusvdwalt/d74ad7013255d275a03817453dfbe28a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello! Please help my for implement this shader in Unity!
Big Thanks!