super-three 0.157.0 → 0.157.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/three.cjs CHANGED
@@ -14749,7 +14749,7 @@ function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha,
14749
14749
  if ( boxMesh === undefined ) {
14750
14750
 
14751
14751
  boxMesh = new Mesh(
14752
- new BoxGeometry( 1, 1, 1 ),
14752
+ new BoxGeometry( 10000, 10000, 10000 ),
14753
14753
  new ShaderMaterial( {
14754
14754
  name: 'BackgroundCubeMaterial',
14755
14755
  uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ),
@@ -17845,6 +17845,103 @@ function WebGLMorphtargets( gl, capabilities, textures ) {
17845
17845
 
17846
17846
  }
17847
17847
 
17848
+ /**
17849
+ * @author fernandojsg / http://fernandojsg.com
17850
+ * @author Takahiro https://github.com/takahirox
17851
+ */
17852
+
17853
+ class WebGLMultiview {
17854
+
17855
+ constructor( renderer, extensions, gl ) {
17856
+
17857
+ this.renderer = renderer;
17858
+
17859
+ this.DEFAULT_NUMVIEWS = 2;
17860
+ this.maxNumViews = 0;
17861
+ this.gl = gl;
17862
+
17863
+ this.extensions = extensions;
17864
+
17865
+ this.available = this.extensions.has( 'OCULUS_multiview' );
17866
+
17867
+ if ( this.available ) {
17868
+
17869
+ const extension = this.extensions.get( 'OCULUS_multiview' );
17870
+
17871
+ this.maxNumViews = this.gl.getParameter( extension.MAX_VIEWS_OVR );
17872
+
17873
+ this.mat4 = [];
17874
+ this.mat3 = [];
17875
+ this.cameraArray = [];
17876
+
17877
+ for ( var i = 0; i < this.maxNumViews; i ++ ) {
17878
+
17879
+ this.mat4[ i ] = new Matrix4();
17880
+ this.mat3[ i ] = new Matrix3();
17881
+
17882
+ }
17883
+
17884
+ }
17885
+
17886
+ }
17887
+
17888
+ //
17889
+ getCameraArray( camera ) {
17890
+
17891
+ if ( camera.isArrayCamera ) return camera.cameras;
17892
+
17893
+ this.cameraArray[ 0 ] = camera;
17894
+
17895
+ return this.cameraArray;
17896
+
17897
+ }
17898
+
17899
+ updateCameraProjectionMatricesUniform( camera, uniforms ) {
17900
+
17901
+ var cameras = this.getCameraArray( camera );
17902
+
17903
+ for ( var i = 0; i < cameras.length; i ++ ) {
17904
+
17905
+ this.mat4[ i ].copy( cameras[ i ].projectionMatrix );
17906
+
17907
+ }
17908
+
17909
+ uniforms.setValue( this.gl, 'projectionMatrices', this.mat4 );
17910
+
17911
+ }
17912
+
17913
+ updateCameraViewMatricesUniform( camera, uniforms ) {
17914
+
17915
+ var cameras = this.getCameraArray( camera );
17916
+
17917
+ for ( var i = 0; i < cameras.length; i ++ ) {
17918
+
17919
+ this.mat4[ i ].copy( cameras[ i ].matrixWorldInverse );
17920
+
17921
+ }
17922
+
17923
+ uniforms.setValue( this.gl, 'viewMatrices', this.mat4 );
17924
+
17925
+ }
17926
+
17927
+ updateObjectMatricesUniforms( object, camera, uniforms ) {
17928
+
17929
+ var cameras = this.getCameraArray( camera );
17930
+
17931
+ for ( var i = 0; i < cameras.length; i ++ ) {
17932
+
17933
+ this.mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
17934
+ this.mat3[ i ].getNormalMatrix( this.mat4[ i ] );
17935
+
17936
+ }
17937
+
17938
+ uniforms.setValue( this.gl, 'modelViewMatrices', this.mat4 );
17939
+ uniforms.setValue( this.gl, 'normalMatrices', this.mat3 );
17940
+
17941
+ }
17942
+
17943
+ }
17944
+
17848
17945
  function WebGLObjects( gl, geometries, attributes, info ) {
17849
17946
 
17850
17947
  let updateMap = new WeakMap();
@@ -19538,6 +19635,8 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19538
19635
  let prefixVertex, prefixFragment;
19539
19636
  let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
19540
19637
 
19638
+ const numMultiviewViews = parameters.numMultiviewViews;
19639
+
19541
19640
  if ( parameters.isRawShaderMaterial ) {
19542
19641
 
19543
19642
  prefixVertex = [
@@ -19944,6 +20043,53 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
19944
20043
  '#define textureCubeGradEXT textureGrad'
19945
20044
  ].join( '\n' ) + '\n' + prefixFragment;
19946
20045
 
20046
+ // Multiview
20047
+
20048
+ if ( numMultiviewViews > 0 ) {
20049
+
20050
+ // TODO: fix light transforms here?
20051
+
20052
+ prefixVertex = [
20053
+ '#extension GL_OVR_multiview : require',
20054
+ 'layout(num_views = ' + numMultiviewViews + ') in;',
20055
+ '#define VIEW_ID gl_ViewID_OVR'
20056
+ ].join( '\n' ) + '\n' + prefixVertex;
20057
+
20058
+ prefixVertex = prefixVertex.replace(
20059
+ [
20060
+ 'uniform mat4 modelViewMatrix;',
20061
+ 'uniform mat4 projectionMatrix;',
20062
+ 'uniform mat4 viewMatrix;',
20063
+ 'uniform mat3 normalMatrix;'
20064
+ ].join( '\n' ),
20065
+ [
20066
+ 'uniform mat4 modelViewMatrices[' + numMultiviewViews + '];',
20067
+ 'uniform mat4 projectionMatrices[' + numMultiviewViews + '];',
20068
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20069
+ 'uniform mat3 normalMatrices[' + numMultiviewViews + '];',
20070
+
20071
+ '#define modelViewMatrix modelViewMatrices[VIEW_ID]',
20072
+ '#define projectionMatrix projectionMatrices[VIEW_ID]',
20073
+ '#define viewMatrix viewMatrices[VIEW_ID]',
20074
+ '#define normalMatrix normalMatrices[VIEW_ID]'
20075
+ ].join( '\n' )
20076
+ );
20077
+
20078
+ prefixFragment = [
20079
+ '#extension GL_OVR_multiview : require',
20080
+ '#define VIEW_ID gl_ViewID_OVR'
20081
+ ].join( '\n' ) + '\n' + prefixFragment;
20082
+
20083
+ prefixFragment = prefixFragment.replace(
20084
+ 'uniform mat4 viewMatrix;',
20085
+ [
20086
+ 'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
20087
+ '#define viewMatrix viewMatrices[VIEW_ID]'
20088
+ ].join( '\n' )
20089
+ );
20090
+
20091
+ }
20092
+
19947
20093
  }
19948
20094
 
19949
20095
  const vertexGlsl = versionString + prefixVertex + vertexShader;
@@ -20108,6 +20254,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
20108
20254
  this.program = program;
20109
20255
  this.vertexShader = glVertexShader;
20110
20256
  this.fragmentShader = glFragmentShader;
20257
+ this.numMultiviewViews = numMultiviewViews;
20111
20258
 
20112
20259
  return this;
20113
20260
 
@@ -20337,6 +20484,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20337
20484
 
20338
20485
  const currentRenderTarget = renderer.getRenderTarget();
20339
20486
 
20487
+ const numMultiviewViews = currentRenderTarget && currentRenderTarget.isWebGLMultiviewRenderTarget ? currentRenderTarget.numViews : 0;
20488
+
20340
20489
  const IS_INSTANCEDMESH = object.isInstancedMesh === true;
20341
20490
 
20342
20491
  const HAS_MAP = !! material.map;
@@ -20427,6 +20576,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20427
20576
  instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
20428
20577
 
20429
20578
  supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES,
20579
+ numMultiviewViews: numMultiviewViews,
20430
20580
  outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
20431
20581
 
20432
20582
  map: HAS_MAP,
@@ -20774,6 +20924,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
20774
20924
  _programLayers.enable( 18 );
20775
20925
  if ( parameters.decodeVideoTexture )
20776
20926
  _programLayers.enable( 19 );
20927
+ if ( parameters.numMultiviewViews )
20928
+ _programLayers.enable( 20 );
20777
20929
 
20778
20930
  array.push( _programLayers.mask );
20779
20931
 
@@ -23609,12 +23761,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
23609
23761
  const maxSamples = capabilities.maxSamples;
23610
23762
  const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
23611
23763
  const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
23764
+ const multiviewExt = extensions.has( 'OCULUS_multiview' ) ? extensions.get( 'OCULUS_multiview' ) : null;
23612
23765
 
23613
23766
  const _videoTextures = new WeakMap();
23614
23767
  let _canvas;
23615
23768
 
23616
23769
  const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
23617
23770
 
23771
+ let _deferredUploads = [];
23772
+ let _deferTextureUploads = false;
23773
+
23618
23774
  // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
23619
23775
  // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
23620
23776
  // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
@@ -24082,8 +24238,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24082
24238
 
24083
24239
  } else {
24084
24240
 
24085
- uploadTexture( textureProperties, texture, slot );
24086
- return;
24241
+ if ( uploadTexture( textureProperties, texture, slot ) ) {
24242
+
24243
+ return;
24244
+
24245
+ }
24087
24246
 
24088
24247
  }
24089
24248
 
@@ -24316,8 +24475,45 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24316
24475
 
24317
24476
  }
24318
24477
 
24478
+ function setDeferTextureUploads( deferFlag ) {
24479
+
24480
+ _deferTextureUploads = deferFlag;
24481
+
24482
+ }
24483
+
24484
+ function runDeferredUploads() {
24485
+
24486
+ const previousDeferSetting = _deferTextureUploads;
24487
+ _deferTextureUploads = false;
24488
+
24489
+ for ( const upload of _deferredUploads ) {
24490
+
24491
+ uploadTexture( upload.textureProperties, upload.texture, upload.slot );
24492
+ upload.texture.isPendingDeferredUpload = false;
24493
+
24494
+ }
24495
+
24496
+ _deferredUploads = [];
24497
+
24498
+ _deferTextureUploads = previousDeferSetting;
24499
+
24500
+ }
24501
+
24319
24502
  function uploadTexture( textureProperties, texture, slot ) {
24320
24503
 
24504
+ if ( _deferTextureUploads ) {
24505
+
24506
+ if ( ! texture.isPendingDeferredUpload ) {
24507
+
24508
+ texture.isPendingDeferredUpload = true;
24509
+ _deferredUploads.push( { textureProperties: textureProperties, texture: texture, slot: slot } );
24510
+
24511
+ }
24512
+
24513
+ return false;
24514
+
24515
+ }
24516
+
24321
24517
  let textureType = _gl.TEXTURE_2D;
24322
24518
 
24323
24519
  if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY;
@@ -24734,6 +24930,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24734
24930
  }
24735
24931
 
24736
24932
  textureProperties.__version = texture.version;
24933
+ return true;
24737
24934
 
24738
24935
  }
24739
24936
 
@@ -24963,7 +25160,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24963
25160
  const width = Math.max( 1, renderTarget.width >> level );
24964
25161
  const height = Math.max( 1, renderTarget.height >> level );
24965
25162
 
24966
- if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
25163
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25164
+
25165
+ state.texStorage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.numViews );
25166
+
25167
+ } else if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
24967
25168
 
24968
25169
  state.texImage3D( textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null );
24969
25170
 
@@ -24977,13 +25178,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24977
25178
 
24978
25179
  state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
24979
25180
 
24980
- if ( useMultisampledRTT( renderTarget ) ) {
25181
+ const multisampled = useMultisampledRTT( renderTarget );
25182
+
25183
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25184
+
25185
+ if ( multisampled ) {
25186
+
25187
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ), 0, renderTarget.numViews );
25188
+
25189
+ } else {
25190
+
25191
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( texture ).__webglTexture, 0, 0, renderTarget.numViews );
24981
25192
 
24982
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25193
+ }
24983
25194
 
24984
25195
  } else if ( textureTarget === _gl.TEXTURE_2D || ( textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ) ) { // see #24753
24985
25196
 
24986
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25197
+ if ( multisampled ) {
25198
+
25199
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );
25200
+
25201
+ } else {
25202
+
25203
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, level );
25204
+
25205
+ }
24987
25206
 
24988
25207
  }
24989
25208
 
@@ -24997,7 +25216,59 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
24997
25216
 
24998
25217
  _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
24999
25218
 
25000
- if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
25219
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25220
+
25221
+ const useMultisample = useMultisampledRTT( renderTarget );
25222
+ const numViews = renderTarget.numViews;
25223
+
25224
+ const depthTexture = renderTarget.depthTexture;
25225
+ let glInternalFormat = _gl.DEPTH_COMPONENT24;
25226
+ let glDepthAttachment = _gl.DEPTH_ATTACHMENT;
25227
+
25228
+ if ( depthTexture && depthTexture.isDepthTexture ) {
25229
+
25230
+ if ( depthTexture.type === FloatType ) {
25231
+
25232
+ glInternalFormat = _gl.DEPTH_COMPONENT32F;
25233
+
25234
+ } else if ( depthTexture.type === UnsignedInt248Type ) {
25235
+
25236
+ glInternalFormat = _gl.DEPTH24_STENCIL8;
25237
+ glDepthAttachment = _gl.DEPTH_STENCIL_ATTACHMENT;
25238
+
25239
+ }
25240
+
25241
+ // we're defaulting to _gl.DEPTH_COMPONENT24 so don't assign here
25242
+ // or else DeepScan will complain
25243
+
25244
+ // else if ( depthTexture.type === UnsignedIntType ) {
25245
+
25246
+ // glInternalFormat = _gl.DEPTH_COMPONENT24;
25247
+
25248
+ // }
25249
+
25250
+ }
25251
+
25252
+ let depthStencilTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25253
+ if ( depthStencilTexture === undefined ) {
25254
+
25255
+ depthStencilTexture = _gl.createTexture();
25256
+ _gl.bindTexture( _gl.TEXTURE_2D_ARRAY, depthStencilTexture );
25257
+ _gl.texStorage3D( _gl.TEXTURE_2D_ARRAY, 1, glInternalFormat, renderTarget.width, renderTarget.height, numViews );
25258
+
25259
+ }
25260
+
25261
+ if ( useMultisample ) {
25262
+
25263
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, getRenderTargetSamples( renderTarget ), 0, numViews );
25264
+
25265
+ } else {
25266
+
25267
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, glDepthAttachment, depthStencilTexture, 0, 0, numViews );
25268
+
25269
+ }
25270
+
25271
+ } else if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
25001
25272
 
25002
25273
  let glInternalFormat = ( isWebGL2 === true ) ? _gl.DEPTH_COMPONENT24 : _gl.DEPTH_COMPONENT16;
25003
25274
 
@@ -25121,37 +25392,85 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25121
25392
  }
25122
25393
 
25123
25394
  setTexture2D( renderTarget.depthTexture, 0 );
25395
+ if ( renderTarget.depthTexture.image.depth != 1 ) {
25396
+
25397
+ setTexture2DArray( renderTarget.depthTexture, 0 );
25398
+
25399
+ } else {
25400
+
25401
+ setTexture2D( renderTarget.depthTexture, 0 );
25402
+
25403
+ }
25124
25404
 
25125
25405
  const webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
25126
25406
  const samples = getRenderTargetSamples( renderTarget );
25127
25407
 
25128
- if ( renderTarget.depthTexture.format === DepthFormat ) {
25408
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25129
25409
 
25130
- if ( useMultisampledRTT( renderTarget ) ) {
25410
+ const useMultisample = useMultisampledRTT( renderTarget );
25411
+ const numViews = renderTarget.numViews;
25131
25412
 
25132
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25413
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25133
25414
 
25134
- } else {
25415
+ if ( useMultisample ) {
25135
25416
 
25136
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25417
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25137
25418
 
25138
- }
25419
+ } else {
25139
25420
 
25140
- } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25421
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25422
+
25423
+ }
25141
25424
 
25142
- if ( useMultisampledRTT( renderTarget ) ) {
25425
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25143
25426
 
25144
- multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25427
+ if ( useMultisample ) {
25428
+
25429
+ multiviewExt.framebufferTextureMultisampleMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, samples, 0, numViews );
25430
+
25431
+ } else {
25432
+
25433
+ multiviewExt.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, webglDepthTexture, 0, 0, numViews );
25434
+
25435
+ }
25145
25436
 
25146
25437
  } else {
25147
25438
 
25148
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25439
+ throw new Error( 'Unknown depthTexture format' );
25149
25440
 
25150
25441
  }
25151
25442
 
25152
25443
  } else {
25153
25444
 
25154
- throw new Error( 'Unknown depthTexture format' );
25445
+ if ( renderTarget.depthTexture.format === DepthFormat ) {
25446
+
25447
+ if ( useMultisampledRTT( renderTarget ) ) {
25448
+
25449
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25450
+
25451
+ } else {
25452
+
25453
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25454
+
25455
+ }
25456
+
25457
+ } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
25458
+
25459
+ if ( useMultisampledRTT( renderTarget ) ) {
25460
+
25461
+ multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples );
25462
+
25463
+ } else {
25464
+
25465
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
25466
+
25467
+ }
25468
+
25469
+ } else {
25470
+
25471
+ throw new Error( 'Unknown depthTexture format' );
25472
+
25473
+ }
25155
25474
 
25156
25475
  }
25157
25476
 
@@ -25430,6 +25749,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25430
25749
 
25431
25750
  }
25432
25751
 
25752
+ if ( renderTarget.isWebGLMultiviewRenderTarget === true ) {
25753
+
25754
+ glTextureType = _gl.TEXTURE_2D_ARRAY;
25755
+
25756
+ }
25757
+
25433
25758
  state.bindTexture( glTextureType, textureProperties.__webglTexture );
25434
25759
  setTextureParameters( glTextureType, texture, supportsMips );
25435
25760
 
@@ -25459,9 +25784,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25459
25784
 
25460
25785
  // Setup depth and stencil buffers
25461
25786
 
25462
- if ( renderTarget.depthBuffer ) {
25787
+ if ( renderTarget.depthBuffer || renderTarget.isWebGLMultiviewRenderTarget === true ) {
25463
25788
 
25464
- setupDepthRenderbuffer( renderTarget );
25789
+ this.setupDepthRenderbuffer( renderTarget );
25465
25790
 
25466
25791
  }
25467
25792
 
@@ -25697,12 +26022,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
25697
26022
  this.setTexture3D = setTexture3D;
25698
26023
  this.setTextureCube = setTextureCube;
25699
26024
  this.rebindTextures = rebindTextures;
26025
+ this.uploadTexture = uploadTexture;
25700
26026
  this.setupRenderTarget = setupRenderTarget;
25701
26027
  this.updateRenderTargetMipmap = updateRenderTargetMipmap;
25702
26028
  this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
26029
+ this.setupDepthTexture = setupDepthTexture;
25703
26030
  this.setupDepthRenderbuffer = setupDepthRenderbuffer;
25704
26031
  this.setupFrameBufferTexture = setupFrameBufferTexture;
25705
26032
  this.useMultisampledRTT = useMultisampledRTT;
26033
+ this.runDeferredUploads = runDeferredUploads;
26034
+ this.setDeferTextureUploads = setDeferTextureUploads;
25706
26035
 
25707
26036
  }
25708
26037
 
@@ -26559,6 +26888,39 @@ Object.assign( WebVRManager.prototype, {
26559
26888
  dispatchEvent: EventDispatcher.prototype.dispatchEvent
26560
26889
  } );
26561
26890
 
26891
+ /**
26892
+ * @author fernandojsg / http://fernandojsg.com
26893
+ * @author Takahiro https://github.com/takahirox
26894
+ */
26895
+
26896
+
26897
+ class WebGLMultiviewRenderTarget extends WebGLRenderTarget {
26898
+
26899
+ constructor( width, height, numViews, options = {} ) {
26900
+
26901
+ super( width, height, options );
26902
+
26903
+ this.depthBuffer = false;
26904
+ this.stencilBuffer = false;
26905
+
26906
+ this.numViews = numViews;
26907
+
26908
+ }
26909
+
26910
+ copy( source ) {
26911
+
26912
+ super.copy( source );
26913
+
26914
+ this.numViews = source.numViews;
26915
+
26916
+ return this;
26917
+
26918
+ }
26919
+
26920
+ }
26921
+
26922
+ WebGLMultiviewRenderTarget.prototype.isWebGLMultiviewRenderTarget = true;
26923
+
26562
26924
  const _moveEvent = { type: 'move' };
26563
26925
 
26564
26926
  class WebXRController {
@@ -26953,7 +27315,7 @@ class DepthTexture extends Texture {
26953
27315
 
26954
27316
  class WebXRManager extends EventDispatcher {
26955
27317
 
26956
- constructor( renderer, gl ) {
27318
+ constructor( renderer, gl, extensions, useMultiview ) {
26957
27319
 
26958
27320
  super();
26959
27321
 
@@ -27009,6 +27371,7 @@ class WebXRManager extends EventDispatcher {
27009
27371
  this.enabled = false;
27010
27372
 
27011
27373
  this.isPresenting = false;
27374
+ this.isMultiview = false;
27012
27375
 
27013
27376
  this.getCameraPose = function ( ) {
27014
27377
 
@@ -27252,29 +27615,51 @@ class WebXRManager extends EventDispatcher {
27252
27615
 
27253
27616
  }
27254
27617
 
27618
+ scope.isMultiview = useMultiview && extensions.has( 'OCULUS_multiview' );
27619
+
27255
27620
  const projectionlayerInit = {
27256
27621
  colorFormat: gl.RGBA8,
27257
27622
  depthFormat: glDepthFormat,
27258
27623
  scaleFactor: framebufferScaleFactor
27259
27624
  };
27260
27625
 
27626
+ if ( scope.isMultiview ) {
27627
+
27628
+ projectionlayerInit.textureType = 'texture-array';
27629
+
27630
+ }
27631
+
27261
27632
  glBinding = new XRWebGLBinding( session, gl );
27262
27633
 
27263
27634
  glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
27264
27635
 
27265
27636
  session.updateRenderState( { layers: [ glProjLayer ] } );
27266
27637
 
27267
- newRenderTarget = new WebGLRenderTarget(
27268
- glProjLayer.textureWidth,
27269
- glProjLayer.textureHeight,
27270
- {
27271
- format: RGBAFormat,
27272
- type: UnsignedByteType,
27273
- depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27274
- stencilBuffer: attributes.stencil,
27275
- colorSpace: renderer.outputColorSpace,
27276
- samples: attributes.antialias ? 4 : 0
27277
- } );
27638
+ const renderTargetOptions = {
27639
+ format: RGBAFormat,
27640
+ type: UnsignedByteType,
27641
+ depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
27642
+ stencilBuffer: attributes.stencil,
27643
+ colorSpace: renderer.outputColorSpace,
27644
+ samples: attributes.antialias ? 4 : 0
27645
+ };
27646
+
27647
+ if ( scope.isMultiview ) {
27648
+
27649
+ const extension = extensions.get( 'OCULUS_multiview' );
27650
+
27651
+ this.maxNumViews = gl.getParameter( extension.MAX_VIEWS_OVR );
27652
+
27653
+ newRenderTarget = new WebGLMultiviewRenderTarget( glProjLayer.textureWidth, glProjLayer.textureHeight, 2, renderTargetOptions );
27654
+
27655
+ } else {
27656
+
27657
+ newRenderTarget = new WebGLRenderTarget(
27658
+ glProjLayer.textureWidth,
27659
+ glProjLayer.textureHeight,
27660
+ renderTargetOptions );
27661
+
27662
+ }
27278
27663
 
27279
27664
  const renderTargetProperties = renderer.properties.get( newRenderTarget );
27280
27665
  renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues;
@@ -28726,6 +29111,7 @@ class WebGLRenderer {
28726
29111
  preserveDrawingBuffer = false,
28727
29112
  powerPreference = 'default',
28728
29113
  failIfMajorPerformanceCaveat = false,
29114
+ multiviewStereo = false,
28729
29115
  } = parameters;
28730
29116
 
28731
29117
  this.isWebGLRenderer = true;
@@ -28960,6 +29346,7 @@ class WebGLRenderer {
28960
29346
  let extensions, capabilities, state, info;
28961
29347
  let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
28962
29348
  let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29349
+ let multiview;
28963
29350
 
28964
29351
  let background, morphtargets, bufferRenderer, indexedBufferRenderer;
28965
29352
 
@@ -28993,6 +29380,7 @@ class WebGLRenderer {
28993
29380
  renderLists = new WebGLRenderLists();
28994
29381
  renderStates = new WebGLRenderStates( extensions, capabilities );
28995
29382
  background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, premultipliedAlpha );
29383
+ multiview = new WebGLMultiview( _this, extensions, _gl );
28996
29384
  shadowMap = new WebGLShadowMap( _this, objects, capabilities );
28997
29385
  uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state );
28998
29386
 
@@ -29015,7 +29403,7 @@ class WebGLRenderer {
29015
29403
 
29016
29404
  // xr
29017
29405
 
29018
- const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this );
29406
+ const xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl, extensions, multiviewStereo ) : new WebVRManager( _this );
29019
29407
 
29020
29408
  this.xr = xr;
29021
29409
 
@@ -29762,13 +30150,23 @@ class WebGLRenderer {
29762
30150
 
29763
30151
  if ( camera.isArrayCamera ) {
29764
30152
 
29765
- const cameras = camera.cameras;
30153
+ if ( xr.enabled && xr.isMultiview ) {
30154
+
30155
+ textures.setDeferTextureUploads( true );
30156
+
30157
+ renderScene( currentRenderList, scene, camera, camera.cameras[ 0 ].viewport );
29766
30158
 
29767
- for ( let i = 0, l = cameras.length; i < l; i ++ ) {
30159
+ } else {
30160
+
30161
+ const cameras = camera.cameras;
29768
30162
 
29769
- const camera2 = cameras[ i ];
30163
+ for ( let i = 0, l = cameras.length; i < l; i ++ ) {
29770
30164
 
29771
- renderScene( currentRenderList, scene, camera2, camera2.viewport );
30165
+ const camera2 = cameras[ i ];
30166
+
30167
+ renderScene( currentRenderList, scene, camera2, camera2.viewport );
30168
+
30169
+ }
29772
30170
 
29773
30171
  }
29774
30172
 
@@ -29796,6 +30194,8 @@ class WebGLRenderer {
29796
30194
 
29797
30195
  if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );
29798
30196
 
30197
+ textures.runDeferredUploads();
30198
+
29799
30199
  if ( xr.enabled && xr.submitFrame ) {
29800
30200
 
29801
30201
  xr.submitFrame();
@@ -30263,6 +30663,7 @@ class WebGLRenderer {
30263
30663
  materialProperties.vertexAlphas = parameters.vertexAlphas;
30264
30664
  materialProperties.vertexTangents = parameters.vertexTangents;
30265
30665
  materialProperties.toneMapping = parameters.toneMapping;
30666
+ materialProperties.numMultiviewViews = parameters.numMultiviewViews;
30266
30667
 
30267
30668
  }
30268
30669
 
@@ -30294,6 +30695,8 @@ class WebGLRenderer {
30294
30695
 
30295
30696
  }
30296
30697
 
30698
+ const numMultiviewViews = _currentRenderTarget && _currentRenderTarget.isWebGLMultiviewRenderTarget ? _currentRenderTarget.numViews : 0;
30699
+
30297
30700
  const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
30298
30701
  const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
30299
30702
 
@@ -30397,6 +30800,10 @@ class WebGLRenderer {
30397
30800
 
30398
30801
  needsProgramChange = true;
30399
30802
 
30803
+ } else if ( materialProperties.numMultiviewViews !== numMultiviewViews ) {
30804
+
30805
+ needsProgramChange = true;
30806
+
30400
30807
  }
30401
30808
 
30402
30809
  } else {
@@ -30443,8 +30850,17 @@ class WebGLRenderer {
30443
30850
 
30444
30851
  // common camera uniforms
30445
30852
 
30446
- p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
30447
- p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
30853
+ if ( program.numMultiviewViews > 0 ) {
30854
+
30855
+ multiview.updateCameraProjectionMatricesUniform( camera, p_uniforms );
30856
+ multiview.updateCameraViewMatricesUniform( camera, p_uniforms );
30857
+
30858
+ } else {
30859
+
30860
+ p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
30861
+ p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
30862
+
30863
+ }
30448
30864
 
30449
30865
  const uCamPos = p_uniforms.map.cameraPosition;
30450
30866
 
@@ -30592,8 +31008,17 @@ class WebGLRenderer {
30592
31008
 
30593
31009
  // common matrices
30594
31010
 
30595
- p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
30596
- p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31011
+ if ( program.numMultiviewViews > 0 ) {
31012
+
31013
+ multiview.updateObjectMatricesUniforms( object, camera, p_uniforms );
31014
+
31015
+ } else {
31016
+
31017
+ p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
31018
+ p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
31019
+
31020
+ }
31021
+
30597
31022
  p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
30598
31023
 
30599
31024
  // UBOs
@@ -30703,20 +31128,16 @@ class WebGLRenderer {
30703
31128
  const renderTargetProperties = properties.get( renderTarget );
30704
31129
  renderTargetProperties.__hasExternalTextures = true;
30705
31130
 
30706
- if ( renderTargetProperties.__hasExternalTextures ) {
31131
+ renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30707
31132
 
30708
- renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
31133
+ if ( ! renderTargetProperties.__autoAllocateDepthBuffer && ! _currentRenderTarget.isWebGLMultiviewRenderTarget ) {
30709
31134
 
30710
- if ( ! renderTargetProperties.__autoAllocateDepthBuffer ) {
31135
+ // The multisample_render_to_texture extension doesn't work properly if there
31136
+ // are midframe flushes and an external depth buffer. Disable use of the extension.
31137
+ if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
30711
31138
 
30712
- // The multisample_render_to_texture extension doesn't work properly if there
30713
- // are midframe flushes and an external depth buffer. Disable use of the extension.
30714
- if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
30715
-
30716
- console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
30717
- renderTargetProperties.__useRenderToTexture = false;
30718
-
30719
- }
31139
+ console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );
31140
+ renderTargetProperties.__useRenderToTexture = false;
30720
31141
 
30721
31142
  }
30722
31143