|
@@ -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();
|
|
@@ -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();
|
|
@@ -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 );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -532,7 +581,6 @@ class WebXRManager extends EventDispatcher {
|
|
|
|
|
|
cameraVRNeedsUpdate = true;
|
|
|
|
|
|
-
|
|
|
}
|
|
|
|
|
|
for ( let i = 0; i < views.length; i ++ ) {
|
|
@@ -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 );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -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 ) {
|
|
@@ -585,6 +631,14 @@ class WebXRManager extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ if ( isMultisample ) {
|
|
|
+
|
|
|
+ state.bindXRFramebuffer( glMultisampledFramebuffer );
|
|
|
+
|
|
|
+ if ( clearStyle !== null ) gl.clear( clearStyle );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
//
|
|
@@ -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();
|