diff --git a/examples/files.js b/examples/files.js index 38a2d23edf7071cd759da26ac0ba8801553daa4b..50d7db340381f0bde9844eb7f44ab466f0ba817a 100644 --- a/examples/files.js +++ b/examples/files.js @@ -214,6 +214,7 @@ var files = { "webgl_postprocessing_crossfade", "webgl_postprocessing_dof", "webgl_postprocessing_dof2", + "webgl_postprocessing_edgedetection", "webgl_postprocessing_glitch", "webgl_postprocessing_godrays", "webgl_postprocessing_masking", diff --git a/examples/js/shaders/EdgeShader2.js b/examples/js/shaders/EdgeShader2.js deleted file mode 100644 index 27f27883b012ba332c8b2098d08785e98ad99143..0000000000000000000000000000000000000000 --- a/examples/js/shaders/EdgeShader2.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog - * - * Edge Detection Shader using Sobel filter - * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector - * - * aspect: vec2 of (1/width, 1/height) - */ - -THREE.EdgeShader2 = { - - uniforms: { - - "tDiffuse": { value: null }, - "aspect": { value: new THREE.Vector2( 512, 512 ) } - }, - - vertexShader: [ - - "varying vec2 vUv;", - - "void main() {", - - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D tDiffuse;", - "varying vec2 vUv;", - "uniform vec2 aspect;", - - - "vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);", - - "mat3 G[2];", - - "const mat3 g0 = mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 );", - "const mat3 g1 = mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 );", - - - "void main(void)", - "{", - "mat3 I;", - "float cnv[2];", - "vec3 sample;", - - "G[0] = g0;", - "G[1] = g1;", - - /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ - "for (float i=0.0; i<3.0; i++)", - "for (float j=0.0; j<3.0; j++) {", - "sample = texture2D( tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", - "I[int(i)][int(j)] = length(sample);", - "}", - - /* calculate the convolution values for all the masks */ - "for (int i=0; i<2; i++) {", - "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", - "cnv[i] = dp3 * dp3; ", - "}", - - "gl_FragColor = vec4(0.5 * sqrt(cnv[0]*cnv[0]+cnv[1]*cnv[1]));", - "} " - - ].join( "\n" ) - -}; diff --git a/examples/js/shaders/EdgeShader.js b/examples/js/shaders/FreiChenShader.js similarity index 99% rename from examples/js/shaders/EdgeShader.js rename to examples/js/shaders/FreiChenShader.js index e2e878f3f7e6ab516f7e05556af84dec259da380..0ca440d7102b8b73c9c64056f530708da57b2fc2 100644 --- a/examples/js/shaders/EdgeShader.js +++ b/examples/js/shaders/FreiChenShader.js @@ -7,7 +7,7 @@ * aspect: vec2 of (1/width, 1/height) */ -THREE.EdgeShader = { +THREE.FreiChenShader = { uniforms: { diff --git a/examples/js/shaders/SobelOperatorShader.js b/examples/js/shaders/SobelOperatorShader.js new file mode 100644 index 0000000000000000000000000000000000000000..7a5284140a466abcaceef8f80f21306c7dae48f9 --- /dev/null +++ b/examples/js/shaders/SobelOperatorShader.js @@ -0,0 +1,90 @@ +/** + * @author Mugen87 / https://github.com/Mugen87 + * + * Sobel Edge Detection (see https://youtu.be/uihBwtPIBxM) + * + * As mentioned in the video the Sobel operator expects a grayscale image as input. + * + */ + +THREE.SobelOperatorShader = { + + uniforms: { + + "tDiffuse": { value: null }, + "resolution": { value: new THREE.Vector2() } + + }, + + vertexShader: [ + + "varying vec2 vUv;", + + "void main() {", + + "vUv = uv;", + + "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + + "}" + + ].join( "\n" ), + + fragmentShader: [ + + "uniform sampler2D tDiffuse;", + "uniform vec2 resolution;", + "varying vec2 vUv;", + + "void main() {", + + "vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );", + + // kernel definition (in glsl matrices are filled in column-major order) + + "const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 );", // x direction kernel + "const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 );", // y direction kernel + + // fetch the 3x3 neighbourhood of a fragment + + // first column + + "float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;", + "float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1, 0 ) ).r;", + "float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1, 1 ) ).r;", + + // second column + + "float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2( 0, -1 ) ).r;", + "float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2( 0, 0 ) ).r;", + "float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2( 0, 1 ) ).r;", + + // third column + + "float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2( 1, -1 ) ).r;", + "float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2( 1, 0 ) ).r;", + "float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2( 1, 1 ) ).r;", + + // gradient value in x direction + + "float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 + ", + "Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 + ", + "Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2; ", + + // gradient value in y direction + + "float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 + ", + "Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 + ", + "Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2; ", + + // magnitute of the total gradient + + "float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );", + + "gl_FragColor = vec4( vec3( G ), 1 );", + + "}" + + ].join( "\n" ) + +}; diff --git a/examples/webgl_postprocessing_edgedetection.html b/examples/webgl_postprocessing_edgedetection.html new file mode 100644 index 0000000000000000000000000000000000000000..30e5212605ea56bd550576a1db70234f19cb11a6 --- /dev/null +++ b/examples/webgl_postprocessing_edgedetection.html @@ -0,0 +1,169 @@ + + + + three.js webgl - postprocessing - edge detection (Sobel) + + + + + + + + + + + + + + + + + + + +
+ three.js - webgl - postprocessing - edge detection (Sobel) +
+ + + + +