diff --git a/examples/webgl_interactive_cubes_gpu.html b/examples/webgl_interactive_cubes_gpu.html index 67c2bcc65d0a13332a3e1f7c907737f3d1486690..370e58805e34fe14e2fd2fde0e546e3d4b452c2a 100644 --- a/examples/webgl_interactive_cubes_gpu.html +++ b/examples/webgl_interactive_cubes_gpu.html @@ -75,8 +75,7 @@ pickingScene = new THREE.Scene(); pickingTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); - pickingTexture.minFilter = THREE.LinearFilter; - pickingTexture.generateMipmaps = false; + pickingTexture.texture.minFilter = THREE.LinearFilter; scene.add( new THREE.AmbientLight( 0x555555 ) ); diff --git a/src/renderers/WebGLRenderTarget.js b/src/renderers/WebGLRenderTarget.js index 0afbe65d97425f00dc481b08cf670f8ca8ceb393..f8173e04daf0e467dfcb0084a05aa90a57d0d223 100644 --- a/src/renderers/WebGLRenderTarget.js +++ b/src/renderers/WebGLRenderTarget.js @@ -1,8 +1,14 @@ /** * @author szimek / https://github.com/szimek/ * @author alteredq / http://alteredqualia.com/ + * @author Marius Kintel / https://github.com/kintel */ +/* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +*/ THREE.WebGLRenderTarget = function ( width, height, options ) { this.uuid = THREE.Math.generateUUID(); @@ -19,8 +25,6 @@ THREE.WebGLRenderTarget = function ( width, height, options ) { this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; - this.shareDepthFrom = options.shareDepthFrom !== undefined ? options.shareDepthFrom : null; - }; THREE.WebGLRenderTarget.prototype = { diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 96d5a27d95b9a70bbd2e6a3f20624bf85434c67d..35d1ed04c0f70ad920deb0f7c993fe2877ebdf44 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3166,14 +3166,20 @@ THREE.WebGLRenderer = function ( parameters ) { // Render targets - function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) { + // Setup storage for target texture and bind it to correct framebuffer + function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) { + var glFormat = paramThreeToGL( renderTarget.texture.format ); + var glType = paramThreeToGL( renderTarget.texture.type ); + state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); } - function setupRenderBuffer ( renderbuffer, renderTarget ) { + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer + function setupRenderBufferStorage ( renderbuffer, renderTarget ) { _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); @@ -3182,13 +3188,6 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height ); _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - /* For some reason this is not working. Defaulting to RGBA4. - } else if ( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - */ - } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); @@ -3196,118 +3195,127 @@ THREE.WebGLRenderer = function ( parameters ) { } else { + // FIXME: We don't support !depth !stencil _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height ); } - } - - this.setRenderTarget = function ( renderTarget ) { - - var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); - - if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { - - var renderTargetProperties = properties.get( renderTarget ); - var textureProperties = properties.get( renderTarget.texture ); + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); - if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true; - if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true; - - renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); + } - textureProperties.__webglTexture = _gl.createTexture(); + // Setup GL resources for a non-texture depth buffer + function setupDepthRenderbuffer( renderTarget ) { - _infoMemory.textures ++; + var renderTargetProperties = properties.get( renderTarget ); - // Setup texture, create render and frame buffers + var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); + if ( isCube ) { - var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ), - glFormat = paramThreeToGL( renderTarget.texture.format ), - glType = paramThreeToGL( renderTarget.texture.type ); + renderTargetProperties.__webglDepthbuffer = []; + for ( var i = 0; i < 6; i ++ ) { - if ( isCube ) { + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); + renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); - renderTargetProperties.__webglFramebuffer = []; - renderTargetProperties.__webglRenderbuffer = []; + } - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + } + else { - setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); - for ( var i = 0; i < 6; i ++ ) { - - renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); - renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer(); - state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); + } + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); - setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); - setupRenderBuffer( renderTargetProperties.__webglRenderbuffer[ i ], renderTarget ); + }; - } + // Set up GL resources for the render target + function setupRenderTarget( renderTarget ) { - if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP ); + var renderTargetProperties = properties.get( renderTarget ); + var textureProperties = properties.get( renderTarget.texture ); - } else { + renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); - renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); + textureProperties.__webglTexture = _gl.createTexture(); - if ( renderTarget.shareDepthFrom ) { + _infoMemory.textures ++; - renderTargetProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer; + var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); + var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ); + var glFormat = paramThreeToGL( renderTarget.texture.format ); + var glType = paramThreeToGL( renderTarget.texture.type ); - } else { + // + // Setup framebuffer + // - renderTargetProperties.__webglRenderbuffer = _gl.createRenderbuffer(); + if ( isCube ) { - } + renderTargetProperties.__webglFramebuffer = []; + for ( var i = 0; i < 6; i ++ ) { - state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); - setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo ); + renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); - state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); + } - setupFrameBuffer( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D ); + } else { - if ( renderTarget.shareDepthFrom ) { + renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); - if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { + } - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer ); + // + // Setup color buffer + // + if ( isCube ) { - } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo ); + for ( var i = 0; i < 6; i ++ ) { - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer ); + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); - } + } - } else { + if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); - setupRenderBuffer( renderTargetProperties.__webglRenderbuffer, renderTarget ); + } else { - } + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); + setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo ); + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D ); - if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D ); + if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D ); + state.bindTexture( _gl.TEXTURE_2D, null ); - } + } - // Release everything + // + // Setup depth and stencil buffers + // + if ( renderTarget.depthBuffer ) { - if ( isCube ) { + setupDepthRenderbuffer( renderTarget ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); + } - } else { + } - state.bindTexture( _gl.TEXTURE_2D, null ); + this.setRenderTarget = function ( renderTarget ) { - } + if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { - _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); - _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); + setupRenderTarget( renderTarget ); } + var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); var framebuffer, width, height, vx, vy; if ( renderTarget ) {