Skip to content

Commit

Permalink
WebGLRenderer: Refactor framebuffer state management. (#21447)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 committed Mar 11, 2021
1 parent 8ef5d5f commit e903c84
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 56 deletions.
3 changes: 0 additions & 3 deletions docs/api/en/renderers/WebGLRenderer.html
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,6 @@ <h3>[method:null setClearAlpha]( [param:Float alpha] )</h3>
<h3>[method:null setClearColor]( [param:Color color], [param:Float alpha] )</h3>
<p>Sets the clear color and opacity.</p>

<h3>[method:null setFramebuffer]( [param:WebGLFramebuffer value] )</h3>
<p>Sets the given WebGLFramebuffer. This method can only be used if no render target is set via [page:WebGLRenderer.setRenderTarget .setRenderTarget]().</p>

<h3>[method:null setPixelRatio]( [param:number value] )</h3>
<p>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</p>

Expand Down
3 changes: 0 additions & 3 deletions docs/api/zh/renderers/WebGLRenderer.html
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,6 @@ <h3>[method:null setClearAlpha]( [param:Float alpha] )</h3>
<h3>[method:null setClearColor]( [param:Color color], [param:Float alpha] )</h3>
<p>设置颜色及其透明度</p>

<h3>[method:null setFramebuffer]( [param:WebGLFramebuffer value] )</h3>
<p>Sets the given WebGLFramebuffer. This method can only be used if no render target is set via [page:WebGLRenderer.setRenderTarget .setRenderTarget]().</p>

<h3>[method:null setPixelRatio]( [param:number value] )</h3>
<p>设置设备像素比。通常用于避免HiDPI设备上绘图模糊</p>

Expand Down
42 changes: 6 additions & 36 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,9 @@ function WebGLRenderer( parameters ) {

// internal state cache

let _framebuffer = null;

let _currentActiveCubeFace = 0;
let _currentActiveMipmapLevel = 0;
let _currentRenderTarget = null;
let _currentFramebuffer = null;
let _currentMaterialId = - 1;

let _currentCamera = null;
Expand Down Expand Up @@ -1763,15 +1760,6 @@ function WebGLRenderer( parameters ) {

}

//
this.setFramebuffer = function ( value ) {

if ( _framebuffer !== value && _currentRenderTarget === null ) _gl.bindFramebuffer( _gl.FRAMEBUFFER, value );

_framebuffer = value;

};

this.getActiveCubeFace = function () {

return _currentActiveCubeFace;
Expand Down Expand Up @@ -1802,7 +1790,7 @@ function WebGLRenderer( parameters ) {

}

let framebuffer = _framebuffer;
let framebuffer = null;
let isCube = false;
let isRenderTarget3D = false;

Expand Down Expand Up @@ -1845,12 +1833,7 @@ function WebGLRenderer( parameters ) {

}

if ( _currentFramebuffer !== framebuffer ) {

_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
_currentFramebuffer = framebuffer;

}
state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

state.viewport( _currentViewport );
state.scissor( _currentScissor );
Expand Down Expand Up @@ -1890,15 +1873,7 @@ function WebGLRenderer( parameters ) {

if ( framebuffer ) {

let restore = false;

if ( framebuffer !== _currentFramebuffer ) {

_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

restore = true;

}
state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

try {

Expand Down Expand Up @@ -1942,11 +1917,10 @@ function WebGLRenderer( parameters ) {

} finally {

if ( restore ) {

_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
// restore framebuffer of current render target if necessary

}
const framebuffer = ( _currentRenderTarget !== null ) ? properties.get( _currentRenderTarget ).__webglFramebuffer : null;
state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

}

Expand Down Expand Up @@ -2093,13 +2067,9 @@ function WebGLRenderer( parameters ) {

this.resetState = function () {

_framebuffer = null;
_currentActiveCubeFace = 0;
_currentActiveMipmapLevel = 0;
_currentRenderTarget = null;
_currentFramebuffer = null;

_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );

state.reset();
bindingStates.reset();
Expand Down
48 changes: 48 additions & 0 deletions src/renderers/webgl/WebGLState.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ function WebGLState( gl, extensions, capabilities ) {

let enabledCapabilities = {};

let xrFramebuffer = null;
let currentBoundFramebuffers = {};

let currentProgram = null;

let currentBlendingEnabled = false;
Expand Down Expand Up @@ -422,6 +425,34 @@ function WebGLState( gl, extensions, capabilities ) {

}

function bindXRFramebuffer( framebuffer ) {

if ( framebuffer !== xrFramebuffer ) {

gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );

xrFramebuffer = framebuffer;

}

}

function bindFramebuffer( target, framebuffer ) {

if ( target === gl.DRAW_FRAMEBUFFER ) target = gl.FRAMEBUFFER;

if ( framebuffer === null && xrFramebuffer !== null ) framebuffer = xrFramebuffer; // use active XR framebuffer if available

if ( currentBoundFramebuffers[ target ] !== framebuffer ) {

gl.bindFramebuffer( target, framebuffer );

currentBoundFramebuffers[ target ] = framebuffer;

}

}

function useProgram( program ) {

if ( currentProgram !== program ) {
Expand Down Expand Up @@ -914,6 +945,17 @@ function WebGLState( gl, extensions, capabilities ) {

gl.activeTexture( gl.TEXTURE0 );

if ( isWebGL2 === true ) {

gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null ); // Equivalent to gl.FRAMEBUFFER
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, null );

} else {

gl.bindFramebuffer( gl.FRAMEBUFFER, null );

}

gl.useProgram( null );

gl.lineWidth( 1 );
Expand All @@ -928,6 +970,9 @@ function WebGLState( gl, extensions, capabilities ) {
currentTextureSlot = null;
currentBoundTextures = {};

xrFramebuffer = null;
currentBoundFramebuffers = {};

currentProgram = null;

currentBlendingEnabled = false;
Expand Down Expand Up @@ -968,6 +1013,9 @@ function WebGLState( gl, extensions, capabilities ) {
enable: enable,
disable: disable,

bindFramebuffer: bindFramebuffer,
bindXRFramebuffer: bindXRFramebuffer,

useProgram: useProgram,

setBlending: setBlending,
Expand Down
22 changes: 11 additions & 11 deletions src/renderers/webgl/WebGLTextures.js
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

}

_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0 );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
state.bindFramebuffer( _gl.FRAMEBUFFER, null );

}

Expand Down Expand Up @@ -945,7 +945,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
const isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );
if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' );

_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {

Expand Down Expand Up @@ -1005,23 +1005,23 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

for ( let i = 0; i < 6; i ++ ) {

_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );

}

} else {

_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );

}

}

_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
state.bindFramebuffer( _gl.FRAMEBUFFER, null );

}

Expand Down Expand Up @@ -1085,7 +1085,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
const samples = getRenderTargetSamples( renderTarget );
_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );

_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer );
_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );

Expand All @@ -1096,7 +1096,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

}

_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
state.bindFramebuffer( _gl.FRAMEBUFFER, null );


} else {
Expand Down Expand Up @@ -1202,8 +1202,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

const renderTargetProperties = properties.get( renderTarget );

_gl.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
_gl.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
state.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );

const width = renderTarget.width;
const height = renderTarget.height;
Expand All @@ -1214,7 +1214,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

_gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST );

_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905
state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905

} else {

Expand Down
10 changes: 7 additions & 3 deletions src/renderers/webxr/WebXRManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { WebXRController } from './WebXRController.js';
function WebXRManager( renderer, gl ) {

const scope = this;
const state = renderer.state;

let session = null;

Expand Down Expand Up @@ -119,10 +120,13 @@ function WebXRManager( renderer, gl ) {
_currentDepthNear = null;
_currentDepthFar = null;

// restore framebuffer/rendering state

state.bindXRFramebuffer( null );
renderer.setRenderTarget( renderer.getRenderTarget() );

//

renderer.setFramebuffer( null );
renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
animation.stop();

scope.isPresenting = false;
Expand Down Expand Up @@ -412,7 +416,7 @@ function WebXRManager( renderer, gl ) {
const views = pose.views;
const baseLayer = session.renderState.baseLayer;

renderer.setFramebuffer( baseLayer.framebuffer );
state.bindXRFramebuffer( baseLayer.framebuffer );

let cameraVRNeedsUpdate = false;

Expand Down

0 comments on commit e903c84

Please sign in to comment.