Ver Fonte

Added dot screen shader / effect. Extended postprocessing demo. Fixed viewport bug for render targets.

alteredq há 14 anos atrás
pai
commit
093bbb1cb9

+ 3 - 2
build/Three.js

@@ -261,8 +261,8 @@ n.createTexture(),b.__webglInit=!0;n.activeTexture(n.TEXTURE0+c);n.bindTexture(n
 if(b&&!b.__webglFramebuffer){if(b.depthBuffer===void 0)b.depthBuffer=!0;if(b.stencilBuffer===void 0)b.stencilBuffer=!0;b.__webglRenderbuffer=n.createRenderbuffer();b.__webglTexture=n.createTexture();if(c){n.bindTexture(n.TEXTURE_CUBE_MAP,b.__webglTexture);B(n.TEXTURE_CUBE_MAP,b,b);b.__webglFramebuffer=[];for(var e=0;e<6;e++)b.__webglFramebuffer[e]=n.createFramebuffer(),n.texImage2D(n.TEXTURE_CUBE_MAP_POSITIVE_X+e,0,K(b.format),b.width,b.height,0,K(b.format),K(b.type),null)}else b.__webglFramebuffer=
 n.createFramebuffer(),n.bindTexture(n.TEXTURE_2D,b.__webglTexture),B(n.TEXTURE_2D,b,b),n.texImage2D(n.TEXTURE_2D,0,K(b.format),b.width,b.height,0,K(b.format),K(b.type),null);n.bindRenderbuffer(n.RENDERBUFFER,b.__webglRenderbuffer);if(c)for(e=0;e<6;++e)n.bindFramebuffer(n.FRAMEBUFFER,b.__webglFramebuffer[e]),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_CUBE_MAP_POSITIVE_X+e,b.__webglTexture,0);else n.bindFramebuffer(n.FRAMEBUFFER,b.__webglFramebuffer),n.framebufferTexture2D(n.FRAMEBUFFER,
 n.COLOR_ATTACHMENT0,n.TEXTURE_2D,b.__webglTexture,0);b.depthBuffer&&!b.stencilBuffer?(n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_COMPONENT16,b.width,b.height),n.framebufferRenderbuffer(n.FRAMEBUFFER,n.DEPTH_ATTACHMENT,n.RENDERBUFFER,b.__webglRenderbuffer)):b.depthBuffer&&b.stencilBuffer?(n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_STENCIL,b.width,b.height),n.framebufferRenderbuffer(n.FRAMEBUFFER,n.DEPTH_STENCIL_ATTACHMENT,n.RENDERBUFFER,b.__webglRenderbuffer)):n.renderbufferStorage(n.RENDERBUFFER,
-n.RGBA4,b.width,b.height);c?n.bindTexture(n.TEXTURE_CUBE_MAP,null):n.bindTexture(n.TEXTURE_2D,null);n.bindRenderbuffer(n.RENDERBUFFER,null);n.bindFramebuffer(n.FRAMEBUFFER,null)}b?(c=c?b.__webglFramebuffer[b.activeCubeFace]:b.__webglFramebuffer,e=b.width,b=b.height):(c=null,e=da,b=ia);c!=M&&(n.bindFramebuffer(n.FRAMEBUFFER,c),n.viewport(ea,Z,e,b),M=c)}function V(b){b instanceof THREE.WebGLRenderTargetCube?(n.bindTexture(n.TEXTURE_CUBE_MAP,b.__webglTexture),n.generateMipmap(n.TEXTURE_CUBE_MAP),n.bindTexture(n.TEXTURE_CUBE_MAP,
-null)):(n.bindTexture(n.TEXTURE_2D,b.__webglTexture),n.generateMipmap(n.TEXTURE_2D),n.bindTexture(n.TEXTURE_2D,null))}function H(b,c){var e;b=="fragment"?e=n.createShader(n.FRAGMENT_SHADER):b=="vertex"&&(e=n.createShader(n.VERTEX_SHADER));n.shaderSource(e,c);n.compileShader(e);if(!n.getShaderParameter(e,n.COMPILE_STATUS))return console.error(n.getShaderInfoLog(e)),console.error(c),null;return e}function S(b){switch(b){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return n.NEAREST;
+n.RGBA4,b.width,b.height);c?n.bindTexture(n.TEXTURE_CUBE_MAP,null):n.bindTexture(n.TEXTURE_2D,null);n.bindRenderbuffer(n.RENDERBUFFER,null);n.bindFramebuffer(n.FRAMEBUFFER,null)}var f,h;b?(c=c?b.__webglFramebuffer[b.activeCubeFace]:b.__webglFramebuffer,e=b.width,b=b.height,h=f=0):(c=null,e=da,b=ia,f=ea,h=Z);c!=M&&(n.bindFramebuffer(n.FRAMEBUFFER,c),n.viewport(f,h,e,b),M=c)}function V(b){b instanceof THREE.WebGLRenderTargetCube?(n.bindTexture(n.TEXTURE_CUBE_MAP,b.__webglTexture),n.generateMipmap(n.TEXTURE_CUBE_MAP),
+n.bindTexture(n.TEXTURE_CUBE_MAP,null)):(n.bindTexture(n.TEXTURE_2D,b.__webglTexture),n.generateMipmap(n.TEXTURE_2D),n.bindTexture(n.TEXTURE_2D,null))}function H(b,c){var e;b=="fragment"?e=n.createShader(n.FRAGMENT_SHADER):b=="vertex"&&(e=n.createShader(n.VERTEX_SHADER));n.shaderSource(e,c);n.compileShader(e);if(!n.getShaderParameter(e,n.COMPILE_STATUS))return console.error(n.getShaderInfoLog(e)),console.error(c),null;return e}function S(b){switch(b){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return n.NEAREST;
 default:return n.LINEAR}}function K(b){switch(b){case THREE.RepeatWrapping:return n.REPEAT;case THREE.ClampToEdgeWrapping:return n.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return n.MIRRORED_REPEAT;case THREE.NearestFilter:return n.NEAREST;case THREE.NearestMipMapNearestFilter:return n.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return n.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return n.LINEAR;case THREE.LinearMipMapNearestFilter:return n.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return n.LINEAR_MIPMAP_LINEAR;
 case THREE.ByteType:return n.BYTE;case THREE.UnsignedByteType:return n.UNSIGNED_BYTE;case THREE.ShortType:return n.SHORT;case THREE.UnsignedShortType:return n.UNSIGNED_SHORT;case THREE.IntType:return n.INT;case THREE.UnsignedShortType:return n.UNSIGNED_INT;case THREE.FloatType:return n.FLOAT;case THREE.AlphaFormat:return n.ALPHA;case THREE.RGBFormat:return n.RGB;case THREE.RGBAFormat:return n.RGBA;case THREE.LuminanceFormat:return n.LUMINANCE;case THREE.LuminanceAlphaFormat:return n.LUMINANCE_ALPHA}return 0}
 var Q=this,n,T=[],X=null,M=null,W=!0,ha=null,ca=null,fa=null,ga=null,$=null,Y=null,P=null,ea=0,Z=0,da=0,ia=0,U=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],ja=new THREE.Matrix4,pa=new Float32Array(16),la=new Float32Array(16),ma=new THREE.Vector4,Fa={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]}},b=b||{},ya=b.canvas!==void 0?b.canvas:document.createElement("canvas"),
@@ -357,6 +357,7 @@ cube:{uniforms:{tCube:{type:"t",value:1,texture:null}},vertexShader:"varying vec
 value:0,texture:null},uImageIncrement:{type:"v2",value:new THREE.Vector2(0.001953125,0)},cKernel:{type:"fv1",value:[]}},vertexShader:"varying vec2 vUv;\nuniform vec2 uImageIncrement;\nvoid main(void) {\nvUv = uv - ((KERNEL_SIZE - 1.0) / 2.0) * uImageIncrement;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform vec2 uImageIncrement;\nuniform float cKernel[KERNEL_SIZE];\nvoid main(void) {\nvec2 imageCoord = vUv;\nvec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );\nfor( int i=0; i<KERNEL_SIZE; ++i ) {\nsum += texture2D( tDiffuse, imageCoord ) * cKernel[i];\nimageCoord += uImageIncrement;\n}\ngl_FragColor = sum;\n}"},
 film:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},time:{type:"f",value:0},nIntensity:{type:"f",value:0.5},sIntensity:{type:"f",value:0.05},sCount:{type:"f",value:4096},grayscale:{type:"i",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float time;\nuniform bool grayscale;\nuniform float nIntensity;\nuniform float sIntensity;\nuniform float sCount;\nvoid main() {\nvec4 cTextureScreen = texture2D( tDiffuse, vUv );\nfloat x = vUv.x * vUv.y * time *  1000.0;\nx = mod( x, 13.0 ) * mod( x, 123.0 );\nfloat dx = mod( x, 0.01 );\nvec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );\nvec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );\ncResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;\ncResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );\nif( grayscale ) {\ncResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );\n}\ngl_FragColor =  vec4( cResult, cTextureScreen.a );\n}"},
 sepia:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},amount:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float amount;\nvoid main() {\nvec4 color = texture2D( tDiffuse, vUv );\nvec3 c = color.rgb;\ncolor.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );\ncolor.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );\ncolor.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );\ngl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );\n}"},
+dotscreen:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},tSize:{type:"v2",value:new THREE.Vector2(256,256)},center:{type:"v2",value:new THREE.Vector2(0.5,0.5)},angle:{type:"f",value:1.57},scale:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform vec2 center;\nuniform float angle;\nuniform float scale;\nuniform vec2 tSize;\nvarying vec2 vUv;\nuniform sampler2D tDiffuse;\nfloat pattern() {\nfloat s = sin( angle ), c = cos( angle );\nvec2 tex = vUv * tSize - center;\nvec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;\nreturn ( sin( point.x ) * sin( point.y ) ) * 4.0;\n}\nvoid main() {\nvec4 color = texture2D( tDiffuse, vUv );\nfloat average = ( color.r + color.g + color.b ) / 3.0;\ngl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );\n}"},
 screen:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},opacity:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float opacity;\nvoid main() {\nvec4 texel = texture2D( tDiffuse, vUv );\ngl_FragColor = opacity * texel;\n}"},basic:{uniforms:{},vertexShader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",
 fragmentShader:"void main() {\ngl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );\n}"}},buildKernel:function(b){var c,e,f,g,j=2*Math.ceil(b*3)+1;j>25&&(j=25);g=(j-1)*0.5;e=Array(j);for(c=f=0;c<j;++c)e[c]=Math.exp(-((c-g)*(c-g))/(2*b*b)),f+=e[c];for(c=0;c<j;++c)e[c]/=f;return e}};
 THREE.AnimationHandler=function(){var b=[],c={},e={update:function(c){for(var e=0;e<b.length;e++)b[e].update(c)},addToUpdate:function(c){b.indexOf(c)===-1&&b.push(c)},removeFromUpdate:function(c){c=b.indexOf(c);c!==-1&&b.splice(c,1)},add:function(b){c[b.name]!==void 0&&console.log("THREE.AnimationHandler.add: Warning! "+b.name+" already exists in library. Overwriting.");c[b.name]=b;if(b.initialized!==!0){for(var e=0;e<b.hierarchy.length;e++){for(var f=0;f<b.hierarchy[e].keys.length;f++){if(b.hierarchy[e].keys[f].time<

+ 1 - 0
build/custom/ThreeExtras.js

@@ -23,6 +23,7 @@ cube:{uniforms:{tCube:{type:"t",value:1,texture:null}},vertexShader:"varying vec
 value:0,texture:null},uImageIncrement:{type:"v2",value:new THREE.Vector2(0.001953125,0)},cKernel:{type:"fv1",value:[]}},vertexShader:"varying vec2 vUv;\nuniform vec2 uImageIncrement;\nvoid main(void) {\nvUv = uv - ((KERNEL_SIZE - 1.0) / 2.0) * uImageIncrement;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform vec2 uImageIncrement;\nuniform float cKernel[KERNEL_SIZE];\nvoid main(void) {\nvec2 imageCoord = vUv;\nvec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );\nfor( int i=0; i<KERNEL_SIZE; ++i ) {\nsum += texture2D( tDiffuse, imageCoord ) * cKernel[i];\nimageCoord += uImageIncrement;\n}\ngl_FragColor = sum;\n}"},
 film:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},time:{type:"f",value:0},nIntensity:{type:"f",value:0.5},sIntensity:{type:"f",value:0.05},sCount:{type:"f",value:4096},grayscale:{type:"i",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float time;\nuniform bool grayscale;\nuniform float nIntensity;\nuniform float sIntensity;\nuniform float sCount;\nvoid main() {\nvec4 cTextureScreen = texture2D( tDiffuse, vUv );\nfloat x = vUv.x * vUv.y * time *  1000.0;\nx = mod( x, 13.0 ) * mod( x, 123.0 );\nfloat dx = mod( x, 0.01 );\nvec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );\nvec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );\ncResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;\ncResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );\nif( grayscale ) {\ncResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );\n}\ngl_FragColor =  vec4( cResult, cTextureScreen.a );\n}"},
 sepia:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},amount:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float amount;\nvoid main() {\nvec4 color = texture2D( tDiffuse, vUv );\nvec3 c = color.rgb;\ncolor.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );\ncolor.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );\ncolor.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );\ngl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );\n}"},
+dotscreen:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},tSize:{type:"v2",value:new THREE.Vector2(256,256)},center:{type:"v2",value:new THREE.Vector2(0.5,0.5)},angle:{type:"f",value:1.57},scale:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform vec2 center;\nuniform float angle;\nuniform float scale;\nuniform vec2 tSize;\nvarying vec2 vUv;\nuniform sampler2D tDiffuse;\nfloat pattern() {\nfloat s = sin( angle ), c = cos( angle );\nvec2 tex = vUv * tSize - center;\nvec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;\nreturn ( sin( point.x ) * sin( point.y ) ) * 4.0;\n}\nvoid main() {\nvec4 color = texture2D( tDiffuse, vUv );\nfloat average = ( color.r + color.g + color.b ) / 3.0;\ngl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );\n}"},
 screen:{uniforms:{tDiffuse:{type:"t",value:0,texture:null},opacity:{type:"f",value:1}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform float opacity;\nvoid main() {\nvec4 texel = texture2D( tDiffuse, vUv );\ngl_FragColor = opacity * texel;\n}"},basic:{uniforms:{},vertexShader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",
 fragmentShader:"void main() {\ngl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );\n}"}},buildKernel:function(a){var b,c,e,f,h=2*Math.ceil(a*3)+1;h>25&&(h=25);f=(h-1)*0.5;c=Array(h);for(b=e=0;b<h;++b)c[b]=Math.exp(-((b-f)*(b-f))/(2*a*a)),e+=c[b];for(b=0;b<h;++b)c[b]/=e;return c}};
 THREE.AnimationHandler=function(){var a=[],b={},c={update:function(c){for(var b=0;b<a.length;b++)a[b].update(c)},addToUpdate:function(c){a.indexOf(c)===-1&&a.push(c)},removeFromUpdate:function(c){c=a.indexOf(c);c!==-1&&a.splice(c,1)},add:function(a){b[a.name]!==void 0&&console.log("THREE.AnimationHandler.add: Warning! "+a.name+" already exists in library. Overwriting.");b[a.name]=a;if(a.initialized!==!0){for(var c=0;c<a.hierarchy.length;c++){for(var e=0;e<a.hierarchy[c].keys.length;e++){if(a.hierarchy[c].keys[e].time<

+ 3 - 3
build/custom/ThreeWebGL.js

@@ -217,9 +217,9 @@ f.TEXTURE_MIN_FILTER,qa(c.minFilter)))}function L(b,c){if(b.needsUpdate){if(!b._
 c),f.bindTexture(f.TEXTURE_2D,b.__webglTexture)}function P(b){var c=b instanceof THREE.WebGLRenderTargetCube;if(b&&!b.__webglFramebuffer){if(b.depthBuffer===void 0)b.depthBuffer=!0;if(b.stencilBuffer===void 0)b.stencilBuffer=!0;b.__webglRenderbuffer=f.createRenderbuffer();b.__webglTexture=f.createTexture();if(c){f.bindTexture(f.TEXTURE_CUBE_MAP,b.__webglTexture);Y(f.TEXTURE_CUBE_MAP,b,b);b.__webglFramebuffer=[];for(var d=0;d<6;d++)b.__webglFramebuffer[d]=f.createFramebuffer(),f.texImage2D(f.TEXTURE_CUBE_MAP_POSITIVE_X+
 d,0,S(b.format),b.width,b.height,0,S(b.format),S(b.type),null)}else b.__webglFramebuffer=f.createFramebuffer(),f.bindTexture(f.TEXTURE_2D,b.__webglTexture),Y(f.TEXTURE_2D,b,b),f.texImage2D(f.TEXTURE_2D,0,S(b.format),b.width,b.height,0,S(b.format),S(b.type),null);f.bindRenderbuffer(f.RENDERBUFFER,b.__webglRenderbuffer);if(c)for(d=0;d<6;++d)f.bindFramebuffer(f.FRAMEBUFFER,b.__webglFramebuffer[d]),f.framebufferTexture2D(f.FRAMEBUFFER,f.COLOR_ATTACHMENT0,f.TEXTURE_CUBE_MAP_POSITIVE_X+d,b.__webglTexture,
 0);else f.bindFramebuffer(f.FRAMEBUFFER,b.__webglFramebuffer),f.framebufferTexture2D(f.FRAMEBUFFER,f.COLOR_ATTACHMENT0,f.TEXTURE_2D,b.__webglTexture,0);b.depthBuffer&&!b.stencilBuffer?(f.renderbufferStorage(f.RENDERBUFFER,f.DEPTH_COMPONENT16,b.width,b.height),f.framebufferRenderbuffer(f.FRAMEBUFFER,f.DEPTH_ATTACHMENT,f.RENDERBUFFER,b.__webglRenderbuffer)):b.depthBuffer&&b.stencilBuffer?(f.renderbufferStorage(f.RENDERBUFFER,f.DEPTH_STENCIL,b.width,b.height),f.framebufferRenderbuffer(f.FRAMEBUFFER,
-f.DEPTH_STENCIL_ATTACHMENT,f.RENDERBUFFER,b.__webglRenderbuffer)):f.renderbufferStorage(f.RENDERBUFFER,f.RGBA4,b.width,b.height);c?f.bindTexture(f.TEXTURE_CUBE_MAP,null):f.bindTexture(f.TEXTURE_2D,null);f.bindRenderbuffer(f.RENDERBUFFER,null);f.bindFramebuffer(f.FRAMEBUFFER,null)}b?(c=c?b.__webglFramebuffer[b.activeCubeFace]:b.__webglFramebuffer,d=b.width,b=b.height):(c=null,d=Fa,b=xa);c!=va&&(f.bindFramebuffer(f.FRAMEBUFFER,c),f.viewport(Aa,Ia,d,b),va=c)}function Q(b){b instanceof THREE.WebGLRenderTargetCube?
-(f.bindTexture(f.TEXTURE_CUBE_MAP,b.__webglTexture),f.generateMipmap(f.TEXTURE_CUBE_MAP),f.bindTexture(f.TEXTURE_CUBE_MAP,null)):(f.bindTexture(f.TEXTURE_2D,b.__webglTexture),f.generateMipmap(f.TEXTURE_2D),f.bindTexture(f.TEXTURE_2D,null))}function ha(b,c){var d;b=="fragment"?d=f.createShader(f.FRAGMENT_SHADER):b=="vertex"&&(d=f.createShader(f.VERTEX_SHADER));f.shaderSource(d,c);f.compileShader(d);if(!f.getShaderParameter(d,f.COMPILE_STATUS))return console.error(f.getShaderInfoLog(d)),console.error(c),
-null;return d}function qa(b){switch(b){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return f.NEAREST;default:return f.LINEAR}}function S(b){switch(b){case THREE.RepeatWrapping:return f.REPEAT;case THREE.ClampToEdgeWrapping:return f.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return f.MIRRORED_REPEAT;case THREE.NearestFilter:return f.NEAREST;case THREE.NearestMipMapNearestFilter:return f.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return f.NEAREST_MIPMAP_LINEAR;
+f.DEPTH_STENCIL_ATTACHMENT,f.RENDERBUFFER,b.__webglRenderbuffer)):f.renderbufferStorage(f.RENDERBUFFER,f.RGBA4,b.width,b.height);c?f.bindTexture(f.TEXTURE_CUBE_MAP,null):f.bindTexture(f.TEXTURE_2D,null);f.bindRenderbuffer(f.RENDERBUFFER,null);f.bindFramebuffer(f.FRAMEBUFFER,null)}var e,g;b?(c=c?b.__webglFramebuffer[b.activeCubeFace]:b.__webglFramebuffer,d=b.width,b=b.height,g=e=0):(c=null,d=Fa,b=xa,e=Aa,g=Ia);c!=va&&(f.bindFramebuffer(f.FRAMEBUFFER,c),f.viewport(e,g,d,b),va=c)}function Q(b){b instanceof
+THREE.WebGLRenderTargetCube?(f.bindTexture(f.TEXTURE_CUBE_MAP,b.__webglTexture),f.generateMipmap(f.TEXTURE_CUBE_MAP),f.bindTexture(f.TEXTURE_CUBE_MAP,null)):(f.bindTexture(f.TEXTURE_2D,b.__webglTexture),f.generateMipmap(f.TEXTURE_2D),f.bindTexture(f.TEXTURE_2D,null))}function ha(b,c){var d;b=="fragment"?d=f.createShader(f.FRAGMENT_SHADER):b=="vertex"&&(d=f.createShader(f.VERTEX_SHADER));f.shaderSource(d,c);f.compileShader(d);if(!f.getShaderParameter(d,f.COMPILE_STATUS))return console.error(f.getShaderInfoLog(d)),
+console.error(c),null;return d}function qa(b){switch(b){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return f.NEAREST;default:return f.LINEAR}}function S(b){switch(b){case THREE.RepeatWrapping:return f.REPEAT;case THREE.ClampToEdgeWrapping:return f.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return f.MIRRORED_REPEAT;case THREE.NearestFilter:return f.NEAREST;case THREE.NearestMipMapNearestFilter:return f.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return f.NEAREST_MIPMAP_LINEAR;
 case THREE.LinearFilter:return f.LINEAR;case THREE.LinearMipMapNearestFilter:return f.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return f.LINEAR_MIPMAP_LINEAR;case THREE.ByteType:return f.BYTE;case THREE.UnsignedByteType:return f.UNSIGNED_BYTE;case THREE.ShortType:return f.SHORT;case THREE.UnsignedShortType:return f.UNSIGNED_SHORT;case THREE.IntType:return f.INT;case THREE.UnsignedShortType:return f.UNSIGNED_INT;case THREE.FloatType:return f.FLOAT;case THREE.AlphaFormat:return f.ALPHA;
 case THREE.RGBFormat:return f.RGB;case THREE.RGBAFormat:return f.RGBA;case THREE.LuminanceFormat:return f.LUMINANCE;case THREE.LuminanceAlphaFormat:return f.LUMINANCE_ALPHA}return 0}var J=this,f,Ba=[],ra=null,va=null,T=!0,Z=null,F=null,V=null,N=null,la=null,wa=null,O=null,Aa=0,Ia=0,Fa=0,xa=0,ia=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],Ca=new THREE.Matrix4,Ea=new Float32Array(16),Ra=new Float32Array(16),Ja=new THREE.Vector4,Ua={ambient:[0,
 0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]}},b=b||{},Ga=b.canvas!==void 0?b.canvas:document.createElement("canvas"),Za=b.stencil!==void 0?b.stencil:!0,$a=b.preserveDrawingBuffer!==void 0?b.preserveDrawingBuffer:!1,ab=b.antialias!==void 0?b.antialias:!1,ua=b.clearColor!==void 0?new THREE.Color(b.clearColor):new THREE.Color(0),Pa=b.clearAlpha!==void 0?b.clearAlpha:0;_maxLights=b.maxLights!==void 0?b.maxLights:4;this.data={vertices:0,faces:0,

+ 50 - 0
examples/js/postprocessing/DotScreenPass.js

@@ -0,0 +1,50 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+THREE.DotScreenPass = function( center, angle, scale ) {
+
+	var shader = THREE.ShaderUtils.lib[ "dotscreen" ];
+
+	this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+
+	if ( center !== undefined )
+		this.uniforms[ "center" ].value.copy( center );
+
+	if ( angle !== undefined )	this.uniforms[ "angle"].value = angle;
+	if ( scale !== undefined )	this.uniforms[ "scale"].value = scale;
+
+	this.material = new THREE.MeshShaderMaterial( {
+
+		uniforms: this.uniforms,
+		vertexShader: shader.vertexShader,
+		fragmentShader: shader.fragmentShader
+
+	} );
+
+	this.renderToScreen = false;
+
+};
+
+THREE.DotScreenPass.prototype = {
+
+	render: function ( renderer, renderTarget, delta ) {
+
+		this.uniforms[ "tDiffuse" ].texture = renderTarget;
+		this.uniforms[ "tSize" ].value.set( renderTarget.width, renderTarget.height );
+
+		THREE.EffectComposer.quad.materials[ 0 ] = this.material;
+
+		if ( this.renderToScreen ) {
+
+			renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera );
+
+		} else {
+
+			renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, renderTarget, false );
+
+		}
+
+	}
+
+};

+ 124 - 29
examples/webgl_postprocessing.html

@@ -17,11 +17,14 @@
 		    }
 
 		    #info {
-					color:#000;
-			position: absolute;
-			top: 0px; width: 100%;
+			color:#000;
+			background-color: rgba( 255, 255, 255, 0.95 );
+			position: relative;
+			margin: 0 auto -2em;
+			top: 0px;
+			width: 550px;
 			padding: 5px;
-
+			z-index:100;
 		    }
 
 		    a { color: red; }
@@ -29,12 +32,13 @@
 	</head>
 	<body>
 
-		<div id="container"></div>
 		<div id="info">
 			<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - webgl postprocessing example -
 			<a href="http://www.ir-ltd.net/infinite-3d-head-scan-released/" target="_blank">Lee Perry-Smith</a> head
 		</div>
 
+		<div id="container"></div>
+
 		<script type="text/javascript" src="../build/Three.js"></script>
 
 		<script type="text/javascript" src="js/postprocessing/EffectComposer.js"></script>
@@ -42,6 +46,8 @@
 		<script type="text/javascript" src="js/postprocessing/BloomPass.js"></script>
 		<script type="text/javascript" src="js/postprocessing/FilmPass.js"></script>
 		<script type="text/javascript" src="js/postprocessing/SepiaPass.js"></script>
+		<script type="text/javascript" src="js/postprocessing/DotScreenPass.js"></script>
+		<script type="text/javascript" src="js/postprocessing/ScreenPass.js"></script>
 
 		<script type="text/javascript" src="js/Detector.js"></script>
 		<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
@@ -84,14 +90,14 @@
 
 			var container, stats;
 
-			var composer;
+			var composerScene, composer1, composer2, composer3, composer4;
 
 			var cameraOrtho, cameraPerspective, sceneModel, sceneBG, renderer, mesh, directionalLight;
 
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
+			var halfWidth = window.innerWidth / 2;
+			var halfHeight = window.innerHeight / 2;
 
-			var rtTexture, materialColor, materialScreen, materialFilm, materialConvolution, blurx, blury, quadBG, quadScreen;
+			var rtTexture, materialColor, material2D, quadBG1, quadBG2;
 
 			var delta = 0.01;
 
@@ -102,7 +108,7 @@
 
 				container = document.getElementById( 'container' );
 
-				cameraOrtho = new THREE.OrthoCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 );
+				cameraOrtho = new THREE.OrthoCamera( -halfWidth, halfWidth, halfHeight, -halfHeight, -10000, 10000 );
 				cameraOrtho.position.z = 100;
 
 				cameraPerspective = new THREE.Camera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
@@ -134,11 +140,12 @@
 
 				} );
 
-				var plane = new THREE.PlaneGeometry( window.innerWidth, window.innerHeight );
+				var plane = new THREE.PlaneGeometry( 1, 1 );
 
-				quadBG = new THREE.Mesh( plane, materialColor );
-				quadBG.position.z = -500;
-				sceneBG.addObject( quadBG );
+				quadBG1 = new THREE.Mesh( plane, materialColor );
+				quadBG1.position.z = -500;
+				quadBG1.scale.set( window.innerWidth, window.innerHeight, 1 );
+				sceneBG.addObject( quadBG1 );
 
 				//
 
@@ -155,22 +162,83 @@
 
 				//
 
-				var renderBackground = new THREE.RenderPass( sceneBG, cameraOrtho );
-				var renderModel = new THREE.RenderPass( sceneModel, cameraPerspective );
 				var effectBloom = new THREE.BloomPass( 0.75 );
 				var effectFilm = new THREE.FilmPass( 0.35, 0.5, 2048, false );
+				var effectFilmBW = new THREE.FilmPass( 0.35, 0.5, 2048, true );
 				var effectSepia = new THREE.SepiaPass( 1.0 );
+				var effectScreen = new THREE.ScreenPass();
+				var effectDotScreen = new THREE.DotScreenPass( new THREE.Vector2( 0, 0 ), 0.5, 0.4 );
 
-				renderModel.clear = false;
 				effectFilm.renderToScreen = true;
+				effectFilmBW.renderToScreen = true;
+				effectDotScreen.renderToScreen = true;
+
+				//
+
+				var renderBackground = new THREE.RenderPass( sceneBG, cameraOrtho );
+				var renderModel = new THREE.RenderPass( sceneModel, cameraPerspective );
+
+				renderModel.clear = false;
+
+				composerScene = new THREE.EffectComposer( renderer );
+
+				composerScene.addPass( renderBackground );
+				composerScene.addPass( renderModel );
+
+				//
+
+				scene2D = new THREE.Scene();
+
+				var shader = THREE.ShaderUtils.lib[ "screen" ];
+
+				material2D = new THREE.MeshShaderMaterial( {
+
+					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
+					vertexShader: shader.vertexShader,
+					fragmentShader: shader.fragmentShader
+
+				} );
+
+				material2D.uniforms[ "tDiffuse" ].texture = composerScene.renderTarget;
 
-				composer = new THREE.EffectComposer( renderer );
+				quadBG2 = new THREE.Mesh( plane, material2D );
+				quadBG2.position.z = -500;
+				quadBG2.scale.set( window.innerWidth, window.innerHeight, 1 );
+				scene2D.addObject( quadBG2 );
 
-				composer.addPass( renderBackground );
-				composer.addPass( renderModel );
-				composer.addPass( effectBloom );
-				composer.addPass( effectSepia );
-				composer.addPass( effectFilm );
+				var renderScene = new THREE.RenderPass( scene2D, cameraOrtho );
+
+				//
+
+				composer1 = new THREE.EffectComposer( renderer );
+
+				composer1.addPass( renderScene );
+				composer1.addPass( effectBloom );
+				composer1.addPass( effectFilmBW );
+
+				//
+
+				composer2 = new THREE.EffectComposer( renderer );
+
+				composer2.addPass( renderScene );
+				composer2.addPass( effectDotScreen );
+
+				//
+
+				composer3 = new THREE.EffectComposer( renderer );
+
+				composer3.addPass( renderScene );
+				composer3.addPass( effectSepia );
+				composer3.addPass( effectFilm );
+
+				//
+
+				composer4 = new THREE.EffectComposer( renderer );
+
+				composer4.addPass( renderScene );
+				composer4.addPass( effectBloom );
+				composer4.addPass( effectSepia );
+				composer4.addPass( effectScreen );
 
 				//
 
@@ -182,19 +250,32 @@
 
 			function onWindowResize( event ) {
 
+				halfWidth = window.innerWidth / 2;
+				halfHeight = window.innerHeight / 2;
+
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				cameraPerspective.aspect = window.innerWidth / window.innerHeight;
 				cameraPerspective.updateProjectionMatrix();
 
-				cameraOrtho.left = window.innerWidth / - 2;
-				cameraOrtho.right = window.innerWidth / 2;
-				cameraOrtho.top = window.innerHeight / 2;
-				cameraOrtho.bottom = window.innerHeight / - 2;
+				cameraOrtho.left = -halfWidth;
+				cameraOrtho.right = halfWidth;
+				cameraOrtho.top = halfHeight;
+				cameraOrtho.bottom = -halfHeight;
 
 				cameraOrtho.updateProjectionMatrix();
 
-				composer.reset();
+				composerScene.reset();
+
+				composer1.reset();
+				composer2.reset();
+				composer3.reset();
+				composer4.reset();
+
+				material2D.uniforms[ "tDiffuse" ].texture = composerScene.renderTarget;
+
+				quadBG1.scale.set( window.innerWidth, window.innerHeight, 1 );
+				quadBG2.scale.set( window.innerWidth, window.innerHeight, 1 );
 
 			}
 
@@ -265,8 +346,22 @@
 
 				materialColor.uniforms.time.value += delta / 2;
 
+				renderer.setViewport( 0, 0, 2 * halfWidth, 2 * halfHeight );
+
 				renderer.clear();
-				composer.render( delta );
+				composerScene.render( delta );
+
+				renderer.setViewport( 0, 0, halfWidth, halfHeight );
+				composer1.render( delta );
+
+				renderer.setViewport( halfWidth, 0, halfWidth, halfHeight );
+				composer2.render( delta );
+
+				renderer.setViewport( 0, halfHeight, halfWidth, halfHeight );
+				composer3.render( delta );
+
+				renderer.setViewport( halfWidth, halfHeight, halfWidth, halfHeight );
+				composer4.render( delta );
 
 			}
 

+ 66 - 0
src/extras/ShaderUtils.js

@@ -614,6 +614,72 @@ THREE.ShaderUtils = {
 
 		},
 
+		/* -------------------------------------------------------------------------
+		//	Dot screen shader
+		//  - based on glfx.js sepia shader
+		//		https://github.com/evanw/glfx.js
+		 ------------------------------------------------------------------------- */
+
+		'dotscreen': {
+
+			uniforms: {
+
+				tDiffuse: { type: "t", value: 0, texture: null },
+				tSize:    { type: "v2", value: new THREE.Vector2( 256, 256 ) },
+				center:   { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },
+				angle:	  { type: "f", value: 1.57 },
+				scale:	  { type: "f", value: 1.0 }
+
+			},
+
+			vertexShader: [
+
+				"varying vec2 vUv;",
+
+				"void main() {",
+
+					"vUv = vec2( uv.x, 1.0 - uv.y );",
+					"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+				"}"
+
+			].join("\n"),
+
+			fragmentShader: [
+
+				"uniform vec2 center;",
+				"uniform float angle;",
+				"uniform float scale;",
+				"uniform vec2 tSize;",
+
+				"varying vec2 vUv;",
+				"uniform sampler2D tDiffuse;",
+
+				"float pattern() {",
+
+					"float s = sin( angle ), c = cos( angle );",
+
+					"vec2 tex = vUv * tSize - center;",
+					"vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;",
+
+					"return ( sin( point.x ) * sin( point.y ) ) * 4.0;",
+
+				"}",
+
+				"void main() {",
+
+					"vec4 color = texture2D( tDiffuse, vUv );",
+
+					"float average = ( color.r + color.g + color.b ) / 3.0;",
+
+					"gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );",
+
+				"}"
+
+			].join("\n")
+
+		},
+
 		/* -------------------------------------------------------------------------
 		//	Full-screen textured quad shader
 		 ------------------------------------------------------------------------- */

+ 7 - 2
src/renderers/WebGLRenderer.js

@@ -5065,7 +5065,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		var framebuffer, width, height;
+		var framebuffer, width, height, vx, vy;
 
 		if ( renderTexture ) {
 
@@ -5082,18 +5082,23 @@ THREE.WebGLRenderer = function ( parameters ) {
 			width = renderTexture.width;
 			height = renderTexture.height;
 
+			vx = 0;
+			vy = 0;
+
 		} else {
 
 			framebuffer = null;
 			width = _viewportWidth;
 			height = _viewportHeight;
+			vx = _viewportX;
+			vy = _viewportY;
 
 		}
 
 		if ( framebuffer != _currentFramebuffer ) {
 
 			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
-			_gl.viewport( _viewportX, _viewportY, width, height );
+			_gl.viewport( vx, vy, width, height );
 
 			_currentFramebuffer = framebuffer;