├── assets ├── snapshot.jpg ├── textures │ ├── 1324.jpg │ ├── 231 2.jpg │ ├── 231.jpg │ ├── dirt8.jpg │ ├── test.jpg │ ├── util.png │ ├── white.jpg │ ├── wood.png │ ├── clouds.png │ ├── crate_1.jpg │ ├── distort.jpg │ ├── 1324-decal.jpg │ ├── 1324-glow.jpg │ ├── circuits.jpg │ ├── distort2.jpg │ ├── lensdirt 2.png │ ├── lensdirt.png │ ├── lensdirt2.jpg │ ├── tilt-shift.png │ ├── 1324-normal.jpg │ ├── earth_sphere.jpg │ └── LensDirtiness_01.jpg └── ascii │ └── 8x16_ascii_font_sorted.gif ├── escheresque_ste.png ├── escheresque_ste_@2X.png ├── fragment-shaders ├── copy-fs.glsl ├── invert-fs.glsl ├── grayscale-fs.glsl ├── pixelate-fs.glsl ├── vignette-fs.glsl ├── brightness-contrast-fs.glsl ├── vr-compose-fs.glsl ├── vignette2-fs.glsl ├── rgb-split-fs.glsl ├── sepia-fs.glsl ├── noise-fs.glsl ├── denoise-fs.glsl ├── box-blur-fs.glsl ├── crossfade-fs.glsl ├── box-blur2-fs.glsl ├── zoom-blur-fs.glsl ├── bloom-fs.glsl ├── dot-screen-fs.glsl ├── bleach-fs.glsl ├── packed-depth-fs.glsl ├── bloom2-fs.glsl ├── halftone-fs.glsl ├── art-fs.glsl ├── ascii-fs.glsl ├── guided-directional-blur-fs.glsl ├── high-pass-fs.glsl ├── barrel-blur-fs.glsl ├── sobel-fs.glsl ├── sobel2-fs.glsl ├── chromatic-aberration-fs.glsl ├── guided-box-blur-fs.glsl ├── dof-fs.glsl ├── guided-box-blur2-fs.glsl ├── zoom-blur2-fs.glsl ├── poisson-disc-blur-fs.glsl ├── halftone2-fs.glsl ├── circular-blur-fs.glsl ├── cga-fs.glsl ├── symetric-fs.glsl ├── bokeh-poison-fs.glsl ├── bokeh-poison-dof-fs.glsl ├── fxaa-fs.glsl ├── frei-chen-fs.glsl ├── fxaa2-fs.glsl ├── ssao-fs.glsl ├── old-video-fs.glsl ├── toon-fs.glsl ├── ssao-simple-fs.glsl ├── blend-fs.glsl └── led-fs.glsl ├── vertex-shaders ├── basic-vs.glsl ├── orto-vs.glsl └── packed-depth-vs.glsl ├── bower.json ├── LICENSE ├── ShaderLoader.js ├── TODO.md ├── editor.html ├── examples ├── invert.html ├── cga.html ├── toon.html ├── dirt-pass.html ├── ascii.html ├── cross-fade.html ├── halftone.html ├── grayscale.html ├── high-pass.html ├── old-video.html ├── dot-screen.html ├── fxaa.html ├── barrel-blur.html ├── circular-blur.html ├── halftone-cmyk.html ├── sobel-edge-detection.html ├── chromatic-aberration.html ├── sepia.html ├── full-box-blur.html ├── pixelate.html ├── noise.html ├── box-blur.html ├── denoise.html ├── rgb-split.html ├── vignette.html ├── halftone2.html ├── vignette2.html ├── zoom-blur.html ├── directional-blur.html ├── led.html ├── guided-full-box-blur.html ├── multipass-bloom.html ├── guided-box-blur.html ├── ssao.html └── dof.html ├── js └── debugTools.js ├── README.md ├── legacy ├── ShaderPasser.js ├── index-0.html └── index-1.html └── demo.html /assets/snapshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/snapshot.jpg -------------------------------------------------------------------------------- /escheresque_ste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/escheresque_ste.png -------------------------------------------------------------------------------- /assets/textures/1324.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/1324.jpg -------------------------------------------------------------------------------- /assets/textures/231 2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/231 2.jpg -------------------------------------------------------------------------------- /assets/textures/231.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/231.jpg -------------------------------------------------------------------------------- /assets/textures/dirt8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/dirt8.jpg -------------------------------------------------------------------------------- /assets/textures/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/test.jpg -------------------------------------------------------------------------------- /assets/textures/util.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/util.png -------------------------------------------------------------------------------- /assets/textures/white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/white.jpg -------------------------------------------------------------------------------- /assets/textures/wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/wood.png -------------------------------------------------------------------------------- /escheresque_ste_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/escheresque_ste_@2X.png -------------------------------------------------------------------------------- /assets/textures/clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/clouds.png -------------------------------------------------------------------------------- /assets/textures/crate_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/crate_1.jpg -------------------------------------------------------------------------------- /assets/textures/distort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/distort.jpg -------------------------------------------------------------------------------- /assets/textures/1324-decal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/1324-decal.jpg -------------------------------------------------------------------------------- /assets/textures/1324-glow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/1324-glow.jpg -------------------------------------------------------------------------------- /assets/textures/circuits.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/circuits.jpg -------------------------------------------------------------------------------- /assets/textures/distort2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/distort2.jpg -------------------------------------------------------------------------------- /assets/textures/lensdirt 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/lensdirt 2.png -------------------------------------------------------------------------------- /assets/textures/lensdirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/lensdirt.png -------------------------------------------------------------------------------- /assets/textures/lensdirt2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/lensdirt2.jpg -------------------------------------------------------------------------------- /assets/textures/tilt-shift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/tilt-shift.png -------------------------------------------------------------------------------- /assets/textures/1324-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/1324-normal.jpg -------------------------------------------------------------------------------- /assets/textures/earth_sphere.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/earth_sphere.jpg -------------------------------------------------------------------------------- /assets/textures/LensDirtiness_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/textures/LensDirtiness_01.jpg -------------------------------------------------------------------------------- /assets/ascii/8x16_ascii_font_sorted.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spite/Wagner/HEAD/assets/ascii/8x16_ascii_font_sorted.gif -------------------------------------------------------------------------------- /fragment-shaders/copy-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | 4 | void main() { 5 | 6 | gl_FragColor = texture2D( tInput, vUv ); 7 | 8 | } -------------------------------------------------------------------------------- /fragment-shaders/invert-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | 4 | void main() { 5 | 6 | gl_FragColor = texture2D( tInput, vUv ); 7 | gl_FragColor.rgb = 1. - gl_FragColor.rgb; 8 | 9 | } -------------------------------------------------------------------------------- /vertex-shaders/basic-vs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | varying vec3 vNormal; 3 | 4 | void main() { 5 | 6 | vUv = uv; 7 | vNormal = normalMatrix * normal; 8 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 9 | 10 | } -------------------------------------------------------------------------------- /vertex-shaders/orto-vs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | void main() { 4 | 5 | vUv = uv; 6 | // vPosition = vec4( modelViewMatrix * vec4( position, 1.0 ) ).xyz; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 8 | 9 | } -------------------------------------------------------------------------------- /fragment-shaders/grayscale-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | 5 | void main() { 6 | 7 | vec3 luma = vec3( .299, 0.587, 0.114 ); 8 | vec4 color = texture2D( tInput, vUv ); 9 | gl_FragColor = vec4( vec3( dot( color.rgb, luma ) ), color.a ); 10 | 11 | } -------------------------------------------------------------------------------- /fragment-shaders/pixelate-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | uniform float amount; 5 | 6 | void main() { 7 | 8 | float d = 1.0 / amount; 9 | float ar = resolution.x / resolution.y; 10 | float u = floor( vUv.x / d ) * d; 11 | d = ar / amount; 12 | float v = floor( vUv.y / d ) * d; 13 | gl_FragColor = texture2D( tInput, vec2( u, v ) ); 14 | 15 | } -------------------------------------------------------------------------------- /fragment-shaders/vignette-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float falloff; 3 | uniform float amount; 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | 8 | vec4 color = texture2D(tInput, vUv); 9 | 10 | float dist = distance(vUv, vec2(0.5, 0.5)); 11 | color.rgb *= smoothstep(0.8, falloff * 0.799, dist * (amount + falloff)); 12 | 13 | gl_FragColor = color; 14 | 15 | } -------------------------------------------------------------------------------- /fragment-shaders/brightness-contrast-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform float brightness; 2 | uniform float contrast; 3 | uniform sampler2D tInput; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | 9 | vec3 color = texture2D(tInput, vUv).rgb; 10 | vec3 colorContrasted = (color) * contrast; 11 | vec3 bright = colorContrasted + vec3(brightness,brightness,brightness); 12 | gl_FragColor.rgb = bright; 13 | gl_FragColor.a = 1.; 14 | 15 | } -------------------------------------------------------------------------------- /fragment-shaders/vr-compose-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | uniform sampler2D leftEyeTexture; 4 | uniform sampler2D rightEyeTexture; 5 | 6 | varying vec2 vUv; 7 | 8 | 9 | void main(void) { 10 | 11 | if( vUv.x < .5 ) { 12 | gl_FragColor = texture2D( leftEyeTexture, vUv * vec2( 2., 1. ) ); 13 | } else { 14 | gl_FragColor = texture2D( rightEyeTexture, vUv * vec2( 2., 1. ) - vec2( 1., 0. ) ); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /fragment-shaders/vignette2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | 5 | uniform float reduction; 6 | uniform float boost; 7 | 8 | void main() { 9 | 10 | vec4 color = texture2D( tInput, vUv ); 11 | 12 | vec2 center = resolution * 0.5; 13 | float vignette = distance( center, gl_FragCoord.xy ) / resolution.x; 14 | vignette = boost - vignette * reduction; 15 | 16 | color.rgb *= vignette; 17 | gl_FragColor = color; 18 | 19 | } -------------------------------------------------------------------------------- /fragment-shaders/rgb-split-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | uniform vec2 resolution; 5 | 6 | void main() { 7 | 8 | vec2 dir = vUv - vec2( .5 ); 9 | float d = .7 * length( dir ); 10 | normalize( dir ); 11 | vec2 value = d * dir * delta; 12 | 13 | vec4 c1 = texture2D( tInput, vUv - value / resolution.x ); 14 | vec4 c2 = texture2D( tInput, vUv ); 15 | vec4 c3 = texture2D( tInput, vUv + value / resolution.y ); 16 | 17 | gl_FragColor = vec4( c1.r, c2.g, c3.b, c1.a + c2.a + c3.b ); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /vertex-shaders/packed-depth-vs.glsl: -------------------------------------------------------------------------------- 1 | varying float depth; 2 | 3 | uniform float mNear; 4 | uniform float mFar; 5 | 6 | void main() { 7 | 8 | vec4 viewPos = vec4( modelViewMatrix * vec4( position, 1.0 ) ); // this will transform the vertex into eyespace 9 | depth = 1. - ( mNear + viewPos.z ) / ( mNear - mFar ); 10 | 11 | vec3 vPosition = vec4( modelViewMatrix * vec4( position, 1.0 ) ).xyz; 12 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 13 | 14 | depth = -viewPos.z; 15 | 16 | depth = (-viewPos.z-mNear)/(mFar-mNear); // will map near..far to 0..1 17 | 18 | } -------------------------------------------------------------------------------- /fragment-shaders/sepia-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float amount; 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | 7 | vec4 color = texture2D(tInput, vUv); 8 | float r = color.r; 9 | float g = color.g; 10 | float b = color.b; 11 | 12 | color.r = min(1.0, (r * (1.0 - (0.607 * amount))) + (g * (0.769 * amount)) + (b * (0.189 * amount))); 13 | color.g = min(1.0, (r * 0.349 * amount) + (g * (1.0 - (0.314 * amount))) + (b * 0.168 * amount)); 14 | color.b = min(1.0, (r * 0.272 * amount) + (g * 0.534 * amount) + (b * (1.0 - (0.869 * amount)))); 15 | 16 | gl_FragColor = color; 17 | 18 | } -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wagner", 3 | "version": "0.0.1", 4 | "main": "Wagner/", 5 | "description": "Effects composer for three.js", 6 | "authors": [ 7 | "Jaume Sanchez" 8 | ], 9 | "license": "MIT", 10 | "moduleType": [ 11 | "globals" 12 | ], 13 | "keywords": [ 14 | "webgl", 15 | "threejs", 16 | "effects", 17 | "composer" 18 | ], 19 | "ignore": [ 20 | "**/.*", 21 | "**/*.png", 22 | "TODO.md", 23 | "index.html", 24 | "gruntfile.js", 25 | "node_modules", 26 | "bower_components", 27 | "examples", 28 | "assets", 29 | "legacy", 30 | "js" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /fragment-shaders/noise-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float amount; 3 | uniform float speed; 4 | uniform float time; 5 | varying vec2 vUv; 6 | 7 | float random(vec2 n, float offset ){ 8 | //return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453); 9 | return .5 - fract(sin(dot(n.xy + vec2( offset, 0. ), vec2(12.9898, 78.233)))* 43758.5453); 10 | } 11 | 12 | void main() { 13 | 14 | vec4 color = texture2D(tInput, vUv); 15 | 16 | //color += amount * ( .5 - random( vec3( 1. ), length( gl_FragCoord ) + speed * .01 * time ) ); 17 | color += vec4( vec3( amount * random( vUv, .00001 * speed * time ) ), 1. ); 18 | 19 | gl_FragColor = color; 20 | 21 | } -------------------------------------------------------------------------------- /fragment-shaders/denoise-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float exponent; 3 | uniform float strength; 4 | uniform vec2 resolution; 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | 9 | vec4 center = texture2D(tInput, vUv); 10 | vec4 color = vec4(0.0); 11 | float total = 0.0; 12 | for (float x = -4.0; x <= 4.0; x += 1.0) { 13 | for (float y = -4.0; y <= 4.0; y += 1.0) { 14 | vec4 sample = texture2D(tInput, vUv + vec2(x, y) / resolution); 15 | float weight = 1.0 - abs(dot(sample.rgb - center.rgb, vec3(0.25))); 16 | weight = pow(weight, exponent); 17 | color += sample * weight; 18 | total += weight; 19 | } 20 | } 21 | gl_FragColor = color / total; 22 | 23 | } -------------------------------------------------------------------------------- /fragment-shaders/box-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | 5 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 6 | 7 | void main() { 8 | 9 | vec4 color=vec4(0.0); 10 | float total=0.0; 11 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 12 | for(float t=-30.0;t<=30.0;t++){ 13 | float percent=(t+offset-0.5)/30.0; 14 | float weight=1.0-abs(percent); 15 | vec4 sample=texture2D(tInput,vUv+delta*percent); 16 | sample.rgb*=sample.a; 17 | color+=sample*weight; 18 | total+=weight; 19 | } 20 | 21 | gl_FragColor=color/total; 22 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 23 | 24 | } -------------------------------------------------------------------------------- /fragment-shaders/crossfade-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform sampler2D tInput2; 3 | uniform sampler2D tFadeMap; 4 | uniform vec2 resolution; 5 | uniform float time; 6 | uniform float amount; 7 | 8 | varying vec2 vUv; 9 | 10 | void main( void ) { 11 | 12 | float range = .2; 13 | vec4 from = texture2D( tInput, vUv ); 14 | vec4 to = texture2D( tInput2, vUv ); 15 | vec3 luma = vec3( .299, 0.587, 0.114 ); 16 | float v = clamp( dot( luma, texture2D( tFadeMap, vUv ).rgb ), 0., 1. - range ); 17 | 18 | float threshold = 0.1; 19 | float r = amount * (1.0 + threshold * 2.0) - threshold; 20 | float m = clamp((v - r)*(1.0/threshold), 0.0, 1.0); 21 | 22 | gl_FragColor = mix( from, to, m ); 23 | 24 | } -------------------------------------------------------------------------------- /fragment-shaders/box-blur2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | uniform vec2 resolution; 5 | 6 | void main() { 7 | 8 | vec4 sum = vec4( 0. ); 9 | vec2 inc = delta / resolution; 10 | 11 | sum += texture2D( tInput, ( vUv - inc * 4. ) ) * 0.051; 12 | sum += texture2D( tInput, ( vUv - inc * 3. ) ) * 0.0918; 13 | sum += texture2D( tInput, ( vUv - inc * 2. ) ) * 0.12245; 14 | sum += texture2D( tInput, ( vUv - inc * 1. ) ) * 0.1531; 15 | sum += texture2D( tInput, ( vUv + inc * 0. ) ) * 0.1633; 16 | sum += texture2D( tInput, ( vUv + inc * 1. ) ) * 0.1531; 17 | sum += texture2D( tInput, ( vUv + inc * 2. ) ) * 0.12245; 18 | sum += texture2D( tInput, ( vUv + inc * 3. ) ) * 0.0918; 19 | sum += texture2D( tInput, ( vUv + inc * 4. ) ) * 0.051; 20 | 21 | gl_FragColor = sum; 22 | 23 | } -------------------------------------------------------------------------------- /fragment-shaders/zoom-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 center; 3 | uniform float strength; 4 | uniform vec2 resolution; 5 | varying vec2 vUv; 6 | 7 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 8 | 9 | void main(){ 10 | vec4 color=vec4(0.0); 11 | float total=0.0; 12 | vec2 toCenter=center-vUv*resolution; 13 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 14 | for(float t=0.0;t<=40.0;t++){ 15 | float percent=(t+offset)/40.0; 16 | float weight=4.0*(percent-percent*percent); 17 | vec4 sample=texture2D(tInput,vUv+toCenter*percent*strength/resolution); 18 | sample.rgb*=sample.a; 19 | color+=sample*weight; 20 | total+=weight; 21 | } 22 | gl_FragColor=color/total; 23 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 24 | } 25 | -------------------------------------------------------------------------------- /fragment-shaders/bloom-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | 4 | void main() 5 | { 6 | vec4 sum = vec4(0); 7 | vec2 texcoord = vUv; 8 | 9 | for( int i= -4 ;i < 4; i++) 10 | { 11 | for ( int j = -3; j < 3; j++) 12 | { 13 | sum += texture2D(tInput, texcoord + vec2(j, i)*0.004) * 0.25; 14 | } 15 | } 16 | if (texture2D(tInput, texcoord).r < 0.3) 17 | { 18 | gl_FragColor = sum*sum*0.012 + texture2D(tInput, texcoord); 19 | } 20 | else 21 | { 22 | if (texture2D(tInput, texcoord).r < 0.5) 23 | { 24 | gl_FragColor = sum*sum*0.009 + texture2D(tInput, texcoord); 25 | } 26 | else 27 | { 28 | gl_FragColor = sum*sum*0.0075 + texture2D(tInput, texcoord); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /fragment-shaders/dot-screen-fs.glsl: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Dot screen shader 5 | * based on glfx.js sepia shader 6 | * https://github.com/evanw/glfx.js 7 | */ 8 | 9 | uniform sampler2D tInput; 10 | uniform vec2 resolution; 11 | varying vec2 vUv; 12 | 13 | vec2 center = .5 * resolution; 14 | float angle = 1.57; 15 | float scale = 1.; 16 | 17 | float pattern() { 18 | float s = sin( angle ), c = cos( angle ); 19 | vec2 tex = vUv * resolution - center; 20 | vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; 21 | return ( sin( point.x ) * sin( point.y ) ) * 4.0; 22 | } 23 | 24 | void main() { 25 | vec4 color = texture2D( tInput, vUv ); 26 | float average = ( color.r + color.g + color.b ) / 3.0; 27 | gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a ); 28 | } -------------------------------------------------------------------------------- /fragment-shaders/bleach-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | uniform float amount; 4 | 5 | varying vec2 vUv; 6 | 7 | const vec4 one = vec4(1.0); 8 | const vec4 two = vec4(2.0); 9 | const vec4 lumcoeff = vec4(0.2125,0.7154,0.0721,0.0); 10 | 11 | vec4 overlay(vec4 myInput, vec4 previousmix, vec4 amount) { 12 | float luminance = dot(previousmix,lumcoeff); 13 | float mixamount = clamp((luminance - 0.45) * 10.0, 0.0, 1.0); 14 | 15 | vec4 branch1 = two * previousmix * myInput; 16 | vec4 branch2 = one - (two * (one - previousmix) * (one - myInput)); 17 | 18 | vec4 result = mix(branch1, branch2, vec4(mixamount) ); 19 | 20 | return mix(previousmix, result, amount); 21 | } 22 | 23 | void main (void) { 24 | vec4 pixel = texture2D(tInput, vUv); 25 | vec4 luma = vec4(vec3(dot(pixel,lumcoeff)), pixel.a); 26 | gl_FragColor = overlay(luma, pixel, vec4(amount)); 27 | } 28 | -------------------------------------------------------------------------------- /fragment-shaders/packed-depth-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform float mNear; 2 | uniform float mFar; 3 | uniform float isPacked; 4 | varying float depth; 5 | 6 | vec4 pack_depth( const in float f ) { 7 | vec4 color; 8 | color.r = floor( f / ( 256. * 256. * 256. ) ); 9 | color.g = floor( ( mod( f, 256. * 256. * 256. ) ) / ( 256. * 256. ) ); 10 | color.b = floor( ( mod( f, 256. * 256. ) ) / 256. ); 11 | color.a = floor( mod( f, 256.) ); 12 | return color / 256.0; 13 | } 14 | 15 | void main() { 16 | 17 | /*float z = gl_FragCoord.z * 2.0 - 1.0 18 | float depth = gl_FragCoord.z / gl_FragCoord.w; 19 | float color = 1. - ( depth - mNear ) / ( mFar - mNear ); 20 | 21 | if( isPacked == 1. ) { 22 | color *= 256. * 256. * 256. * 256.; 23 | gl_FragColor = pack_depth( color ); 24 | } else { 25 | gl_FragColor = vec4( vec3( color ), 1. ); 26 | }*/ 27 | 28 | gl_FragColor = vec4( vec3( 1. - depth ), 1. ); 29 | // gl_FragColor = vec4( vNormal.xyz, color ); 30 | 31 | } -------------------------------------------------------------------------------- /fragment-shaders/bloom2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | float kernel = .005; 4 | float scale = 1.; 5 | float thresh = 1.; 6 | 7 | void main() 8 | { 9 | vec4 sum = vec4(0); 10 | 11 | // mess of for loops due to gpu compiler/hardware limitations 12 | int j=-2; 13 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 14 | j=-1; 15 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 16 | j=0; 17 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 18 | j=1; 19 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 20 | j=2; 21 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 22 | sum/=25.0; 23 | 24 | vec4 s=texture2D(tInput, vUv); 25 | gl_FragColor=s; 26 | 27 | // use the blurred colour if it's bright enough 28 | if (length(sum)>thresh) 29 | { 30 | gl_FragColor +=sum*scale; 31 | } 32 | } -------------------------------------------------------------------------------- /fragment-shaders/halftone-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | uniform float pixelSize; 5 | 6 | void main(void) { 7 | 8 | vec2 p = vUv; 9 | 10 | float pixelsPerRow = resolution.x / pixelSize; 11 | float pixelsPerCol = resolution.y / pixelSize; 12 | 13 | float pixelSizeX = 1.0 / pixelsPerRow; 14 | float dx = mod(p.x, pixelSizeX ) - pixelSizeX *0.5; 15 | float pixelSizeY = 1.0 / pixelsPerCol; 16 | float dy = mod(p.y, pixelSizeY ) - pixelSizeY * 0.5; 17 | float pixelSize = pixelSizeX;//sqrt( pixelSizeX * pixelSizeX + pixelSizeY + pixelSizeY ); 18 | 19 | p.x -= dx; 20 | p.y -= dy; 21 | vec3 col = texture2D(tInput, p).rgb; 22 | vec3 luma = vec3( .299, 0.587, 0.114 ); 23 | float bright = dot( col.rgb, luma ); 24 | 25 | float dist = sqrt(dx*dx + dy*dy); 26 | float rad = bright * pixelSize * 1.; 27 | float m = step( dist, rad ); 28 | 29 | vec3 col2 = mix(vec3(0.0), vec3(1.0), m); 30 | gl_FragColor = vec4(col2, 1.0); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /fragment-shaders/art-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | varying vec2 vUv; 4 | float level( in float value, in float min, in float max ) { 5 | return min / 255.0 + ( max - min ) * value / 255.0; 6 | } 7 | float gamma( in float value, in float g ) { 8 | return pow( value, 1.0 / g ); 9 | } 10 | void main(void) { 11 | 12 | vec4 color = texture2D( tInput, vUv ); 13 | float r = color.r; 14 | float g = color.g; 15 | float b = color.b; 16 | r = level( r, 0.0, 255.0 ); 17 | g = level( g, 0.0, 184.0 ); 18 | b = level( b, 0.0, 113.0 ); 19 | r = gamma( r, 1.10 ); 20 | g = gamma( g, 0.95 ); 21 | b = gamma( b, 1.04 ); 22 | r = level( r, 10.0, 240.0 ); 23 | g = level( g, 10.0, 240.0 ); 24 | b = level( b, 10.0, 240.0 ); 25 | r = gamma( r, 0.87 ); 26 | g = gamma( g, 0.87 ); 27 | b = gamma( b, 0.87 ); 28 | float yL = .2126 * color.r + .7152 * color.g + .0722 * color.b; 29 | r += yL; g += yL; b += yL; 30 | gl_FragColor = vec4( r, g, b, color.a ); 31 | 32 | } -------------------------------------------------------------------------------- /fragment-shaders/ascii-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform vec2 resolution; 3 | uniform sampler2D tInput; 4 | uniform sampler2D tAscii; 5 | const vec2 fontSize = vec2(8.0,16.0); 6 | 7 | vec4 lookupASCII(float asciiValue){ 8 | 9 | vec2 pos = mod(gl_FragCoord.xy,fontSize.xy); 10 | 11 | pos = pos / vec2(2048.0,16.0); 12 | pos.x += asciiValue; 13 | return vec4(texture2D(tAscii,pos).rgb,1.0); 14 | 15 | } 16 | 17 | void main(void) { 18 | 19 | vec2 invViewport = vec2(1.0) / resolution; 20 | vec2 pixelSize = fontSize; 21 | vec4 sum = vec4(0.0); 22 | vec2 uvClamped = vUv-mod(vUv,pixelSize * invViewport); 23 | for (float x=0.0;x size ) { 48 | if( mod( gl_FragCoord.y, dSize ) > size ) { 49 | base.rgb = c1; 50 | } else { 51 | base.rgb = c2; 52 | } 53 | } else { 54 | if( mod( gl_FragCoord.y, dSize ) > size ) { 55 | base.rgb = c2; 56 | } else { 57 | base.rgb = c1; 58 | } 59 | } 60 | 61 | gl_FragColor = vec4( base.rgb, base.a ); 62 | 63 | } -------------------------------------------------------------------------------- /editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Wagner - Minefield! 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Go fullscreen 18 |
19 |
20 | 21 | 22 |
23 |
24 |
    25 |
    26 |
    27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /fragment-shaders/symetric-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform float xReverse; 4 | uniform float yReverse; 5 | uniform float xMirror; 6 | uniform float yMirror; 7 | uniform float angle; 8 | uniform vec2 mirrorCenter; 9 | vec2 nvUv; 10 | 11 | void main() { 12 | 13 | nvUv = vUv; 14 | 15 | if (xReverse == 1.) { 16 | 17 | nvUv.x = (1.0 - vUv.x ); 18 | 19 | if(xMirror == 1.) { 20 | 21 | if(vUv.x < 0.5) { 22 | nvUv.x = 1.0 - (nvUv.x) - (0.5 - mirrorCenter.x ) ; 23 | } 24 | else { 25 | nvUv.x = nvUv.x - (0.5 - mirrorCenter.x); 26 | } 27 | } 28 | } 29 | 30 | else if(xMirror == 1.) { 31 | 32 | if(vUv.x < 0.5) { 33 | nvUv.x = 1.0 - (nvUv.x) - (0.5 - mirrorCenter.x ) ; 34 | } 35 | else { 36 | nvUv.x = nvUv.x - (0.5 - mirrorCenter.x); 37 | } 38 | } 39 | 40 | if (yReverse == 1.) { 41 | 42 | nvUv.y = (1.0 - vUv.y ); 43 | 44 | if(yMirror == 1.) { 45 | if(vUv.y < 0.5) { 46 | nvUv.y = 1.0 - (nvUv.y) - (0.5 - mirrorCenter.y ) ; 47 | } 48 | else { 49 | nvUv.y = nvUv.y - (0.5 - mirrorCenter.y); 50 | } 51 | } 52 | } 53 | 54 | else if(yMirror == 1.) { 55 | 56 | if(vUv.y < 0.5) { 57 | nvUv.y = 1.0 - (nvUv.y) - (0.5 - mirrorCenter.y ) ; 58 | } 59 | else { 60 | nvUv.y = nvUv.y - (0.5 - mirrorCenter.y); 61 | } 62 | } 63 | 64 | 65 | float sin_factor = sin(angle); 66 | float cos_factor = cos(angle); 67 | vec2 origin = vec2(0.5 ,0.5); 68 | 69 | vec2 temp = (nvUv - origin); 70 | 71 | temp = temp * mat2(cos_factor, sin_factor, -sin_factor, cos_factor); 72 | 73 | nvUv = (temp + origin); 74 | 75 | gl_FragColor = texture2D( tInput, nvUv ); 76 | gl_FragColor.rgb = gl_FragColor.rgb; 77 | } 78 | -------------------------------------------------------------------------------- /fragment-shaders/bokeh-poison-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform float radius; 5 | uniform float amount; 6 | uniform vec2 resolution; 7 | 8 | // Bokeh disc. 9 | // by David Hoskins. 10 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 11 | 12 | #define ITERATIONS 150.0 13 | 14 | #define ONEOVER_ITR 1.0 / ITERATIONS 15 | #define PI 3.141596 16 | 17 | // This is (3.-sqrt(5.0))*PI radians, which doesn't precompiled for some reason. 18 | // The compiler is a dunce I tells-ya!! 19 | #define GOLDEN_ANGLE 2.39996323 20 | 21 | //------------------------------------------------------------------------------------------- 22 | // This creates the 2D offset for the next point. 23 | // (r-1.0) is the same as sqrt(0, 1, 2, 3...) 24 | vec2 Sample(in float theta, inout float r) 25 | { 26 | r += 1.0 / r; 27 | return (r-1.0) * vec2(cos(theta), sin(theta)) * .06; 28 | } 29 | 30 | //------------------------------------------------------------------------------------------- 31 | vec3 Bokeh(sampler2D tex, vec2 uv, float radius, float amount) 32 | { 33 | vec3 acc = vec3(0.0); 34 | vec3 div = vec3(0.0); 35 | vec2 pixel = vec2(resolution.y/resolution.x, 1.0) * radius * .025; 36 | float r = 1.0; 37 | for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE) 38 | { 39 | 40 | vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz; 41 | // col = col * col * 1.2; // ...contrast it for better highlights 42 | vec3 bokeh = vec3(.5) + pow(col, vec3(10.0)) * amount; 43 | acc += col * bokeh; 44 | div += bokeh; 45 | } 46 | return acc / div; 47 | } 48 | 49 | //------------------------------------------------------------------------------------------- 50 | void main(void) 51 | { 52 | vec2 uv = gl_FragCoord.xy / resolution.xy; 53 | 54 | gl_FragColor = vec4(Bokeh(tInput, uv*vec2(1.0, 1.0), radius * ( 1. - texture2D( tBias, uv ).r ), amount ), 1.0); 55 | 56 | } -------------------------------------------------------------------------------- /fragment-shaders/bokeh-poison-dof-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform float radius; 5 | uniform float amount; 6 | uniform vec2 resolution; 7 | uniform float focalDistance; 8 | uniform float aperture; 9 | 10 | // Bokeh disc. 11 | // by David Hoskins. 12 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 13 | 14 | #define ITERATIONS 150.0 15 | 16 | #define ONEOVER_ITR 1.0 / ITERATIONS 17 | #define PI 3.141596 18 | 19 | // This is (3.-sqrt(5.0))*PI radians, which doesn't precompiled for some reason. 20 | // The compiler is a dunce I tells-ya!! 21 | #define GOLDEN_ANGLE 2.39996323 22 | 23 | //------------------------------------------------------------------------------------------- 24 | // This creates the 2D offset for the next point. 25 | // (r-1.0) is the same as sqrt(0, 1, 2, 3...) 26 | vec2 Sample(in float theta, inout float r) 27 | { 28 | r += 1.0 / r; 29 | return (r-1.0) * vec2(cos(theta), sin(theta)) * .06; 30 | } 31 | 32 | //------------------------------------------------------------------------------------------- 33 | vec3 Bokeh(sampler2D tex, vec2 uv, float radius, float amount) 34 | { 35 | vec3 acc = vec3(0.0); 36 | vec3 div = vec3(0.0); 37 | vec2 pixel = vec2(resolution.y/resolution.x, 1.0) * radius * .025; 38 | float r = 1.0; 39 | for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE) 40 | { 41 | 42 | vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz; 43 | // col = col * col * 1.2; // ...contrast it for better highlights 44 | vec3 bokeh = vec3(.5) + pow(col, vec3(10.0)) * amount; 45 | acc += col * bokeh; 46 | div += bokeh; 47 | } 48 | return acc / div; 49 | } 50 | 51 | float sampleBias( vec2 uv ) { 52 | float d = abs( texture2D( tBias, uv ).r - focalDistance ); 53 | return d * aperture;//min( d * aperture, .005 ); 54 | //return unpack_depth( texture2D( tBias, uv ) ); 55 | } 56 | 57 | //------------------------------------------------------------------------------------------- 58 | void main(void) 59 | { 60 | vec2 uv = gl_FragCoord.xy / resolution.xy; 61 | float bias = sampleBias( vUv ); 62 | 63 | gl_FragColor = vec4(Bokeh(tInput, uv*vec2(1.0, 1.0), radius * bias, amount ), 1.0); 64 | 65 | } -------------------------------------------------------------------------------- /fragment-shaders/fxaa-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | varying vec2 vUv; 4 | 5 | #define FXAA_REDUCE_MIN (1.0/128.0) 6 | #define FXAA_REDUCE_MUL (1.0/8.0) 7 | #define FXAA_SPAN_MAX 8.0 8 | 9 | void main() { 10 | 11 | vec2 res = 1. / resolution; 12 | 13 | vec3 rgbNW = texture2D( tInput, ( vUv.xy + vec2( -1.0, -1.0 ) * res ) ).xyz; 14 | vec3 rgbNE = texture2D( tInput, ( vUv.xy + vec2( 1.0, -1.0 ) * res ) ).xyz; 15 | vec3 rgbSW = texture2D( tInput, ( vUv.xy + vec2( -1.0, 1.0 ) * res ) ).xyz; 16 | vec3 rgbSE = texture2D( tInput, ( vUv.xy + vec2( 1.0, 1.0 ) * res ) ).xyz; 17 | vec4 rgbaM = texture2D( tInput, vUv.xy * res ); 18 | vec3 rgbM = rgbaM.xyz; 19 | vec3 luma = vec3( 0.299, 0.587, 0.114 ); 20 | 21 | float lumaNW = dot( rgbNW, luma ); 22 | float lumaNE = dot( rgbNE, luma ); 23 | float lumaSW = dot( rgbSW, luma ); 24 | float lumaSE = dot( rgbSE, luma ); 25 | float lumaM = dot( rgbM, luma ); 26 | float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) ); 27 | float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) ); 28 | 29 | vec2 dir; 30 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 31 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 32 | 33 | float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN ); 34 | 35 | float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce ); 36 | dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX), 37 | max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), 38 | dir * rcpDirMin)) * res; 39 | vec4 rgbA = (1.0/2.0) * ( 40 | texture2D(tInput, vUv.xy + dir * (1.0/3.0 - 0.5)) + 41 | texture2D(tInput, vUv.xy + dir * (2.0/3.0 - 0.5))); 42 | vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( 43 | texture2D(tInput, vUv.xy + dir * (0.0/3.0 - 0.5)) + 44 | texture2D(tInput, vUv.xy + dir * (3.0/3.0 - 0.5))); 45 | float lumaB = dot(rgbB, vec4(luma, 0.0)); 46 | 47 | if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) { 48 | gl_FragColor = rgbA; 49 | } else { 50 | gl_FragColor = rgbB; 51 | } 52 | 53 | //gl_FragColor = vec4( texture2D( tInput,vUv ).xyz, 1. ); 54 | } -------------------------------------------------------------------------------- /examples/invert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Invert Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /examples/cga.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner CGA Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/toon.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Toon Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/dirt-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Dirt Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/ascii.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner ASCII Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/cross-fade.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Cross-fade Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/halftone.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Halftone Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/grayscale.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Grayscale Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/high-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner High-pass Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/old-video.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Old Video Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/dot-screen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Dot Screen Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/fxaa.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner FXAA (Fast approXimate Anti-Aliasing) Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/barrel-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Barrel Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/circular-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Circular Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/halftone-cmyk.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Halftone CMYK Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/sobel-edge-detection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Sobel Edge Detection Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /js/debugTools.js: -------------------------------------------------------------------------------- 1 | 2 | ( function() { 3 | 4 | function _h( f, c ) { 5 | return function() { 6 | var res = f.apply( this, arguments ); 7 | c.apply( this, arguments ); 8 | return res; 9 | } 10 | } 11 | 12 | function processErrors( errors, source ) { 13 | 14 | var css = '#shaderReport{ box-sizing: border-box; position: absolute; left: 0; top: 0; \ 15 | right: 0; font-family: monaco, monospace; font-size: 12px; z-index: 10000; \ 16 | background-color: #b70000; color: #ffffff; white-space: normal; \ 17 | text-shadow: 0 -1px 0 rgba(0,0,0,.6); line-height: 1.2em; list-style-type: none; \ 18 | padding: 0; margin: 0; max-height: 300px; overflow: auto; } \ 19 | #shaderReport li{ padding: 10px; border-top: 1px solid rgba( 255, 255, 255, .2 ); \ 20 | border-bottom: 1px solid rgba( 0, 0, 0, .2 ) } \ 21 | #shaderReport li p{ padding: 0; margin: 0 } \ 22 | #shaderReport li:nth-child(odd){ background-color: #c9542b }\ 23 | #shaderReport li p:first-child{ color: #eee }'; 24 | 25 | var el = document.createElement( 'style' ); 26 | document.getElementsByTagName( 'head' )[ 0 ].appendChild( el ); 27 | el.textContent = css; 28 | 29 | var report = document.createElement( 'ul' ); 30 | report.setAttribute( 'id', 'shaderReport' ); 31 | document.body.appendChild( report ); 32 | 33 | var re = /ERROR: [\d]+:([\d]+): (.+)/gmi; 34 | var lines = source.split( '\n' ); 35 | 36 | var m; 37 | while ((m = re.exec( errors )) != null) { 38 | if (m.index === re.lastIndex) { 39 | re.lastIndex++; 40 | } 41 | var li = document.createElement( 'li' ); 42 | var code = '

    ERROR "' + m[ 2 ] + '" in line ' + m[ 1 ] + '

    ' 43 | code += '

    ' + lines[ m[ 1 ] - 1 ].replace( /^[ \t]+/g, '' ) + '

    '; 44 | li.innerHTML = code; 45 | report.appendChild( li ); 46 | } 47 | 48 | } 49 | 50 | WebGLRenderingContext.prototype.compileShader = _h( 51 | WebGLRenderingContext.prototype.compileShader, 52 | function( shader ) { 53 | 54 | if ( !this.getShaderParameter( shader, this.COMPILE_STATUS ) ) { 55 | 56 | var errors = this.getShaderInfoLog( shader ); 57 | var source = this.getShaderSource( shader ); 58 | 59 | processErrors( errors, source ); 60 | 61 | } 62 | } 63 | ); 64 | 65 | } )(); -------------------------------------------------------------------------------- /examples/chromatic-aberration.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Chromatic Aberration Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/sepia.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Sepia Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/full-box-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Box Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/pixelate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Pixelate Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /fragment-shaders/frei-chen-fs.glsl: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Frei-Chen filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | */ 8 | 9 | uniform sampler2D tInput; 10 | varying vec2 vUv; 11 | uniform vec2 resolution; 12 | vec2 texel = vec2(1.0 / resolution.x, 1.0 / resolution.y); 13 | mat3 G[9]; 14 | // hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45 15 | const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 ); 16 | const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 ); 17 | const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 ); 18 | const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 ); 19 | const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 ); 20 | const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 ); 21 | const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 ); 22 | const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 ); 23 | const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 ); 24 | 25 | void main(void) { 26 | 27 | G[0] = g0, 28 | G[1] = g1, 29 | G[2] = g2, 30 | G[3] = g3, 31 | G[4] = g4, 32 | G[5] = g5, 33 | G[6] = g6, 34 | G[7] = g7, 35 | G[8] = g8; 36 | 37 | mat3 I; 38 | float cnv[9]; 39 | vec3 sample; 40 | 41 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 42 | for (float i=0.0; i<3.0; i++) { 43 | for (float j=0.0; j<3.0; j++) { 44 | sample = texture2D(tInput, vUv + texel * vec2(i-1.0,j-1.0) ).rgb; 45 | I[int(i)][int(j)] = length(sample); 46 | } 47 | } 48 | 49 | /* calculate the convolution values for all the masks */ 50 | for (int i=0; i<9; i++) { 51 | float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]); 52 | cnv[i] = dp3 * dp3; 53 | } 54 | 55 | float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]); 56 | float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M); 57 | 58 | gl_FragColor = vec4(vec3(sqrt(M/S)), texture2D( tInput, vUv ).a ); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /examples/noise.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Noise Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/box-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Box Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/denoise.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Denoise Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/rgb-split.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Pixelate Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/vignette.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Vignette Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/halftone2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Halftone Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/vignette2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Vignette2 Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/zoom-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Zoom Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /fragment-shaders/fxaa2-fs.glsl: -------------------------------------------------------------------------------- 1 | // FXAA shader, GLSL code adapted from: 2 | // http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA 3 | // Whitepaper describing the technique: 4 | // http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf 5 | 6 | // from: https://code.google.com/p/processing/source/browse/trunk/processing/java/libraries/opengl/examples/Shaders/FXAA/data/fxaa.glsl?r=9668 7 | 8 | uniform sampler2D tInput; 9 | uniform vec2 resolution; 10 | varying vec2 vUv; 11 | // The inverse of the texture dimensions along X and Y 12 | vec2 texcoordOffset = 1. / resolution; 13 | 14 | //varying vec4 vertColor; 15 | vec4 vertTexcoord = vec4( vUv, 1., 1. ); 16 | 17 | void main() { 18 | // The parameters are hardcoded for now, but could be 19 | // made into uniforms to control fromt he program. 20 | float FXAA_SPAN_MAX = 8.0; 21 | float FXAA_REDUCE_MUL = 1.0/8.0; 22 | float FXAA_REDUCE_MIN = (1.0/128.0); 23 | 24 | vec3 rgbNW = texture2D(tInput, vertTexcoord.xy + (vec2(-1.0, -1.0) * texcoordOffset)).xyz; 25 | vec3 rgbNE = texture2D(tInput, vertTexcoord.xy + (vec2(+1.0, -1.0) * texcoordOffset)).xyz; 26 | vec3 rgbSW = texture2D(tInput, vertTexcoord.xy + (vec2(-1.0, +1.0) * texcoordOffset)).xyz; 27 | vec3 rgbSE = texture2D(tInput, vertTexcoord.xy + (vec2(+1.0, +1.0) * texcoordOffset)).xyz; 28 | vec3 rgbM = texture2D(tInput, vertTexcoord.xy).xyz; 29 | 30 | vec3 luma = vec3(0.299, 0.587, 0.114); 31 | float lumaNW = dot(rgbNW, luma); 32 | float lumaNE = dot(rgbNE, luma); 33 | float lumaSW = dot(rgbSW, luma); 34 | float lumaSE = dot(rgbSE, luma); 35 | float lumaM = dot( rgbM, luma); 36 | 37 | float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); 38 | float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 39 | 40 | vec2 dir; 41 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 42 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 43 | 44 | float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); 45 | 46 | float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); 47 | 48 | dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), 49 | max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset; 50 | 51 | vec3 rgbA = (1.0/2.0) * ( 52 | texture2D(tInput, vertTexcoord.xy + dir * (1.0/3.0 - 0.5)).xyz + 53 | texture2D(tInput, vertTexcoord.xy + dir * (2.0/3.0 - 0.5)).xyz); 54 | vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( 55 | texture2D(tInput, vertTexcoord.xy + dir * (0.0/3.0 - 0.5)).xyz + 56 | texture2D(tInput, vertTexcoord.xy + dir * (3.0/3.0 - 0.5)).xyz); 57 | float lumaB = dot(rgbB, luma); 58 | 59 | if((lumaB < lumaMin) || (lumaB > lumaMax)){ 60 | gl_FragColor.xyz=rgbA; 61 | } else { 62 | gl_FragColor.xyz=rgbB; 63 | } 64 | gl_FragColor.a = 1.0; 65 | 66 | //gl_FragColor *= vertColor; 67 | } -------------------------------------------------------------------------------- /examples/directional-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Directional blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /fragment-shaders/ssao-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tDepth; 3 | uniform sampler2D tInput; 4 | uniform vec2 resolution; 5 | uniform float isPacked; 6 | uniform float onlyOcclusion; 7 | 8 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 9 | 10 | float unpack_depth(const in vec4 color) { 11 | return ( color.r * 256. * 256. * 256. + color.g * 256. * 256. + color.b * 256. + color.a ) / ( 256. * 256. * 256. ); 12 | } 13 | 14 | float sampleDepth( vec2 uv ) { 15 | if( isPacked == 1. ) { 16 | return unpack_depth( texture2D( tDepth, uv ) ); 17 | } else { 18 | return texture2D( tDepth, uv ).r; 19 | } 20 | } 21 | 22 | float occlusion = 0.; 23 | float depth = sampleDepth( vUv ); 24 | float ac = 0.; 25 | 26 | void checkDepth( vec2 uv ) { // from iq's tutorial 27 | float zd = 10.0 * min( depth - sampleDepth( uv ), 0.0 ); 28 | ac += zd; 29 | occlusion += 1.0 / ( 1. + zd * zd ); 30 | } 31 | 32 | void main() { 33 | 34 | float r = 4.; 35 | float xi = r / resolution.x; 36 | float yi = r / resolution.y; 37 | 38 | checkDepth( vUv + vec2( - 2. * xi, - 2. * yi ) ); 39 | checkDepth( vUv + vec2( - xi, - 2. * yi ) ); 40 | checkDepth( vUv + vec2( 0., - 2. * yi ) ); 41 | checkDepth( vUv + vec2( xi, - 2. * yi ) ); 42 | checkDepth( vUv + vec2( 2. * xi, - 2. * yi ) ); 43 | 44 | checkDepth( vUv + vec2( - 2. * xi, - yi ) ); 45 | checkDepth( vUv + vec2( - xi, - yi ) ); 46 | checkDepth( vUv + vec2( 0., - yi ) ); 47 | checkDepth( vUv + vec2( xi, - yi ) ); 48 | checkDepth( vUv + vec2( 2. * xi, - yi ) ); 49 | 50 | checkDepth( vUv + vec2( - 2. * xi, 0. ) ); 51 | checkDepth( vUv + vec2( - xi, 0. ) ); 52 | checkDepth( vUv + vec2( xi, 0. ) ); 53 | checkDepth( vUv + vec2( 2. * xi, 0. ) ); 54 | 55 | checkDepth( vUv + vec2( - 2. * xi, yi ) ); 56 | checkDepth( vUv + vec2( - xi, yi ) ); 57 | checkDepth( vUv + vec2( 0., yi ) ); 58 | checkDepth( vUv + vec2( xi, yi ) ); 59 | checkDepth( vUv + vec2( 2. * xi, yi ) ); 60 | 61 | checkDepth( vUv + vec2( - 2. * xi, 2. * yi ) ); 62 | checkDepth( vUv + vec2( - xi, 2. * yi ) ); 63 | checkDepth( vUv + vec2( 0., 2. * yi ) ); 64 | checkDepth( vUv + vec2( xi, 2. * yi ) ); 65 | checkDepth( vUv + vec2( 2. * xi, 2. * yi ) ); 66 | 67 | occlusion /= 24.; 68 | occlusion += .02 * random( vec3( gl_FragCoord.xy, depth ), length( gl_FragCoord ) ); 69 | 70 | /*if( onlyOcclusion == 1. ) { 71 | gl_FragColor = vec4( vec3( occlusion ), 1. ); 72 | } else { 73 | vec3 color = texture2D( tInput, vUv ).rgb; 74 | color = mix( vec3( 0. ), color, occlusion ); 75 | gl_FragColor = vec4( color, 1. ); 76 | }*/ 77 | 78 | 79 | float inBlack = 0.; 80 | float inWhite = 255.; 81 | float inGamma = 10.; 82 | float outBlack = 0.; 83 | float outWhite = 255.; 84 | 85 | //occlusion = ( pow( ( ( occlusion * 255.0) - inBlack) / (inWhite - inBlack), inGamma) * (outWhite - outBlack) + outBlack) / 255.0; 86 | 87 | gl_FragColor = vec4( vec3( occlusion ), 1. ); 88 | 89 | } -------------------------------------------------------------------------------- /examples/led.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner LED Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Wagner 2 | ====== 3 | 4 | Effects composer for three.js 5 | 6 | This is a WIP version of a new proposal for an effect composer for three.js 7 | 8 | There's a demo with the latest-ish version of the code here [demo](http://www.clicktorelease.com/tmp/wagner). Here's a snapshot to give you an idea of what it can achieve: 9 | 10 | ![Image](./assets/snapshot.jpg) 11 | 12 | Please use it only for review and test purposes. Don't hesitate to add issues or open a conversation about design decisions. 13 | 14 | Basic usage 15 | ---------- 16 | 17 | ```js 18 | /* 19 | Include the libs 20 | 21 | */ 22 | 23 | var composer = new WAGNER.Composer( renderer ); 24 | composer.setSize( window.innerWidth, window.innerHeight ); // or whatever resolution 25 | 26 | var zoomBlurPass = new WAGNER.ZoomBlurPass(); 27 | var multiPassBloomPass = new WAGNER.MultiPassBloomPass(); 28 | 29 | renderer.autoClearColor = true; 30 | composer.reset(); 31 | composer.render( scene, camera ); 32 | composer.pass( multiPassBloomPass ); 33 | composer.pass( zoomBlurPass ); 34 | composer.toScreen(); 35 | ``` 36 | 37 | What works 38 | ---------- 39 | 40 | - Passes are by default RGBA 41 | - Ping-pong buffers when chaining passes 42 | - ShaderLoader is being replaced, but you can use it to load .glsl files. It hides all the XHR stuff 43 | - Composing with Wagner for effects that run chained with the same resolution (e.g. full-screen effects) 44 | - Basic effects implemented in the new WAGNER.Pass class: 45 | - Blend pass: all single pass. Current blend modes implemented: normal, darken, multiply, lighten, screen, overlay, soft light, hard light 46 | - Invert: single pass, inverts colours 47 | - Box Blur: single pass, blur in one direction specified in vec2 delta uniform 48 | - Full Box Blur: multipass, 2 box blur in two directions 49 | - Zoom Blur: single pass 50 | - Sepia, Noise, Denoise, Vignette, edge detection 51 | - Multi Pass Bloom: multipass, applies blur and blends with Screen mode 52 | - DOF (simple) 53 | - SSAO (simple) 54 | - uniform reflection from GLSL source is working enough to be usable for most cases 55 | - settings different path for shader loading 56 | 57 | What still doesn't work / needs work 58 | ------------------------------------ 59 | 60 | - ~~ShaderLoader will probably be removed, or be transparent to the user~~ 61 | - ~~Passing parameters to WAGNER.ShaderPass from main code~~ 62 | - ~~Correct use of textures of different dimensions along the chain~~ 63 | - Resizing correctly all render targets 64 | - ~~Multiple Composers working at the same time~~ 65 | - Shaders that are not ported to WAGNER.Pass: ~~pixelate~~, ~~rgb split~~, different single-pass bloom 66 | - Shaders that haven't even been ported to WAGNER: camera motion blur, directional blur, gamma, levels, 67 | - Alias definition of passes (previously loadPass()) legacy 68 | - uniform reflection from GLSL source doesn't support structures (I don't even know if WebGL supports structures) 69 | 70 | Credits 71 | ------- 72 | 73 | Composer following the work of alteredq's [THREE.EffectComposer](https://github.com/mrdoob/three.js/blob/master/examples/js/postprocessing/EffectComposer.js) 74 | 75 | Most of the shaders are from [https://github.com/evanw/glfx.js](https://github.com/evanw/glfx.js). Others are from different sources and forums, papers, or my own. 76 | 77 | License 78 | ======= 79 | 80 | MIT licensed 81 | 82 | Copyright (C) 2014 Jaume Sanchez Elias - All shaders are copyright of their respective authors. 83 | 84 | I'm trying to trace the original source for some of the common shaders. If your code is featured in the shaders folders, and wish to be correctly credited, or the code removed, please open an issue. 85 | 86 | http://www.clicktorelease.com -------------------------------------------------------------------------------- /fragment-shaders/old-video-fs.glsl: -------------------------------------------------------------------------------- 1 | #define BLACK_AND_WHITE 2 | #define LINES_AND_FLICKER 3 | #define BLOTCHES 4 | #define GRAIN 5 | 6 | #define FREQUENCY 15.0 7 | 8 | uniform sampler2D tInput; 9 | uniform vec2 resolution; 10 | uniform float time; 11 | 12 | vec2 uv; 13 | 14 | float rand(vec2 co){ 15 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 16 | } 17 | 18 | float rand(float c){ 19 | return rand(vec2(c,1.0)); 20 | } 21 | 22 | float randomLine(float seed) 23 | { 24 | float b = 0.01 * rand(seed); 25 | float a = rand(seed+1.0); 26 | float c = rand(seed+2.0) - 0.5; 27 | float mu = rand(seed+3.0); 28 | 29 | float l = 1.0; 30 | 31 | if ( mu > 0.2) 32 | l = pow( abs(a * uv.x + b * uv.y + c ), 1.0/8.0 ); 33 | else 34 | l = 2.0 - pow( abs(a * uv.x + b * uv.y + c), 1.0/8.0 ); 35 | 36 | return mix(0.5, 1.0, l); 37 | } 38 | 39 | // Generate some blotches. 40 | float randomBlotch(float seed) 41 | { 42 | float x = rand(seed); 43 | float y = rand(seed+1.0); 44 | float s = 0.01 * rand(seed+2.0); 45 | 46 | vec2 p = vec2(x,y) - uv; 47 | p.x *= resolution.x / resolution.y; 48 | float a = atan(p.y,p.x); 49 | float v = 1.0; 50 | float ss = s*s * (sin(6.2831*a*x)*0.1 + 1.0); 51 | 52 | if ( dot(p,p) < ss ) v = 0.2; 53 | else 54 | v = pow(dot(p,p) - ss, 1.0/16.0); 55 | 56 | return mix(0.3 + 0.2 * (1.0 - (s / 0.02)), 1.0, v); 57 | } 58 | 59 | 60 | void main(void) 61 | { 62 | uv = gl_FragCoord.xy / resolution.xy; 63 | 64 | // Set frequency of global effect to 20 variations per second 65 | float t = float(int(time * FREQUENCY)); 66 | 67 | // Get some image movement 68 | vec2 suv = uv + 0.002 * vec2( rand(t), rand(t + 23.0)); 69 | 70 | // Get the image 71 | vec3 image = texture2D( tInput, vec2(suv.x, suv.y) ).xyz; 72 | 73 | #ifdef BLACK_AND_WHITE 74 | // Pass it to B/W 75 | float luma = dot( vec3(0.2126, 0.7152, 0.0722), image ); 76 | vec3 oldImage = luma * vec3(0.7, 0.7, 0.7); 77 | #else 78 | vec3 oldImage = image; 79 | #endif 80 | 81 | // Create a time-varyting vignetting effect 82 | float vI = 16.0 * (uv.x * (1.0-uv.x) * uv.y * (1.0-uv.y)); 83 | vI *= mix( 0.7, 1.0, rand(t + 0.5)); 84 | 85 | // Add additive flicker 86 | vI += 1.0 + 0.4 * rand(t+8.); 87 | 88 | // Add a fixed vignetting (independent of the flicker) 89 | vI *= pow(16.0 * uv.x * (1.0-uv.x) * uv.y * (1.0-uv.y), 0.4); 90 | 91 | // Add some random lines (and some multiplicative flicker. Oh well.) 92 | #ifdef LINES_AND_FLICKER 93 | int l = int(8.0 * rand(t+7.0)); 94 | 95 | if ( 0 < l ) vI *= randomLine( t+6.0+17.* float(0)); 96 | if ( 1 < l ) vI *= randomLine( t+6.0+17.* float(1)); 97 | if ( 2 < l ) vI *= randomLine( t+6.0+17.* float(2)); 98 | if ( 3 < l ) vI *= randomLine( t+6.0+17.* float(3)); 99 | if ( 4 < l ) vI *= randomLine( t+6.0+17.* float(4)); 100 | if ( 5 < l ) vI *= randomLine( t+6.0+17.* float(5)); 101 | if ( 6 < l ) vI *= randomLine( t+6.0+17.* float(6)); 102 | if ( 7 < l ) vI *= randomLine( t+6.0+17.* float(7)); 103 | 104 | #endif 105 | 106 | // Add some random blotches. 107 | #ifdef BLOTCHES 108 | int s = int( max(8.0 * rand(t+18.0) -2.0, 0.0 )); 109 | 110 | if ( 0 < s ) vI *= randomBlotch( t+6.0+19.* float(0)); 111 | if ( 1 < s ) vI *= randomBlotch( t+6.0+19.* float(1)); 112 | if ( 2 < s ) vI *= randomBlotch( t+6.0+19.* float(2)); 113 | if ( 3 < s ) vI *= randomBlotch( t+6.0+19.* float(3)); 114 | if ( 4 < s ) vI *= randomBlotch( t+6.0+19.* float(4)); 115 | if ( 5 < s ) vI *= randomBlotch( t+6.0+19.* float(5)); 116 | 117 | #endif 118 | 119 | // Show the image modulated by the defects 120 | gl_FragColor.xyz = oldImage * vI; 121 | 122 | // Add some grain (thanks, Jose!) 123 | #ifdef GRAIN 124 | gl_FragColor.xyz *= (1.0+(rand(uv+t*.01)-.2)*.15); 125 | #endif 126 | 127 | } -------------------------------------------------------------------------------- /legacy/ShaderPasser.js: -------------------------------------------------------------------------------- 1 | 2 | var Composer = function( source, settings ) { 3 | 4 | var _source = source, 5 | _settings = settings || {}, 6 | _shaders = {}; 7 | 8 | _settings.scale = _settings.scale || 1; 9 | 10 | var _scene = new THREE.Scene(); 11 | var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 ); 12 | 13 | var _read = new THREE.WebGLRenderTarget( window.innerWidth / _settings.scale, window.innerHeight / _settings.scale, { 14 | minFilter: THREE.LinearFilter, 15 | magFilter: THREE.LinearFilter, 16 | format: THREE.RGBFormat 17 | } ); 18 | 19 | var _write = _read.clone(); 20 | 21 | window.addEventListener( 'resize', _resize ); 22 | 23 | var blitShader = new THREE.ShaderMaterial( { 24 | 25 | uniforms: { 26 | tDiffuse: { type: "t", value: 0, texture: _read } 27 | }, 28 | vertexShader: document.getElementById( 'vertexShader' ).textContent, 29 | fragmentShader: document.getElementById( 'fs_Normal' ).textContent, 30 | 31 | depthWrite: false, 32 | depthTest: false 33 | 34 | } ); 35 | 36 | _source = _read; 37 | 38 | var _quad = new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ), blitShader ); 39 | _quad.position.z = -100; 40 | _scene.add( _quad ); 41 | 42 | _resize(); 43 | 44 | function _resize() { 45 | 46 | //_read.width = _write.width = window.innerWidth / _settings.scale; 47 | //_read.height = _write.height = window.innerHeight / _settings.scale; 48 | _camera.projectionMatrix.makeOrthographic( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 ); 49 | _quad.scale.set( window.innerWidth, window.innerHeight ); 50 | _quad.updateMatrix(); 51 | 52 | } 53 | 54 | function _reset( source ) { 55 | 56 | _source = source?source:_read; 57 | _target = _write; 58 | 59 | } 60 | 61 | function _applyShader( a, b ) { 62 | 63 | if( a instanceof THREE.Scene ) { 64 | _target.width = window.innerWidth / _settings.scale; 65 | _target.height = window.innerHeight / _settings.scale; 66 | _settings.renderer.render( a, b, _target, true ); 67 | 68 | _quad.material.uniforms[ 'tDiffuse' ].value = _target; 69 | //if( _quad.material.uniforms[ 'resolution' ] ) _quad.material.uniforms[ 'resolution' ].value.set( window.innerWidth / _settings.scale, window.innerHeight / _settings.scale ); 70 | } else { 71 | var shader = a; 72 | var uniforms = b; 73 | _quad.material = shader; 74 | _quad.material.uniforms[ 'tDiffuse' ].value = _source; 75 | for( var j in uniforms ) { 76 | _quad.material.uniforms[ j ].value = uniforms[ j ]; 77 | } 78 | if( _quad.material.uniforms[ 'resolution' ] ) _quad.material.uniforms[ 'resolution' ].value.set( window.innerWidth / _settings.scale, window.innerHeight / _settings.scale ); 79 | _settings.renderer.render( _scene, _camera, _target, false ); 80 | } 81 | 82 | var tmp = _source; 83 | _source = _target; 84 | _target = tmp; 85 | 86 | } 87 | 88 | function _blit() { 89 | 90 | //_quad.material.wireframe = true; 91 | _settings.renderer.render( _scene, _camera ); 92 | 93 | } 94 | 95 | function _clone( _output ) { 96 | 97 | _quad.material = blitShader; 98 | _quad.material.uniforms[ 'tDiffuse' ].value = _source; 99 | //if( _quad.material.uniforms[ 'resolution' ] ) _quad.material.uniforms[ 'resolution' ].value.set( window.innerWidth, window.innerHeight ); 100 | _settings.renderer.render( _scene, _camera, _output, false ); 101 | 102 | } 103 | 104 | return { 105 | 106 | pass: _applyShader, 107 | blit: _blit, 108 | get result(){ return _source; }, 109 | set source( s ){ _source = s; }, 110 | reset: _reset, 111 | clone: _clone 112 | 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /examples/guided-full-box-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Guided Full Box Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Wagner - Minefield! 6 | 7 | 8 | 81 | 82 | 83 | 84 | 85 | 86 |
    87 | Go fullscreen 88 |
    89 | Shaders Stack Order (reverse) 90 | 91 |
    92 |
    This is the minefield playground for Wagner, a new composer for three.js. 93 |
    Check out the repo here https://github.com/spite/Wagner and contribute, 94 |
    open an issue, suggest your ideas. This is extremely work in progress! 95 |
    Made with and for three.js | Stats by rStats | @thespite | clicktorelease.com 96 |
    97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /examples/multipass-bloom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Multipass Bloom Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /examples/guided-box-blur.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Guided Box Blur Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /examples/ssao.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner SSAO (Screen Space Ambient Occlusion) Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /examples/dof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wagner - Minefield! 5 | 6 | 7 | 25 | 26 | 27 | 28 | 29 |
    30 | Go fullscreen 31 |
    Wagner Simple DOF (Depth of Field) Pass
    32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /legacy/index-0.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - render-to-texture 5 | 6 | 7 | 20 | 21 | 22 | 23 |
    24 | 25 | 26 | 27 | 28 | 29 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /fragment-shaders/toon-fs.glsl: -------------------------------------------------------------------------------- 1 | // Based on http://coding-experiments.blogspot.sg/2011/01/toon-pixel-shader.html 2 | 3 | uniform vec3 resolution; 4 | uniform sampler2D tInput; 5 | varying vec2 vUv; 6 | 7 | #define HueLevCount 6 8 | #define SatLevCount 7 9 | #define ValLevCount 4 10 | float HueLevels[HueLevCount]; 11 | float SatLevels[SatLevCount]; 12 | float ValLevels[ValLevCount]; 13 | 14 | vec3 RGBtoHSV( float r, float g, float b) { 15 | float minv, maxv, delta; 16 | vec3 res; 17 | 18 | minv = min(min(r, g), b); 19 | maxv = max(max(r, g), b); 20 | res.z = maxv; // v 21 | 22 | delta = maxv - minv; 23 | 24 | if( maxv != 0.0 ) 25 | res.y = delta / maxv; // s 26 | else { 27 | // r = g = b = 0 // s = 0, v is undefined 28 | res.y = 0.0; 29 | res.x = -1.0; 30 | return res; 31 | } 32 | 33 | if( r == maxv ) 34 | res.x = ( g - b ) / delta; // between yellow & magenta 35 | else if( g == maxv ) 36 | res.x = 2.0 + ( b - r ) / delta; // between cyan & yellow 37 | else 38 | res.x = 4.0 + ( r - g ) / delta; // between magenta & cyan 39 | 40 | res.x = res.x * 60.0; // degrees 41 | if( res.x < 0.0 ) 42 | res.x = res.x + 360.0; 43 | 44 | return res; 45 | } 46 | 47 | vec3 HSVtoRGB(float h, float s, float v ) { 48 | int i; 49 | float f, p, q, t; 50 | vec3 res; 51 | 52 | if( s == 0.0 ) { 53 | // achromatic (grey) 54 | res.x = v; 55 | res.y = v; 56 | res.z = v; 57 | return res; 58 | } 59 | 60 | h /= 60.0; // sector 0 to 5 61 | i = int(floor( h )); 62 | f = h - float(i); // factorial part of h 63 | p = v * ( 1.0 - s ); 64 | q = v * ( 1.0 - s * f ); 65 | t = v * ( 1.0 - s * ( 1.0 - f ) ); 66 | 67 | if (i==0) { 68 | res.x = v; 69 | res.y = t; 70 | res.z = p; 71 | } else if (i==1) { 72 | res.x = q; 73 | res.y = v; 74 | res.z = p; 75 | } else if (i==2) { 76 | res.x = p; 77 | res.y = v; 78 | res.z = t; 79 | } else if (i==3) { 80 | res.x = p; 81 | res.y = q; 82 | res.z = v; 83 | } else if (i==4) { 84 | res.x = t; 85 | res.y = p; 86 | res.z = v; 87 | } else if (i==5) { 88 | res.x = v; 89 | res.y = p; 90 | res.z = q; 91 | } 92 | 93 | return res; 94 | } 95 | 96 | float nearestLevel(float col, int mode) { 97 | 98 | if (mode==0) { 99 | for (int i =0; i= HueLevels[i] && col <= HueLevels[i+1]) { 101 | return HueLevels[i+1]; 102 | } 103 | } 104 | } 105 | 106 | if (mode==1) { 107 | for (int i =0; i= SatLevels[i] && col <= SatLevels[i+1]) { 109 | return SatLevels[i+1]; 110 | } 111 | } 112 | } 113 | 114 | 115 | if (mode==2) { 116 | for (int i =0; i= ValLevels[i] && col <= ValLevels[i+1]) { 118 | return ValLevels[i+1]; 119 | } 120 | } 121 | } 122 | 123 | 124 | } 125 | 126 | // averaged pixel intensity from 3 color channels 127 | float avg_intensity(vec4 pix) { 128 | return (pix.r + pix.g + pix.b)/3.; 129 | } 130 | 131 | vec4 get_pixel(vec2 coords, float dx, float dy) { 132 | return texture2D(tInput,coords + vec2(dx, dy)); 133 | } 134 | 135 | // returns pixel color 136 | float IsEdge(in vec2 coords){ 137 | float dxtex = 1.0 / resolution.x ; 138 | float dytex = 1.0 / resolution.y ; 139 | 140 | float pix[9]; 141 | 142 | int k = -1; 143 | float delta; 144 | 145 | // read neighboring pixel intensities 146 | float pix0 = avg_intensity(get_pixel(coords,-1.0*dxtex, -1.0*dytex)); 147 | float pix1 = avg_intensity(get_pixel(coords,-1.0*dxtex, 0.0*dytex)); 148 | float pix2 = avg_intensity(get_pixel(coords,-1.0*dxtex, 1.0*dytex)); 149 | float pix3 = avg_intensity(get_pixel(coords,0.0*dxtex, -1.0*dytex)); 150 | float pix4 = avg_intensity(get_pixel(coords,0.0*dxtex, 0.0*dytex)); 151 | float pix5 = avg_intensity(get_pixel(coords,0.0*dxtex, 1.0*dytex)); 152 | float pix6 = avg_intensity(get_pixel(coords,1.0*dxtex, -1.0*dytex)); 153 | float pix7 = avg_intensity(get_pixel(coords,1.0*dxtex, 0.0*dytex)); 154 | float pix8 = avg_intensity(get_pixel(coords,1.0*dxtex, 1.0*dytex)); 155 | // average color differences around neighboring pixels 156 | delta = (abs(pix1-pix7)+ 157 | abs(pix5-pix3) + 158 | abs(pix0-pix8)+ 159 | abs(pix2-pix6) 160 | )/4.; 161 | 162 | return clamp(5.5*delta,0.0,1.0); 163 | } 164 | 165 | void main(void) 166 | { 167 | 168 | HueLevels[0] = 0.0; 169 | HueLevels[1] = 80.0; 170 | HueLevels[2] = 160.0; 171 | HueLevels[3] = 240.0; 172 | HueLevels[4] = 320.0; 173 | HueLevels[5] = 360.0; 174 | 175 | SatLevels[0] = 0.0; 176 | SatLevels[1] = 0.1; 177 | SatLevels[2] = 0.3; 178 | SatLevels[3] = 0.5; 179 | SatLevels[4] = 0.6; 180 | SatLevels[5] = 0.8; 181 | SatLevels[6] = 1.0; 182 | 183 | ValLevels[0] = 0.0; 184 | ValLevels[1] = 0.3; 185 | ValLevels[2] = 0.6; 186 | ValLevels[3] = 1.0; 187 | 188 | vec4 colorOrg = texture2D( tInput, vUv ); 189 | vec3 vHSV = RGBtoHSV(colorOrg.r,colorOrg.g,colorOrg.b); 190 | vHSV.x = nearestLevel(vHSV.x, 0); 191 | vHSV.y = nearestLevel(vHSV.y, 1); 192 | vHSV.z = nearestLevel(vHSV.z, 2); 193 | float edg = IsEdge(vUv); 194 | vec3 vRGB = (edg >= 0.3)? vec3(0.0,0.0,0.0):HSVtoRGB(vHSV.x,vHSV.y,vHSV.z); 195 | gl_FragColor = vec4(vRGB.x,vRGB.y,vRGB.z,1.0); 196 | } -------------------------------------------------------------------------------- /legacy/index-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - render-to-texture 5 | 6 | 7 | 20 | 21 | 22 | 23 |
    24 | 25 | 26 | 27 | 28 | 29 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /fragment-shaders/ssao-simple-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | uniform sampler2D tDepth; 4 | uniform vec2 resolution; 5 | uniform float zNear; 6 | uniform float zFar; 7 | uniform float strength; 8 | 9 | // ------------- 10 | 11 | /* 12 | SSAO GLSL shader v1.2 13 | assembled by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com) 14 | original technique is made by Arkano22 (www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 15 | 16 | changelog: 17 | 1.2 - added fog calculation to mask AO. Minor fixes. 18 | 1.1 - added spiral sampling method from here: 19 | (http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere) 20 | */ 21 | //uniform sampler2D bgl_RenderedTexture; 22 | 23 | #define PI 3.14159265 24 | 25 | float width = resolution.x; //texture width 26 | float height = resolution.y; //texture height 27 | 28 | vec2 texCoord = vUv; 29 | 30 | //------------------------------------------ 31 | //general stuff 32 | 33 | //user variables 34 | uniform int samples; //ao sample count //64.0 35 | uniform float radius; //ao radius //5.0 36 | 37 | float aoclamp = 0.125; //depth clamp - reduces haloing at screen edges 38 | bool noise = true; //use noise instead of pattern for sample dithering 39 | float noiseamount = 0.0002; //dithering amount 40 | 41 | float diffarea = 0.3; //self-shadowing reduction 42 | float gdisplace = 0.4; //gauss bell center //0.4 43 | 44 | bool mist = false; //use mist? 45 | float miststart = 0.0; //mist start 46 | float mistend = zFar; //mist end 47 | 48 | bool onlyAO = false; //use only ambient occlusion pass? 49 | float lumInfluence = 0.7; //how much luminance affects occlusion 50 | 51 | //-------------------------------------------------------- 52 | 53 | vec2 rand(vec2 coord) //generating noise/pattern texture for dithering 54 | { 55 | float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0; 56 | float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0; 57 | 58 | if (noise) 59 | { 60 | noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0; 61 | noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0; 62 | } 63 | return vec2(noiseX,noiseY)*noiseamount; 64 | } 65 | 66 | float doMist() 67 | { 68 | float zdepth = texture2D(tDepth,texCoord.xy).x; 69 | float depth = -zFar * zNear / (zdepth * (zFar - zNear) - zFar); 70 | return clamp((depth-miststart)/mistend,0.0,1.0); 71 | } 72 | 73 | float readDepth(vec2 coord) 74 | { 75 | if (vUv.x<0.0||vUv.y<0.0) return 1.0; 76 | else { 77 | float z_b = texture2D(tDepth, coord ).x; 78 | float z_n = 2.0 * z_b - 1.0; 79 | return (2.0 * zNear) / (zFar + zNear - z_n * (zFar-zNear)); 80 | } 81 | } 82 | 83 | int compareDepthsFar(float depth1, float depth2) { 84 | float garea = 2.0; //gauss bell width 85 | float diff = (depth1 - depth2)*100.0; //depth difference (0-100) 86 | //reduce left bell width to avoid self-shadowing 87 | if (diff 0) 128 | { 129 | temp2 = compareDepths(readDepth(coord2),depth); 130 | temp += (1.0-temp)*temp2; 131 | } 132 | 133 | return temp; 134 | } 135 | 136 | void main(void) 137 | { 138 | vec2 noise = rand(texCoord); 139 | float depth = readDepth(texCoord); 140 | 141 | float w = (1.0 / width)/clamp(depth,aoclamp,1.0)+(noise.x*(1.0-noise.x)); 142 | float h = (1.0 / height)/clamp(depth,aoclamp,1.0)+(noise.y*(1.0-noise.y)); 143 | 144 | float pw = 0.0; 145 | float ph = 0.0; 146 | 147 | float ao = 0.0; 148 | 149 | float dl = PI * (3.0 - sqrt(5.0)); 150 | float dz = 1.0 / float(samples); 151 | float l = 0.0; 152 | float z = 1.0 - dz/2.0; 153 | 154 | for (int i = 0; i < 64; i++) 155 | { 156 | if (i > samples) break; 157 | float r = sqrt(1.0 - z); 158 | 159 | pw = cos(l) * r; 160 | ph = sin(l) * r; 161 | ao += calAO(depth,pw*w,ph*h); 162 | z = z - dz; 163 | l = l + dl; 164 | } 165 | 166 | 167 | ao /= float(samples); 168 | ao *= strength; 169 | ao = 1.0-ao; 170 | 171 | if (mist) 172 | { 173 | ao = mix(ao, 1.0, doMist()); 174 | } 175 | 176 | /* 177 | vec3 color = texture2D(bgl_RenderedTexture,texCoord).rgb; 178 | 179 | vec3 lumcoeff = vec3(0.299,0.587,0.114); 180 | float lum = dot(color.rgb, lumcoeff); 181 | vec3 luminance = vec3(lum, lum, lum); 182 | 183 | vec3 final = vec3(color*mix(vec3(ao),vec3(1.0),luminance*lumInfluence));//mix(color*ao, white, luminance) 184 | 185 | if (onlyAO) 186 | { 187 | final = vec3(mix(vec3(ao),vec3(1.0),luminance*lumInfluence)); //ambient occlusion only 188 | } 189 | */ 190 | //vec3 final = vec3(depth/1.0); 191 | vec3 final = vec3(depth); 192 | 193 | gl_FragColor = vec4(final,1.0); 194 | 195 | } -------------------------------------------------------------------------------- /fragment-shaders/blend-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tInput2; 4 | uniform vec2 resolution; 5 | uniform vec2 resolution2; 6 | uniform float aspectRatio; 7 | uniform float aspectRatio2; 8 | uniform int mode; 9 | uniform int sizeMode; 10 | uniform float opacity; 11 | 12 | vec2 vUv2; 13 | 14 | float applyOverlayToChannel( float base, float blend ) { 15 | 16 | return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend))); 17 | 18 | } 19 | 20 | float applySoftLightToChannel( float base, float blend ) { 21 | 22 | return ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend))); 23 | 24 | } 25 | 26 | float applyColorBurnToChannel( float base, float blend ) { 27 | 28 | return ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0)); 29 | 30 | } 31 | 32 | float applyColorDodgeToChannel( float base, float blend ) { 33 | 34 | return ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0)); 35 | 36 | } 37 | 38 | float applyLinearBurnToChannel( float base, float blend ) { 39 | 40 | return max(base + blend - 1., 0.0 ); 41 | 42 | } 43 | 44 | float applyLinearDodgeToChannel( float base, float blend ) { 45 | 46 | return min( base + blend, 1. ); 47 | 48 | } 49 | 50 | float applyLinearLightToChannel( float base, float blend ) { 51 | 52 | return ( blend < .5 ) ? applyLinearBurnToChannel( base, 2. * blend ) : applyLinearDodgeToChannel( base, 2. * ( blend - .5 ) ); 53 | 54 | } 55 | 56 | void main() { 57 | 58 | vUv2 = vUv; 59 | 60 | if( sizeMode == 1 ) { 61 | 62 | if( aspectRatio2 > aspectRatio ) { 63 | vUv2.x = vUv.x * aspectRatio / aspectRatio2; 64 | vUv2.x += .5 * ( 1. - aspectRatio / aspectRatio2 ); 65 | vUv2.y = vUv.y; 66 | } 67 | 68 | if( aspectRatio2 < aspectRatio ) { 69 | vUv2.x = vUv.x; 70 | vUv2.y = vUv.y * aspectRatio2 / aspectRatio; 71 | vUv2.y += .5 * ( 1. - aspectRatio2 / aspectRatio ); 72 | } 73 | 74 | } 75 | 76 | vec4 base = texture2D( tInput, vUv ); 77 | vec4 blend = texture2D( tInput2, vUv2 ); 78 | 79 | if( mode == 1 ) { // normal 80 | 81 | gl_FragColor = base; 82 | gl_FragColor.a *= opacity; 83 | return; 84 | 85 | } 86 | 87 | if( mode == 2 ) { // dissolve 88 | 89 | } 90 | 91 | if( mode == 3 ) { // darken 92 | 93 | gl_FragColor = min( base, blend ); 94 | return; 95 | 96 | } 97 | 98 | if( mode == 4 ) { // multiply 99 | 100 | gl_FragColor = base * blend; 101 | return; 102 | 103 | } 104 | 105 | if( mode == 5 ) { // color burn 106 | 107 | gl_FragColor = vec4( 108 | applyColorBurnToChannel( base.r, blend.r ), 109 | applyColorBurnToChannel( base.g, blend.g ), 110 | applyColorBurnToChannel( base.b, blend.b ), 111 | applyColorBurnToChannel( base.a, blend.a ) 112 | ); 113 | return; 114 | 115 | } 116 | 117 | if( mode == 6 ) { // linear burn 118 | 119 | gl_FragColor = max(base + blend - 1.0, 0.0); 120 | return; 121 | 122 | } 123 | 124 | if( mode == 7 ) { // darker color 125 | 126 | } 127 | 128 | if( mode == 8 ) { // lighten 129 | 130 | gl_FragColor = max( base, blend ); 131 | return; 132 | 133 | } 134 | 135 | if( mode == 9 ) { // screen 136 | 137 | gl_FragColor = (1.0 - ((1.0 - base) * (1.0 - blend))); 138 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 139 | return; 140 | 141 | } 142 | 143 | if( mode == 10 ) { // color dodge 144 | 145 | gl_FragColor = vec4( 146 | applyColorDodgeToChannel( base.r, blend.r ), 147 | applyColorDodgeToChannel( base.g, blend.g ), 148 | applyColorDodgeToChannel( base.b, blend.b ), 149 | applyColorDodgeToChannel( base.a, blend.a ) 150 | ); 151 | return; 152 | 153 | } 154 | 155 | if( mode == 11 ) { // linear dodge 156 | 157 | gl_FragColor = min(base + blend, 1.0); 158 | return; 159 | 160 | } 161 | 162 | if( mode == 12 ) { // lighter color 163 | 164 | } 165 | 166 | if( mode == 13 ) { // overlay 167 | 168 | gl_FragColor = gl_FragColor = vec4( 169 | applyOverlayToChannel( base.r, blend.r ), 170 | applyOverlayToChannel( base.g, blend.g ), 171 | applyOverlayToChannel( base.b, blend.b ), 172 | applyOverlayToChannel( base.a, blend.a ) 173 | ); 174 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 175 | 176 | return; 177 | 178 | } 179 | 180 | if( mode == 14 ) { // soft light 181 | 182 | gl_FragColor = vec4( 183 | applySoftLightToChannel( base.r, blend.r ), 184 | applySoftLightToChannel( base.g, blend.g ), 185 | applySoftLightToChannel( base.b, blend.b ), 186 | applySoftLightToChannel( base.a, blend.a ) 187 | ); 188 | return; 189 | 190 | } 191 | 192 | if( mode == 15 ) { // hard light 193 | 194 | gl_FragColor = vec4( 195 | applyOverlayToChannel( base.r, blend.r ), 196 | applyOverlayToChannel( base.g, blend.g ), 197 | applyOverlayToChannel( base.b, blend.b ), 198 | applyOverlayToChannel( base.a, blend.a ) 199 | ); 200 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 201 | return; 202 | 203 | } 204 | 205 | if( mode == 16 ) { // vivid light 206 | 207 | } 208 | 209 | if( mode == 17 ) { // linear light 210 | 211 | gl_FragColor = vec4( 212 | applyLinearLightToChannel( base.r, blend.r ), 213 | applyLinearLightToChannel( base.g, blend.g ), 214 | applyLinearLightToChannel( base.b, blend.b ), 215 | applyLinearLightToChannel( base.a, blend.a ) 216 | ); 217 | return; 218 | 219 | } 220 | 221 | if( mode == 18 ) { // pin light 222 | 223 | } 224 | 225 | if( mode == 19 ) { // hard mix 226 | 227 | } 228 | 229 | if( mode == 20 ) { // difference 230 | 231 | gl_FragColor = abs( base - blend ); 232 | gl_FragColor.a = base.a + blend.b; 233 | return; 234 | 235 | } 236 | 237 | if( mode == 21 ) { // exclusion 238 | 239 | gl_FragColor = base + blend - 2. * base * blend; 240 | 241 | } 242 | 243 | if( mode == 22 ) { // substract 244 | 245 | } 246 | 247 | if( mode == 23 ) { // divide 248 | 249 | } 250 | 251 | gl_FragColor = vec4( 1., 0., 1., 1. ); 252 | 253 | } -------------------------------------------------------------------------------- /fragment-shaders/led-fs.glsl: -------------------------------------------------------------------------------- 1 | /************************************************************* 2 | *Shader by: Jason Gorski 3 | *Email: jasejc@aol.com 4 | *CS594 University of Illinios at Chicago 5 | * 6 | *LED Billboard Tutorial 7 | *For more information about this shader view the tutorial page 8 | *at http://www2.uic.edu/~jgorsk2 or email me 9 | *************************************************************/ 10 | 11 | #define KERNEL_SIZE 9 12 | 13 | uniform int pixelSize; //size of bigger "pixel regions". These regions are forced to be square 14 | uniform vec2 resolution; //dimensions in pixels of tInput 15 | uniform sampler2D tInput; //texure to be applied to billboard quad 16 | 17 | //uniforms added since billboard1 18 | uniform float tolerance; //a tolerance used to determine the amount of blurring along the edge of the circle defining our "pixel region" 19 | uniform float pixelRadius; //the radius of the circle that will be our "pixel region", values > 0.5 hit the edge of the "pixel region" 20 | 21 | //uniforms added since billboard2 22 | uniform int luminanceSteps; //number of shades of color our LED billboard will display 23 | uniform float luminanceBoost; //used to brighten or darken image 24 | 25 | //uniforms added since billboard3 26 | uniform float colorBoost; //used to adjust the color intensity 27 | uniform float burntOutPercent; //not exactly a "percent", but it determines how many LEDs are burnt out 28 | uniform sampler2D noiseTexture; //noise texture used with burntOutPercent 29 | 30 | varying vec2 vUv; 31 | 32 | vec2 texCoords[KERNEL_SIZE]; //stores texture lookup offsets from a base case 33 | 34 | //gets the light intensity of the color (same as luminance in applyLuminanceStepping) 35 | float getIntensity(in vec4 color) 36 | { return (color.r + color.g + color.b)/3.0; } 37 | 38 | //apply colorBoost 39 | vec4 applyColorBoost(in vec4 color) 40 | { 41 | vec4 boostedColor = color; 42 | float max = max(color.r,max(color.g, color.b)); //determine max intensity of channels 43 | bvec3 maxes = equal(vec3(color),vec3(max)); //contains which channels == max 44 | 45 | //any channels == max are boosted by the colorBoost 46 | if(maxes.r) 47 | boostedColor += vec4(2.0*colorBoost,-colorBoost,-colorBoost,0.0); 48 | 49 | if(maxes.g) 50 | boostedColor += vec4(-colorBoost,2.0*colorBoost,-colorBoost,0.0); 51 | 52 | if(maxes.b) 53 | boostedColor += vec4(-colorBoost,-colorBoost,2.0*colorBoost,0.0); 54 | 55 | return boostedColor; 56 | } 57 | 58 | //apply luminanceSteps & luminanceBoost 59 | vec4 applyLuminanceStepping(in vec4 color) 60 | { 61 | float sum = color.r + color.g + color.b; 62 | float luminance = sum/3.0; //brightness or luminance of color 63 | vec3 ratios = vec3(color.r/luminance, color.g/luminance, color.b/luminance); //ratio stores each channel's contribution to the luminance 64 | 65 | float luminanceStep = 1.0/float(luminanceSteps); //how big each luminance bin is 66 | float luminanceBin = ceil(luminance/luminanceStep); //figure out which bin the color is in 67 | float luminanceFactor = luminanceStep * luminanceBin + luminanceBoost; //store the luminance of the color we are making including luminanceBoost 68 | 69 | return vec4(ratios * luminanceFactor,1.0); //use ratios * luminanceFactor as our new color so that original color hue is maintained 70 | } 71 | 72 | void main(void) 73 | { 74 | vec4 avgColor; //will hold our averaged color from our sample points 75 | vec2 texCoordsStep = 1.0/(vec2(float(resolution.x),float(resolution.y))/float(pixelSize)); //width of "pixel region" in texture coords 76 | vec2 pixelRegionCoords = fract( vUv/texCoordsStep); //x and y coordinates within "pixel region" 77 | vec2 pixelBin = floor( vUv/texCoordsStep); //"pixel region" number counting away from base case 78 | vec2 inPixelStep = texCoordsStep/3.0; //width of "pixel region" divided by 3 (for KERNEL_SIZE = 9, 3x3 square) 79 | vec2 inPixelHalfStep = inPixelStep/2.0; 80 | 81 | //the center of our "pixel region" is computed earlier now so we don't waste time computing other colors if we are in a burnt out region 82 | texCoords[4] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 83 | 84 | //if light intensity of our noise texture <= burntOutPercent we are burnt out, otherwise continue computing "pixel region" color 85 | /* if(getIntensity(texture2D(noiseTexture, texCoords[4].st)) <= burntOutPercent) { 86 | gl_FragColor = vec4(0.1,0.1,0.1,1.0) + (0.3*(tolerance + luminanceBoost)); //try to match up color-wise with the edge of our "pixel region" 87 | } else {*/ 88 | //use offset (pixelBin * texCoordsStep) from base case (the lower left corner of billboard) to compute texCoords 89 | texCoords[0] = vec2(inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 90 | texCoords[1] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 91 | texCoords[2] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 92 | texCoords[3] = vec2(inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 93 | //texCoords[4] moved to top. See note above. 94 | texCoords[5] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 95 | texCoords[6] = vec2(inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 96 | texCoords[7] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 97 | texCoords[8] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 98 | 99 | //take average of 9 pixel samples 100 | avgColor = texture2D(tInput, texCoords[0]) + 101 | texture2D(tInput, texCoords[1]) + 102 | texture2D(tInput, texCoords[2]) + 103 | texture2D(tInput, texCoords[3]) + 104 | texture2D(tInput, texCoords[4]) + 105 | texture2D(tInput, texCoords[5]) + 106 | texture2D(tInput, texCoords[6]) + 107 | texture2D(tInput, texCoords[7]) + 108 | texture2D(tInput, texCoords[8]); 109 | 110 | avgColor /= float(KERNEL_SIZE); 111 | 112 | //get a new color with the discretized luminance value 113 | avgColor = applyLuminanceStepping(avgColor); 114 | //adjust the color 115 | avgColor = applyColorBoost(avgColor); 116 | 117 | //blend between fragments in the circle and out of the circle defining our "pixel region" 118 | //Equation of a circle: (x - h)^2 + (y - k)^2 = r^2 119 | vec2 powers = pow(abs(pixelRegionCoords - 0.5),vec2(2.0)); 120 | float radiusSqrd = pow(pixelRadius,2.0); 121 | float gradient = smoothstep(radiusSqrd-tolerance, radiusSqrd+tolerance, powers.x+powers.y); 122 | 123 | gl_FragColor = mix(avgColor, vec4(0.1,0.1,0.1,1.0), gradient); 124 | // } 125 | 126 | } 127 | --------------------------------------------------------------------------------