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