diff --git a/build/Three.js b/build/Three.js index 05a67be2..340cbc9b 100644 --- a/build/Three.js +++ b/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; i25&&(j=25);g=(j-1)*0.5;e=Array(j);for(c=f=0;c25&&(h=25);f=(h-1)*0.5;c=Array(h);for(b=e=0;b -
three.js - webgl postprocessing example - Lee Perry-Smith head
+
+ @@ -42,6 +46,8 @@ + + @@ -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 ); + + 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; - effectFilm.renderToScreen = true; - composer = new THREE.EffectComposer( renderer ); + composerScene = new THREE.EffectComposer( renderer ); - composer.addPass( renderBackground ); - composer.addPass( renderModel ); - composer.addPass( effectBloom ); - composer.addPass( effectSepia ); - composer.addPass( effectFilm ); + 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; + + quadBG2 = new THREE.Mesh( plane, material2D ); + quadBG2.position.z = -500; + quadBG2.scale.set( window.innerWidth, window.innerHeight, 1 ); + scene2D.addObject( quadBG2 ); + + 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 ); } diff --git a/src/extras/ShaderUtils.js b/src/extras/ShaderUtils.js index b9f224e0..9da0fbf9 100644 --- a/src/extras/ShaderUtils.js +++ b/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 ------------------------------------------------------------------------- */ diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 5f62abf2..93b89513 100644 --- a/src/renderers/WebGLRenderer.js +++ b/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;