Image edge detection with OpenGL/WebGL

The following OpenGL/WebGL fragment shader can quickly extract image edges using parallel computing.

Source Code

precision mediump float;

#define KERNEL_SIZE 3
// our texture
uniform sampler2D u_image;
uniform vec2 u_textureSize;
uniform float u_kernel[KERNEL_SIZE];
#define M_PI 3.141592654
#define GET_PIXEL(_x, _y) (texture2D(u_image, textCoord + onePixel*vec2(_x, _y)))

void main() {
	vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
	vec2 textCoord = gl_FragCoord.xy / u_textureSize;
	float dx = (length(GET_PIXEL(-1, -1)*u_kernel[0] +
				GET_PIXEL(-1,  0)*u_kernel[1] +
				GET_PIXEL(-1, +1)*u_kernel[2]) -
			   length(GET_PIXEL(+1, -1)*u_kernel[0] +
				GET_PIXEL(+1,  0)*u_kernel[1] +
				GET_PIXEL(+1, +1)*u_kernel[2]));
	float dy = (length(GET_PIXEL(-1, -1)*u_kernel[0] +
				GET_PIXEL(0, -1)*u_kernel[1] +
				GET_PIXEL(+1, -1)*u_kernel[2]) -
			   length(GET_PIXEL(-1, +1)*u_kernel[0] +
				GET_PIXEL(0, +1)*u_kernel[1] +
				GET_PIXEL(+1, +1)*u_kernel[2]));

   float theta = (atan(dy, dx) + M_PI) / (2.0*M_PI);
   gl_FragColor = vec4(length(vec2(dx, dy)), theta, 0.0, 1.0);

This code snippet is part of our online open source image analysis library and shows how to calculate the gradient size and orientation.


  • Initially, the shader obtains the mask coefficients through the uniform variable u_kernel
  • Then it calculates the horizontal and vertical gradients dx and dy
  • The next step is to find the gradient orientation theta. Note that we should scale the orientation angle from range [0.0, 2.0*PI] to [0.0, 1.0].
  • Finally, the gradient parameters are set to the first two components of the vector gl_FragColor.

Related Algorithms

Online Demo