super-three 0.163.0 → 0.164.0

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.
Files changed (114) hide show
  1. package/build/three.cjs +473 -245
  2. package/build/three.module.js +473 -245
  3. package/build/three.module.min.js +2 -2
  4. package/examples/jsm/animation/CCDIKSolver.js +4 -2
  5. package/examples/jsm/exporters/GLTFExporter.js +45 -1
  6. package/examples/jsm/exporters/USDZExporter.js +7 -1
  7. package/examples/jsm/libs/draco/README.md +2 -2
  8. package/examples/jsm/loaders/EXRLoader.js +283 -99
  9. package/examples/jsm/loaders/GLTFLoader.js +53 -0
  10. package/examples/jsm/loaders/KTX2Loader.js +3 -6
  11. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  12. package/examples/jsm/loaders/lwo/IFFParser.js +8 -5
  13. package/examples/jsm/materials/MeshGouraudMaterial.js +7 -1
  14. package/examples/jsm/math/Octree.js +26 -20
  15. package/examples/jsm/nodes/Nodes.js +4 -3
  16. package/examples/jsm/nodes/accessors/AccessorsUtils.js +16 -1
  17. package/examples/jsm/nodes/accessors/ClippingNode.js +3 -2
  18. package/examples/jsm/nodes/accessors/MaterialNode.js +107 -3
  19. package/examples/jsm/nodes/accessors/StorageBufferNode.js +9 -0
  20. package/examples/jsm/nodes/accessors/TextureNode.js +21 -3
  21. package/examples/jsm/nodes/accessors/TextureSizeNode.js +1 -1
  22. package/examples/jsm/nodes/code/FunctionNode.js +0 -8
  23. package/examples/jsm/nodes/core/Node.js +8 -0
  24. package/examples/jsm/nodes/core/NodeBuilder.js +5 -9
  25. package/examples/jsm/nodes/core/OutputStructNode.js +2 -1
  26. package/examples/jsm/nodes/core/PropertyNode.js +10 -0
  27. package/examples/jsm/nodes/display/BumpMapNode.js +7 -26
  28. package/examples/jsm/nodes/display/FrontFacingNode.js +13 -0
  29. package/examples/jsm/nodes/display/ViewportDepthNode.js +1 -1
  30. package/examples/jsm/nodes/display/ViewportNode.js +4 -2
  31. package/examples/jsm/nodes/display/ViewportTextureNode.js +4 -1
  32. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +26 -7
  33. package/examples/jsm/nodes/functions/BSDF/D_GGX_Anisotropic.js +28 -0
  34. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -3
  35. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +29 -0
  36. package/examples/jsm/nodes/functions/PhongLightingModel.js +1 -1
  37. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +164 -10
  38. package/examples/jsm/nodes/functions/ShadowMaskModel.js +31 -0
  39. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +18 -4
  40. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -1
  41. package/examples/jsm/nodes/lighting/EnvironmentNode.js +11 -2
  42. package/examples/jsm/nodes/lighting/IrradianceNode.js +24 -0
  43. package/examples/jsm/nodes/lighting/LightsNode.js +11 -1
  44. package/examples/jsm/nodes/lighting/PointLightNode.js +2 -1
  45. package/examples/jsm/nodes/lighting/SpotLightNode.js +2 -1
  46. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +10 -6
  47. package/examples/jsm/nodes/materials/Materials.js +1 -0
  48. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -2
  49. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  50. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +76 -5
  51. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +11 -4
  52. package/examples/jsm/nodes/materials/NodeMaterial.js +31 -41
  53. package/examples/jsm/nodes/materials/ShadowNodeMaterial.js +34 -0
  54. package/examples/jsm/nodes/pmrem/PMREMUtils.js +1 -1
  55. package/examples/jsm/nodes/shadernode/ShaderNode.js +2 -8
  56. package/examples/jsm/physics/JoltPhysics.js +281 -0
  57. package/examples/jsm/postprocessing/RenderTransitionPass.js +193 -0
  58. package/examples/jsm/renderers/common/Background.js +3 -3
  59. package/examples/jsm/renderers/common/ClippingContext.js +1 -1
  60. package/examples/jsm/renderers/common/RenderList.js +1 -1
  61. package/examples/jsm/renderers/common/RenderObject.js +43 -1
  62. package/examples/jsm/renderers/common/Renderer.js +129 -14
  63. package/examples/jsm/renderers/common/Textures.js +1 -1
  64. package/examples/jsm/renderers/common/extras/PMREMGenerator.js +13 -17
  65. package/examples/jsm/renderers/common/nodes/Nodes.js +31 -47
  66. package/examples/jsm/renderers/webgl/WebGLBackend.js +7 -21
  67. package/examples/jsm/renderers/webgl/WebGLBufferRenderer.js +5 -1
  68. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +6 -0
  69. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +21 -7
  70. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -21
  71. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +33 -45
  72. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +16 -1
  73. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -1
  74. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  75. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  76. package/examples/jsm/utils/SceneUtils.js +60 -1
  77. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  78. package/examples/jsm/webxr/XRHandModelFactory.js +4 -2
  79. package/package.json +1 -1
  80. package/src/constants.js +1 -1
  81. package/src/core/RenderTarget.js +8 -0
  82. package/src/extras/PMREMGenerator.js +12 -11
  83. package/src/loaders/FileLoader.js +1 -1
  84. package/src/loaders/MaterialLoader.js +1 -0
  85. package/src/materials/Material.js +2 -0
  86. package/src/materials/MeshPhysicalMaterial.js +20 -0
  87. package/src/objects/BatchedMesh.js +23 -0
  88. package/src/objects/Line.js +66 -43
  89. package/src/renderers/WebGLRenderer.js +92 -61
  90. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  91. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -0
  92. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +17 -9
  93. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  94. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +47 -13
  95. package/src/renderers/shaders/ShaderChunk.js +0 -2
  96. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  97. package/src/renderers/shaders/ShaderLib.js +1 -0
  98. package/src/renderers/webgl/WebGLBackground.js +18 -3
  99. package/src/renderers/webgl/WebGLBufferRenderer.js +36 -0
  100. package/src/renderers/webgl/WebGLCapabilities.js +33 -1
  101. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +36 -0
  102. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  103. package/src/renderers/webgl/WebGLProgram.js +3 -5
  104. package/src/renderers/webgl/WebGLPrograms.js +5 -0
  105. package/src/renderers/webgl/WebGLRenderStates.js +6 -2
  106. package/src/renderers/webgl/WebGLShadowMap.js +25 -25
  107. package/src/renderers/webgl/WebGLTextures.js +68 -60
  108. package/src/renderers/webgl/WebGLUtils.js +3 -21
  109. package/src/renderers/webxr/WebXRManager.js +2 -4
  110. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +0 -318
  111. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +0 -26
  112. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +0 -792
  113. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +0 -51
  114. package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +0 -10
@@ -7,12 +7,16 @@ import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
7
7
  import { BufferGeometry } from '../core/BufferGeometry.js';
8
8
  import { Float32BufferAttribute } from '../core/BufferAttribute.js';
9
9
 
10
- const _start = /*@__PURE__*/ new Vector3();
11
- const _end = /*@__PURE__*/ new Vector3();
10
+ const _vStart = /*@__PURE__*/ new Vector3();
11
+ const _vEnd = /*@__PURE__*/ new Vector3();
12
+
12
13
  const _inverseMatrix = /*@__PURE__*/ new Matrix4();
13
14
  const _ray = /*@__PURE__*/ new Ray();
14
15
  const _sphere = /*@__PURE__*/ new Sphere();
15
16
 
17
+ const _intersectPointOnRay = /*@__PURE__*/ new Vector3();
18
+ const _intersectPointOnSegment = /*@__PURE__*/ new Vector3();
19
+
16
20
  class Line extends Object3D {
17
21
 
18
22
  constructor( geometry = new BufferGeometry(), material = new LineBasicMaterial() ) {
@@ -54,11 +58,11 @@ class Line extends Object3D {
54
58
 
55
59
  for ( let i = 1, l = positionAttribute.count; i < l; i ++ ) {
56
60
 
57
- _start.fromBufferAttribute( positionAttribute, i - 1 );
58
- _end.fromBufferAttribute( positionAttribute, i );
61
+ _vStart.fromBufferAttribute( positionAttribute, i - 1 );
62
+ _vEnd.fromBufferAttribute( positionAttribute, i );
59
63
 
60
64
  lineDistances[ i ] = lineDistances[ i - 1 ];
61
- lineDistances[ i ] += _start.distanceTo( _end );
65
+ lineDistances[ i ] += _vStart.distanceTo( _vEnd );
62
66
 
63
67
  }
64
68
 
@@ -99,10 +103,6 @@ class Line extends Object3D {
99
103
  const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
100
104
  const localThresholdSq = localThreshold * localThreshold;
101
105
 
102
- const vStart = new Vector3();
103
- const vEnd = new Vector3();
104
- const interSegment = new Vector3();
105
- const interRay = new Vector3();
106
106
  const step = this.isLineSegments ? 2 : 1;
107
107
 
108
108
  const index = geometry.index;
@@ -119,31 +119,28 @@ class Line extends Object3D {
119
119
  const a = index.getX( i );
120
120
  const b = index.getX( i + 1 );
121
121
 
122
- vStart.fromBufferAttribute( positionAttribute, a );
123
- vEnd.fromBufferAttribute( positionAttribute, b );
122
+ const intersect = checkIntersection( this, raycaster, _ray, localThresholdSq, a, b );
123
+
124
+ if ( intersect ) {
124
125
 
125
- const distSq = _ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
126
+ intersects.push( intersect );
126
127
 
127
- if ( distSq > localThresholdSq ) continue;
128
+ }
129
+
130
+ }
128
131
 
129
- interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
132
+ if ( this.isLineLoop ) {
130
133
 
131
- const distance = raycaster.ray.origin.distanceTo( interRay );
134
+ const a = index.getX( end - 1 );
135
+ const b = index.getX( start );
132
136
 
133
- if ( distance < raycaster.near || distance > raycaster.far ) continue;
137
+ const intersect = checkIntersection( this, raycaster, _ray, localThresholdSq, a, b );
134
138
 
135
- intersects.push( {
139
+ if ( intersect ) {
136
140
 
137
- distance: distance,
138
- // What do we want? intersection point on the ray or on the segment??
139
- // point: raycaster.ray.at( distance ),
140
- point: interSegment.clone().applyMatrix4( this.matrixWorld ),
141
- index: i,
142
- face: null,
143
- faceIndex: null,
144
- object: this
141
+ intersects.push( intersect );
145
142
 
146
- } );
143
+ }
147
144
 
148
145
  }
149
146
 
@@ -154,31 +151,25 @@ class Line extends Object3D {
154
151
 
155
152
  for ( let i = start, l = end - 1; i < l; i += step ) {
156
153
 
157
- vStart.fromBufferAttribute( positionAttribute, i );
158
- vEnd.fromBufferAttribute( positionAttribute, i + 1 );
154
+ const intersect = checkIntersection( this, raycaster, _ray, localThresholdSq, i, i + 1 );
155
+
156
+ if ( intersect ) {
159
157
 
160
- const distSq = _ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
158
+ intersects.push( intersect );
161
159
 
162
- if ( distSq > localThresholdSq ) continue;
160
+ }
163
161
 
164
- interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
162
+ }
165
163
 
166
- const distance = raycaster.ray.origin.distanceTo( interRay );
164
+ if ( this.isLineLoop ) {
167
165
 
168
- if ( distance < raycaster.near || distance > raycaster.far ) continue;
166
+ const intersect = checkIntersection( this, raycaster, _ray, localThresholdSq, end - 1, start );
169
167
 
170
- intersects.push( {
168
+ if ( intersect ) {
171
169
 
172
- distance: distance,
173
- // What do we want? intersection point on the ray or on the segment??
174
- // point: raycaster.ray.at( distance ),
175
- point: interSegment.clone().applyMatrix4( this.matrixWorld ),
176
- index: i,
177
- face: null,
178
- faceIndex: null,
179
- object: this
170
+ intersects.push( intersect );
180
171
 
181
- } );
172
+ }
182
173
 
183
174
  }
184
175
 
@@ -219,4 +210,36 @@ class Line extends Object3D {
219
210
 
220
211
  }
221
212
 
213
+ function checkIntersection( object, raycaster, ray, thresholdSq, a, b ) {
214
+
215
+ const positionAttribute = object.geometry.attributes.position;
216
+
217
+ _vStart.fromBufferAttribute( positionAttribute, a );
218
+ _vEnd.fromBufferAttribute( positionAttribute, b );
219
+
220
+ const distSq = ray.distanceSqToSegment( _vStart, _vEnd, _intersectPointOnRay, _intersectPointOnSegment );
221
+
222
+ if ( distSq > thresholdSq ) return;
223
+
224
+ _intersectPointOnRay.applyMatrix4( object.matrixWorld ); // Move back to world space for distance calculation
225
+
226
+ const distance = raycaster.ray.origin.distanceTo( _intersectPointOnRay );
227
+
228
+ if ( distance < raycaster.near || distance > raycaster.far ) return;
229
+
230
+ return {
231
+
232
+ distance: distance,
233
+ // What do we want? intersection point on the ray or on the segment??
234
+ // point: raycaster.ray.at( distance ),
235
+ point: _intersectPointOnSegment.clone().applyMatrix4( object.matrixWorld ),
236
+ index: a,
237
+ face: null,
238
+ faceIndex: null,
239
+ object: object
240
+
241
+ };
242
+
243
+ }
244
+
222
245
  export { Line };
@@ -3,9 +3,7 @@ import {
3
3
  BackSide,
4
4
  FrontSide,
5
5
  DoubleSide,
6
- RGBAFormat,
7
6
  HalfFloatType,
8
- FloatType,
9
7
  UnsignedByteType,
10
8
  NoToneMapping,
11
9
  LinearMipmapLinearFilter,
@@ -26,7 +24,6 @@ import {
26
24
  import { Color } from '../math/Color.js';
27
25
  import { Frustum } from '../math/Frustum.js';
28
26
  import { Matrix4 } from '../math/Matrix4.js';
29
- import { Vector2 } from '../math/Vector2.js';
30
27
  import { Vector3 } from '../math/Vector3.js';
31
28
  import { Vector4 } from '../math/Vector4.js';
32
29
  import { WebGLAnimation } from './webgl/WebGLAnimation.js';
@@ -208,7 +205,6 @@ class WebGLRenderer {
208
205
 
209
206
  const _projScreenMatrix = new Matrix4();
210
207
 
211
- const _vector2 = new Vector2();
212
208
  const _vector3 = new Vector3();
213
209
 
214
210
  const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };
@@ -225,10 +221,7 @@ class WebGLRenderer {
225
221
 
226
222
  function getContext( contextName, contextAttributes ) {
227
223
 
228
- const context = canvas.getContext( contextName, contextAttributes );
229
- if ( context !== null ) return context;
230
-
231
- return null;
224
+ return canvas.getContext( contextName, contextAttributes );
232
225
 
233
226
  }
234
227
 
@@ -296,10 +289,10 @@ class WebGLRenderer {
296
289
  extensions = new WebGLExtensions( _gl );
297
290
  extensions.init();
298
291
 
299
- capabilities = new WebGLCapabilities( _gl, extensions, parameters );
300
-
301
292
  utils = new WebGLUtils( _gl, extensions );
302
293
 
294
+ capabilities = new WebGLCapabilities( _gl, extensions, parameters, utils );
295
+
303
296
  state = new WebGLState( _gl );
304
297
 
305
298
  info = new WebGLInfo( _gl );
@@ -865,7 +858,15 @@ class WebGLRenderer {
865
858
 
866
859
  if ( object.isBatchedMesh ) {
867
860
 
868
- renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
861
+ if ( object._multiDrawInstances !== null ) {
862
+
863
+ renderer.renderMultiDrawInstances( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances );
864
+
865
+ } else {
866
+
867
+ renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
868
+
869
+ }
869
870
 
870
871
  } else if ( object.isInstancedMesh ) {
871
872
 
@@ -915,7 +916,7 @@ class WebGLRenderer {
915
916
  if ( targetScene === null ) targetScene = scene;
916
917
 
917
918
  currentRenderState = renderStates.get( targetScene );
918
- currentRenderState.init();
919
+ currentRenderState.init( camera );
919
920
 
920
921
  renderStateStack.push( currentRenderState );
921
922
 
@@ -1132,7 +1133,7 @@ class WebGLRenderer {
1132
1133
  if ( scene.isScene === true ) scene.onBeforeRender( _this, scene, camera, _currentRenderTarget );
1133
1134
 
1134
1135
  currentRenderState = renderStates.get( scene, renderStateStack.length );
1135
- currentRenderState.init();
1136
+ currentRenderState.init( camera );
1136
1137
 
1137
1138
  renderStateStack.push( currentRenderState );
1138
1139
 
@@ -1157,6 +1158,13 @@ class WebGLRenderer {
1157
1158
 
1158
1159
  }
1159
1160
 
1161
+ const renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
1162
+ if ( renderBackground ) {
1163
+
1164
+ background.addToRenderList( currentRenderList, scene );
1165
+
1166
+ }
1167
+
1160
1168
  //
1161
1169
 
1162
1170
  this.info.render.frame ++;
@@ -1173,20 +1181,30 @@ class WebGLRenderer {
1173
1181
 
1174
1182
  if ( this.info.autoReset === true ) this.info.reset();
1175
1183
 
1184
+ // render scene
1176
1185
 
1177
- //
1186
+ const opaqueObjects = currentRenderList.opaque;
1187
+ const transmissiveObjects = currentRenderList.transmissive;
1178
1188
 
1179
- if ( xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false ) {
1189
+ currentRenderState.setupLights( _this._useLegacyLights );
1180
1190
 
1181
- background.render( currentRenderList, scene );
1191
+ if ( camera.isArrayCamera ) {
1182
1192
 
1183
- }
1193
+ const cameras = camera.cameras;
1184
1194
 
1185
- // render scene
1195
+ if ( transmissiveObjects.length > 0 ) {
1186
1196
 
1187
- currentRenderState.setupLights( _this._useLegacyLights );
1197
+ for ( let i = 0, l = cameras.length; i < l; i ++ ) {
1188
1198
 
1189
- if ( camera.isArrayCamera ) {
1199
+ const camera2 = cameras[ i ];
1200
+
1201
+ renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera2 );
1202
+
1203
+ }
1204
+
1205
+ }
1206
+
1207
+ if ( renderBackground ) background.render( scene );
1190
1208
 
1191
1209
  if ( xr.enabled && xr.isMultiview ) {
1192
1210
 
@@ -1196,8 +1214,6 @@ class WebGLRenderer {
1196
1214
 
1197
1215
  } else {
1198
1216
 
1199
- const cameras = camera.cameras;
1200
-
1201
1217
  for ( let i = 0, l = cameras.length; i < l; i ++ ) {
1202
1218
 
1203
1219
  const camera2 = cameras[ i ];
@@ -1210,6 +1226,10 @@ class WebGLRenderer {
1210
1226
 
1211
1227
  } else {
1212
1228
 
1229
+ if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera );
1230
+
1231
+ if ( renderBackground ) background.render( scene );
1232
+
1213
1233
  renderScene( currentRenderList, scene, camera );
1214
1234
 
1215
1235
  }
@@ -1251,6 +1271,8 @@ class WebGLRenderer {
1251
1271
 
1252
1272
  currentRenderState = renderStateStack[ renderStateStack.length - 1 ];
1253
1273
 
1274
+ if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, currentRenderState.state.camera );
1275
+
1254
1276
  } else {
1255
1277
 
1256
1278
  currentRenderState = null;
@@ -1395,8 +1417,6 @@ class WebGLRenderer {
1395
1417
 
1396
1418
  if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, camera );
1397
1419
 
1398
- if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera );
1399
-
1400
1420
  if ( viewport ) state.viewport( _currentViewport.copy( viewport ) );
1401
1421
 
1402
1422
  if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
@@ -1423,19 +1443,18 @@ class WebGLRenderer {
1423
1443
 
1424
1444
  }
1425
1445
 
1426
- if ( currentRenderState.state.transmissionRenderTarget === null ) {
1446
+ if ( currentRenderState.state.transmissionRenderTarget[ camera.id ] === undefined ) {
1427
1447
 
1428
- currentRenderState.state.transmissionRenderTarget = new WebGLRenderTarget( 1, 1, {
1448
+ currentRenderState.state.transmissionRenderTarget[ camera.id ] = new WebGLRenderTarget( 1, 1, {
1429
1449
  generateMipmaps: true,
1430
1450
  type: ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType,
1431
1451
  minFilter: LinearMipmapLinearFilter,
1432
1452
  samples: 4,
1433
- stencilBuffer: stencil
1453
+ stencilBuffer: stencil,
1454
+ resolveDepthBuffer: false,
1455
+ resolveStencilBuffer: false
1434
1456
  } );
1435
1457
 
1436
- const renderTargetProperties = properties.get( currentRenderState.state.transmissionRenderTarget );
1437
- renderTargetProperties.__isTransmissionRenderTarget = true;
1438
-
1439
1458
  // debug
1440
1459
 
1441
1460
  /*
@@ -1448,10 +1467,10 @@ class WebGLRenderer {
1448
1467
 
1449
1468
  }
1450
1469
 
1451
- const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget;
1470
+ const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget[ camera.id ];
1452
1471
 
1453
- _this.getDrawingBufferSize( _vector2 );
1454
- transmissionRenderTarget.setSize( _vector2.x, _vector2.y );
1472
+ const activeViewport = camera.viewport || _currentViewport;
1473
+ transmissionRenderTarget.setSize( activeViewport.z, activeViewport.w );
1455
1474
 
1456
1475
  //
1457
1476
 
@@ -1469,44 +1488,57 @@ class WebGLRenderer {
1469
1488
  const currentToneMapping = _this.toneMapping;
1470
1489
  _this.toneMapping = NoToneMapping;
1471
1490
 
1491
+ // Remove viewport from camera to avoid nested render calls resetting viewport to it (e.g Reflector).
1492
+ // Transmission render pass requires viewport to match the transmissionRenderTarget.
1493
+ const currentCameraViewport = camera.viewport;
1494
+ if ( camera.viewport !== undefined ) camera.viewport = undefined;
1495
+
1496
+ currentRenderState.setupLightsView( camera );
1497
+
1498
+ if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, camera );
1499
+
1472
1500
  renderObjects( opaqueObjects, scene, camera );
1473
1501
 
1474
1502
  textures.updateMultisampleRenderTarget( transmissionRenderTarget );
1475
1503
  textures.updateRenderTargetMipmap( transmissionRenderTarget );
1476
1504
 
1477
- let renderTargetNeedsUpdate = false;
1505
+ if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === false ) { // see #28131
1478
1506
 
1479
- for ( let i = 0, l = transmissiveObjects.length; i < l; i ++ ) {
1507
+ let renderTargetNeedsUpdate = false;
1480
1508
 
1481
- const renderItem = transmissiveObjects[ i ];
1509
+ for ( let i = 0, l = transmissiveObjects.length; i < l; i ++ ) {
1482
1510
 
1483
- const object = renderItem.object;
1484
- const geometry = renderItem.geometry;
1485
- const material = renderItem.material;
1486
- const group = renderItem.group;
1511
+ const renderItem = transmissiveObjects[ i ];
1487
1512
 
1488
- if ( material.side === DoubleSide && object.layers.test( camera.layers ) ) {
1513
+ const object = renderItem.object;
1514
+ const geometry = renderItem.geometry;
1515
+ const material = renderItem.material;
1516
+ const group = renderItem.group;
1489
1517
 
1490
- const currentSide = material.side;
1518
+ if ( material.side === DoubleSide && object.layers.test( camera.layers ) ) {
1491
1519
 
1492
- material.side = BackSide;
1493
- material.needsUpdate = true;
1520
+ const currentSide = material.side;
1494
1521
 
1495
- renderObject( object, scene, camera, geometry, material, group );
1522
+ material.side = BackSide;
1523
+ material.needsUpdate = true;
1524
+
1525
+ renderObject( object, scene, camera, geometry, material, group );
1496
1526
 
1497
- material.side = currentSide;
1498
- material.needsUpdate = true;
1527
+ material.side = currentSide;
1528
+ material.needsUpdate = true;
1499
1529
 
1500
- renderTargetNeedsUpdate = true;
1530
+ renderTargetNeedsUpdate = true;
1531
+
1532
+ }
1501
1533
 
1502
1534
  }
1503
1535
 
1504
- }
1536
+ if ( renderTargetNeedsUpdate === true ) {
1505
1537
 
1506
- if ( renderTargetNeedsUpdate === true ) {
1538
+ textures.updateMultisampleRenderTarget( transmissionRenderTarget );
1539
+ textures.updateRenderTargetMipmap( transmissionRenderTarget );
1507
1540
 
1508
- textures.updateMultisampleRenderTarget( transmissionRenderTarget );
1509
- textures.updateRenderTargetMipmap( transmissionRenderTarget );
1541
+ }
1510
1542
 
1511
1543
  }
1512
1544
 
@@ -1514,6 +1546,8 @@ class WebGLRenderer {
1514
1546
 
1515
1547
  _this.setClearColor( _currentClearColor, _currentClearAlpha );
1516
1548
 
1549
+ if ( currentCameraViewport !== undefined ) camera.viewport = currentCameraViewport;
1550
+
1517
1551
  _this.toneMapping = currentToneMapping;
1518
1552
 
1519
1553
  }
@@ -2061,7 +2095,7 @@ class WebGLRenderer {
2061
2095
 
2062
2096
  }
2063
2097
 
2064
- materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget );
2098
+ materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[ camera.id ] );
2065
2099
 
2066
2100
  WebGLUniforms.upload( _gl, getUniformList( materialProperties ), m_uniforms, textures );
2067
2101
 
@@ -2361,17 +2395,14 @@ class WebGLRenderer {
2361
2395
  const textureFormat = texture.format;
2362
2396
  const textureType = texture.type;
2363
2397
 
2364
- if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2398
+ if ( ! capabilities.textureFormatReadable( textureFormat ) ) {
2365
2399
 
2366
2400
  console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
2367
2401
  return;
2368
2402
 
2369
2403
  }
2370
2404
 
2371
- const halfFloatSupportedByExt = ( textureType === HalfFloatType ) && ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) );
2372
-
2373
- if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // Edge and Chrome Mac < 52 (#9513)
2374
- textureType !== FloatType && ! halfFloatSupportedByExt ) {
2405
+ if ( ! capabilities.textureTypeReadable( textureType ) ) {
2375
2406
 
2376
2407
  console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
2377
2408
  return;
@@ -2455,9 +2486,9 @@ class WebGLRenderer {
2455
2486
 
2456
2487
  this.copyTextureToTexture3D = function ( sourceBox, position, srcTexture, dstTexture, level = 0 ) {
2457
2488
 
2458
- const width = Math.round( sourceBox.max.x - sourceBox.min.x );
2459
- const height = Math.round( sourceBox.max.y - sourceBox.min.y );
2460
- const depth = sourceBox.max.z - sourceBox.min.z + 1;
2489
+ const width = sourceBox.max.x - sourceBox.min.x;
2490
+ const height = sourceBox.max.y - sourceBox.min.y;
2491
+ const depth = sourceBox.max.z - sourceBox.min.z;
2461
2492
  const glFormat = utils.convert( dstTexture.format );
2462
2493
  const glType = utils.convert( dstTexture.type );
2463
2494
  let glTarget;
@@ -75,6 +75,12 @@ material.roughness = min( material.roughness, 1.0 );
75
75
 
76
76
  #endif
77
77
 
78
+ #ifdef USE_DISPERSION
79
+
80
+ material.dispersion = dispersion;
81
+
82
+ #endif
83
+
78
84
  #ifdef USE_IRIDESCENCE
79
85
 
80
86
  material.iridescence = iridescence;
@@ -6,6 +6,7 @@ struct PhysicalMaterial {
6
6
  float roughness;
7
7
  vec3 specularColor;
8
8
  float specularF90;
9
+ float dispersion;
9
10
 
10
11
  #ifdef USE_CLEARCOAT
11
12
  float clearcoat;
@@ -168,24 +168,32 @@ vec3 AgXToneMapping( vec3 color ) {
168
168
  // https://modelviewer.dev/examples/tone-mapping
169
169
 
170
170
  vec3 NeutralToneMapping( vec3 color ) {
171
- float startCompression = 0.8 - 0.04;
172
- float desaturation = 0.15;
171
+
172
+ const float StartCompression = 0.8 - 0.04;
173
+ const float Desaturation = 0.15;
173
174
 
174
175
  color *= toneMappingExposure;
175
176
 
176
- float x = min(color.r, min(color.g, color.b));
177
+ float x = min( color.r, min( color.g, color.b ) );
178
+
177
179
  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
180
+
178
181
  color -= offset;
179
182
 
180
- float peak = max(color.r, max(color.g, color.b));
181
- if (peak < startCompression) return color;
183
+ float peak = max( color.r, max( color.g, color.b ) );
184
+
185
+ if ( peak < StartCompression ) return color;
186
+
187
+ float d = 1. - StartCompression;
188
+
189
+ float newPeak = 1. - d * d / ( peak + d - StartCompression );
182
190
 
183
- float d = 1. - startCompression;
184
- float newPeak = 1. - d * d / (peak + d - startCompression);
185
191
  color *= newPeak / peak;
186
192
 
187
- float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
188
- return mix(color, newPeak * vec3(1, 1, 1), g);
193
+ float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );
194
+
195
+ return mix( color, vec3( newPeak ), g );
196
+
189
197
  }
190
198
 
191
199
  vec3 CustomToneMapping( vec3 color ) { return color; }
@@ -25,7 +25,7 @@ export default /* glsl */`
25
25
 
26
26
  vec4 transmitted = getIBLVolumeRefraction(
27
27
  n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,
28
- pos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,
28
+ pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,
29
29
  material.attenuationColor, material.attenuationDistance );
30
30
 
31
31
  material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );
@@ -169,22 +169,56 @@ export default /* glsl */`
169
169
 
170
170
  vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,
171
171
  const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,
172
- const in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,
172
+ const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,
173
173
  const in vec3 attenuationColor, const in float attenuationDistance ) {
174
174
 
175
- vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );
176
- vec3 refractedRayExit = position + transmissionRay;
175
+ vec4 transmittedLight;
176
+ vec3 transmittance;
177
+
178
+ #ifdef USE_DISPERSION
179
+
180
+ float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;
181
+ vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );
182
+
183
+ for ( int i = 0; i < 3; i ++ ) {
184
+
185
+ vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );
186
+ vec3 refractedRayExit = position + transmissionRay;
187
+
188
+ // Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
189
+ vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
190
+ vec2 refractionCoords = ndcPos.xy / ndcPos.w;
191
+ refractionCoords += 1.0;
192
+ refractionCoords /= 2.0;
193
+
194
+ // Sample framebuffer to get pixel the refracted ray hits.
195
+ vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );
196
+ transmittedLight[ i ] = transmissionSample[ i ];
197
+ transmittedLight.a += transmissionSample.a;
198
+
199
+ transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];
200
+
201
+ }
202
+
203
+ transmittedLight.a /= 3.0;
204
+
205
+ #else
206
+
207
+ vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );
208
+ vec3 refractedRayExit = position + transmissionRay;
209
+
210
+ // Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
211
+ vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
212
+ vec2 refractionCoords = ndcPos.xy / ndcPos.w;
213
+ refractionCoords += 1.0;
214
+ refractionCoords /= 2.0;
215
+
216
+ // Sample framebuffer to get pixel the refracted ray hits.
217
+ transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
218
+ transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );
219
+
220
+ #endif
177
221
 
178
- // Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
179
- vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
180
- vec2 refractionCoords = ndcPos.xy / ndcPos.w;
181
- refractionCoords += 1.0;
182
- refractionCoords /= 2.0;
183
-
184
- // Sample framebuffer to get pixel the refracted ray hits.
185
- vec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
186
-
187
- vec3 transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );
188
222
  vec3 attenuatedColor = transmittance * transmittedLight.rgb;
189
223
 
190
224
  // Get the specular component.
@@ -40,7 +40,6 @@ import fog_pars_vertex from './ShaderChunk/fog_pars_vertex.glsl.js';
40
40
  import fog_fragment from './ShaderChunk/fog_fragment.glsl.js';
41
41
  import fog_pars_fragment from './ShaderChunk/fog_pars_fragment.glsl.js';
42
42
  import gradientmap_pars_fragment from './ShaderChunk/gradientmap_pars_fragment.glsl.js';
43
- import lightmap_fragment from './ShaderChunk/lightmap_fragment.glsl.js';
44
43
  import lightmap_pars_fragment from './ShaderChunk/lightmap_pars_fragment.glsl.js';
45
44
  import lights_lambert_fragment from './ShaderChunk/lights_lambert_fragment.glsl.js';
46
45
  import lights_lambert_pars_fragment from './ShaderChunk/lights_lambert_pars_fragment.glsl.js';
@@ -169,7 +168,6 @@ export const ShaderChunk = {
169
168
  fog_fragment: fog_fragment,
170
169
  fog_pars_fragment: fog_pars_fragment,
171
170
  gradientmap_pars_fragment: gradientmap_pars_fragment,
172
- lightmap_fragment: lightmap_fragment,
173
171
  lightmap_pars_fragment: lightmap_pars_fragment,
174
172
  lights_lambert_fragment: lights_lambert_fragment,
175
173
  lights_lambert_pars_fragment: lights_lambert_pars_fragment,
@@ -95,6 +95,10 @@ uniform float opacity;
95
95
  uniform float clearcoatRoughness;
96
96
  #endif
97
97
 
98
+ #ifdef USE_DISPERSION
99
+ uniform float dispersion;
100
+ #endif
101
+
98
102
  #ifdef USE_IRIDESCENCE
99
103
  uniform float iridescence;
100
104
  uniform float iridescenceIOR;