Mr.doob hai 1 ano
pai
achega
231731baff
Modificáronse 100 ficheiros con 5592 adicións e 6043 borrados
  1. 2847 3202
      build/three.cjs
  2. 2167 2257
      build/three.core.js
  3. 0 0
      build/three.core.min.js
  4. 0 0
      build/three.module.js
  5. 0 0
      build/three.module.min.js
  6. 5 5
      build/three.tsl.js
  7. 0 0
      build/three.tsl.min.js
  8. 0 0
      build/three.webgpu.js
  9. 0 0
      build/three.webgpu.min.js
  10. 0 0
      build/three.webgpu.nodes.js
  11. 0 0
      build/three.webgpu.nodes.min.js
  12. 1 1
      docs/api/ar/core/Layers.html
  13. 1 1
      docs/api/ar/lights/PointLight.html
  14. 1 7
      docs/api/ar/loaders/LoaderUtils.html
  15. 1 1
      docs/api/en/core/Layers.html
  16. 1 1
      docs/api/en/lights/PointLight.html
  17. 0 7
      docs/api/en/loaders/LoaderUtils.html
  18. 1 3
      docs/api/it/core/Layers.html
  19. 1 1
      docs/api/it/lights/PointLight.html
  20. 0 8
      docs/api/it/loaders/LoaderUtils.html
  21. 1 3
      docs/api/ko/core/Layers.html
  22. 1 1
      docs/api/zh/lights/PointLight.html
  23. 0 8
      docs/api/zh/loaders/LoaderUtils.html
  24. 10 0
      editor/js/Menubar.View.js
  25. 1 0
      editor/js/Viewport.Info.js
  26. 7 5
      examples/files.json
  27. 0 1
      examples/jsm/Addons.js
  28. 12 2
      examples/jsm/controls/ArcballControls.js
  29. 17 4
      examples/jsm/csm/CSMShadowNode.js
  30. 0 174
      examples/jsm/effects/PeppersGhostEffect.js
  31. 1 1
      examples/jsm/exporters/DRACOExporter.js
  32. 5 4
      examples/jsm/exporters/GLTFExporter.js
  33. 1 1
      examples/jsm/exporters/OBJExporter.js
  34. 2 2
      examples/jsm/exporters/PLYExporter.js
  35. 11 11
      examples/jsm/exporters/USDZExporter.js
  36. 4 4
      examples/jsm/helpers/TextureHelperGPU.js
  37. 6 0
      examples/jsm/interactive/HTMLMesh.js
  38. 3 4
      examples/jsm/lines/LineMaterial.js
  39. 4 4
      examples/jsm/loaders/ColladaLoader.js
  40. 1 1
      examples/jsm/loaders/DRACOLoader.js
  41. 22 21
      examples/jsm/loaders/FBXLoader.js
  42. 5 0
      examples/jsm/loaders/GLTFLoader.js
  43. 66 26
      examples/jsm/loaders/KTX2Loader.js
  44. 53 2
      examples/jsm/loaders/LDrawLoader.js
  45. 3 3
      examples/jsm/loaders/MTLLoader.js
  46. 121 19
      examples/jsm/loaders/PCDLoader.js
  47. 2 2
      examples/jsm/loaders/VRMLLoader.js
  48. 18 1
      examples/jsm/math/Octree.js
  49. 18 16
      examples/jsm/objects/SkyMesh.js
  50. 19 2
      examples/jsm/postprocessing/AfterimagePass.js
  51. 1 1
      examples/jsm/postprocessing/BloomPass.js
  52. 1 1
      examples/jsm/postprocessing/BokehPass.js
  53. 40 0
      examples/jsm/postprocessing/FXAAPass.js
  54. 1 1
      examples/jsm/postprocessing/GTAOPass.js
  55. 1 1
      examples/jsm/postprocessing/HalftonePass.js
  56. 1 1
      examples/jsm/postprocessing/OutlinePass.js
  57. 1 1
      examples/jsm/postprocessing/Pass.js
  58. 1 1
      examples/jsm/postprocessing/RenderPixelatedPass.js
  59. 1 1
      examples/jsm/postprocessing/RenderTransitionPass.js
  60. 1 1
      examples/jsm/postprocessing/SAOPass.js
  61. 1 1
      examples/jsm/postprocessing/SMAAPass.js
  62. 1 1
      examples/jsm/postprocessing/SSAARenderPass.js
  63. 1 1
      examples/jsm/postprocessing/SSAOPass.js
  64. 1 1
      examples/jsm/postprocessing/SSRPass.js
  65. 1 1
      examples/jsm/postprocessing/SavePass.js
  66. 1 1
      examples/jsm/postprocessing/UnrealBloomPass.js
  67. 2 2
      examples/jsm/tsl/display/FXAANode.js
  68. 1 27
      examples/jsm/tsl/display/GaussianBlurNode.js
  69. 8 8
      examples/jsm/tsl/display/SMAANode.js
  70. 2 2
      examples/jsm/tsl/display/TRAAPassNode.js
  71. 28 5
      examples/jsm/tsl/display/hashBlur.js
  72. 3 3
      examples/jsm/tsl/shadows/TileShadowNode.js
  73. 0 145
      examples/misc_lookat.html
  74. BIN=BIN
      examples/models/fbx/monkey.fbm/UVTexture.png
  75. BIN=BIN
      examples/models/fbx/monkey.fbx
  76. BIN=BIN
      examples/models/fbx/monkey_embedded_texture.fbx
  77. BIN=BIN
      examples/models/gltf/venice_mask.glb
  78. BIN=BIN
      examples/models/pcd/binary/Zaghetto_8bit.pcd
  79. 16 6
      examples/physics_ammo_instancing.html
  80. 21 8
      examples/physics_jolt_instancing.html
  81. 16 6
      examples/physics_rapier_instancing.html
  82. BIN=BIN
      examples/screenshots/misc_lookat.jpg
  83. BIN=BIN
      examples/screenshots/physics_jolt_instancing.jpg
  84. BIN=BIN
      examples/screenshots/webgl_effects_peppersghost.jpg
  85. BIN=BIN
      examples/screenshots/webgl_geometry_dynamic.jpg
  86. BIN=BIN
      examples/screenshots/webgl_instancing_dynamic.jpg
  87. BIN=BIN
      examples/screenshots/webgl_layers.jpg
  88. BIN=BIN
      examples/screenshots/webgl_lights_pointlights.jpg
  89. BIN=BIN
      examples/screenshots/webgl_loader_texture_ktx2.jpg
  90. BIN=BIN
      examples/screenshots/webgl_materials_normalmap.jpg
  91. BIN=BIN
      examples/screenshots/webgl_random_uv.jpg
  92. BIN=BIN
      examples/screenshots/webgl_tonemapping.jpg
  93. BIN=BIN
      examples/screenshots/webgpu_compute_cloth.jpg
  94. BIN=BIN
      examples/screenshots/webgpu_compute_particles.jpg
  95. BIN=BIN
      examples/screenshots/webgpu_compute_particles_fluid.jpg
  96. BIN=BIN
      examples/screenshots/webgpu_compute_water.jpg
  97. BIN=BIN
      examples/screenshots/webgpu_layers.jpg
  98. BIN=BIN
      examples/screenshots/webgpu_lights_pointlights.jpg
  99. BIN=BIN
      examples/screenshots/webgpu_lights_projector.jpg
  100. BIN=BIN
      examples/screenshots/webgpu_reflection_blurred.jpg

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2847 - 3202
build/three.cjs


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2167 - 2257
build/three.core.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.core.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.module.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.module.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 5 - 5
build/three.tsl.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.tsl.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.webgpu.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.webgpu.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.webgpu.nodes.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/three.webgpu.nodes.min.js


+ 1 - 1
docs/api/ar/core/Layers.html

@@ -25,7 +25,7 @@
 	 
 		<h2>أمثلة (Examples)</h2>
 	 
-		<p>[example:webgl_layers WebGL / layers]</p>
+		<p>[example:webgpu_layers WebGPU / layers]</p>
 	 
 		<h2>المنشئ (Constructor)</h2>
 	 

+ 1 - 1
docs/api/ar/lights/PointLight.html

@@ -30,7 +30,7 @@
 		<h2>أمثلة (Examples)</h2>
 			
 		<p>
-		[example:webgl_lights_pointlights lights / pointlights ]<br />
+		[example:webgpu_lights_pointlights lights / pointlights ]<br />
 		[example:webgl_effects_anaglyph effects / anaglyph ]<br />
 		[example:webgl_geometry_text geometry / text ]<br />
 		[example:webgl_lensflares lensflares ]

+ 1 - 7
docs/api/ar/loaders/LoaderUtils.html

@@ -12,13 +12,7 @@
 		<p class="desc">كائن يحتوي على العديد من وظائف المحمل المساعدة.</p>
 
 		<h2>الطرق (Methods)</h2>
-	 
-		<h3>[method:String decodeText]( [param:TypedArray array] )</h3>
-		<p>[page:TypedArray array] — تدفق بايتات كمصفوفة مكتوبة.</p>
-		<p>
-		تأخذ الوظيفة تدفق بايتات كمدخل وتعيد تمثيلًا للسلسلة
-		</p>
-	 
+	 	 
 		<h3>[method:String extractUrlBase]( [param:String url] )</h3>
 		<p>[page:String url] — عنوان url الذي سيتم استخراج العنوان الأساسي منه.</p>
 		<p>استخراج الأساس من عنوان URL.</p>

+ 1 - 1
docs/api/en/core/Layers.html

@@ -25,7 +25,7 @@
 
 		<h2>Examples</h2>
 
-		<p>[example:webgl_layers WebGL / layers]</p>
+		<p>[example:webgpu_layers WebGPU / layers]</p>
 
 		<h2>Constructor</h2>
 

+ 1 - 1
docs/api/en/lights/PointLight.html

@@ -31,7 +31,7 @@ scene.add( light );
 		<h2>Examples</h2>
 
 		<p>
-			[example:webgl_lights_pointlights lights / pointlights ]<br />
+			[example:webgpu_lights_pointlights lights / pointlights ]<br />
 			[example:webgl_effects_anaglyph effects / anaglyph ]<br />
 			[example:webgl_geometry_text geometry / text ]<br />
 			[example:webgl_lensflares lensflares ]

+ 0 - 7
docs/api/en/loaders/LoaderUtils.html

@@ -13,13 +13,6 @@
 
 		<h2>Functions</h2>
 
-		<h3>[method:String decodeText]( [param:TypedArray array] )</h3>
-		<p>[page:TypedArray array] — A stream of bytes as a typed array.</p>
-		<p>
-			The function takes a stream of bytes as input and returns a string
-			representation.
-		</p>
-
 		<h3>[method:String extractUrlBase]( [param:String url] )</h3>
 		<p>[page:String url] — The url to extract the base url from.</p>
 		<p>Extract the base from the URL.</p>

+ 1 - 3
docs/api/it/core/Layers.html

@@ -22,9 +22,7 @@
 
 		<h2>Esempi</h2>
 
-		<p>
-			[example:webgl_layers WebGL / layers]
-		</p>
+		<p>[example:webgpu_layers WebGPU / layers]</p>
 
 		<h2>Costruttore</h2>
 

+ 1 - 1
docs/api/it/lights/PointLight.html

@@ -29,7 +29,7 @@ scene.add( light );
 		<h2>Esempi</h2>
 
 		<p>
-			[example:webgl_lights_pointlights lights / pointlights ]<br />
+			[example:webgpu_lights_pointlights lights / pointlights ]<br />
 			[example:webgl_effects_anaglyph effects / anaglyph ]<br />
 			[example:webgl_geometry_text geometry / text ]<br />
 			[example:webgl_lensflares lensflares ]

+ 0 - 8
docs/api/it/loaders/LoaderUtils.html

@@ -13,14 +13,6 @@
 
 		<h2>Funzioni</h2>
 
-		<h3>[method:String decodeText]( [param:TypedArray array] )</h3>
-		<p>
-		[page:TypedArray array] —  Uno stream di byte come array tipizzato.
-		</p>
-		<p>
-      La funzione prende uno stream di byte in input e restituisce una rappresentazione di stringa.
-		</p>
-
 		<h3>[method:String extractUrlBase]( [param:String url] )</h3>
 		<p>
 		[page:String url] —  La url da cui estrarre la url di base.

+ 1 - 3
docs/api/ko/core/Layers.html

@@ -21,9 +21,7 @@
 
 		<h2>예제</h2>
 
-		<p>
-			[example:webgl_layers WebGL / layers]
-		</p>
+		<p>[example:webgpu_layers WebGPU / layers]</p>
 
 		<h2>생성자</h2>
 

+ 1 - 1
docs/api/zh/lights/PointLight.html

@@ -28,7 +28,7 @@
 		<h2>例子</h2>
 
 		<p>
-			[example:webgl_lights_pointlights lights / pointlights ]<br />
+			[example:webgpu_lights_pointlights lights / pointlights ]<br />
 			[example:webgl_effects_anaglyph effects / anaglyph ]<br />
 			[example:webgl_geometry_text geometry / text ]<br />
 			[example:webgl_lensflares lensflares ]

+ 0 - 8
docs/api/zh/loaders/LoaderUtils.html

@@ -13,14 +13,6 @@
 
 		<h2>函数</h2>
 
-		<h3>[method:String decodeText]( [param:TypedArray array] )</h3>
-		<p>
-		[page:TypedArray array] — 作为类型化数组的字节流
-		</p>
-		<p>
-			该函数将字节流作为输入并返回字符串作为表示。
-		</p>
-
 		<h3>[method:String extractUrlBase]( [param:String url] )</h3>
 		<p>
 		[page:String url] — 从基本URL中,进行提取的URL。

+ 10 - 0
editor/js/Menubar.View.js

@@ -84,6 +84,16 @@ function MenubarView( editor ) {
 
 	options.add( option );
 
+	// new helpers are visible by default, the global visibility state
+	// of helpers is managed in this component. every time a helper is added,
+	// we request a viewport updated by firing the showHelpersChanged signal.
+
+	signals.helperAdded.add( function () {
+
+		signals.showHelpersChanged.dispatch( states );
+
+	} );
+
 	//
 
 	options.add( new UIHorizontalRule() );

+ 1 - 0
editor/js/Viewport.Info.js

@@ -33,6 +33,7 @@ function ViewportInfo( editor ) {
 
 	signals.objectAdded.add( update );
 	signals.objectRemoved.add( update );
+	signals.objectChanged.add( update );
 	signals.geometryChanged.add( update );
 	signals.sceneRendered.add( updateFrametime );
 

+ 7 - 5
examples/files.json

@@ -19,7 +19,6 @@
 		"webgl_effects_anaglyph",
 		"webgl_effects_ascii",
 		"webgl_effects_parallaxbarrier",
-		"webgl_effects_peppersghost",
 		"webgl_effects_stereo",
 		"webgl_framebuffer_texture",
 		"webgl_geometries",
@@ -29,7 +28,6 @@
 		"webgl_geometry_convex",
 		"webgl_geometry_csg",
 		"webgl_geometry_cube",
-		"webgl_geometry_dynamic",
 		"webgl_geometry_extrude_shapes",
 		"webgl_geometry_extrude_splines",
 		"webgl_geometry_minecraft",
@@ -56,13 +54,11 @@
 		"webgl_interactive_points",
 		"webgl_interactive_raycasting_points",
 		"webgl_interactive_voxelpainter",
-		"webgl_layers",
 		"webgl_lensflares",
 		"webgl_lightprobe",
 		"webgl_lightprobe_cubecamera",
 		"webgl_lights_hemisphere",
 		"webgl_lights_physical",
-		"webgl_lights_pointlights",
 		"webgl_lights_spotlight",
 		"webgl_lights_spotlights",
 		"webgl_lights_rectarealight",
@@ -313,8 +309,10 @@
 		"webgpu_clipping",
 		"webgpu_compute_audio",
 		"webgpu_compute_birds",
+		"webgpu_compute_cloth",
 		"webgpu_compute_geometry",
 		"webgpu_compute_particles",
+		"webgpu_compute_particles_fluid",
 		"webgpu_compute_particles_rain",
 		"webgpu_compute_particles_snow",
 		"webgpu_compute_points",
@@ -335,6 +333,7 @@
 		"webgpu_instance_sprites",
 		"webgpu_instance_uniform",
 		"webgpu_instancing_morph",
+		"webgpu_layers",
 		"webgpu_lensflares",
 		"webgpu_lightprobe",
 		"webgpu_lightprobe_cubecamera",
@@ -342,6 +341,8 @@
 		"webgpu_lights_ies_spotlight",
 		"webgpu_lights_phong",
 		"webgpu_lights_physical",
+		"webgpu_lights_pointlights",
+		"webgpu_lights_projector",
 		"webgpu_lights_rectarealight",
 		"webgpu_lights_selective",
 		"webgpu_lights_spotlight",
@@ -415,6 +416,7 @@
 		"webgpu_postprocessing",
 		"webgpu_procedural_texture",
 		"webgpu_reflection",
+		"webgpu_reflection_blurred",
 		"webgpu_refraction",
 		"webgpu_rendertarget_2d-array_3d",
 		"webgpu_rtt",
@@ -460,6 +462,7 @@
 		"webgpu_volume_lighting_rectarea",
 		"webgpu_volume_perlin",
 		"webgpu_water",
+		"webgpu_xr_rollercoaster",
 		"webgpu_xr_cubes",
 		"webgpu_xr_native_layers"
 	],
@@ -535,7 +538,6 @@
 		"misc_exporter_usdz",
 		"misc_exporter_exr",
 		"misc_exporter_ktx2",
-		"misc_lookat",
 		"misc_raycaster_helper"
 	],
 	"css2d": [

+ 0 - 1
examples/jsm/Addons.js

@@ -28,7 +28,6 @@ export * from './effects/AnaglyphEffect.js';
 export * from './effects/AsciiEffect.js';
 export * from './effects/OutlineEffect.js';
 export * from './effects/ParallaxBarrierEffect.js';
-export * from './effects/PeppersGhostEffect.js';
 export * from './effects/StereoEffect.js';
 
 export * from './environments/DebugEnvironment.js';

+ 12 - 2
examples/jsm/controls/ArcballControls.js

@@ -196,6 +196,7 @@ class ArcballControls extends Controls {
 		this._farPos0 = 0;
 		this._cameraMatrixState0 = new Matrix4();
 		this._gizmoMatrixState0 = new Matrix4();
+		this._target0 = new Vector3();
 
 		//pointers array
 		this._button = - 1;
@@ -2229,6 +2230,7 @@ class ArcballControls extends Controls {
 	 */
 	reset() {
 
+		this.target.copy( this._target0 );
 		this.object.zoom = this._zoom0;
 
 		if ( this.object.isPerspectiveCamera ) {
@@ -2301,7 +2303,8 @@ class ArcballControls extends Controls {
 					cameraNear: this.object.near,
 					cameraUp: this.object.up,
 					cameraZoom: this.object.zoom,
-					gizmoMatrix: this._gizmos.matrix
+					gizmoMatrix: this._gizmos.matrix,
+					target: this.target
 
 				}
 			} );
@@ -2316,7 +2319,8 @@ class ArcballControls extends Controls {
 					cameraNear: this.object.near,
 					cameraUp: this.object.up,
 					cameraZoom: this.object.zoom,
-					gizmoMatrix: this._gizmos.matrix
+					gizmoMatrix: this._gizmos.matrix,
+					target: this.target
 
 				}
 			} );
@@ -2347,6 +2351,10 @@ class ArcballControls extends Controls {
 	 */
 	saveState() {
 
+		this.object.updateMatrix();
+		this._gizmos.updateMatrix();
+
+		this._target0.copy( this.target );
 		this._cameraMatrixState0.copy( this.object.matrix );
 		this._gizmoMatrixState0.copy( this._gizmos.matrix );
 		this._nearPos = this.object.near;
@@ -2947,6 +2955,8 @@ class ArcballControls extends Controls {
 
 		if ( state.arcballState != undefined ) {
 
+			this.target.fromArray( state.arcballState.target );
+
 			this._cameraMatrixState.fromArray( state.arcballState.cameraMatrix.elements );
 			this._cameraMatrixState.decompose( this.object.position, this.object.quaternion, this.object.scale );
 

+ 17 - 4
examples/jsm/csm/CSMShadowNode.js

@@ -163,7 +163,6 @@ class CSMShadowNode extends ShadowBaseNode {
 		this.mainFrustum = new CSMFrustum( data );
 
 		const light = this.light;
-		const parent = light.parent;
 
 		for ( let i = 0; i < this.cascades; i ++ ) {
 
@@ -175,9 +174,6 @@ class CSMShadowNode extends ShadowBaseNode {
 
 			this.lights.push( lwLight );
 
-			parent.add( lwLight );
-			parent.add( lwLight.target );
-
 			lwLight.shadow = lShadow;
 
 			this._shadowNodes.push( shadow( lwLight, lShadow ) );
@@ -503,9 +499,26 @@ class CSMShadowNode extends ShadowBaseNode {
 	updateBefore( /*builder*/ ) {
 
 		const light = this.light;
+		const parent = light.parent;
 		const camera = this.camera;
 		const frustums = this.frustums;
 
+		// make sure the placeholder light objects which represent the
+		// multiple cascade shadow casters are part of the scene graph
+
+		for ( let i = 0; i < this.lights.length; i ++ ) {
+
+			const lwLight = this.lights[ i ];
+
+			if ( lwLight.parent === null ) {
+
+				parent.add( lwLight.target );
+				parent.add( lwLight );
+
+			}
+
+		}
+
 		_lightDirection.subVectors( light.target.position, light.position ).normalize();
 
 		// for each frustum we need to find its min-max box aligned with the light orientation

+ 0 - 174
examples/jsm/effects/PeppersGhostEffect.js

@@ -1,174 +0,0 @@
-import {
-	PerspectiveCamera,
-	Quaternion,
-	Vector3
-} from 'three';
-
-/**
- * A class that implements a peppers ghost effect.
- *
- * Reference: [Reflective Prism]{@link http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS}
- *
- * @three_import import { PeppersGhostEffect } from 'three/addons/effects/PeppersGhostEffect.js';
- */
-class PeppersGhostEffect {
-
-	/**
-	 * Constructs a new peppers ghost effect.
-	 *
-	 * @param {(WebGPURenderer|WebGLRenderer)} renderer - The renderer.
-	 */
-	constructor( renderer ) {
-
-		const scope = this;
-
-		scope.cameraDistance = 15;
-		scope.reflectFromAbove = false;
-
-		// Internals
-		let _halfWidth, _width, _height;
-
-		const _cameraF = new PerspectiveCamera(); //front
-		const _cameraB = new PerspectiveCamera(); //back
-		const _cameraL = new PerspectiveCamera(); //left
-		const _cameraR = new PerspectiveCamera(); //right
-
-		const _position = new Vector3();
-		const _quaternion = new Quaternion();
-		const _scale = new Vector3();
-
-		// Initialization
-		renderer.autoClear = false;
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} width - The width of the effect in logical pixels.
-		 * @param {number} height - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( width, height ) {
-
-			_halfWidth = width / 2;
-			if ( width < height ) {
-
-				_width = width / 3;
-				_height = width / 3;
-
-			} else {
-
-				_width = height / 3;
-				_height = height / 3;
-
-			}
-
-			renderer.setSize( width, height );
-
-		};
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
-
-			if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
-			camera.matrixWorld.decompose( _position, _quaternion, _scale );
-
-			// front
-			_cameraF.position.copy( _position );
-			_cameraF.quaternion.copy( _quaternion );
-			_cameraF.translateZ( scope.cameraDistance );
-			_cameraF.lookAt( scene.position );
-
-			// back
-			_cameraB.position.copy( _position );
-			_cameraB.quaternion.copy( _quaternion );
-			_cameraB.translateZ( - ( scope.cameraDistance ) );
-			_cameraB.lookAt( scene.position );
-			_cameraB.rotation.z += 180 * ( Math.PI / 180 );
-
-			// left
-			_cameraL.position.copy( _position );
-			_cameraL.quaternion.copy( _quaternion );
-			_cameraL.translateX( - ( scope.cameraDistance ) );
-			_cameraL.lookAt( scene.position );
-			_cameraL.rotation.x += 90 * ( Math.PI / 180 );
-
-			// right
-			_cameraR.position.copy( _position );
-			_cameraR.quaternion.copy( _quaternion );
-			_cameraR.translateX( scope.cameraDistance );
-			_cameraR.lookAt( scene.position );
-			_cameraR.rotation.x += 90 * ( Math.PI / 180 );
-
-
-			renderer.clear();
-			renderer.setScissorTest( true );
-
-			renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
-			renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
-
-			if ( scope.reflectFromAbove ) {
-
-				renderer.render( scene, _cameraB );
-
-			} else {
-
-				renderer.render( scene, _cameraF );
-
-			}
-
-			renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
-			renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );
-
-			if ( scope.reflectFromAbove ) {
-
-				renderer.render( scene, _cameraF );
-
-			} else {
-
-				renderer.render( scene, _cameraB );
-
-			}
-
-			renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
-			renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
-
-			if ( scope.reflectFromAbove ) {
-
-				renderer.render( scene, _cameraR );
-
-			} else {
-
-				renderer.render( scene, _cameraL );
-
-			}
-
-			renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
-			renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );
-
-			if ( scope.reflectFromAbove ) {
-
-				renderer.render( scene, _cameraL );
-
-			} else {
-
-				renderer.render( scene, _cameraR );
-
-			}
-
-			renderer.setScissorTest( false );
-
-		};
-
-	}
-
-}
-
-export { PeppersGhostEffect };

+ 1 - 1
examples/jsm/exporters/DRACOExporter.js

@@ -241,7 +241,7 @@ function createVertexColorSRGBArray( attribute ) {
 
 		_color.fromBufferAttribute( attribute, i );
 
-		ColorManagement.fromWorkingColorSpace( _color, SRGBColorSpace );
+		ColorManagement.workingToColorSpace( _color, SRGBColorSpace );
 
 		array[ i * itemSize ] = _color.r;
 		array[ i * itemSize + 1 ] = _color.g;

+ 5 - 4
examples/jsm/exporters/GLTFExporter.js

@@ -2408,6 +2408,9 @@ class GLTFWriter {
 
 		if ( object.isSkinnedMesh ) this.skins.push( object );
 
+		const nodeIndex = json.nodes.push( nodeDef ) - 1;
+		nodeMap.set( object, nodeIndex );
+
 		if ( object.children.length > 0 ) {
 
 			const children = [];
@@ -2418,9 +2421,9 @@ class GLTFWriter {
 
 				if ( child.visible || options.onlyVisible === false ) {
 
-					const nodeIndex = await this.processNodeAsync( child );
+					const childNodeIndex = await this.processNodeAsync( child );
 
-					if ( nodeIndex !== null ) children.push( nodeIndex );
+					if ( childNodeIndex !== null ) children.push( childNodeIndex );
 
 				}
 
@@ -2436,8 +2439,6 @@ class GLTFWriter {
 
 		} );
 
-		const nodeIndex = json.nodes.push( nodeDef ) - 1;
-		nodeMap.set( object, nodeIndex );
 		return nodeIndex;
 
 	}

+ 1 - 1
examples/jsm/exporters/OBJExporter.js

@@ -250,7 +250,7 @@ class OBJExporter {
 
 						color.fromBufferAttribute( colors, i );
 
-						ColorManagement.fromWorkingColorSpace( color, SRGBColorSpace );
+						ColorManagement.workingToColorSpace( color, SRGBColorSpace );
 
 						output += ' ' + color.r + ' ' + color.g + ' ' + color.b;
 

+ 2 - 2
examples/jsm/exporters/PLYExporter.js

@@ -320,7 +320,7 @@ class PLYExporter {
 
 							tempColor.fromBufferAttribute( colors, i );
 
-							ColorManagement.fromWorkingColorSpace( tempColor, SRGBColorSpace );
+							ColorManagement.workingToColorSpace( tempColor, SRGBColorSpace );
 
 							output.setUint8( vOffset, Math.floor( tempColor.r * 255 ) );
 							vOffset += 1;
@@ -479,7 +479,7 @@ class PLYExporter {
 
 							tempColor.fromBufferAttribute( colors, i );
 
-							ColorManagement.fromWorkingColorSpace( tempColor, SRGBColorSpace );
+							ColorManagement.workingToColorSpace( tempColor, SRGBColorSpace );
 
 							line += ' ' +
 								Math.floor( tempColor.r * 255 ) + ' ' +

+ 11 - 11
examples/jsm/exporters/USDZExporter.js

@@ -315,16 +315,16 @@ function buildXform( object, geometry, material ) {
 
 	}
 
-	return `def Xform "${ name }" (
-	prepend references = @./geometries/Geometry_${ geometry.id }.usda@</Geometry>
-	prepend apiSchemas = ["MaterialBindingAPI"]
-)
-{
-	matrix4d xformOp:transform = ${ transform }
-	uniform token[] xformOpOrder = ["xformOp:transform"]
-
-	rel material:binding = </Materials/Material_${ material.id }>
-}
+	return `			def Xform "${ name }" (
+				prepend references = @./geometries/Geometry_${ geometry.id }.usda@</Geometry>
+				prepend apiSchemas = ["MaterialBindingAPI"]
+			)
+			{
+				matrix4d xformOp:transform = ${ transform }
+				uniform token[] xformOpOrder = ["xformOp:transform"]
+
+				rel material:binding = </Materials/Material_${ material.id }>
+			}
 
 `;
 
@@ -827,7 +827,7 @@ function buildCamera( camera ) {
  *
  * @typedef {Object} USDZExporter~Options
  * @property {number} [maxTextureSize=1024] - The maximum texture size that is going to be exported.
- * @property {boolean} [includeAnchoringProperties=false] - Whether to include anchoring properties or not.
+ * @property {boolean} [includeAnchoringProperties=true] - Whether to include anchoring properties or not.
  * @property {Object} [ar] - If `includeAnchoringProperties` is set to `true`, the anchoring type and alignment
  * can be configured via `ar.anchoring.type` and `ar.planeAnchoring.alignment`.
  * @property {boolean} [quickLookCompatible=false] - Whether to make the exported USDZ compatible to QuickLook

+ 4 - 4
examples/jsm/helpers/TextureHelperGPU.js

@@ -51,7 +51,7 @@ class TextureHelper extends Mesh {
 
 			colorNode = texture3D( texture ).sample( uvw );
 
-		} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+		} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
 
 			colorNode = textureNode( texture ).sample( uvw.xy ).depth( uvw.z );
 
@@ -100,7 +100,7 @@ function getImageCount( texture ) {
 
 		return 6;
 
-	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+	} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
 
 		return texture.image.depth;
 
@@ -122,7 +122,7 @@ function getAlpha( texture ) {
 
 		return 1;
 
-	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+	} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
 
 		return Math.max( 1 / texture.image.depth, 0.25 );
 
@@ -192,7 +192,7 @@ function createSliceGeometry( texture, width, height, depth ) {
 			const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
 			const w = sliceCount === 1
 				? 1
-				: texture.isDataArrayTexture || texture.isCompressedArrayTexture
+				: texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture
 					? i
 					: i / ( sliceCount - 1 );
 

+ 6 - 0
examples/jsm/interactive/HTMLMesh.js

@@ -578,6 +578,12 @@ function htmlevent( element, event, x, y ) {
 
 				}
 
+				if ( element instanceof HTMLInputElement && ( element.type === 'text' || element.type === 'number' ) && ( event === 'mousedown' || event === 'click' ) ) {
+
+					element.focus();
+
+				}
+
 			}
 
 			for ( let i = 0; i < element.childNodes.length; i ++ ) {

+ 3 - 4
examples/jsm/lines/LineMaterial.js

@@ -311,6 +311,9 @@ ShaderLib[ 'line' ] = {
 
 		void main() {
 
+			float alpha = opacity;
+			vec4 diffuseColor = vec4( diffuse, alpha );
+
 			#include <clipping_planes_fragment>
 
 			#ifdef USE_DASH
@@ -321,8 +324,6 @@ ShaderLib[ 'line' ] = {
 
 			#endif
 
-			float alpha = opacity;
-
 			#ifdef WORLD_UNITS
 
 				// Find the closest points on the view ray and the line segment
@@ -387,8 +388,6 @@ ShaderLib[ 'line' ] = {
 
 			#endif
 
-			vec4 diffuseColor = vec4( diffuse, alpha );
-
 			#include <logdepthbuf_fragment>
 			#include <color_fragment>
 

+ 4 - 4
examples/jsm/loaders/ColladaLoader.js

@@ -1718,9 +1718,9 @@ class ColladaLoader extends Loader {
 
 			}
 
-			ColorManagement.toWorkingColorSpace( material.color, SRGBColorSpace );
-			if ( material.specular ) ColorManagement.toWorkingColorSpace( material.specular, SRGBColorSpace );
-			if ( material.emissive ) ColorManagement.toWorkingColorSpace( material.emissive, SRGBColorSpace );
+			ColorManagement.colorSpaceToWorking( material.color, SRGBColorSpace );
+			if ( material.specular ) ColorManagement.colorSpaceToWorking( material.specular, SRGBColorSpace );
+			if ( material.emissive ) ColorManagement.colorSpaceToWorking( material.emissive, SRGBColorSpace );
 
 			//
 
@@ -2057,7 +2057,7 @@ class ColladaLoader extends Loader {
 					case 'color':
 						const array = parseFloats( child.textContent );
 						data.color = new Color().fromArray( array );
-						ColorManagement.toWorkingColorSpace( data.color, SRGBColorSpace );
+						ColorManagement.colorSpaceToWorking( data.color, SRGBColorSpace );
 						break;
 
 					case 'falloff_angle':

+ 1 - 1
examples/jsm/loaders/DRACOLoader.js

@@ -310,7 +310,7 @@ class DRACOLoader extends Loader {
 		for ( let i = 0, il = attribute.count; i < il; i ++ ) {
 
 			_color.fromBufferAttribute( attribute, i );
-			ColorManagement.toWorkingColorSpace( _color, SRGBColorSpace );
+			ColorManagement.colorSpaceToWorking( _color, SRGBColorSpace );
 			attribute.setXYZ( i, _color.r, _color.g, _color.b );
 
 		}

+ 22 - 21
examples/jsm/loaders/FBXLoader.js

@@ -348,6 +348,11 @@ class FBXTreeParser {
 				type = 'image/tga';
 				break;
 
+			case 'webp':
+
+				type = 'image/webp';
+				break;
+
 			default:
 
 				console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' );
@@ -437,21 +442,10 @@ class FBXTreeParser {
 	// load a texture specified as a blob or data URI, or via an external URL using TextureLoader
 	loadTexture( textureNode, images ) {
 
-		const nonNativeExtensions = new Set( [ 'tga', 'tif', 'tiff', 'exr', 'dds', 'hdr', 'ktx2' ] );
-
 		const extension = textureNode.FileName.split( '.' ).pop().toLowerCase();
 
-		const loader = nonNativeExtensions.has( extension ) ? this.manager.getHandler( `.${extension}` ) : this.textureLoader;
-
-		if ( ! loader ) {
-
-			console.warn(
-				`FBXLoader: ${extension.toUpperCase()} loader not found, creating placeholder texture for`,
-				textureNode.RelativeFilename
-			);
-			return new Texture();
-
-		}
+		let loader = this.manager.getHandler( `.${extension}` );
+		if ( loader === null) loader = this.textureLoader;
 
 		const loaderPath = loader.path;
 
@@ -477,6 +471,13 @@ class FBXTreeParser {
 
 		}
 
+		if ( fileName === undefined ) {
+
+			console.warn( 'FBXLoader: Undefined filename, creating placeholder texture.' );
+			return new Texture();
+
+		}
+
 		const texture = loader.load( fileName );
 
 		// revert to initial path
@@ -568,12 +569,12 @@ class FBXTreeParser {
 
 		if ( materialNode.Diffuse ) {
 
-			parameters.color = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.Diffuse.value ), SRGBColorSpace );
+			parameters.color = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.Diffuse.value ), SRGBColorSpace );
 
 		} else if ( materialNode.DiffuseColor && ( materialNode.DiffuseColor.type === 'Color' || materialNode.DiffuseColor.type === 'ColorRGB' ) ) {
 
 			// The blender exporter exports diffuse here instead of in materialNode.Diffuse
-			parameters.color = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.DiffuseColor.value ), SRGBColorSpace );
+			parameters.color = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.DiffuseColor.value ), SRGBColorSpace );
 
 		}
 
@@ -585,12 +586,12 @@ class FBXTreeParser {
 
 		if ( materialNode.Emissive ) {
 
-			parameters.emissive = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.Emissive.value ), SRGBColorSpace );
+			parameters.emissive = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.Emissive.value ), SRGBColorSpace );
 
 		} else if ( materialNode.EmissiveColor && ( materialNode.EmissiveColor.type === 'Color' || materialNode.EmissiveColor.type === 'ColorRGB' ) ) {
 
 			// The blender exporter exports emissive color here instead of in materialNode.Emissive
-			parameters.emissive = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.EmissiveColor.value ), SRGBColorSpace );
+			parameters.emissive = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.EmissiveColor.value ), SRGBColorSpace );
 
 		}
 
@@ -636,12 +637,12 @@ class FBXTreeParser {
 
 		if ( materialNode.Specular ) {
 
-			parameters.specular = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.Specular.value ), SRGBColorSpace );
+			parameters.specular = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.Specular.value ), SRGBColorSpace );
 
 		} else if ( materialNode.SpecularColor && materialNode.SpecularColor.type === 'Color' ) {
 
 			// The blender exporter exports specular color here instead of in materialNode.Specular
-			parameters.specular = ColorManagement.toWorkingColorSpace( new Color().fromArray( materialNode.SpecularColor.value ), SRGBColorSpace );
+			parameters.specular = ColorManagement.colorSpaceToWorking( new Color().fromArray( materialNode.SpecularColor.value ), SRGBColorSpace );
 
 		}
 
@@ -1192,7 +1193,7 @@ class FBXTreeParser {
 
 			if ( lightAttribute.Color !== undefined ) {
 
-				color = ColorManagement.toWorkingColorSpace( new Color().fromArray( lightAttribute.Color.value ), SRGBColorSpace );
+				color = ColorManagement.colorSpaceToWorking( new Color().fromArray( lightAttribute.Color.value ), SRGBColorSpace );
 
 			}
 
@@ -2390,7 +2391,7 @@ class GeometryParser {
 		for ( let i = 0, c = new Color(); i < buffer.length; i += 4 ) {
 
 			c.fromArray( buffer, i );
-			ColorManagement.toWorkingColorSpace( c, SRGBColorSpace );
+			ColorManagement.colorSpaceToWorking( c, SRGBColorSpace );
 			c.toArray( buffer, i );
 
 		}

+ 5 - 0
examples/jsm/loaders/GLTFLoader.js

@@ -4451,6 +4451,11 @@ class GLTFParser {
 
 				parser.associations.set( node, {} );
 
+			} else if ( nodeDef.mesh !== undefined && parser.meshCache.refs[ nodeDef.mesh ] > 1 ) {
+
+				const mapping = parser.associations.get( node );
+				parser.associations.set( node, { ...mapping } );
+
 			}
 
 			parser.associations.get( node ).nodes = nodeIndex;

+ 66 - 26
examples/jsm/loaders/KTX2Loader.js

@@ -1,60 +1,76 @@
 import {
-	CompressedTexture,
 	CompressedArrayTexture,
 	CompressedCubeTexture,
+	CompressedTexture,
 	Data3DTexture,
 	DataTexture,
 	FileLoader,
 	FloatType,
 	HalfFloatType,
-	NoColorSpace,
 	LinearFilter,
 	LinearMipmapLinearFilter,
 	LinearSRGBColorSpace,
 	Loader,
-	RedFormat,
-	RGB_BPTC_UNSIGNED_Format,
-	RGB_ETC1_Format,
-	RGB_ETC2_Format,
-	RGB_PVRTC_4BPPV1_Format,
+	NoColorSpace,
+	RGBAFormat,
 	RGBA_ASTC_4x4_Format,
 	RGBA_ASTC_6x6_Format,
 	RGBA_BPTC_Format,
+	RGBA_S3TC_DXT3_Format,
 	RGBA_ETC2_EAC_Format,
 	RGBA_PVRTC_4BPPV1_Format,
-	RGBA_S3TC_DXT5_Format,
 	RGBA_S3TC_DXT1_Format,
-	RGBAFormat,
+	RGBA_S3TC_DXT5_Format,
+	RGB_BPTC_UNSIGNED_Format,
+	RGB_ETC1_Format,
+	RGB_ETC2_Format,
+	RGB_PVRTC_4BPPV1_Format,
+	RGB_S3TC_DXT1_Format,
 	RGFormat,
+	RedFormat,
 	SRGBColorSpace,
-	UnsignedByteType,
+	UnsignedByteType
 } from 'three';
 import { WorkerPool } from '../utils/WorkerPool.js';
 import {
 	read,
 	KHR_DF_FLAG_ALPHA_PREMULTIPLIED,
+	KHR_DF_PRIMARIES_BT709,
+	KHR_DF_PRIMARIES_DISPLAYP3,
+	KHR_DF_PRIMARIES_UNSPECIFIED,
 	KHR_DF_TRANSFER_SRGB,
 	KHR_SUPERCOMPRESSION_NONE,
 	KHR_SUPERCOMPRESSION_ZSTD,
-	VK_FORMAT_UNDEFINED,
-	VK_FORMAT_R16_SFLOAT,
-	VK_FORMAT_R16G16_SFLOAT,
+	VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT,
+	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
+	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
+	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
+	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
+	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
+	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
+	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
+	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
+	VK_FORMAT_BC3_SRGB_BLOCK,
+	VK_FORMAT_BC3_UNORM_BLOCK,
+	VK_FORMAT_BC5_SNORM_BLOCK,
+	VK_FORMAT_BC5_UNORM_BLOCK,
+	VK_FORMAT_BC7_SRGB_BLOCK,
+	VK_FORMAT_BC7_UNORM_BLOCK,
+	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
+	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
 	VK_FORMAT_R16G16B16A16_SFLOAT,
-	VK_FORMAT_R32_SFLOAT,
-	VK_FORMAT_R32G32_SFLOAT,
+	VK_FORMAT_R16G16_SFLOAT,
+	VK_FORMAT_R16_SFLOAT,
 	VK_FORMAT_R32G32B32A32_SFLOAT,
-	VK_FORMAT_R8_SRGB,
-	VK_FORMAT_R8_UNORM,
-	VK_FORMAT_R8G8_SRGB,
-	VK_FORMAT_R8G8_UNORM,
+	VK_FORMAT_R32G32_SFLOAT,
+	VK_FORMAT_R32_SFLOAT,
 	VK_FORMAT_R8G8B8A8_SRGB,
 	VK_FORMAT_R8G8B8A8_UNORM,
-	VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT,
-	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
-	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
-	KHR_DF_PRIMARIES_UNSPECIFIED,
-	KHR_DF_PRIMARIES_BT709,
-	KHR_DF_PRIMARIES_DISPLAYP3
+	VK_FORMAT_R8G8_SRGB,
+	VK_FORMAT_R8G8_UNORM,
+	VK_FORMAT_R8_SRGB,
+	VK_FORMAT_R8_UNORM,
+	VK_FORMAT_UNDEFINED
 } from '../libs/ktx-parse.module.js';
 import { ZSTDDecoder } from '../libs/zstddec.module.js';
 import { DisplayP3ColorSpace, LinearDisplayP3ColorSpace } from '../math/ColorSpaces.js';
@@ -311,8 +327,10 @@ class KTX2Loader extends Loader {
 
 		const loader = new FileLoader( this.manager );
 
-		loader.setResponseType( 'arraybuffer' );
+		loader.setPath( this.path );
+		loader.setCrossOrigin( this.crossOrigin );
 		loader.setWithCredentials( this.withCredentials );
+		loader.setResponseType( 'arraybuffer' );
 
 		loader.load( url, ( buffer ) => {
 
@@ -919,10 +937,29 @@ const FORMAT_MAP = {
 	[ VK_FORMAT_R8_SRGB ]: RedFormat,
 	[ VK_FORMAT_R8_UNORM ]: RedFormat,
 
+	[ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK ]: RGB_ETC2_Format,
+	[ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK ]: RGBA_ETC2_EAC_Format,
+
 	[ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT ]: RGBA_ASTC_4x4_Format,
+	[ VK_FORMAT_ASTC_4x4_SRGB_BLOCK ]: RGBA_ASTC_4x4_Format,
+	[ VK_FORMAT_ASTC_4x4_UNORM_BLOCK ]: RGBA_ASTC_4x4_Format,
 	[ VK_FORMAT_ASTC_6x6_SRGB_BLOCK ]: RGBA_ASTC_6x6_Format,
 	[ VK_FORMAT_ASTC_6x6_UNORM_BLOCK ]: RGBA_ASTC_6x6_Format,
 
+	[ VK_FORMAT_BC1_RGBA_UNORM_BLOCK ]: RGBA_S3TC_DXT1_Format,
+	[ VK_FORMAT_BC1_RGBA_SRGB_BLOCK ]: RGBA_S3TC_DXT1_Format,
+	[ VK_FORMAT_BC1_RGB_UNORM_BLOCK ]: RGB_S3TC_DXT1_Format,
+	[ VK_FORMAT_BC1_RGB_SRGB_BLOCK ]: RGB_S3TC_DXT1_Format,
+
+	[ VK_FORMAT_BC3_SRGB_BLOCK ]: RGBA_S3TC_DXT3_Format,
+	[ VK_FORMAT_BC3_UNORM_BLOCK ]: RGBA_S3TC_DXT3_Format,
+
+	[ VK_FORMAT_BC5_SNORM_BLOCK ]: RGBA_S3TC_DXT5_Format,
+	[ VK_FORMAT_BC5_UNORM_BLOCK ]: RGBA_S3TC_DXT5_Format,
+
+	[ VK_FORMAT_BC7_SRGB_BLOCK ]: RGBA_BPTC_Format,
+	[ VK_FORMAT_BC7_UNORM_BLOCK ]: RGBA_BPTC_Format,
+
 };
 
 const TYPE_MAP = {
@@ -942,6 +979,9 @@ const TYPE_MAP = {
 	[ VK_FORMAT_R8_SRGB ]: UnsignedByteType,
 	[ VK_FORMAT_R8_UNORM ]: UnsignedByteType,
 
+	[ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK ]: UnsignedByteType,
+	[ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK ]: UnsignedByteType,
+
 	[ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT ]: HalfFloatType,
 	[ VK_FORMAT_ASTC_6x6_SRGB_BLOCK ]: UnsignedByteType,
 	[ VK_FORMAT_ASTC_6x6_UNORM_BLOCK ]: UnsignedByteType,

+ 53 - 2
examples/jsm/loaders/LDrawLoader.js

@@ -1885,7 +1885,7 @@ class LDrawLoader extends Loader {
 
 		}
 
-		this.setMaterials( materials );
+		this.addMaterials( materials );
 
 	}
 
@@ -1907,7 +1907,7 @@ class LDrawLoader extends Loader {
 		fileLoader.load( url, text => {
 
 			// Initializes the materials library with default materials
-			this.setMaterials( [] );
+			this.addDefaultMaterials();
 
 			this.partsCache
 				.parseModel( text )
@@ -1948,16 +1948,61 @@ class LDrawLoader extends Loader {
 
 	}
 
+	/**
+	 * Sets the loader's material library. This method clears existing
+	 * material definitions.
+	 *
+	 * @param {Array<Material>} materials - The materials to set.
+	 * @return {LDrawLoader} A reference to this loader.
+	 */
 	setMaterials( materials ) {
 
+		this.clearMaterials();
+		this.addMaterials( materials );
+
+		return this;
+
+	}
+
+	/**
+	 * Clears the loader's material library.
+	 *
+	 * @return {LDrawLoader} A reference to this loader.
+	 */
+	clearMaterials() {
+
 		this.materialLibrary = {};
 		this.materials = [];
+
+		return this;
+
+	}
+
+	/**
+	 * Adds a list of materials to the loader's material library.
+	 *
+	 * @param {Array<Material>} materials - The materials to add.
+	 * @return {LDrawLoader} A reference to this loader.
+	 */
+	addMaterials( materials ) {
+
 		for ( let i = 0, l = materials.length; i < l; i ++ ) {
 
 			this.addMaterial( materials[ i ] );
 
 		}
 
+		return this;
+
+	}
+
+	/**
+	 * Initializes the loader with default materials.
+	 *
+	 * @return {LDrawLoader} A reference to this loader.
+	 */
+	addDefaultMaterials() {
+
 		// Add default main triangle and line edge materials (used in pieces that can be colored with a main color)
 		this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Main_Colour CODE 16 VALUE #FF8080 EDGE #333333' ) ) );
 		this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Edge_Colour CODE 24 VALUE #A0A0A0 EDGE #333333' ) ) );
@@ -1982,6 +2027,12 @@ class LDrawLoader extends Loader {
 
 	}
 
+	/**
+	 * Adds a single material to the loader's material library.
+	 *
+	 * @param {Material} material - The material to add.
+	 * @return {LDrawLoader} A reference to this loader.
+	 */
 	addMaterial( material ) {
 
 		// Adds a material to the material library which is on top of the parse scopes stack. And also to the materials array

+ 3 - 3
examples/jsm/loaders/MTLLoader.js

@@ -392,21 +392,21 @@ class MaterialCreator {
 
 					// Diffuse color (color under white light) using RGB values
 
-					params.color = ColorManagement.toWorkingColorSpace( new Color().fromArray( value ), SRGBColorSpace );
+					params.color = ColorManagement.colorSpaceToWorking( new Color().fromArray( value ), SRGBColorSpace );
 
 					break;
 
 				case 'ks':
 
 					// Specular color (color when light is reflected from shiny surface) using RGB values
-					params.specular = ColorManagement.toWorkingColorSpace( new Color().fromArray( value ), SRGBColorSpace );
+					params.specular = ColorManagement.colorSpaceToWorking( new Color().fromArray( value ), SRGBColorSpace );
 
 					break;
 
 				case 'ke':
 
 					// Emissive using RGB values
-					params.emissive = ColorManagement.toWorkingColorSpace( new Color().fromArray( value ), SRGBColorSpace );
+					params.emissive = ColorManagement.colorSpaceToWorking( new Color().fromArray( value ), SRGBColorSpace );
 
 					break;
 

+ 121 - 19
examples/jsm/loaders/PCDLoader.js

@@ -97,6 +97,71 @@ class PCDLoader extends Loader {
 
 	}
 
+	/**
+	 * Get dataview value by field type and size.
+	 *
+	 * @param {DataView} dataview - The DataView to read from.
+	 * @param {number} offset - The offset to start reading from.
+	 * @param {'F' | 'U' | 'I'} type - Field type.
+	 * @param {number} size - Field size.
+	 * @returns {number} Field value.
+	 */
+	_getDataView( dataview, offset, type, size ) {
+
+		switch ( type ) {
+
+			case 'F': {
+
+				if ( size === 8 ) {
+
+					return dataview.getFloat64( offset, this.littleEndian );
+
+				}
+
+				return dataview.getFloat32( offset, this.littleEndian );
+
+			}
+
+			case 'I': {
+
+				if ( size === 1 ) {
+
+					return dataview.getInt8( offset );
+
+				}
+
+				if ( size === 2 ) {
+
+					return dataview.getInt16( offset, this.littleEndian );
+
+				}
+
+				return dataview.getInt32( offset, this.littleEndian );
+
+			}
+
+			case 'U': {
+
+				if ( size === 1 ) {
+
+					return dataview.getUint8( offset );
+
+				}
+
+				if ( size === 2 ) {
+
+					return dataview.getUint16( offset, this.littleEndian );
+
+				}
+
+				return dataview.getUint32( offset, this.littleEndian );
+
+			}
+
+		}
+
+	}
+
 	/**
 	 * Parses the given PCD data and returns a point cloud.
 	 *
@@ -160,9 +225,40 @@ class PCDLoader extends Loader {
 
 		}
 
-		function parseHeader( data ) {
+		function parseHeader( binaryData ) {
 
 			const PCDheader = {};
+
+			const buffer = new Uint8Array( binaryData );
+
+			let data = '', line = '', i = 0, end = false;
+
+			const max = buffer.length;
+
+			while ( i < max && end === false ) {
+
+				const char = String.fromCharCode( buffer[ i ++ ] );
+
+				if ( char === '\n' || char === '\r' ) {
+
+					if ( line.trim().toLowerCase().startsWith( 'data' ) ) {
+
+						end = true;
+
+					}
+
+					line = '';
+
+				} else {
+
+					line += char;
+
+				}
+
+				data += char;
+
+			}
+
 			const result1 = data.search( /[\r\n]DATA\s(\S*)\s/i );
 			const result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
 
@@ -268,11 +364,9 @@ class PCDLoader extends Loader {
 
 		}
 
-		const textData = new TextDecoder().decode( data );
+		// parse header
 
-		// parse header (always ascii format)
-
-		const PCDheader = parseHeader( textData );
+		const PCDheader = parseHeader( data );
 
 		// parse data
 
@@ -289,6 +383,7 @@ class PCDLoader extends Loader {
 		if ( PCDheader.data === 'ascii' ) {
 
 			const offset = PCDheader.offset;
+			const textData = new TextDecoder().decode( data );
 			const pcdData = textData.slice( PCDheader.headerLen );
 			const lines = pcdData.split( '\n' );
 
@@ -381,9 +476,9 @@ class PCDLoader extends Loader {
 					const xIndex = PCDheader.fields.indexOf( 'x' );
 					const yIndex = PCDheader.fields.indexOf( 'y' );
 					const zIndex = PCDheader.fields.indexOf( 'z' );
-					position.push( dataview.getFloat32( ( PCDheader.points * offset.x ) + PCDheader.size[ xIndex ] * i, this.littleEndian ) );
-					position.push( dataview.getFloat32( ( PCDheader.points * offset.y ) + PCDheader.size[ yIndex ] * i, this.littleEndian ) );
-					position.push( dataview.getFloat32( ( PCDheader.points * offset.z ) + PCDheader.size[ zIndex ] * i, this.littleEndian ) );
+					position.push( this._getDataView( dataview, ( PCDheader.points * offset.x ) + PCDheader.size[ xIndex ] * i, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
+					position.push( this._getDataView( dataview, ( PCDheader.points * offset.y ) + PCDheader.size[ yIndex ] * i, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
+					position.push( this._getDataView( dataview, ( PCDheader.points * offset.z ) + PCDheader.size[ zIndex ] * i, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
 
 				}
 
@@ -406,16 +501,16 @@ class PCDLoader extends Loader {
 					const xIndex = PCDheader.fields.indexOf( 'normal_x' );
 					const yIndex = PCDheader.fields.indexOf( 'normal_y' );
 					const zIndex = PCDheader.fields.indexOf( 'normal_z' );
-					normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_x ) + PCDheader.size[ xIndex ] * i, this.littleEndian ) );
-					normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_y ) + PCDheader.size[ yIndex ] * i, this.littleEndian ) );
-					normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_z ) + PCDheader.size[ zIndex ] * i, this.littleEndian ) );
+					normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_x ) + PCDheader.size[ xIndex ] * i, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
+					normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_y ) + PCDheader.size[ yIndex ] * i, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
+					normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_z ) + PCDheader.size[ zIndex ] * i, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
 
 				}
 
 				if ( offset.intensity !== undefined ) {
 
 					const intensityIndex = PCDheader.fields.indexOf( 'intensity' );
-					intensity.push( dataview.getFloat32( ( PCDheader.points * offset.intensity ) + PCDheader.size[ intensityIndex ] * i, this.littleEndian ) );
+					intensity.push( this._getDataView( dataview, ( PCDheader.points * offset.intensity ) + PCDheader.size[ intensityIndex ] * i, PCDheader.type[ intensityIndex ], PCDheader.size[ intensityIndex ] ) );
 
 				}
 
@@ -441,9 +536,12 @@ class PCDLoader extends Loader {
 
 				if ( offset.x !== undefined ) {
 
-					position.push( dataview.getFloat32( row + offset.x, this.littleEndian ) );
-					position.push( dataview.getFloat32( row + offset.y, this.littleEndian ) );
-					position.push( dataview.getFloat32( row + offset.z, this.littleEndian ) );
+					const xIndex = PCDheader.fields.indexOf( 'x' );
+					const yIndex = PCDheader.fields.indexOf( 'y' );
+					const zIndex = PCDheader.fields.indexOf( 'z' );
+					position.push( this._getDataView( dataview, row + offset.x, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
+					position.push( this._getDataView( dataview, row + offset.y, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
+					position.push( this._getDataView( dataview, row + offset.z, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
 
 				}
 
@@ -461,15 +559,19 @@ class PCDLoader extends Loader {
 
 				if ( offset.normal_x !== undefined ) {
 
-					normal.push( dataview.getFloat32( row + offset.normal_x, this.littleEndian ) );
-					normal.push( dataview.getFloat32( row + offset.normal_y, this.littleEndian ) );
-					normal.push( dataview.getFloat32( row + offset.normal_z, this.littleEndian ) );
+					const xIndex = PCDheader.fields.indexOf( 'normal_x' );
+					const yIndex = PCDheader.fields.indexOf( 'normal_y' );
+					const zIndex = PCDheader.fields.indexOf( 'normal_z' );
+					normal.push( this._getDataView( dataview, row + offset.normal_x, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
+					normal.push( this._getDataView( dataview, row + offset.normal_y, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
+					normal.push( this._getDataView( dataview, row + offset.normal_z, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
 
 				}
 
 				if ( offset.intensity !== undefined ) {
 
-					intensity.push( dataview.getFloat32( row + offset.intensity, this.littleEndian ) );
+					const intensityIndex = PCDheader.fields.indexOf( 'intensity' );
+					intensity.push( this._getDataView( dataview, row + offset.intensity, PCDheader.type[ intensityIndex ], PCDheader.size[ intensityIndex ] ) );
 
 				}
 

+ 2 - 2
examples/jsm/loaders/VRMLLoader.js

@@ -3141,7 +3141,7 @@ class VRMLLoader extends Loader {
 
 				color.fromBufferAttribute( attribute, i );
 
-				ColorManagement.toWorkingColorSpace( color, SRGBColorSpace );
+				ColorManagement.colorSpaceToWorking( color, SRGBColorSpace );
 
 				attribute.setXYZ( i, color.r, color.g, color.b );
 
@@ -3248,7 +3248,7 @@ class VRMLLoader extends Loader {
 
 				color.copy( colorA ).lerp( colorB, t );
 
-				ColorManagement.toWorkingColorSpace( color, SRGBColorSpace );
+				ColorManagement.colorSpaceToWorking( color, SRGBColorSpace );
 
 				colorAttribute.setXYZ( index, color.r, color.g, color.b );
 

+ 18 - 1
examples/jsm/math/Octree.js

@@ -130,6 +130,23 @@ class Octree {
 		 */
 		this.layers = new Layers();
 
+		/**
+		 * The number of triangles a leaf can store before it is split.
+		 *
+		 * @type {number}
+		 * @default 8
+		 */
+		this.trianglesPerLeaf = 8;
+
+		/**
+		 * The maximum level of the Octree. It defines the maximum
+		 * hierarchical depth of the data structure.
+		 *
+		 * @type {number}
+		 * @default 16
+		 */
+		this.maxLevel = 16;
+
 		// private
 
 		this.subTrees = [];
@@ -231,7 +248,7 @@ class Octree {
 
 			const len = subTrees[ i ].triangles.length;
 
-			if ( len > 8 && level < 16 ) {
+			if ( len > this.trianglesPerLeaf && level < this.maxLevel ) {
 
 				subTrees[ i ].split( level + 1 );
 

+ 18 - 16
examples/jsm/objects/SkyMesh.js

@@ -6,7 +6,7 @@ import {
 	NodeMaterial
 } from 'three/webgpu';
 
-import { Fn, float, vec3, acos, add, mul, clamp, cos, dot, exp, max, mix, modelViewProjection, normalize, positionWorld, pow, smoothstep, sub, varying, varyingProperty, vec4, uniform, cameraPosition } from 'three/tsl';
+import { Fn, float, vec3, acos, add, mul, clamp, cos, dot, exp, max, mix, modelViewProjection, normalize, positionWorld, pow, smoothstep, sub, varyingProperty, vec4, uniform, cameraPosition } from 'three/tsl';
 
 /**
  * Represents a skydome for scene backgrounds. Based on [A Practical Analytic Model for Daylight]{@link https://www.researchgate.net/publication/220720443_A_Practical_Analytic_Model_for_Daylight}
@@ -91,6 +91,14 @@ class SkyMesh extends Mesh {
 		 */
 		this.isSky = true;
 
+		// Varyings
+
+		const vSunDirection = varyingProperty( 'vec3' );
+		const vSunE = varyingProperty( 'float' );
+		const vSunfade = varyingProperty( 'float' );
+		const vBetaR = varyingProperty( 'vec3' );
+		const vBetaM = varyingProperty( 'vec3' );
+
 		const vertexNode = /*@__PURE__*/ Fn( () => {
 
 			// constants for atmospheric scattering
@@ -118,35 +126,35 @@ class SkyMesh extends Mesh {
 
 			// varying sun position
 
-			const vSunDirection = normalize( this.sunPosition );
-			varyingProperty( 'vec3', 'vSunDirection' ).assign( vSunDirection );
+			const sunDirection = normalize( this.sunPosition );
+			vSunDirection.assign( sunDirection );
 
 			// varying sun intensity
 
-			const angle = dot( vSunDirection, this.upUniform );
+			const angle = dot( sunDirection, this.upUniform );
 			const zenithAngleCos = clamp( angle, - 1, 1 );
 			const sunIntensity = EE.mul( max( 0.0, float( 1.0 ).sub( pow( e, cutoffAngle.sub( acos( zenithAngleCos ) ).div( steepness ).negate() ) ) ) );
-			varyingProperty( 'float', 'vSunE' ).assign( sunIntensity );
+			vSunE.assign( sunIntensity );
 
 			// varying sun fade
 
-			const vSunfade = float( 1.0 ).sub( clamp( float( 1.0 ).sub( exp( this.sunPosition.y.div( 450000.0 ) ) ), 0, 1 ) );
-			varyingProperty( 'float', 'vSunfade' ).assign( vSunfade );
+			const sunfade = float( 1.0 ).sub( clamp( float( 1.0 ).sub( exp( this.sunPosition.y.div( 450000.0 ) ) ), 0, 1 ) );
+			vSunfade.assign( sunfade );
 
 			// varying vBetaR
 
-			const rayleighCoefficient = this.rayleigh.sub( float( 1.0 ).mul( float( 1.0 ).sub( vSunfade ) ) );
+			const rayleighCoefficient = this.rayleigh.sub( float( 1.0 ).mul( float( 1.0 ).sub( sunfade ) ) );
 
 			// extinction (absorption + out scattering)
 			// rayleigh coefficients
-			varyingProperty( 'vec3', 'vBetaR' ).assign( totalRayleigh.mul( rayleighCoefficient ) );
+			vBetaR.assign( totalRayleigh.mul( rayleighCoefficient ) );
 
 			// varying vBetaM
 
 			const c = float( 0.2 ).mul( this.turbidity ).mul( 10E-18 );
 			const totalMie = float( 0.434 ).mul( c ).mul( MieConst );
 
-			varyingProperty( 'vec3', 'vBetaM' ).assign( totalMie.mul( this.mieCoefficient ) );
+			vBetaM.assign( totalMie.mul( this.mieCoefficient ) );
 
 			// position
 
@@ -159,12 +167,6 @@ class SkyMesh extends Mesh {
 
 		const fragmentNode = /*@__PURE__*/ Fn( () => {
 
-			const vSunDirection = varying( vec3(), 'vSunDirection' );
-			const vSunE = varying( float(), 'vSunE' );
-			const vSunfade = varying( float(), 'vSunfade' );
-			const vBetaR = varying( vec3(), 'vBetaR' );
-			const vBetaM = varying( vec3(), 'vBetaM' );
-
 			// constants for atmospheric scattering
 			const pi = float( 3.141592653589793238462643383279502884197169 );
 

+ 19 - 2
examples/jsm/postprocessing/AfterimagePass.js

@@ -43,7 +43,7 @@ class AfterimagePass extends Pass {
 		 */
 		this.uniforms = UniformsUtils.clone( AfterimageShader.uniforms );
 
-		this.uniforms[ 'damp' ].value = damp;
+		this.damp = damp;
 
 		/**
 		 * The composition material.
@@ -89,6 +89,23 @@ class AfterimagePass extends Pass {
 
 	}
 
+	/**
+	 * The damping intensity, from 0.0 to 1.0. A higher value means a stronger after image effect.
+	 *
+	 * @type {number}
+	 */
+	get damp() {
+
+		return this.uniforms[ 'damp' ].value;
+
+	}
+
+	set damp( value ) {
+
+		this.uniforms[ 'damp' ].value = value;
+
+	}
+
 	/**
 	 * Performs the after image pass.
 	 *
@@ -137,7 +154,7 @@ class AfterimagePass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/BloomPass.js

@@ -167,7 +167,7 @@ class BloomPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/BokehPass.js

@@ -179,7 +179,7 @@ class BokehPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 40 - 0
examples/jsm/postprocessing/FXAAPass.js

@@ -0,0 +1,40 @@
+import { FXAAShader } from '../shaders/FXAAShader.js';
+import { ShaderPass } from './ShaderPass.js';
+
+/**
+ * A pass for applying FXAA.
+ *
+ * ```js
+ * const fxaaPass = new FXAAPass();
+ * composer.addPass( fxaaPass );
+ * ```
+ *
+ * @augments ShaderPass
+ * @three_import import { FXAAPass } from 'three/addons/postprocessing/FXAAPass.js';
+ */
+class FXAAPass extends ShaderPass {
+
+	/**
+	 * Constructs a new FXAA pass.
+	 */
+	constructor() {
+
+		super( FXAAShader );
+
+	}
+
+	/**
+	 * Sets the size of the pass.
+	 *
+	 * @param {number} width - The width to set.
+	 * @param {number} height - The height to set.
+	 */
+	setSize( width, height ) {
+
+		this.material.uniforms[ 'resolution' ].value.set( 1 / width, 1 / height );
+
+	}
+
+}
+
+export { FXAAPass };

+ 1 - 1
examples/jsm/postprocessing/GTAOPass.js

@@ -242,7 +242,7 @@ class GTAOPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/HalftonePass.js

@@ -108,7 +108,7 @@ class HalftonePass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
  	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/OutlinePass.js

@@ -269,7 +269,7 @@ class OutlinePass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/Pass.js

@@ -69,7 +69,7 @@ class Pass {
 	 *
 	 * @abstract
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( /* width, height */ ) {}
 

+ 1 - 1
examples/jsm/postprocessing/RenderPixelatedPass.js

@@ -121,7 +121,7 @@ class RenderPixelatedPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/RenderTransitionPass.js

@@ -129,7 +129,7 @@ class RenderTransitionPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SAOPass.js

@@ -294,7 +294,7 @@ class SAOPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SMAAPass.js

@@ -178,7 +178,7 @@ class SMAAPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SSAARenderPass.js

@@ -141,7 +141,7 @@ class SSAARenderPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SSAOPass.js

@@ -351,7 +351,7 @@ class SSAOPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SSRPass.js

@@ -654,7 +654,7 @@ class SSRPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/SavePass.js

@@ -105,7 +105,7 @@ class SavePass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 1 - 1
examples/jsm/postprocessing/UnrealBloomPass.js

@@ -242,7 +242,7 @@ class UnrealBloomPass extends Pass {
 	 * Sets the size of the pass.
 	 *
 	 * @param {number} width - The width to set.
-	 * @param {number} height - The width to set.
+	 * @param {number} height - The height to set.
 	 */
 	setSize( width, height ) {
 

+ 2 - 2
examples/jsm/tsl/display/FXAANode.js

@@ -123,8 +123,8 @@ class FXAANode extends TempNode {
 			const se = SampleLuminanceOffset( texSize, uv, 1.0, 1.0 );
 			const sw = SampleLuminanceOffset( texSize, uv, - 1.0, 1.0 );
 
-			const highest = max( max( max( max( s, e ), n ), w ), m );
-			const lowest = min( min( min( min( s, e ), n ), w ), m );
+			const highest = max( s, e, n, w, m );
+			const lowest = min( s, e, n, w, m );
 			const contrast = highest.sub( lowest );
 
 			return { m, n, e, s, w, ne, nw, se, sw, highest, lowest, contrast };

+ 1 - 27
examples/jsm/tsl/display/GaussianBlurNode.js

@@ -1,36 +1,10 @@
 import { RenderTarget, Vector2, NodeMaterial, RendererUtils, QuadMesh, TempNode, NodeUpdateType } from 'three/webgpu';
-import { nodeObject, Fn, If, float, uv, uniform, convertToTexture, vec2, vec4, passTexture, mul } from 'three/tsl';
+import { nodeObject, Fn, float, uv, uniform, convertToTexture, vec2, vec4, passTexture, mul, premult, unpremult } from 'three/tsl';
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 
 let _rendererState;
 
-const premult = /*@__PURE__*/ Fn( ( [ color ] ) => {
-
-	return vec4( color.rgb.mul( color.a ), color.a );
-
-} ).setLayout( {
-	name: 'premult',
-	type: 'vec4',
-	inputs: [
-		{ name: 'color', type: 'vec4' }
-	]
-} );
-
-const unpremult = /*@__PURE__*/ Fn( ( [ color ] ) => {
-
-	If( color.a.equal( 0.0 ), () => vec4( 0.0 ) );
-
-	return vec4( color.rgb.div( color.a ), color.a );
-
-} ).setLayout( {
-	name: 'unpremult',
-	type: 'vec4',
-	inputs: [
-		{ name: 'color', type: 'vec4' }
-	]
-} );
-
 /**
  * Post processing node for creating a gaussian blur effect.
  *

+ 8 - 8
examples/jsm/tsl/display/SMAANode.js

@@ -321,11 +321,11 @@ class SMAANode extends TempNode {
 			// Calculate left and top deltas:
 			const Cleft = this.textureNode.sample( vOffset0.xy ).rgb.toVar();
 			let t = abs( C.sub( Cleft ) );
-			delta.x = max( max( t.r, t.g ), t.b );
+			delta.x = max( t.r, t.g, t.b );
 
 			const Ctop = this.textureNode.sample( vOffset0.zw ).rgb.toVar();
 			t = abs( C.sub( Ctop ) );
-			delta.y = max( max( t.r, t.g ), t.b );
+			delta.y = max( t.r, t.g, t.b );
 
 			// We do the usual threshold:
 			const edges = step( threshold, delta.xy ).toVar();
@@ -336,26 +336,26 @@ class SMAANode extends TempNode {
 			// Calculate right and bottom deltas:
 			const Cright = this.textureNode.sample( vOffset1.xy ).rgb.toVar();
 			t = abs( C.sub( Cright ) );
-			delta.z = max( max( t.r, t.g ), t.b );
+			delta.z = max( t.r, t.g, t.b );
 
 			const Cbottom = this.textureNode.sample( vOffset1.zw ).rgb.toVar();
 			t = abs( C.sub( Cbottom ) );
-			delta.w = max( max( t.r, t.g ), t.b );
+			delta.w = max( t.r, t.g, t.b );
 
 			// Calculate the maximum delta in the direct neighborhood:
-			let maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w ).toVar();
+			let maxDelta = max( delta.x, delta.y, delta.z, delta.w ).toVar();
 
 			// Calculate left-left and top-top deltas:
 			const Cleftleft = this.textureNode.sample( vOffset2.xy ).rgb.toVar();
 			t = abs( C.sub( Cleftleft ) );
-			delta.z = max( max( t.r, t.g ), t.b );
+			delta.z = max( t.r, t.g, t.b );
 
 			const Ctoptop = this.textureNode.sample( vOffset2.zw ).rgb.toVar();
 			t = abs( C.sub( Ctoptop ) );
-			delta.w = max( max( t.r, t.g ), t.b );
+			delta.w = max( t.r, t.g, t.b );
 
 			// Calculate the final maximum delta:
-			maxDelta = max( max( maxDelta, delta.z ), delta.w );
+			maxDelta = max( maxDelta, delta.z, delta.w );
 
 			// Local contrast adaptation in action:
 			edges.xy.mulAssign( vec2( step( float( 0.5 ).mul( maxDelta ), delta.xy ) ) );

+ 2 - 2
examples/jsm/tsl/display/TRAAPassNode.js

@@ -380,8 +380,8 @@ class TRAAPassNode extends PassNode {
 			const currentWeight = float( 0.05 ).toVar();
 			const historyWeight = currentWeight.oneMinus().toVar();
 
-			const compressedCurrent = currentColor.mul( float( 1 ).div( ( max( max( currentColor.r, currentColor.g ), currentColor.b ).add( 1.0 ) ) ) );
-			const compressedHistory = clampedHistoryColor.mul( float( 1 ).div( ( max( max( clampedHistoryColor.r, clampedHistoryColor.g ), clampedHistoryColor.b ).add( 1.0 ) ) ) );
+			const compressedCurrent = currentColor.mul( float( 1 ).div( ( max( currentColor.r, currentColor.g, currentColor.b ).add( 1.0 ) ) ) );
+			const compressedHistory = clampedHistoryColor.mul( float( 1 ).div( ( max( clampedHistoryColor.r, clampedHistoryColor.g, clampedHistoryColor.b ).add( 1.0 ) ) ) );
 
 			const luminanceCurrent = luminance( compressedCurrent.rgb );
 			const luminanceHistory = luminance( compressedHistory.rgb );

+ 28 - 5
examples/jsm/tsl/display/hashBlur.js

@@ -1,4 +1,4 @@
-import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4 } from 'three/tsl';
+import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4, premult, unpremult } from 'three/tsl';
 
 /**
  * Applies a hash blur effect to the given texture node.
@@ -8,12 +8,35 @@ import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4 } from 'three/
  * @function
  * @param {Node<vec4>} textureNode - The texture node that should be blurred.
  * @param {Node<float>} [bluramount=float(0.1)] - This node determines the amount of blur.
- * @param {Node<float>} [repeats=float(45)] - This node determines the quality of the blur. A higher value produces a less grainy result but is also more expensive.
+ * @param {Object} [options={}] - Additional options for the hash blur effect.
+ * @param {Node<float>} [options.repeats=float(45)] - The number of iterations for the blur effect.
+ * @param {Node<vec4>} [options.mask=null] - A mask node to control the alpha blending of the blur.
+ * @param {boolean} [options.premultipliedAlpha=false] - Whether to use premultiplied alpha for the blur effect.
  * @return {Node<vec4>} The blurred texture node.
  */
-export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0.1 ), repeats = float( 45 ) ] ) => {
+export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0.1 ), options = {} ] ) => {
 
-	const draw = ( uv ) => textureNode.sample( uv );
+	const {
+		repeats = float( 45 ),
+		mask = null,
+		premultipliedAlpha = false
+	} = options;
+
+	const draw = ( uv ) => {
+
+		let sample = textureNode.sample( uv );
+
+		if ( mask !== null ) {
+
+			const alpha = mask.sample( uv ).x;
+
+			sample = vec4( sample.rgb, sample.a.mul( alpha ) );
+
+		}
+
+		return premultipliedAlpha ? premult( sample ) : sample;
+
+	};
 
 	const targetUV = textureNode.uvNode || uv();
 	const blurred_image = vec4( 0. ).toVar();
@@ -28,6 +51,6 @@ export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0
 
 	blurred_image.divAssign( repeats );
 
-	return blurred_image;
+	return premultipliedAlpha ? unpremult( blurred_image ) : blurred_image;
 
 } );

+ 3 - 3
examples/jsm/tsl/shadows/TileShadowNode.js

@@ -4,7 +4,7 @@ import {
 	ShadowBaseNode,
 	Plane,
 	Line3,
-	DepthArrayTexture,
+	DepthTexture,
 	LessCompare,
 	Vector2,
 	RedFormat,
@@ -159,10 +159,10 @@ class TileShadowNode extends ShadowBaseNode {
 		// Clear existing lights/nodes if re-initializing
 		this.disposeLightsAndNodes();
 
-		const depthTexture = new DepthArrayTexture( shadowWidth, shadowHeight, tileCount );
+		const depthTexture = new DepthTexture( shadowWidth, shadowHeight, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, tileCount );
 		depthTexture.compareFunction = LessCompare;
 		depthTexture.name = 'ShadowDepthArrayTexture';
-		const shadowMap = builder.createRenderTargetArray( shadowWidth, shadowHeight, tileCount, { format: RedFormat } );
+		const shadowMap = builder.createRenderTarget( shadowWidth, shadowHeight, { format: RedFormat, depth: tileCount } );
 		shadowMap.depthTexture = depthTexture;
 		shadowMap.texture.name = 'ShadowTexture';
 		this.shadowMap = shadowMap;

+ 0 - 145
examples/misc_lookat.html

@@ -1,145 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js misc - lookAt</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<link type="text/css" rel="stylesheet" href="main.css">
-		<style>
-			body {
-				background-color: #fff;
-				color: #444;
-			}
-
-			a {
-				color: #08b;
-			}
-		</style>
-	</head>
-	<body>
-		<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Object3D.lookAt() example</div>
-
-		<script type="importmap">
-			{
-				"imports": {
-					"three": "../build/three.module.js",
-					"three/addons/": "./jsm/"
-				}
-			}
-		</script>
-
-		<script type="module">
-
-			import * as THREE from 'three';
-
-			import Stats from 'three/addons/libs/stats.module.js';
-
-			let camera, scene, renderer, stats;
-
-			let sphere;
-
-			let mouseX = 0, mouseY = 0;
-
-			let windowHalfX = window.innerWidth / 2;
-			let windowHalfY = window.innerHeight / 2;
-
-			document.addEventListener( 'mousemove', onDocumentMouseMove );
-
-			init();
-
-			function init() {
-
-				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 15000 );
-				camera.position.z = 3200;
-
-				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xffffff );
-
-				sphere = new THREE.Mesh( new THREE.SphereGeometry( 100, 20, 20 ), new THREE.MeshNormalMaterial() );
-				scene.add( sphere );
-
-				const geometry = new THREE.CylinderGeometry( 0, 10, 100, 12 );
-				geometry.rotateX( Math.PI / 2 );
-
-				const material = new THREE.MeshNormalMaterial();
-
-				for ( let i = 0; i < 1000; i ++ ) {
-
-					const mesh = new THREE.Mesh( geometry, material );
-					mesh.position.x = Math.random() * 4000 - 2000;
-					mesh.position.y = Math.random() * 4000 - 2000;
-					mesh.position.z = Math.random() * 4000 - 2000;
-					mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 4 + 2;
-					scene.add( mesh );
-
-				}
-
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.setAnimationLoop( animate );
-				document.body.appendChild( renderer.domElement );
-
-				stats = new Stats();
-				document.body.appendChild( stats.dom );
-
-				//
-
-				window.addEventListener( 'resize', onWindowResize );
-
-			}
-
-			function onWindowResize() {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
-
-			}
-
-			//
-
-			function animate() {
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				const time = Date.now() * 0.0005;
-
-				sphere.position.x = Math.sin( time * 0.7 ) * 2000;
-				sphere.position.y = Math.cos( time * 0.5 ) * 2000;
-				sphere.position.z = Math.cos( time * 0.3 ) * 2000;
-
-				for ( let i = 1, l = scene.children.length; i < l; i ++ ) {
-
-					scene.children[ i ].lookAt( sphere.position );
-
-				}
-
-				camera.position.x += ( mouseX - camera.position.x ) * .05;
-				camera.position.y += ( - mouseY - camera.position.y ) * .05;
-				camera.lookAt( scene.position );
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-
-	</body>
-</html>

BIN=BIN
examples/models/fbx/monkey.fbm/UVTexture.png


BIN=BIN
examples/models/fbx/monkey.fbx


BIN=BIN
examples/models/fbx/monkey_embedded_texture.fbx


BIN=BIN
examples/models/gltf/venice_mask.glb


BIN=BIN
examples/models/pcd/binary/Zaghetto_8bit.pcd


+ 16 - 6
examples/physics_ammo_instancing.html

@@ -60,14 +60,24 @@
 				dirLight.shadow.camera.zoom = 2;
 				scene.add( dirLight );
 
-				const floor = new THREE.Mesh(
+				const shadowPlane = new THREE.Mesh(
+					new THREE.PlaneGeometry( 10, 10 ),
+					new THREE.ShadowMaterial( {
+						color: 0x444444
+					} ),
+				);
+				shadowPlane.rotation.x = - Math.PI / 2;
+				shadowPlane.receiveShadow = true;
+				scene.add( shadowPlane );
+
+				const floorCollider = new THREE.Mesh(
 					new THREE.BoxGeometry( 10, 5, 10 ),
-					new THREE.ShadowMaterial( { color: 0x444444 } )
+					new THREE.MeshBasicMaterial( { color: 0x666666 } )
 				);
-				floor.position.y = - 2.5;
-				floor.receiveShadow = true;
-				floor.userData.physics = { mass: 0 };
-				scene.add( floor );
+				floorCollider.position.y = - 2.5;
+				floorCollider.userData.physics = { mass: 0 };
+				floorCollider.visible = false;
+				scene.add( floorCollider );
 
 				//
 

+ 21 - 8
examples/physics_jolt_instancing.html

@@ -15,7 +15,9 @@
 		<script type="importmap">
 			{
 				"imports": {
-					"three": "../build/three.module.js",
+					"three": "../build/three.webgpu.js",
+					"three/webgpu": "../build/three.webgpu.js",
+					"three/tsl": "../build/three.tsl.js",
 					"three/addons/": "./jsm/"
 				}
 			}
@@ -56,16 +58,27 @@
 				dirLight.position.set( 5, 5, 5 );
 				dirLight.castShadow = true;
 				dirLight.shadow.camera.zoom = 2;
+				dirLight.shadow.bias = - 0.001;
 				scene.add( dirLight );
 
-				const floor = new THREE.Mesh(
+				const shadowPlane = new THREE.Mesh(
+					new THREE.PlaneGeometry( 10, 10 ),
+					new THREE.ShadowMaterial( {
+						color: 0x444444
+					} ),
+				);
+				shadowPlane.rotation.x = - Math.PI / 2;
+				shadowPlane.receiveShadow = true;
+				scene.add( shadowPlane );
+
+				const floorCollider = new THREE.Mesh(
 					new THREE.BoxGeometry( 10, 5, 10 ),
-					new THREE.ShadowMaterial( { color: 0x444444 } )
+					new THREE.MeshBasicMaterial( { color: 0x666666 } )
 				);
-				floor.position.y = - 2.5;
-				floor.receiveShadow = true;
-				floor.userData.physics = { mass: 0 };
-				scene.add( floor );
+				floorCollider.position.y = - 2.5;
+				floorCollider.userData.physics = { mass: 0 };
+				floorCollider.visible = false;
+				scene.add( floorCollider );
 
 				//
 
@@ -114,7 +127,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer = new THREE.WebGPURenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );

+ 16 - 6
examples/physics_rapier_instancing.html

@@ -58,14 +58,24 @@
 				dirLight.shadow.camera.zoom = 2;
 				scene.add( dirLight );
 
-				const floor = new THREE.Mesh(
+				const shadowPlane = new THREE.Mesh(
+					new THREE.PlaneGeometry( 10, 10 ),
+					new THREE.ShadowMaterial( {
+						color: 0x444444
+					} ),
+				);
+				shadowPlane.rotation.x = - Math.PI / 2;
+				shadowPlane.receiveShadow = true;
+				scene.add( shadowPlane );
+
+				const floorCollider = new THREE.Mesh(
 					new THREE.BoxGeometry( 10, 5, 10 ),
-					new THREE.ShadowMaterial( { color: 0x444444 } )
+					new THREE.MeshBasicMaterial( { color: 0x666666 } )
 				);
-				floor.position.y = - 2.5;
-				floor.receiveShadow = true;
-				floor.userData.physics = { mass: 0 };
-				scene.add( floor );
+				floorCollider.position.y = - 2.5;
+				floorCollider.userData.physics = { mass: 0 };
+				floorCollider.visible = false;
+				scene.add( floorCollider );
 
 				//
 

BIN=BIN
examples/screenshots/misc_lookat.jpg


BIN=BIN
examples/screenshots/physics_jolt_instancing.jpg


BIN=BIN
examples/screenshots/webgl_effects_peppersghost.jpg


BIN=BIN
examples/screenshots/webgl_geometry_dynamic.jpg


BIN=BIN
examples/screenshots/webgl_instancing_dynamic.jpg


BIN=BIN
examples/screenshots/webgl_layers.jpg


BIN=BIN
examples/screenshots/webgl_lights_pointlights.jpg


BIN=BIN
examples/screenshots/webgl_loader_texture_ktx2.jpg


BIN=BIN
examples/screenshots/webgl_materials_normalmap.jpg


BIN=BIN
examples/screenshots/webgl_random_uv.jpg


BIN=BIN
examples/screenshots/webgl_tonemapping.jpg


BIN=BIN
examples/screenshots/webgpu_compute_cloth.jpg


BIN=BIN
examples/screenshots/webgpu_compute_particles.jpg


BIN=BIN
examples/screenshots/webgpu_compute_particles_fluid.jpg


BIN=BIN
examples/screenshots/webgpu_compute_water.jpg


BIN=BIN
examples/screenshots/webgpu_layers.jpg


BIN=BIN
examples/screenshots/webgpu_lights_pointlights.jpg


BIN=BIN
examples/screenshots/webgpu_lights_projector.jpg


BIN=BIN
examples/screenshots/webgpu_reflection_blurred.jpg


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio

粤ICP备19079148号