Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 103 additions & 29 deletions src/renderers/webxr/WebXRManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class WebXRManager extends EventDispatcher {
let glFramebuffer = null;
let glProjLayer = null;
let glBaseLayer = null;
let isMultisample = false;
let glMultisampledFramebuffer = null;
let glColorRenderbuffer = null;
let glDepthRenderbuffer = null;
let depthStyle = null;
let clearStyle = null;

const controllers = [];
const inputSourcesMap = new Map();
Expand Down Expand Up @@ -133,6 +139,15 @@ class WebXRManager extends EventDispatcher {
state.bindXRFramebuffer( null );
renderer.setRenderTarget( renderer.getRenderTarget() );

if ( glFramebuffer ) gl.deleteFramebuffer( glFramebuffer );
if ( glMultisampledFramebuffer ) gl.deleteFramebuffer( glMultisampledFramebuffer );
if ( glColorRenderbuffer ) gl.deleteRenderbuffer( glColorRenderbuffer );
if ( glDepthRenderbuffer ) gl.deleteRenderbuffer( glDepthRenderbuffer );
glFramebuffer = null;
glMultisampledFramebuffer = null;
glColorRenderbuffer = null;
glDepthRenderbuffer = null;

//

animation.stop();
Expand Down Expand Up @@ -216,46 +231,80 @@ class WebXRManager extends EventDispatcher {

session.updateRenderState( { baseLayer: glBaseLayer } );

} else if ( gl instanceof WebGLRenderingContext ) {

// Use old style webgl layer because we can't use MSAA
// WebGL2 support.

const layerInit = {
antialias: true,
alpha: attributes.alpha,
depth: attributes.depth,
stencil: attributes.stencil,
framebufferScaleFactor: framebufferScaleFactor
};

glBaseLayer = new XRWebGLLayer( session, gl, layerInit );

session.updateRenderState( { layers: [ glBaseLayer ] } );

} else {

let depthFormat = 0;
isMultisample = attributes.antialias;
let depthFormat = null;

// for anti-aliased output, use classic webgllayer for now
if ( attributes.antialias ) {

const layerInit = {
antialias: true,
alpha: attributes.alpha,
depth: attributes.depth,
stencil: attributes.stencil,
framebufferScaleFactor: framebufferScaleFactor
};
if ( attributes.depth ) {

glBaseLayer = new XRWebGLLayer( session, gl, layerInit );
clearStyle = gl.DEPTH_BUFFER_BIT;

session.updateRenderState( { layers: [ glBaseLayer ] } );
if ( attributes.stencil ) clearStyle |= gl.STENCIL_BUFFER_BIT;

} else {
depthStyle = attributes.stencil ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
depthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;

if ( attributes.depth ) {
}

const projectionlayerInit = {
colorFormat: attributes.alpha ? gl.RGBA8 : gl.RGB8,
depthFormat: depthFormat,
scaleFactor: framebufferScaleFactor
};

depthFormat = attributes.stencil ? gl.DEPTH_STENCIL : gl.DEPTH_COMPONENT;
glBinding = new XRWebGLBinding( session, gl );

}
glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );

const projectionlayerInit = {
colorFormat: attributes.alpha ? gl.RGBA : gl.RGB,
depthFormat: depthFormat,
scaleFactor: framebufferScaleFactor
};
glFramebuffer = gl.createFramebuffer();

glBinding = new XRWebGLBinding( session, gl );
session.updateRenderState( { layers: [ glProjLayer ] } );

glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
if ( isMultisample ) {

glFramebuffer = gl.createFramebuffer();
glMultisampledFramebuffer = gl.createFramebuffer();
glColorRenderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, glColorRenderbuffer );
gl.renderbufferStorageMultisample(
gl.RENDERBUFFER,
4,
gl.RGBA8,
glProjLayer.textureWidth,
glProjLayer.textureHeight );
state.bindFramebuffer( gl.FRAMEBUFFER, glMultisampledFramebuffer );
gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, glColorRenderbuffer );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );

session.updateRenderState( { layers: [ glProjLayer ] } );
if ( depthFormat !== null ) {

glDepthRenderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, glDepthRenderbuffer );
gl.renderbufferStorageMultisample( gl.RENDERBUFFER, 4, depthFormat, glProjLayer.textureWidth, glProjLayer.textureHeight );
gl.framebufferRenderbuffer( gl.FRAMEBUFFER, depthStyle, gl.RENDERBUFFER, glDepthRenderbuffer );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );

}

state.bindFramebuffer( gl.FRAMEBUFFER, null );

}

Expand Down Expand Up @@ -532,7 +581,6 @@ class WebXRManager extends EventDispatcher {

cameraVRNeedsUpdate = true;


}

for ( let i = 0; i < views.length; i ++ ) {
Expand All @@ -553,7 +601,7 @@ class WebXRManager extends EventDispatcher {

if ( glSubImage.depthStencilTexture !== undefined ) {

gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, glSubImage.depthStencilTexture, 0 );
gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, glSubImage.depthStencilTexture, 0 );

}

Expand All @@ -566,9 +614,7 @@ class WebXRManager extends EventDispatcher {
const camera = cameras[ i ];

camera.matrix.fromArray( view.transform.matrix );

camera.projectionMatrix.fromArray( view.projectionMatrix );

camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );

if ( i === 0 ) {
Expand All @@ -585,6 +631,14 @@ class WebXRManager extends EventDispatcher {

}

if ( isMultisample ) {

state.bindXRFramebuffer( glMultisampledFramebuffer );

if ( clearStyle !== null ) gl.clear( clearStyle );

}

}

//
Expand All @@ -602,6 +656,26 @@ class WebXRManager extends EventDispatcher {

if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame );

if ( isMultisample ) {

const width = glProjLayer.textureWidth;
const height = glProjLayer.textureHeight;

state.bindFramebuffer( gl.READ_FRAMEBUFFER, glMultisampledFramebuffer );
state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, glFramebuffer );
// Invalidate the depth here to avoid flush of the depth data to main memory.
gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, [ depthStyle ] );
gl.invalidateFramebuffer( gl.DRAW_FRAMEBUFFER, [ depthStyle ] );
gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
// Invalidate the MSAA buffer because it's not needed anymore.
gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, [ gl.COLOR_ATTACHMENT0 ] );
state.bindFramebuffer( gl.READ_FRAMEBUFFER, null );
state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );

state.bindFramebuffer( gl.FRAMEBUFFER, glMultisampledFramebuffer );

}

}

const animation = new WebGLAnimation();
Expand Down