# 3D Understand the implementation of sobel filter

## Recommended Posts

I am new to shader programming. I was learning how to detect edges using shaders these days. And I found the UnityChan toon shader project. But I found it difficulty to understand when I read its implementation of sobel filter.

Especially for these s few lines:(From Line166)

depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL

depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B

depthsDiag -= centerDepth;
depthsAxis /= centerDepth;

It seems to try to get the diagonal and axial depth values. But I don't know why we need to substract centerDepth from depthsDiag and divide depthsAxis by centerDepth?

Another confusion comes from these a few lines when it tries to return the final color from fragment shader:(From line 191)

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), _Exponent); //NK float4 Col = tex2D(_MainTex, i.uv[0].xy); Col = _EdgesColor * Col * (1.0 - Sobel) + Sobel; return Col * lerp(tex2D(_MainTex, i.uv[0].xy), _TestColor, _BgFade);

What does Sobel = 1.0-pow(saturate(Sobel), _Exponent) do? And what dose Col = _EdgesColor * Col * (1.0 - Sobel) + Sobel mean?

Sorry for my bad English and hope anyone could help me understand this.

##### Share on other sites

Have you looked at https://en.wikipedia.org/wiki/Sobel_operator for an explanation of the Sobel filter?

The final value "Sobel" is how much 'edge' there is (1: edge, 0: no edge -- or vice versa, not sure by heart). The rest is just a way to present it to the user/screen. Just try to solve the equation on paper for Sobel == 1 and Sobel == 0 and you'll see what it does with the colours.

##### Share on other sites
6 hours ago, pcmaster said:

Have you looked at https://en.wikipedia.org/wiki/Sobel_operator for an explanation of the Sobel filter?

The final value "Sobel" is how much 'edge' there is (1: edge, 0: no edge -- or vic﻿e versa, not sure by heart). The rest is just a way to present it to the user/screen. Just try to solve the equation on paper for Sobel == 1 and Sobel == 0 and you'll see what it does with the colours.

Thank you for replying. I have read the wiki for several times. Its exlanation is simple and straitforward. After written down the expressions on paper, I understood what Sobel means. But I still cannot understand using the diagonal and axial depths values and treating them differently.

depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR

depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL

depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B

depthsDiag -= centerDepth;

depthsAxis /= centerDepth;

After doing these, it seems to try to convolute the depths values with sobel operator. But the kernel is somehow different from the common one?

 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;

Could you give me any hint on that?

Thank you

##### Share on other sites

I'm afraid, I can't. I unfortunately don't have time to try what it does.

In a version I have, both DepthsDiag and DepthsAxis are divided by CenterDepth, which is about the only significant difference.

I expect it'll just cause a bit different edge in the horizontal/vertical directions.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 9
• 9
• 9
• 34
• 16
• ### Forum Statistics

• Total Topics
634123
• Total Posts
3015654
×