Last active
January 19, 2024 10:41
-
-
Save mattatz/d14898c16008e3ad1abe to your computer and use it in GitHub Desktop.
Sobel filter shader for Unity.
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 "Mattatz/SobelFilter" { | |
Properties { | |
_MainTex ("Base (RGB)", 2D) = "white" {} | |
_DeltaX ("Delta X", Float) = 0.01 | |
_DeltaY ("Delta Y", Float) = 0.01 | |
} | |
SubShader { | |
Tags { "RenderType"="Opaque" } | |
LOD 200 | |
CGINCLUDE | |
#include "UnityCG.cginc" | |
sampler2D _MainTex; | |
float _DeltaX; | |
float _DeltaY; | |
float sobel (sampler2D tex, float2 uv) { | |
float2 delta = float2(_DeltaX, _DeltaY); | |
float4 hr = float4(0, 0, 0, 0); | |
float4 vt = float4(0, 0, 0, 0); | |
hr += tex2D(tex, (uv + float2(-1.0, -1.0) * delta)) * 1.0; | |
hr += tex2D(tex, (uv + float2( 0.0, -1.0) * delta)) * 0.0; | |
hr += tex2D(tex, (uv + float2( 1.0, -1.0) * delta)) * -1.0; | |
hr += tex2D(tex, (uv + float2(-1.0, 0.0) * delta)) * 2.0; | |
hr += tex2D(tex, (uv + float2( 0.0, 0.0) * delta)) * 0.0; | |
hr += tex2D(tex, (uv + float2( 1.0, 0.0) * delta)) * -2.0; | |
hr += tex2D(tex, (uv + float2(-1.0, 1.0) * delta)) * 1.0; | |
hr += tex2D(tex, (uv + float2( 0.0, 1.0) * delta)) * 0.0; | |
hr += tex2D(tex, (uv + float2( 1.0, 1.0) * delta)) * -1.0; | |
vt += tex2D(tex, (uv + float2(-1.0, -1.0) * delta)) * 1.0; | |
vt += tex2D(tex, (uv + float2( 0.0, -1.0) * delta)) * 2.0; | |
vt += tex2D(tex, (uv + float2( 1.0, -1.0) * delta)) * 1.0; | |
vt += tex2D(tex, (uv + float2(-1.0, 0.0) * delta)) * 0.0; | |
vt += tex2D(tex, (uv + float2( 0.0, 0.0) * delta)) * 0.0; | |
vt += tex2D(tex, (uv + float2( 1.0, 0.0) * delta)) * 0.0; | |
vt += tex2D(tex, (uv + float2(-1.0, 1.0) * delta)) * -1.0; | |
vt += tex2D(tex, (uv + float2( 0.0, 1.0) * delta)) * -2.0; | |
vt += tex2D(tex, (uv + float2( 1.0, 1.0) * delta)) * -1.0; | |
return sqrt(hr * hr + vt * vt); | |
} | |
float4 frag (v2f_img IN) : COLOR { | |
float s = sobel(_MainTex, IN.uv); | |
return float4(s, s, s, 1); | |
} | |
ENDCG | |
Pass { | |
CGPROGRAM | |
#pragma vertex vert_img | |
#pragma fragment frag | |
ENDCG | |
} | |
} | |
FallBack "Diffuse" | |
} |
You DO realize that these multiplications are the weights needed for a Sobel Filter? Read up on Convolution Filters, you will understand what I mean.
Yes of course, but if a sample is multiplied by a constant value of zero, it will have no influence on the sum, and therefore it would be better to omit this sample to avoid an expensive texture lookup. There is a difference between the mathematical description of a kernel and how it is appropriate to implement it.
Maybe my phrasing was unecessarily rude - I just ran the code through DXC Compiler Explorer, and I can see that it will optimize away those lines anyway, so it's not like it matters.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You DO realize that these multiplications are the weights needed for a Sobel Filter? Read up on Convolution Filters, you will understand what I mean.