Mr.doob 1 year ago
parent
commit
7c8c0e2c1e
100 changed files with 7705 additions and 3334 deletions
  1. 732 697
      build/three.cjs
  2. 732 697
      build/three.js
  3. 0 0
      build/three.min.js
  4. 732 697
      build/three.module.js
  5. 0 0
      build/three.module.min.js
  6. 1 1
      docs/api/ar/geometries/CapsuleGeometry.html
  7. 210 44
      docs/api/ar/math/Matrix3.html
  8. 579 78
      docs/api/ar/math/Matrix4.html
  9. 4 0
      docs/api/ar/math/Quaternion.html
  10. 4 4
      docs/api/ar/objects/SkinnedMesh.html
  11. 14 3
      docs/api/ar/renderers/WebGLRenderer.html
  12. 4 0
      docs/api/en/constants/CustomBlendingEquations.html
  13. 1 1
      docs/api/en/extras/core/Curve.html
  14. 1 1
      docs/api/en/geometries/CapsuleGeometry.html
  15. 1 1
      docs/api/en/lights/Light.html
  16. 1 1
      docs/api/en/loaders/managers/LoadingManager.html
  17. 16 1
      docs/api/en/materials/Material.html
  18. 210 41
      docs/api/en/math/Matrix3.html
  19. 579 75
      docs/api/en/math/Matrix4.html
  20. 4 0
      docs/api/en/math/Quaternion.html
  21. 4 4
      docs/api/en/objects/SkinnedMesh.html
  22. 14 3
      docs/api/en/renderers/WebGLRenderer.html
  23. 1 1
      docs/api/fr/geometries/CapsuleGeometry.html
  24. 1 1
      docs/api/it/geometries/CapsuleGeometry.html
  25. 210 45
      docs/api/it/math/Matrix3.html
  26. 580 84
      docs/api/it/math/Matrix4.html
  27. 4 0
      docs/api/it/math/Quaternion.html
  28. 4 3
      docs/api/it/objects/SkinnedMesh.html
  29. 13 2
      docs/api/it/renderers/WebGLRenderer.html
  30. 1 1
      docs/api/ko/animation/AnimationObjectGroup.html
  31. 1 1
      docs/api/ko/animation/AnimationUtils.html
  32. 1 1
      docs/api/ko/geometries/CapsuleGeometry.html
  33. 19 16
      docs/api/zh/geometries/BoxGeometry.html
  34. 1 1
      docs/api/zh/geometries/CapsuleGeometry.html
  35. 22 17
      docs/api/zh/geometries/PlaneGeometry.html
  36. 16 7
      docs/api/zh/helpers/AxesHelper.html
  37. 210 45
      docs/api/zh/math/Matrix3.html
  38. 579 84
      docs/api/zh/math/Matrix4.html
  39. 4 0
      docs/api/zh/math/Quaternion.html
  40. 7 0
      docs/api/zh/objects/Mesh.html
  41. 4 3
      docs/api/zh/objects/SkinnedMesh.html
  42. 12 2
      docs/api/zh/renderers/WebGLRenderer.html
  43. 15 0
      docs/examples/en/controls/OrbitControls.html
  44. 70 0
      docs/examples/en/geometries/SDFGeometryGenerator.html
  45. 1 1
      docs/examples/en/objects/Lensflare.html
  46. 122 0
      docs/examples/en/webxr/XREstimatedLight.html
  47. 1 1
      docs/examples/zh/objects/Lensflare.html
  48. 3 1
      docs/index.html
  49. 7 1
      docs/list.json
  50. 2 2
      docs/manual/en/introduction/Creating-a-scene.html
  51. 1 1
      docs/manual/ko/introduction/Creating-a-scene.html
  52. 2 2
      docs/manual/ko/introduction/FAQ.html
  53. 1 1
      docs/manual/ko/introduction/How-to-update-things.html
  54. 2 2
      docs/manual/ko/introduction/Installation.html
  55. 52 63
      docs/manual/zh/introduction/Creating-a-scene.html
  56. 191 87
      docs/manual/zh/introduction/Installation.html
  57. 110 0
      docs/manual/zh/introduction/Libraries-and-Plugins.html
  58. 19 14
      docs/manual/zh/introduction/WebGL-compatibility-check.html
  59. 1 0
      docs/scenes/material-browser.html
  60. 2 0
      editor/js/Editor.js
  61. 0 65
      editor/js/Menubar.Edit.js
  62. 1 1
      editor/js/Sidebar.Animation.js
  63. 3 1
      editor/js/Sidebar.Material.MapProperty.js
  64. 1 1
      editor/js/Sidebar.Scene.js
  65. 0 3
      editor/js/Strings.js
  66. 7 0
      editor/js/Viewport.js
  67. 33 4
      editor/js/libs/ui.three.js
  68. 0 3
      editor/sw.js
  69. 6 0
      examples/files.json
  70. 3 1
      examples/index.html
  71. 290 0
      examples/jsm/Addons.js
  72. 26 0
      examples/jsm/controls/FlyControls.js
  73. 12 1
      examples/jsm/controls/OrbitControls.js
  74. 27 11
      examples/jsm/controls/TransformControls.js
  75. 1 1
      examples/jsm/csm/CSMShader.js
  76. 72 2
      examples/jsm/exporters/GLTFExporter.js
  77. 174 0
      examples/jsm/geometries/InstancedPointsGeometry.js
  78. 144 0
      examples/jsm/geometries/SDFGeometryGenerator.js
  79. 6 1
      examples/jsm/libs/lottie_canvas.module.js
  80. 13 75
      examples/jsm/libs/opentype.module.js
  81. 201 0
      examples/jsm/libs/surfaceNet.js
  82. 12 3
      examples/jsm/loaders/GLTFLoader.js
  83. 162 0
      examples/jsm/loaders/LUTImageLoader.js
  84. 89 93
      examples/jsm/loaders/lwo/IFFParser.js
  85. 2 0
      examples/jsm/materials/MeshGouraudMaterial.js
  86. 0 55
      examples/jsm/math/Capsule.js
  87. 70 3
      examples/jsm/math/Octree.js
  88. 103 11
      examples/jsm/modifiers/SimplifyModifier.js
  89. 3 3
      examples/jsm/modifiers/TessellateModifier.js
  90. 6 6
      examples/jsm/nodes/Nodes.js
  91. 3 3
      examples/jsm/nodes/accessors/CubeTextureNode.js
  92. 0 76
      examples/jsm/nodes/accessors/ExtendedMaterialNode.js
  93. 3 3
      examples/jsm/nodes/accessors/InstanceNode.js
  94. 21 0
      examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js
  95. 0 29
      examples/jsm/nodes/accessors/LineMaterialNode.js
  96. 68 31
      examples/jsm/nodes/accessors/MaterialNode.js
  97. 1 2
      examples/jsm/nodes/accessors/ModelNode.js
  98. 5 5
      examples/jsm/nodes/accessors/MorphNode.js
  99. 1 1
      examples/jsm/nodes/accessors/NormalNode.js
  100. 1 1
      examples/jsm/nodes/accessors/PositionNode.js

File diff suppressed because it is too large
+ 732 - 697
build/three.cjs


File diff suppressed because it is too large
+ 732 - 697
build/three.js


File diff suppressed because it is too large
+ 0 - 0
build/three.min.js


File diff suppressed because it is too large
+ 732 - 697
build/three.module.js


File diff suppressed because it is too large
+ 0 - 0
build/three.module.min.js


+ 1 - 1
docs/api/ar/geometries/CapsuleGeometry.html

@@ -47,7 +47,7 @@
 		<h2>المنشئ (Constructor)</h2>
 
  		<h3>
- 		[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])
+ 		[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])
  		</h3>
  		<p>
  		radius — نصف قطر الكبسولة. اختياري؛ الافتراضي هو 1.<br />

+ 210 - 44
docs/api/ar/math/Matrix3.html

@@ -86,19 +86,76 @@ m.elements = [ 11, 21, 31,
 		<p>
 		يستخرج [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) الأساس]
 		لهذه المصفوفة في ثلاثة متجهات محورية مقدمة. إذا كانت هذه المصفوفة
-		هي:
-		<code>
-	 a, b, c, 
-	 d, e, f, 
-	 g, h, i 
-		</code>
+		هي:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>d</mi></mtd>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+						<mtd><mi>i</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math><br /><br />
+
 		ثم سيتم تعيين [page:Vector3 xAxis] ، [page:Vector3 yAxis] ، [page:Vector3 zAxis]
-		إلى:
-		<code>
-	 xAxis = (a, d, g) 
-	 yAxis = (b, e, h) 
-	 zAxis = (c, f, i) 
-		</code>
+		إلى:<br /><br />
+
+		<math>
+			<mrow>
+				<mi>xAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>,
+
+		<math>
+			<mrow>
+				<mi>yAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>, and
+
+		<math>
+			<mrow>
+				<mi>zAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>
@@ -135,12 +192,31 @@ m.elements = [ 11, 21, 31,
 	 
 		<h3>[method:this identity]()</h3>
 		<p>
-		يعيد هذه المصفوفة إلى مصفوفة الهوية 3x3:
-		<code> 
-	 1, 0, 0 
-	 0, 1, 0 
-	 0, 0, 1 
-		</code>
+		يعيد هذه المصفوفة إلى مصفوفة الهوية 3x3:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
@@ -149,12 +225,47 @@ m.elements = [ 11, 21, 31,
 		عكس عقارب الساعة.<br /><br />
 	 
 		يضع هذه المصفوفة كتحول دوران ثنائي الأبعاد بـ [page:Float theta]
-		راديان. المصفوفة الناتجة ستكون:
-		<code>
-	 cos(θ) -sin(θ) 0 
-	 sin(θ) cos(θ) 0 
-	 0 0 1
-		</code>
+		راديان. المصفوفة الناتجة ستكون:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>-sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
@@ -162,12 +273,31 @@ m.elements = [ 11, 21, 31,
 		[page:Float x] - المبلغ الذي يتم قياسه في المحور X.<br />
 		[page:Float y] - المبلغ الذي يتم قياسه في المحور Y.<br />
 	 
-		يضع هذه المصفوفة كتحول قياس ثنائي الأبعاد:
-		<code> 
-	 x, 0, 0, 
-	 0, y, 0, 
-	 0, 0, 1 
-		</code>
+		يضع هذه المصفوفة كتحول قياس ثنائي الأبعاد:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
@@ -178,12 +308,31 @@ m.elements = [ 11, 21, 31,
 		[page:Float x] - المبلغ الذي يتم ترجمته في المحور X.<br />
 		[page:Float y] - المبلغ الذي يتم ترجمته في المحور Y.<br />
 	 
-		يضع هذه المصفوفة كتحويل ترجمة ثنائي الأبعاد:
-		<code>
-	 1, 0, x, 
-	 0, 1, y, 
-	 0, 0, 1 
-		</code>
+		يضع هذه المصفوفة كتحويل ترجمة ثنائي الأبعاد:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
@@ -207,15 +356,32 @@ m.elements = [ 11, 21, 31,
 		[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )
 		</h3>
 		<p>
-		[page:Float n11] - القيمة التي يتم وضعها في الصف 1 ، العمود 1.<br />
-		[page:Float n12] - القيمة التي يتم وضعها في الصف 1 ، العمود 2.<br />
-		...<br />
-		...<br />
-		[page:Float n32] - القيمة التي يتم وضعها في الصف 3 ، العمود 2.<br />
-		[page:Float n33] - القيمة التي يتم وضعها في الصف 3 ، العمود 3.<br /><br />
-	 
 		يضع قيم المصفوفة 3x3 على
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order تسلسل قيم رئيسية للصف].
+		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order تسلسل قيم رئيسية للصف]:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>n11</mi></mtd>
+						<mtd><mi>n12</mi></mtd>
+						<mtd><mi>n13</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n21</mi></mtd>
+						<mtd><mi>n22</mi></mtd>
+						<mtd><mi>n23</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n31</mi></mtd>
+						<mtd><mi>n32</mi></mtd>
+						<mtd><mi>n33</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>

+ 579 - 78
docs/api/ar/math/Matrix4.html

@@ -63,7 +63,7 @@
 
 		<h2>ملاحظة حول ترتيب الصف الرئيسي والعمود الرئيسي</h2>
 		<p>
-		يأخذ الباني وطريقة [page:set]() المعاملات في
+		يأخذ الباني وطريقة [page:.set set]() المعاملات في
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major] 
 		ترتيب ، في حين يتم تخزينها داخليًا في مصفوفة [page:.elements elements] بترتيب العمود الرئيسي. <br /><br />
 	 
@@ -194,20 +194,85 @@
 		<p>
 		يستخرج[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 		من هذه المصفوفة في المتجهات الثلاثة المحورية المقدمة. إذا كانت هذه المصفوفة
-		:
-		<code>
-	 a، b، c، d، 
-	 e، f، g، h، 
-	 i، j، k، l، 
-	 m، n، o، p 
-		</code>
+		:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math><br /><br />
+
 		ثم سيتم تعيين[page:Vector3 xAxis] ،[page:Vector3 yAxis] ،[page:Vector3 zAxis]
-		إلى:
-		<code>
-	 xAxis = (a, e, i) 
-	 yAxis = (b, f, j) 
-	 zAxis = (c, g, k) 
-		</code>
+		إلى:<br /><br />
+
+		<math>
+			<mrow>
+				<mi>xAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>,
+
+		<math>
+			<mrow>
+				<mi>yAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>j</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>, and
+
+		<math>
+			<mrow>
+				<mi>zAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>k</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
@@ -272,13 +337,40 @@
 		</h3>
 		<p>
 		قم بتعيين هذا إلى [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
-		مصفوفة تتكون من المتجهات الأساسية الثلاثة المقدمة:
-		<code>
-		xAxis.x، yAxis.x، zAxis.x، 0، 
-		xAxis.y، yAxis.y، zAxis.y، 0، 
-		xAxis.z، yAxis.z، zAxis.z، 0، 
-		0, 		0, 		0, 	   1
-		</code>
+		مصفوفة تتكون من المتجهات الأساسية الثلاثة المقدمة:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>xAxis.x</mi></mtd>
+						<mtd><mi>yAxis.x</mi></mtd>
+						<mtd><mi>zAxis.x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.y</mi></mtd>
+						<mtd><mi>yAxis.y</mi></mtd>
+						<mtd><mi>zAxis.y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.z</mi></mtd>
+						<mtd><mi>yAxis.z</mi></mtd>
+						<mtd><mi>zAxis.z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 		 
 		<h3>
@@ -314,13 +406,136 @@
 		[page:Quaternion q] ، كما هو مبين
 		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion هنا]. ال
 		باقي من المصفوفة يتم تعيينه إلى المعرف. لذلك ، بالنظر إلى[page:Quaternion q] =
-		w + xi + yj + zk ، فإن المصفوفة الناتجة ستكون:
-		<code>
-1-2y²-2z² 	2xy-2zw 	2xz+2yw 	0 
-2xy+2zw   	1-2x²-2z² 	2yz-2xw 	0 
-2xz-2yw   	2yz+2xw   	1-2x²-2y²   0
-	0 			0	 		0 		1
-			</code>
+		w + xi + yj + zk ، فإن المصفوفة الناتجة ستكون:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>y</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>z</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>x</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>z</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>x</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>y</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
@@ -328,13 +543,61 @@
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور X بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
-		<code>
-1 		0	 		0 			0 
-0 	cos(&theta;) -sin(&theta;) 	0 
-0 	sin(&theta;) cos(&theta;) 	0 
-0 		0			0 			1
-		</code>
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
@@ -342,11 +605,61 @@
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور Y بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
-		<code>
-		cos(&theta;) 0 sin(&theta;) 0 0 1 0 0 -sin(&theta;) 0 cos(&theta;) 0 0 0
-		0 1
-		</code>
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
@@ -354,13 +667,61 @@
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور Z بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
-		<code>
-cos(&theta;) -sin(&theta;) 0 0 
-sin(&theta;) cos(&theta;)  0 0 
-0 		0 	1   0 
-0 		0	0   1
-				</code>
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+			
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>
@@ -371,13 +732,40 @@ sin(&theta;) cos(&theta;)  0 0
 		[page:Float y] - المقدار الذي يجب تغييره في محور Y. <br />
 		[page:Float z] - المقدار الذي يجب تغييره في محور Z. <br /><br />
 	 
-		يضع هذه المصفوفة كتحويل قياس:
-		<code>
-	 x، 0، 0، 0، 
-	 0، y، 0، 0، 
-	 0، 0، z، 0، 
-	 0، 0، 0، 1 
-		</code>
+		يضع هذه المصفوفة كتحويل قياس:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 	 
 		<h3>
@@ -392,12 +780,40 @@ sin(&theta;) cos(&theta;)  0 0
 		[page:Float zx] - المقدار الذي يجب قصه Z بواسطة X. <br />
 		[page:Float zy] - المقدار الذي يجب قصه Z بواسطة Y. <br /><br />
 		 
-		يضع هذه المصفوفة كتحويل قص:
-		<code> 
-		1، yx، zx، 0، 
-		xy، 1، zy، 0، 
-		xz، yz، 1، 0، 
-		0، 0، 0، 1 </code>
+		يضع هذه المصفوفة كتحويل قص:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi><mi>x</mi></mtd>
+						<mtd><mi>z</mi><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>y</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>z</mi></mtd>
+						<mtd><mi>y</mi><mi>z</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 		 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
@@ -405,12 +821,40 @@ sin(&theta;) cos(&theta;)  0 0
 		[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // واجهة برمجة التطبيقات الاختيارية
 		</h3>
 		<p>
-		يضع هذه المصفوفة كتحويل ترجمة من متجه [page:Vector3 v] ، أو أرقام [page:Float x] ، [page:Float y] و [page:Float z]:
-		<code> 
-		1، 0، 0، x، 
-		0، 1، 0، y، 
-		0، 0، 1، z، 
-		0، 0، 0، 1 </code>
+		يضع هذه المصفوفة كتحويل ترجمة من متجه [page:Vector3 v] ، أو أرقام [page:Float x] ، [page:Float y] و [page:Float z]:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 		 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
@@ -453,18 +897,75 @@ sin(&theta;) cos(&theta;)  0 0
 		<p>
 		يضع مكون الموضع لهذه المصفوفة من المتجه [page:Vector3 v] ،
 		دون التأثير على بقية المصفوفة - أي إذا كانت المصفوفة هي
-		حاليا:
-		<code>
-		a, b, c, d, 
-		e, f, g, h, 
-		i, j, k, l, 
-		m, n, o, p </code>
-		هذا يصبح:
-		<code>
-		a, b, c, v.x, 
-		e, f, g, v.y, 
-		i, j, k, v.z, 
-		m, n, o, p </code>
+		حاليا:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math><br /><br />
+
+		هذا يصبح:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>v.x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>v.y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>v.z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 		 
 		<h3>

+ 4 - 0
docs/api/ar/math/Quaternion.html

@@ -19,6 +19,10 @@
 		التكرار عبر مثيل [name] سيعطي مكوناته (x، y، z، w)
 		بالترتيب المقابل.
 		</p>
+
+		<p>
+			لاحظ أن three.js تتوقع أن يتم تسوية Quaternions.
+		</p>
 		 
 		<h2>مثال الكود</h2>
 		 

+ 4 - 4
docs/api/ar/objects/SkinnedMesh.html

@@ -99,10 +99,10 @@
 		
 		<h3>[property:String bindMode]</h3>
 		<p>
-		إما "مرفق" أو "منفصل". "مرفق" يستخدم
-		خاصية [page:SkinnedMesh.matrixWorld] لمصفوفة التحويل الأساسية لـ
-		العظام. "منفصل" يستخدم [page:SkinnedMesh.bindMatrix]. الافتراضي هو
-		"مرفق".
+			Either `AttachedBindMode` or `DetachedBindMode`. `AttachedBindMode` means the skinned mesh
+			shares the same world space as the skeleton. This is not true when using `DetachedBindMode`
+			which is useful when sharing a skeleton across multiple skinned meshes.
+			Default is `AttachedBindMode`.
 		</p>
 		
 		<h3>[property:Matrix4 bindMatrix]</h3>

+ 14 - 3
docs/api/ar/renderers/WebGLRenderer.html

@@ -350,11 +350,22 @@
 		</p>
 		 
 		<h3>
-		[method:undefined compile]( [param:Object3D scene], [param:Camera camera] )
+		[method:Set compile]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )
 		</h3>
 		<p>
-		يجمع جميع المواد في المشهد مع الكاميرا. هذا مفيد لـ
-		تجميع الشادرات قبل العرض الأول.
+		يجمع جميع المواد الموجودة في المشهد بالكاميرا. يعد هذا مفيدًا لتجميع التظليل مسبقًا قبل العرض الأول.
+		إذا كنت تريد إضافة كائن ثلاثي الأبعاد إلى مشهد موجود، فاستخدم المعلمة الاختيارية الثالثة لتطبيق المشهد المستهدف. <br />
+		لاحظ أنه يجب تكوين إضاءة المشهد قبل استدعاء هذه الطريقة.
+		</p>
+
+		<h3>
+			[method:Promise compileAsync]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )
+		</h3>
+		<p>
+			إصدار غير متزامن من [page:WebGLRenderer.compile .compile](). تقوم الطريقة بإرجاع Promise 
+			الذي يتم حله عندما يمكن عرض الكائن أو المشهد ثلاثي الأبعاد المحدد دون توقف غير ضروري بسبب تجميع التظليل.<br /><br />
+			
+			تستخدم هذه الطريقة *KHR_parallel_shader_compile*.
 		</p>
 		 
 		<h3>

+ 4 - 0
docs/api/en/constants/CustomBlendingEquations.html

@@ -52,6 +52,10 @@
 		THREE.DstColorFactor
 		THREE.OneMinusDstColorFactor 
 		THREE.SrcAlphaSaturateFactor
+		THREE.ConstantColorFactor
+		THREE.OneMinusConstantColorFactor
+		THREE.ConstantAlphaFactor
+		THREE.OneMinusConstantAlphaFactor
 		</code>
 
 		<h2>Destination Factors</h2>

+ 1 - 1
docs/api/en/extras/core/Curve.html

@@ -77,7 +77,7 @@
 
 		<h3>[method:undefined updateArcLengths]()</h3>
 		<p>
-			Update the cumlative segment distance cache. The method must be called
+			Update the cumulative segment distance cache. The method must be called
 			every time curve parameters are changed. If an updated curve is part of a
 			composed curve like [page:CurvePath], [page:.updateArcLengths]() must be
 			called on the composed curve, too.

+ 1 - 1
docs/api/en/geometries/CapsuleGeometry.html

@@ -48,7 +48,7 @@ const capsule = new THREE.Mesh( geometry, material ); scene.add( capsule );
 		<h2>Constructor</h2>
 
 		<h3>
-			[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])
+			[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])
 		</h3>
 		<p>
 			radius — Radius of the capsule. Optional; defaults to `1`.<br />

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

@@ -40,7 +40,7 @@
 		<h3>[property:Float intensity]</h3>
 		<p>
 			The light's intensity, or strength.<br />
-			Tthe units of intensity depend on the type of light.<br />
+			The units of intensity depend on the type of light.<br />
 			Default - `1.0`.
 		</p>
 

+ 1 - 1
docs/api/en/loaders/managers/LoadingManager.html

@@ -87,7 +87,7 @@
 
 		<p>
 			[example:webgl_loader_obj WebGL / loader / obj]<br />
-			[example:webgl_postprocessing_outline WebGL / postprocesing / outline]
+			[example:webgl_postprocessing_outline WebGL / postprocessing / outline]
 		</p>
 
 		<h2>Constructor</h2>

+ 16 - 1
docs/api/en/materials/Material.html

@@ -49,6 +49,20 @@
 			`true`). Default is `false`.
 		</p>
 
+		<h3>[property:Float blendAlpha]</h3>
+		<p>
+			Represents the alpha value of the constant blend color. Default is `0`.
+
+			This property has only an effect when using custom blending with [page:CustomBlendingEquation ConstantAlpha] or [page:CustomBlendingEquation OneMinusConstantAlpha].
+		</p>
+
+		<h3>[property:Color blendColor]</h3>
+		<p>
+			Represent the RGB values of the constant blend color. Default is `0x000000`.<br />
+
+			This property has only an effect when using custom blending with [page:CustomBlendingEquation ConstantColor] or [page:CustomBlendingEquation OneMinusConstantColor].
+		</p>
+
 		<h3>[property:Integer blendDst]</h3>
 		<p>
 			Blending destination. Default is [page:CustomBlendingEquation OneMinusSrcAlphaFactor]. 
@@ -147,7 +161,8 @@
 		<h3>[property:Boolean depthTest]</h3>
 		<p>
 			Whether to have depth test enabled when rendering this material. Default
-			is `true`.
+			is `true`. When the depth test is disabled, the depth write will also be
+			implicitly disabled.
 		</p>
 
 		<h3>[property:Boolean depthWrite]</h3>

+ 210 - 41
docs/api/en/math/Matrix3.html

@@ -86,19 +86,76 @@ m.elements = [ 11, 21, 31,
 		<p>
 			Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 			of this matrix into the three axis vectors provided. If this matrix
-			is:
-			<code>
-a, b, c, 
-d, e, f, 
-g, h, i 
-			</code>
+			is:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>d</mi></mtd>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+							<mtd><mi>i</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
-			will be set to:
-			<code>
-xAxis = (a, d, g) 
-yAxis = (b, e, h) 
-zAxis = (c, f, i) 
-			</code>
+			will be set to:<br /><br />
+
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
+
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
+
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>
@@ -136,11 +193,31 @@ zAxis = (c, f, i)
 
 		<h3>[method:this identity]()</h3>
 		<p>
-			Resets this matrix to the 3x3 identity matrix:
-			<code> 
-1, 0, 0 
-0, 1, 0 
-0, 0, 1 	</code>
+			Resets this matrix to the 3x3 identity matrix:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
@@ -149,12 +226,47 @@ zAxis = (c, f, i)
 			counterclockwise.<br /><br />
 
 			Sets this matrix as a 2D rotational transformation by [page:Float theta]
-			radians. The resulting matrix will be:
-			<code>
-cos(&theta;) -sin(&theta;) 0 
-sin(&theta;) cos(&theta;) 0 
-0 0 1
-			</code>
+			radians. The resulting matrix will be:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mi>-sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
@@ -162,11 +274,31 @@ sin(&theta;) cos(&theta;) 0
 			[page:Float x] - the amount to scale in the X axis.<br />
 			[page:Float y] - the amount to scale in the Y axis.<br />
 
-			Sets this matrix as a 2D scale transform:
-			<code> 
-x, 0, 0, 
-0, y, 0, 
-0, 0, 1 	</code>
+			Sets this matrix as a 2D scale transform:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
@@ -177,11 +309,31 @@ x, 0, 0,
 			[page:Float x] - the amount to translate in the X axis.<br />
 			[page:Float y] - the amount to translate in the Y axis.<br />
 
-			Sets this matrix as a 2D translation transform:
-			<code>
-1, 0, x, 
-0, 1, y, 
-0, 0, 1 	</code>
+			Sets this matrix as a 2D translation transform:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
@@ -205,16 +357,33 @@ x, 0, 0,
 			[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )
 		</h3>
 		<p>
-			[page:Float n11] - value to put in row 1, col 1.<br />
-			[page:Float n12] - value to put in row 1, col 2.<br />
-			...<br />
-			...<br />
-			[page:Float n32] - value to put in row 3, col 2.<br />
-			[page:Float n33] - value to put in row 3, col 3.<br /><br />
-
 			Sets the 3x3 matrix values to the given
 			[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major]
-			sequence of values.
+			sequence of values:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>n11</mi></mtd>
+							<mtd><mi>n12</mi></mtd>
+							<mtd><mi>n13</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>n21</mi></mtd>
+							<mtd><mi>n22</mi></mtd>
+							<mtd><mi>n23</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>n31</mi></mtd>
+							<mtd><mi>n32</mi></mtd>
+							<mtd><mi>n33</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>

+ 579 - 75
docs/api/en/math/Matrix4.html

@@ -62,7 +62,7 @@
 
 		<h2>A Note on Row-Major and Column-Major Ordering</h2>
 		<p>
-			The constructor and [page:set]() method take arguments in
+			The constructor and [page:.set set]() method take arguments in
 			[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major] 
 			order, while internally they are stored in the [page:.elements elements] array in column-major order.<br /><br />
 
@@ -191,18 +191,85 @@ m.elements = [ 11, 21, 31, 41,
 		<p>
 			Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 			of this matrix into the three axis vectors provided. If this matrix
-			is:
-		<code>
-a, b, c, d, 
-e, f, g, h, 
-i, j, k, l, 
-m, n, o, p </code>
+			is:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
-			will be set to:
-			<code>
-xAxis = (a, e, i) 
-yAxis = (b, f, j) 
-zAxis = (c, g, k) </code>
+			will be set to:<br /><br />
+
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
+
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>j</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
+
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>k</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
@@ -268,13 +335,40 @@ zAxis = (c, g, k) </code>
 		</h3>
 		<p>
 			Set this to the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
-			matrix consisting of the three provided basis vectors:
-			<code>
-xAxis.x, yAxis.x, zAxis.x, 0, 
-xAxis.y, yAxis.y, zAxis.y, 0, 
-xAxis.z, yAxis.z, zAxis.z, 0, 
-	0, 		0, 		0, 	   1
-			</code>
+			matrix consisting of the three provided basis vectors:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>xAxis.x</mi></mtd>
+							<mtd><mi>yAxis.x</mi></mtd>
+							<mtd><mi>zAxis.x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.y</mi></mtd>
+							<mtd><mi>yAxis.y</mi></mtd>
+							<mtd><mi>zAxis.y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.z</mi></mtd>
+							<mtd><mi>yAxis.z</mi></mtd>
+							<mtd><mi>zAxis.z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>
@@ -311,13 +405,136 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 			[page:Quaternion q], as outlined
 			[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here]. The
 			rest of the matrix is set to the identity. So, given [page:Quaternion q] =
-			w + xi + yj + zk, the resulting matrix will be:
-			<code>
-1-2y²-2z² 	2xy-2zw 	2xz+2yw 	0 
-2xy+2zw   	1-2x²-2z² 	2yz-2xw 	0 
-2xz-2yw   	2yz+2xw   	1-2x²-2y²   0
-	0 			0	 		0 		1
-			</code>
+			w + xi + yj + zk, the resulting matrix will be:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>y</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>z</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>y</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>z</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>z</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>y</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>z</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>x</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>z</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>z</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>z</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>z</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>x</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>y</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
@@ -325,13 +542,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 			[page:Float theta] — Rotation angle in radians.<br /><br />
 
 			Sets this matrix as a rotational transformation around the X axis by
-			[page:Float theta] (&theta;) radians. The resulting matrix will be:
-			<code>
-	1 		0	 		0 			0 
-	0 	cos(&theta;) -sin(&theta;) 	0 
-	0 	sin(&theta;) cos(&theta;) 	0 
-	0 		0			0 			1
-			</code>
+			[page:Float theta] (&theta;) radians. The resulting matrix will be:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mo>-</mo>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
@@ -339,11 +604,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 			[page:Float theta] — Rotation angle in radians.<br /><br />
 
 			Sets this matrix as a rotational transformation around the Y axis by
-			[page:Float theta] (&theta;) radians. The resulting matrix will be:
-			<code>
-				cos(&theta;) 0 sin(&theta;) 0 0 1 0 0 -sin(&theta;) 0 cos(&theta;) 0 0 0
-				0 1
-			</code>
+			[page:Float theta] (&theta;) radians. The resulting matrix will be:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mo>-</mo>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
@@ -351,13 +666,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 			[page:Float theta] — Rotation angle in radians.<br /><br />
 
 			Sets this matrix as a rotational transformation around the Z axis by
-			[page:Float theta] (&theta;) radians. The resulting matrix will be:
-			<code>
-cos(&theta;) -sin(&theta;) 0 0 
-sin(&theta;) cos(&theta;)  0 0 
-	0 			0 		   1 0 
-	0 			0		   0 1
-			</code>
+			[page:Float theta] (&theta;) radians. The resulting matrix will be:<br /><br />
+			
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mo>-</mo>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mi>sin</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mi>cos</mi>
+								<mi>&theta;</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>
@@ -368,12 +731,40 @@ sin(&theta;) cos(&theta;)  0 0
 			[page:Float y] - the amount to scale in the Y axis.<br />
 			[page:Float z] - the amount to scale in the Z axis.<br /><br />
 
-			Sets this matrix as scale transform:
-			<code>
-x, 0, 0, 0, 
-0, y, 0, 0, 
-0, 0, z, 0, 
-0, 0, 0, 1 </code>
+			Sets this matrix as scale transform:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>
@@ -388,12 +779,40 @@ x, 0, 0, 0,
 			[page:Float zx] - the amount to shear Z by X.<br />
 			[page:Float zy] - the amount to shear Z by Y.<br /><br />
 
-			Sets this matrix as a shear transform:
-			<code> 
-1, yx, zx, 0, 
-xy, 1, zy, 0, 
-xz, yz, 1, 0, 
-0, 0, 0, 1 </code>
+			Sets this matrix as a shear transform:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>y</mi><mi>x</mi></mtd>
+							<mtd><mi>z</mi><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>x</mi><mi>y</mi></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>z</mi><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>x</mi><mi>z</mi></mtd>
+							<mtd><mi>y</mi><mi>z</mi></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
@@ -401,12 +820,40 @@ xz, yz, 1, 0,
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 		</h3>
 		<p>
-			Sets this matrix as a translation transform from vector [page:Vector3 v], or numbers [page:Float x], [page:Float y] and [page:Float z]:
-			<code> 
-1, 0, 0, x, 
-0, 1, 0, y, 
-0, 0, 1, z, 
-0, 0, 0, 1 </code>
+			Sets this matrix as a translation transform from vector [page:Vector3 v], or numbers [page:Float x], [page:Float y] and [page:Float z]:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>z</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
@@ -449,18 +896,75 @@ xz, yz, 1, 0,
 		<p>
 			Sets the position component for this matrix from vector [page:Vector3 v],
 			without affecting the rest of the matrix - i.e. if the matrix is
-			currently:
-			<code>
-a, b, c, d, 
-e, f, g, h, 
-i, j, k, l, 
-m, n, o, p </code>
-			This becomes:
-			<code>
-a, b, c, v.x, 
-e, f, g, v.y, 
-i, j, k, v.z, 
-m, n, o, p </code>
+			currently:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			This becomes:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>v.x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>v.y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>v.z</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>

+ 4 - 0
docs/api/en/math/Quaternion.html

@@ -20,6 +20,10 @@
 			in the corresponding order.
 		</p>
 
+		<p>
+			Note that three.js expects Quaternions to be normalized.
+		</p>
+
 		<h2>Code Example</h2>
 
 		<code>

+ 4 - 4
docs/api/en/objects/SkinnedMesh.html

@@ -99,10 +99,10 @@
 
 		<h3>[property:String bindMode]</h3>
 		<p>
-			Either "attached" or "detached". "attached" uses the
-			[page:SkinnedMesh.matrixWorld] property for the base transform matrix of
-			the bones. "detached" uses the [page:SkinnedMesh.bindMatrix]. Default is
-			"attached".
+			Either `AttachedBindMode` or `DetachedBindMode`. `AttachedBindMode` means the skinned mesh
+			shares the same world space as the skeleton. This is not true when using `DetachedBindMode`
+			which is useful when sharing a skeleton across multiple skinned meshes.
+			Default is `AttachedBindMode`.
 		</p>
 
 		<h3>[property:Matrix4 bindMatrix]</h3>

+ 14 - 3
docs/api/en/renderers/WebGLRenderer.html

@@ -348,11 +348,22 @@ document.body.appendChild( renderer.domElement );
 		</p>
 
 		<h3>
-			[method:undefined compile]( [param:Object3D scene], [param:Camera camera] )
+			[method:Set compile]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )
 		</h3>
 		<p>
-			Compiles all materials in the scene with the camera. This is useful to
-			precompile shaders before the first rendering.
+			Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first rendering.
+			If you want to add a 3D object to an existing scene, use the third optional parameter for applying the target scene.<br />
+			Note that the (target) scene's lighting and environment should be configured before calling this method.
+		</p>	
+
+		<h3>
+			[method:Promise compileAsync]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )
+		</h3>
+		<p>
+			Asynchronous version of [page:WebGLRenderer.compile .compile](). The method returns a Promise that resolves when the 
+			given scene can be rendered without unnecessary stalling due to shader compilation.<br /><br />
+			
+			This method makes use of the *KHR_parallel_shader_compile* WebGL extension.
 		</p>
 
 		<h3>

+ 1 - 1
docs/api/fr/geometries/CapsuleGeometry.html

@@ -44,7 +44,7 @@
 
 		<h2>Constructeur</h2>
 
-		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])</h3>
+		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])</h3>
 		<p>
 
 		radius — Rayon de la capsule. Optionnel; par défaut à 1.<br />

+ 1 - 1
docs/api/it/geometries/CapsuleGeometry.html

@@ -44,7 +44,7 @@
 
 		<h2>Costruttore</h2>
 
-		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])</h3>
+		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])</h3>
 		<p>
 
 		radius — Raggio della capsula. Opzionale; il valore predefinito è 1.<br />

+ 210 - 45
docs/api/it/math/Matrix3.html

@@ -81,18 +81,75 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
-			nei tre vettori asse forniti. Se questa matrice è:
-		<code>
-a, b, c,
-d, e, f,
-g, h, i
-		</code>
-		allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a:
-		<code>
-xAxis = (a, d, g)
-yAxis = (b, e, h)
-zAxis = (c, f, i)
-		</code>
+			nei tre vettori asse forniti. Se questa matrice è:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>d</mi></mtd>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+							<mtd><mi>i</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a:<br /><br />
+
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
+
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
+
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
@@ -122,13 +179,31 @@ zAxis = (c, f, i)
 
 		<h3>[method:this identity]()</h3>
 		<p>
-			Reimposta questa matrice alla matrice identità 3x3:
-		<code>
-1, 0, 0
-0, 1, 0
-0, 0, 1
-		</code>
-
+			Reimposta questa matrice alla matrice identità 3x3:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
@@ -136,12 +211,47 @@ zAxis = (c, f, i)
 		[page:Float theta] — Angolo di rotazione in radianti. I valori positivi ruotano in senso antiorario.<br /><br />
 
 		Imposta questa matrice come una trasformazione rotazionale 2D di [page:Float teta] radianti.
-		La matrice risultante sarà:
-		<code>
-cos(&theta;) -sin(&theta;) 0
-sin(&theta;) cos(&theta;)  0
-0      0       1
-		</code>
+		La matrice risultante sarà:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>-sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
@@ -149,12 +259,31 @@ sin(&theta;) cos(&theta;)  0
 		[page:Float x] - la quantità da scalare sull'asse X.<br />
 		[page:Float y] - la quantità da scalare sull'asse Y.<br />
 
-		Imposta questa matrice come una trasformazione di scala 2D:
-		<code>
-x, 0, 0,
-0, y, 0,
-0, 0, 1
-		</code>
+		Imposta questa matrice come una trasformazione di scala 2D:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
@@ -165,12 +294,31 @@ x, 0, 0,
 		[page:Float x] - la quantità da translare sull'asse X.<br />
 		[page:Float y] - la quantità da translare sull'asse Y.<br />
 
-		Imposta questa matrice come una trasformazione di traslazione 2D:
-		<code>
-1, 0, x,
-0, 1, y,
-0, 0, 1
-		</code>
+		Imposta questa matrice come una trasformazione di traslazione 2D:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
@@ -190,15 +338,32 @@ x, 0, 0,
 
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
-		[page:Float n11] - valore da inserire nella riga 1, colonna 1.<br />
-		[page:Float n12] - valore da inserire nella riga 1, colonna 2.<br />
-		...<br />
-		...<br />
-		[page:Float n32] - valore da inserire nella riga 3, colonna 2.<br />
-		[page:Float n33] - valore da inserire nella riga 3, colonna 3.<br /><br />
-
 		Imposta i valori della matrice 3x3 sulla sequenza di valori della
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] specificata.
+		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] specificata.<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>n11</mi></mtd>
+						<mtd><mi>n12</mi></mtd>
+						<mtd><mi>n13</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n21</mi></mtd>
+						<mtd><mi>n22</mi></mtd>
+						<mtd><mi>n23</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n31</mi></mtd>
+						<mtd><mi>n32</mi></mtd>
+						<mtd><mi>n33</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>

+ 580 - 84
docs/api/it/math/Matrix4.html

@@ -54,7 +54,7 @@
 
 		<h2>Una nota sull'ordine delle Row-Major (righe principali) e delle Column-Major (colonne principali)</h2>
 		<p>
-			Il metodo [page:set]() accetta gli argomenti in ordine 
+			Il metodo [page:.set set]() accetta gli argomenti in ordine 
 			[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major], mentre internamente 
 			vengono memorizzati nell'array [page:.elements elements] nell'ordine column-major.<br /><br />
 
@@ -164,19 +164,85 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
-			nei tre vettori asse forniti. Se questa matrice è:
-		<code>
-a, b, c, d,
-e, f, g, h,
-i, j, k, l,
-m, n, o, p
-		</code>
-		allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a:
-		<code>
-xAxis = (a, e, i)
-yAxis = (b, f, j)
-zAxis = (c, g, k)
-		</code>
+			nei tre vettori asse forniti. Se questa matrice è:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
+			will be set to:<br /><br />
+
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
+
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>j</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
+
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>k</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
@@ -226,13 +292,40 @@ zAxis = (c, g, k)
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 			Imposta questo sulla matrice di [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] composta dai tre
-			vettori di base forniti:
-		<code>
-xAxis.x, yAxis.x, zAxis.x, 0,
-xAxis.y, yAxis.y, zAxis.y, 0,
-xAxis.z, yAxis.z, zAxis.z, 0,
-0,       0,       0,       1
-		</code>
+			vettori di base forniti:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>xAxis.x</mi></mtd>
+							<mtd><mi>yAxis.x</mi></mtd>
+							<mtd><mi>zAxis.x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.y</mi></mtd>
+							<mtd><mi>yAxis.y</mi></mtd>
+							<mtd><mi>zAxis.y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.z</mi></mtd>
+							<mtd><mi>yAxis.z</mi></mtd>
+							<mtd><mi>zAxis.z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
@@ -258,13 +351,136 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		<p>
 			Imposta il componente rotazinoe di questa matrice alla rotazione specificata da [page:Quaternion q], come 
 			descritto [link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion qui].
-			Il resto della matrice è impostato all'identità. Quindi, dato [page:Quaternion q] = w + xi + yj + zk, la matrice risultante sarà:
-		<code>
-1-2y²-2z²    2xy-2zw    2xz+2yw    0
-2xy+2zw      1-2x²-2z²  2yz-2xw    0
-2xz-2yw      2yz+2xw    1-2x²-2y²  0
-0            0          0          1
-		</code>
+			Il resto della matrice è impostato all'identità. Quindi, dato [page:Quaternion q] = w + xi + yj + zk, la matrice risultante sarà:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>y</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>z</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>y</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>z</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>z</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>y</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>z</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>x</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>z</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>z</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>z</mi>
+								<mo>-</mo>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>2</mn>
+								<mi>y</mi>
+								<mi>z</mi>
+								<mo>+</mo>
+								<mn>2</mn>
+								<mi>x</mi>
+								<mi>w</mi>
+							</mtd>
+							<mtd>
+								<mn>1</mn>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>x</mi>
+									<mn>2</mn>
+								</msup>
+								<mo>-</mo>
+								<mn>2</mn>
+								<msup>
+									<mi>y</mi>
+									<mn>2</mn>
+								</msup>
+							</mtd>
+							<mtd>
+								<mn>0</mn>
+							</mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
@@ -272,13 +488,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse X in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:
-		<code>
-1 0      0        0
-0 cos(&theta;) -sin(&theta;)  0
-0 sin(&theta;) cos(&theta;)   0
-0 0      0        1
-		</code>
+		La matrice risultante sarà:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
@@ -286,13 +550,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Y in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:
-		<code>
-cos(&theta;)  0 sin(&theta;) 0
-0       1 0      0
--sin(&theta;) 0 cos(&theta;) 0
-0       0 0      1
-		</code>
+		La matrice risultante sarà:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
@@ -300,13 +612,61 @@ cos(&theta;)  0 sin(&theta;) 0
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Z in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:
-		<code>
-cos(&theta;) -sin(&theta;) 0 0
-sin(&theta;) cos(&theta;)  0 0
-0      0       1 0
-0      0       0 1
-		</code>
+		La matrice risultante sarà:<br /><br />
+			
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
@@ -315,13 +675,40 @@ sin(&theta;) cos(&theta;)  0 0
 			[page:Float y] - la quantità da scalare sull'asse Y.<br />
 			[page:Float z] - la quantità da scalare sull'asse Z.<br /><br />
 
-			Imposta questa matrice come trasformazione di scala:
-			<code>
-x, 0, 0, 0,
-0, y, 0, 0,
-0, 0, z, 0,
-0, 0, 0, 1
-			</code>
+			Imposta questa matrice come trasformazione di scala:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], [param:Float yz], [param:Float zx], [param:Float zy] )</h3>
@@ -333,13 +720,40 @@ x, 0, 0, 0,
 			[page:Float zx] - la quantità di taglio di Z per X.<br />
 			[page:Float zy] - la quantità di taglio di Z per Y.<br /><br />
 
-			Imposta questa matrice come trasformata di taglio:
-<code>
-1,   yx,  zx,  0,
-xy,   1,  zy,  0,
-xz,  yz,   1,  0,
-0,    0,   0,  1
-</code>
+			Imposta questa matrice come trasformata di taglio:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>y</mi><mi>x</mi></mtd>
+							<mtd><mi>z</mi><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>x</mi><mi>y</mi></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>z</mi><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>x</mi><mi>z</mi></mtd>
+							<mtd><mi>y</mi><mi>z</mi></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
@@ -347,13 +761,40 @@ xz,  yz,   1,  0,
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 		</h3>
 		<p>
-			Imposta questa matrice come una trasformata di traslazione dal vettore [page:Vector3 v]:
-		<code>
-1, 0, 0, x,
-0, 1, 0, y,
-0, 0, 1, z,
-0, 0, 0, 1
-		</code>
+			Imposta questa matrice come una trasformata di traslazione dal vettore [page:Vector3 v]:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mi>z</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
@@ -384,20 +825,75 @@ xz,  yz,   1,  0,
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<p>
 			Imposta la componente posizione per questa matrice dal vettore [page:Vector3 v], senza influenzare 
-			il resto della matrice - ovvero se la matrice è attulmente:
-<code>
-a, b, c, d,
-e, f, g, h,
-i, j, k, l,
-m, n, o, p
-</code>
-Questa diventa:
-<code>
-a, b, c, v.x,
-e, f, g, v.y,
-i, j, k, v.z,
-m, n, o, p
-</code>
+			il resto della matrice - ovvero se la matrice è attulmente:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			Questa diventa:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>v.x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>v.y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>v.z</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>

+ 4 - 0
docs/api/it/math/Quaternion.html

@@ -18,6 +18,10 @@
 			L'iterazione di un'istanza di [name] produrrà le sue componenti (x, y, z, w) nell'ordine corrispondente.
 		</p>
 
+		<p>
+			Tieni presente che three.js prevede che i quaternioni siano normalizzati.
+		</p>
+
 		<h2>Codice di Esempio</h2>
 
 		<code>

+ 4 - 3
docs/api/it/objects/SkinnedMesh.html

@@ -101,10 +101,11 @@
 		<h2>Proprietà</h2>
 		<p>Vedi la classe base [page:Mesh] per le proprietà comuni.</p>
 
-		<h3>[property:String bindMode]</h3>
 		<p>
-			O "attached" o "detached". "attached" utilizza la proprietà [page:SkinnedMesh.matrixWorld]
-			per la matrice di trasformazione delle ossa. "detached" utilizza [page:SkinnedMesh.bindMatrix]. Il valore predefinito è "attached".
+			Either `AttachedBindMode` or `DetachedBindMode`. `AttachedBindMode` means the skinned mesh
+			shares the same world space as the skeleton. This is not true when using `DetachedBindMode`
+			which is useful when sharing a skeleton across multiple skinned meshes.
+			Default is `AttachedBindMode`.
 		</p>
 
 		<h3>[property:Matrix4 bindMatrix]</h3>

+ 13 - 2
docs/api/it/renderers/WebGLRenderer.html

@@ -307,8 +307,19 @@
 		<h3>[method:undefined clearStencil]( )</h3>
 		<p>Cancella il buffer di stencil. Equivalente a chiamare [page:WebGLRenderer.clear .clear]( false, false, true ).</p>
 
-		<h3>[method:undefined compile]( [param:Object3D scene], [param:Camera camera] )</h3>
-		<p>Compila tutti i materiali nella scena con la telecamera. Questo è utile per precompilare le ombre prima del primo rendering.</p>
+		<h3>[method:Set compile]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )</h3>
+		<p>
+			Compila tutti i materiali nella scena con la telecamera. Questo è utile per precompilare le ombre prima del primo rendering.
+			Se desideri aggiungere un oggetto 3D a una scena esistente, utilizza il terzo parametro opzionale per applicare la scena di destinazione.<br/>
+			Tieni presente che l'illuminazione della scena deve essere configurata prima di chiamare questo metodo.
+		</p>
+
+		<h3>[method:Promise compileAsync]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )</h3>
+		<p>
+			Versione asincrona di [page:WebGLRenderer.compile .compile](). Il metodo restituisce una Promise che si risolve quando è possibile eseguire 
+			il rendering di un determinato oggetto 3D o scena senza inutili stalli dovuti alla compilazione dello shader.<br /><br />
+			Questo metodo utilizza *KHR_parallel_shader_compile*.
+		</p>
 
 		<h3>[method:undefined copyFramebufferToTexture]( [param:Vector2 position], [param:FramebufferTexture texture], [param:Number level] )</h3>
 		<p>

+ 1 - 1
docs/api/ko/animation/AnimationObjectGroup.html

@@ -46,7 +46,7 @@
 
 		<h3>[property:Boolean isAnimationObjectGroup]</h3>
 		<p>
-			Read-only flag to check if a given object is of type [name].
+			주어진 객체가 [name] 타입인지 확인하기 위한 읽기 전용 플래그입니다.
 		</p>
 
 

+ 1 - 1
docs/api/ko/animation/AnimationUtils.html

@@ -39,7 +39,7 @@
 
 		<h3>[method:AnimationClip makeClipAdditive]( [param:AnimationClip targetClip], [param:Number referenceFrame], [param:AnimationClip referenceClip], [param:Number fps] )</h3>
 		<p>
-		Converts the keyframes of the given animation clip to an additive format.
+		주어진 애니메이션 클립의 keyframe들을 additive 포맷으로 변경해줍니다.
 		</p>
 
 		<h3>[method:Array sortedArray]( values, stride, order )</h3>

+ 1 - 1
docs/api/ko/geometries/CapsuleGeometry.html

@@ -45,7 +45,7 @@
 
 		<h2>생성자</h2>
 
-		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])</h3>
+		<h3>[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])</h3>
 		<p>
 
 		radius — 캡슐의 반경입니다. Optional; 기본값은 1 입니다.<br />

+ 19 - 16
docs/api/zh/geometries/BoxGeometry.html

@@ -11,7 +11,9 @@
 
 		<h1>立方缓冲几何体([name])</h1>
 
-		<p class="desc">[name]是四边形的原始几何类,它通常使用构造函数所提供的“width”、“height”、“depth”参数来创建立方体或者不规则四边形。</p>
+		<p class="desc">
+			[name] 是四边形的原始几何类,它通常使用构造函数所提供的 “width”、“height”、“depth” 参数来创建立方体或者不规则四边形。
+		</p>
 
 		<iframe id="scene" src="scenes/geometry-browser.html#BoxGeometry"></iframe>
 
@@ -33,36 +35,37 @@
 
 		<h2>代码示例</h2>
 
-		<code>const geometry = new THREE.BoxGeometry( 1, 1, 1 );
-		const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
-		const cube = new THREE.Mesh( geometry, material );
+		<code>
+		const geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
+		const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 
+		const cube = new THREE.Mesh( geometry, material ); 
 		scene.add( cube );
 		</code>
 
-		<h2>构造</h2>
+		<h2>构造函数(Constructor)</h2>
 
 		<h3>[name]([param:Float width], [param:Float height], [param:Float depth], [param:Integer widthSegments], [param:Integer heightSegments], [param:Integer depthSegments])</h3>
 		<p>
-		width — X轴上面的宽度,默认值为1。<br />
-		height — Y轴上面的高度,默认值为1。<br />
-		depth — Z轴上面的深度,默认值为1。<br />
-		widthSegments — (可选)宽度的分段数,默认值是1。<br />
-		heightSegments — (可选)高度的分段数,默认值是1。<br />
-		depthSegments — (可选)深度的分段数,默认值是1。
+		width — X 轴上面的宽度,默认值为 `1`。<br />
+		height — Y 轴上面的高度,默认值为 `1`。<br />
+		depth — Z 轴上面的深度,默认值为 `1`。<br />
+		widthSegments — (可选)宽度的分段数,默认值是 `1`。<br />
+		heightSegments — (可选)高度的分段数,默认值是 `1`。<br />
+		depthSegments — (可选)深度的分段数,默认值是 `1`
 		</p>
 
-		<h2>属性</h2>
-		<p>共有属性请参见其基类[page:BufferGeometry]。</p>
+		<h2>属性(Properties)</h2>
+		<p>共有属性请参见其基类 [page:BufferGeometry]。</p>
 
 		<h3>[property:Object parameters]</h3>
 		<p>
 			一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。
 		</p>
 
-		<h2>方法(Methods)</h2>
-		<p>共有方法请参见其基类[page:BufferGeometry]。</p>
+		<h2>方法(Methods)</h2>
+		<p>共有方法请参见其基类 [page:BufferGeometry]。</p>
 
-		<h2>源码</h2>
+		<h2>源码(Source)</h2>
 
 		<p>
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 1 - 1
docs/api/zh/geometries/CapsuleGeometry.html

@@ -47,7 +47,7 @@ const capsule = new THREE.Mesh( geometry, material ); scene.add( capsule );
 		<h2>构造函数</h2>
 
 		<h3>
-			[name]([param:Float radius], [param:Float length], [param:Integer capSubdivisions], [param:Integer radialSegments])
+			[name]([param:Float radius], [param:Float length], [param:Integer capSegments], [param:Integer radialSegments])
 		</h3>
 		<p>
 			radius — 胶囊半径。可选的; 默认值为1。<br />

+ 22 - 17
docs/api/zh/geometries/PlaneGeometry.html

@@ -13,7 +13,10 @@
 
 		<p class="desc">一个用于生成平面几何体的类。</p>
 
-		<iframe id="scene" src="scenes/geometry-browser.html#PlaneGeometry"></iframe>
+		<iframe
+			id="scene"
+			src="scenes/geometry-browser.html#PlaneGeometry"
+		></iframe>
 
 		<script>
 
@@ -30,37 +33,39 @@
 		}
 
 		</script>
-
 		<h2>代码示例</h2>
 
-		<code>const geometry = new THREE.PlaneGeometry( 1, 1 );
-		const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
-		const plane = new THREE.Mesh( geometry, material );
-		scene.add( plane );
+		<code>
+const geometry = new THREE.PlaneGeometry( 1, 1 );
+const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
+const plane = new THREE.Mesh( geometry, material );
+scene.add( plane );
 		</code>
 
-		<h2>构造</h2>
+		<h2>构造函数(Constructor)</h2>
 
-		<h3>[name]([param:Float width], [param:Float height], [param:Integer widthSegments], [param:Integer heightSegments])</h3>
+		<h3>
+			[name]([param:Float width], [param:Float height], [param:Integer widthSegments], [param:Integer heightSegments])
+		</h3>
 		<p>
-			width — 平面沿着X轴的宽度。默认值是1。<br />
-			height — 平面沿着Y轴的高度。默认值是1。<br />
-			widthSegments — (可选)平面的宽度分段数,默认值是1。<br />
-			heightSegments — (可选)平面的高度分段数,默认值是1。
+			width — 平面沿着 X 轴的宽度。默认值是 `1`。<br />
+			height — 平面沿着 Y 轴的高度。默认值是 `1`。<br />
+			widthSegments — (可选)平面的宽度分段数,默认值是 `1`。<br />
+			heightSegments — (可选)平面的高度分段数,默认值是 `1`
 		</p>
 
-		<h2>属性</h2>
-		<p>共有属性请参见其基类[page:BufferGeometry]。</p>
+		<h2>属性(Properties)</h2>
+		<p>共有属性请参见其基类 [page:BufferGeometry]。</p>
 
-		<h3>.parameters</h3>
+		<h3>[property:Object parameters]</h3>
 		<p>
 			一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。
 		</p>
 
-		<h2>方法(Methods)</h2>
+		<h2>方法(Methods)</h2>
 		<p>共有方法请参见其基类[page:BufferGeometry]。</p>
 
-		<h2>源码</h2>
+		<h2>源码(Source)</h2>
 
 		<p>
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 16 - 7
docs/api/zh/helpers/AxesHelper.html

@@ -29,22 +29,31 @@
 			[example:webgl_loader_nrrd WebGL / loader / nrrd]
 		</p>
 
-		<h2>构造函数</h2>
-
-
+		<h2>构造函数(Constructor)</h2>
 		<h3>[name]( [param:Number size] )</h3>
 		<p>
-		[page:Number size] -- (可选的) 表示代表轴的线段长度. 默认为 *1*.
+		[page:Number size] -- (可选的) 表示代表轴的线段长度. 默认为 `1`.
 		</p>
 
-		<h2>属性</h2>
+		<h2>属性(Properties)</h2>
 		<p>请到基类 [page:LineSegments] 页面查看公共属性.</p>
 
-		<h2>方法</h2>
+		<h2>方法(Methods)</h2>
 		<p>请到基类 [page:LineSegments] 页面查看公共方法.</p>
 
-		<h2>源码</h2>
+		<h3>
+			[method:this setColors]( [param:Color xAxisColor], [param:Color yAxisColor], [param:Color zAxisColor] )
+		</h3>
+		<p>
+			将轴颜色设置为 [page:Color xAxisColor], [page:Color yAxisColor],[page:Color zAxisColor]。
+		</p>
+
+		<h3>[method:undefined dispose]()</h3>
+		<p>
+			释放此实例分配的GPU相关资源。每当应用程序中不再使用此实例时,请调用此方法。
+		</p>
 
+		<h2>源码(Source)</h2>
 		<p>
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 		</p>

+ 210 - 45
docs/api/zh/math/Matrix3.html

@@ -79,18 +79,75 @@ m.elements = [ 11, 21, 31,
 
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
-		将该矩阵的基向量 [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 提取到提供的三个轴向中。如果该矩阵如下:
-		<code>
-a, b, c,
-d, e, f,
-g, h, i
-		</code>
-		那么 [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] 将会被设置为:
-		<code>
-xAxis = (a, d, g)
-yAxis = (b, e, h)
-zAxis = (c, f, i)
-		</code>
+		将该矩阵的基向量 [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 提取到提供的三个轴向中。如果该矩阵如下:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>d</mi></mtd>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+						<mtd><mi>i</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math><br /><br />
+
+		那么 [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] 将会被设置为:<br /><br />
+
+		<math>
+			<mrow>
+				<mi>xAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>,
+
+		<math>
+			<mrow>
+				<mi>yAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>, and
+
+		<math>
+			<mrow>
+				<mi>zAxis</mi>
+				<mo>=</mo>
+				<mo>[</mo>
+				<mtable>
+					<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+					<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
@@ -116,13 +173,31 @@ zAxis = (c, f, i)
 
 		<h3>[method:this identity]()</h3>
 		<p>
-			将此矩阵重置为3x3单位矩阵:
-				<code>
-1, 0, 0
-0, 1, 0
-0, 0, 1
-		</code>
-
+			将此矩阵重置为3x3单位矩阵:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
@@ -130,12 +205,47 @@ zAxis = (c, f, i)
 		[page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.<br /><br />
 
 		Sets this matrix as a 2D rotational transformation by [page:Float theta] radians.
-		The resulting matrix will be:
-		<code>
-cos(&theta;) -sin(&theta;) 0
-sin(&theta;) cos(&theta;)  0
-0      0       1
-		</code>
+		The resulting matrix will be:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>-sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
@@ -143,12 +253,31 @@ sin(&theta;) cos(&theta;)  0
 		[page:Float x] - the amount to scale in the X axis.<br />
 		[page:Float y] - the amount to scale in the Y axis.<br />
 
-		Sets this matrix as a 2D scale transform:
-		<code>
-x, 0, 0,
-0, y, 0,
-0, 0, 1
-		</code>
+		Sets this matrix as a 2D scale transform:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
@@ -159,12 +288,31 @@ x, 0, 0,
 		[page:Float x] - the amount to translate in the X axis.<br />
 		[page:Float y] - the amount to translate in the Y axis.<br />
 
-		Sets this matrix as a 2D translation transform:
-		<code>
-1, 0, x,
-0, 1, y,
-0, 0, 1
-		</code>
+		Sets this matrix as a 2D translation transform:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
@@ -178,14 +326,31 @@ x, 0, 0,
 
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
-		[page:Float n11] - 设置第一行第一列的值。<br />
-		[page:Float n12] - 设置第一行第二列的值。<br />
-		...<br />
-		...<br />
-		[page:Float n32] - 设置第三行第二列的值。<br />
-		[page:Float n33] - 设置第三行第三列的值。<br /><br />
-
-		使用行优先 [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] 的格式来设置该矩阵。
+		使用行优先 [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] 的格式来设置该矩阵:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>n11</mi></mtd>
+						<mtd><mi>n12</mi></mtd>
+						<mtd><mi>n13</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n21</mi></mtd>
+						<mtd><mi>n22</mi></mtd>
+						<mtd><mi>n23</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n31</mi></mtd>
+						<mtd><mi>n32</mi></mtd>
+						<mtd><mi>n33</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>

+ 579 - 84
docs/api/zh/math/Matrix4.html

@@ -48,7 +48,7 @@
 
 		<h2>注意行优先列优先的顺序。</h2>
 		<p>
-				设置[page:set]()方法参数采用行优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major],
+				设置[page:.set set]()方法参数采用行优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major],
 				而它们在内部是用列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]顺序存储在数组当中。<br /><br />
 
 				这意味着
@@ -152,19 +152,84 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 			将矩阵的基向量[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]提取到指定的3个轴向量中。
-			如果矩阵如下:
-		<code>
-a, b, c, d,
-e, f, g, h,
-i, j, k, l,
-m, n, o, p
-		</code>
-		然后x轴y轴z轴被设为:
-		<code>
-xAxis = (a, e, i)
-yAxis = (b, f, j)
-zAxis = (c, g, k)
-		</code>
+			如果矩阵如下:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			然后x轴y轴z轴被设为:<br /><br />
+
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
+
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>j</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
+
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>k</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
@@ -208,13 +273,40 @@ zAxis = (c, g, k)
 
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
-			通过给定的三个向量设置该矩阵为基矩阵[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]:
-		<code>
-xAxis.x, yAxis.x, zAxis.x, 0,
-xAxis.y, yAxis.y, zAxis.y, 0,
-xAxis.z, yAxis.z, zAxis.z, 0,
-0,       0,       0,       1
-		</code>
+			通过给定的三个向量设置该矩阵为基矩阵[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>xAxis.x</mi></mtd>
+							<mtd><mi>yAxis.x</mi></mtd>
+							<mtd><mi>zAxis.x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.y</mi></mtd>
+							<mtd><mi>yAxis.y</mi></mtd>
+							<mtd><mi>zAxis.y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>xAxis.z</mi></mtd>
+							<mtd><mi>yAxis.z</mi></mtd>
+							<mtd><mi>zAxis.z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
@@ -239,13 +331,136 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		<h3>[method:this makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
 		<p>
 		将这个矩阵的旋转分量设置为四元数[page:Quaternion q]指定的旋转,如下链接所诉[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here]。
-		矩阵的其余部分被设为单位矩阵。因此,给定四元数[page:Quaternion q] = w + xi + yj + zk,得到的矩阵为:
-		<code>
-1-2y²-2z²    2xy-2zw    2xz+2yw    0
-2xy+2zw      1-2x²-2z²  2yz-2xw    0
-2xz-2yw      2yz+2xw    1-2x²-2y²  0
-0            0          0          1
-		</code>
+		矩阵的其余部分被设为单位矩阵。因此,给定四元数[page:Quaternion q] = w + xi + yj + zk,得到的矩阵为:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>y</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>z</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>x</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>z</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>x</mi>
+								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
+								<mi>y</mi>
+								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
@@ -253,13 +468,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 		把该矩阵设置为绕x轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:
-		<code>
-1 0      0        0
-0 cos(&theta;) -sin(&theta;)  0
-0 sin(&theta;) cos(&theta;)   0
-0 0      0        1
-		</code>
+		结果如下:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
@@ -267,13 +530,61 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 		把该矩阵设置为绕Y轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:
-		<code>
-cos(&theta;)  0 sin(&theta;) 0
-0       1 0      0
--sin(&theta;) 0 cos(&theta;) 0
-0       0 0      1
-		</code>
+		结果如下:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
@@ -281,13 +592,61 @@ cos(&theta;)  0 sin(&theta;) 0
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 		把该矩阵设置为绕z轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:
-		<code>
-cos(&theta;) -sin(&theta;) 0 0
-sin(&theta;) cos(&theta;)  0 0
-0      0       1 0
-0      0       0 1
-		</code>
+		结果如下:<br /><br />
+			
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mo>-</mo>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
@@ -296,13 +655,40 @@ sin(&theta;) cos(&theta;)  0 0
 			[page:Float y] - 在Y轴方向的缩放比。<br />
 			[page:Float z] - 在Z轴方向的缩放比。<br /><br />
 
-			将这个矩阵设置为缩放变换:
-			<code>
-x, 0, 0, 0,
-0, y, 0, 0,
-0, 0, z, 0,
-0, 0, 0, 1
-			</code>
+			将这个矩阵设置为缩放变换:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>x</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>y</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mi>z</mi></mtd>
+							<mtd><mn>0</mn></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>0</mn></mtd>
+							<mtd><mn>1</mn></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:this makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
@@ -311,13 +697,40 @@ x, 0, 0, 0,
 		[page:Float y] - 在Y轴上剪切的量。<br />
 		[page:Float z] - 在Z轴上剪切的量。<br /><br />
 
-		将此矩阵设置为剪切变换:
-<code>
-1, y, z, 0,
-x, 1, z, 0,
-x, y, 1, 0,
-0, 0, 0, 1
-</code>
+		将此矩阵设置为剪切变换:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi><mi>x</mi></mtd>
+						<mtd><mi>z</mi><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>y</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>z</mi></mtd>
+						<mtd><mi>y</mi><mi>z</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
@@ -325,13 +738,40 @@ x, y, 1, 0,
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 		</h3>
 		<p>
-		取传入参数[param:Vector3 v]中值设设置该矩阵为平移变换:
-		<code>
-1, 0, 0, x,
-0, 1, 0, y,
-0, 0, 1, z,
-0, 0, 0, 1
-		</code>
+		取传入参数[param:Vector3 v]中值设设置该矩阵为平移变换:<br /><br />
+
+		<math>
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
@@ -360,20 +800,75 @@ x, y, 1, 0,
 		<h3>[method:this setPosition]( [param:Vector3 v] )</h3>
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<p>
-			取传入参数[param:Vector3 v]中值设置该矩阵的位置分量,不影响该矩阵的其余部分——即,如果该矩阵当前为:
-<code>
-a, b, c, d,
-e, f, g, h,
-i, j, k, l,
-m, n, o, p
-</code>
-变成:
-<code>
-a, b, c, v.x,
-e, f, g, v.y,
-i, j, k, v.z,
-m, n, o, p
-</code>
+			取传入参数[param:Vector3 v]中值设置该矩阵的位置分量,不影响该矩阵的其余部分——即,如果该矩阵当前为:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>d</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>h</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>l</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math><br /><br />
+
+			变成:<br /><br />
+
+			<math>
+				<mrow>
+					<mo>[</mo>
+					<mtable>
+						<mtr>
+							<mtd><mi>a</mi></mtd>
+							<mtd><mi>b</mi></mtd>
+							<mtd><mi>c</mi></mtd>
+							<mtd><mi>v.x</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>e</mi></mtd>
+							<mtd><mi>f</mi></mtd>
+							<mtd><mi>g</mi></mtd>
+							<mtd><mi>v.y</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>i</mi></mtd>
+							<mtd><mi>j</mi></mtd>
+							<mtd><mi>k</mi></mtd>
+							<mtd><mi>v.z</mi></mtd>
+						</mtr>
+						<mtr>
+							<mtd><mi>m</mi></mtd>
+							<mtd><mi>n</mi></mtd>
+							<mtd><mi>o</mi></mtd>
+							<mtd><mi>p</mi></mtd>
+						</mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
 		</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>

+ 4 - 0
docs/api/zh/math/Quaternion.html

@@ -18,6 +18,10 @@
 			对 [name] 实例进行遍历将按相应的顺序生成它的分量 (x, y, z, w)。
 		</p>
 
+		<p>
+			請注意, Three.js 期望四元數標準化。
+		</p>
+
 		<h2>代码示例</h2>
 
 		<code>

+ 7 - 0
docs/api/zh/objects/Mesh.html

@@ -73,6 +73,13 @@
 		<h3>[method:Mesh clone]()</h3>
 		<p>返回这个[name]对象及其子级的克隆。</p>
 
+		<h3>
+			[method:Vector3 getVertexPosition]( [param:Integer index], [param:Vector3 target] )
+		</h3>
+		<p>
+			获取给定索引处顶点的局部空间位置,同时考虑变形目标和蒙皮的当前动画状态。
+		</p>
+
 		<h3>[method:undefined raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 			在一条投射出去的[page:Ray](射线)和这个网格之间产生交互。

+ 4 - 3
docs/api/zh/objects/SkinnedMesh.html

@@ -100,9 +100,10 @@
 
 		<h3>[property:String bindMode]</h3>
 		<p>
-			“attached”(附加)或者“detached”(分离)。“attached”使用[page:SkinnedMesh.matrixWorld]
-			属性作为对骨骼的基本变换矩阵,“detached”则使用[page:SkinnedMesh.bindMatrix]。
-			默认值是“attached”。
+			Either `AttachedBindMode` or `DetachedBindMode`. `AttachedBindMode` means the skinned mesh
+			shares the same world space as the skeleton. This is not true when using `DetachedBindMode`
+			which is useful when sharing a skeleton across multiple skinned meshes.
+			Default is `AttachedBindMode`.
 		</p>
 
 		<h3>[property:Matrix4 bindMatrix]</h3>

+ 12 - 2
docs/api/zh/renderers/WebGLRenderer.html

@@ -268,8 +268,18 @@
 		<h3>[method:undefined clearStencil]( )</h3>
 		<p>清除模板缓存。相当于调用[page:WebGLRenderer.clear .clear]( false, false, true )</p>
 
-		<h3>[method:undefined compile]( [param:Object3D scene], [param:Camera camera] )</h3>
-		<p>使用相机编译场景中的所有材质。这对于在首次渲染之前预编译着色器很有用。</p>
+		<h3>[method:Set compile]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )</h3>
+		<p>
+			使用相机编译场景中的所有材质。这对于在首次渲染之前预编译着色器很有用。
+			如果要将 3D 对象添加到现有场景,请使用第三个可选参数来应用目标场景。<br />
+			请注意,在调用此方法之前应配置场景的照明。
+		</p>
+
+		<h3>[method:Promise compileAsync]( [param:Object3D scene], [param:Camera camera], [param:Scene targetScene] )</h3>
+		<p>
+			[page:WebGLRenderer.compile .compile]() 的异步版本。该方法返回一个 Promise。它解决了何时可以渲染给定的 3D 对象或场景,而不会因着色器编译而出现不必要的停顿。<br /><br />
+			此方法利用 *KHR_parallel_shader_compile*。
+		</p>
 
 		<h3>[method:undefined copyFramebufferToTexture]( [param:Vector2 position], [param:FramebufferTexture texture], [param:Number level] )</h3>
 		<p>将当前WebGLFramebuffer中的像素复制到2D纹理中。可访问[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/copyTexImage2D WebGLRenderingContext.copyTexImage2D].</p>

+ 15 - 0
docs/examples/en/controls/OrbitControls.html

@@ -181,6 +181,16 @@ controls.keys = {
 			How far you can zoom out ( [page:OrthographicCamera] only ). Default is Infinity.
 		</p>
 
+		<h3>[property:Float minTargetRadius]</h3>
+		<p>
+			How close you can get the target to the 3D [page:.cursor]. Default is 0.
+		</p>
+
+		<h3>[property:Float maxTargetRadius]</h3>
+		<p>
+			How far you can move the target from the 3D [page:.cursor]. Default is Infinity.
+		</p>
+
 		<h3>[property:Float minAzimuthAngle]</h3>
 		<p>
 			How far you can orbit horizontally, lower limit. If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI ). Default is Infinity.
@@ -252,6 +262,11 @@ controls.mouseButtons = {
 			the focus of the controls.
 		</p>
 
+		<h3>[property:Vector3 cursor]</h3>
+		<p>
+			The focus point of the [page:.minTargetRadius] and [page:.maxTargetRadius] limits. It can be updated manually at any point to change the center of interest for the [page:.target].
+		</p>
+
 		<h3>[property:Object touches]</h3>
 		<p>
 			This object contains references to the touch actions used by the controls.

+ 70 - 0
docs/examples/en/geometries/SDFGeometryGenerator.html

@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			[name] generates instances of [page:BufferGeometry] from a Signed Distance Function</br>
+            Uses <a href="https://www.npmjs.com/package/isosurface" target="_blank" > Mikola Lysenko's Isosurface</a>
+		</p>
+
+		<h2>Import</h2>
+
+		<p>
+			[name] is an add-on, and must be imported explicitly.
+			See [link:#manual/introduction/Installation Installation / Addons].
+		</p>
+
+		<code>
+			import { SDFGeometryGenerator } from 'three/addons/geometries/SDFGeometryGenerator.js';
+		</code>
+
+		<h2>Code Example</h2>
+
+		<code>
+		const generator = new SDFGeometryGenerator( renderer );
+		const sdf = 'float dist( vec3 p ){ return length(p) - 0.5; }' // glsl
+		const geometry = generator.generate( 64, sdf, 1 ); // ~> THREE.BufferGeometry
+		</code>
+
+		<h2>Examples</h2>
+
+		<p>[example:webgl_geometry_sdf geometry / sdf ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:WebGLRenderer renderer] )</h3>
+		
+		<p>
+			[page:WebGLRenderer renderer] -- The renderer used to render the scene. <br />
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:BufferGeometry generate]( [param:Int resolution], [param:String distanceField], [param:Int bounds] )</h3>
+		
+		<p>
+			<b>resolution</b> - Int [ mandatory ] Amount of 'voxels' used for triangulation. Must be power of 2. <br/>Gets heavy after 256, most machines won't be able to process over 512. Defaults to 64. 
+		</p>
+		<p>
+			<b>distanceField</b> - String [ mandatory ] String with glsl distance function. Name of function must be 'dist', with a vec3 argument. ( see code above ). Defaults to a sphere distance.
+		</p>
+		<p>
+			<b>bounds</b> - Int [ optional ] Bounds in which signed distance field will be evaluated. Defaults to 1.
+		</p>
+
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/SDFGeometry.js examples/jsm/geometries/SDFGeometryGenerator.js]
+		</p>
+	</body>
+</html>

+ 1 - 1
docs/examples/en/objects/Lensflare.html

@@ -23,7 +23,7 @@
 		</p>
 
 		<code>
-			import { Lensflare } from 'three/addons/objects/Lensflare.js';
+			import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js';
 		</code>
 
 		<h2>Code Example</h2>

+ 122 - 0
docs/examples/en/webxr/XREstimatedLight.html

@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Group] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			XREstimatedLight uses WebXR's light estimation to create
+			a light probe, a directional light, and (optionally) an environment map
+			that model the user's real-world environment and lighting.<br>
+			As WebXR updates the light and environment estimation, XREstimatedLight
+			automatically updates the light probe, directional light, and environment map.<br><br>
+
+			It's important to specify `light-estimation` as an optional or required
+			feature when creating the WebXR session, otherwise the light estimation
+			can't work.<br><br> 
+
+			See <a href="https://developer.mozilla.org/en-US/docs/Web/API/XRLightProbe#browser_compatibility">here</a>
+			for browser compatibility information, as this is still an experimental feature in WebXR.<br><br>
+
+
+			To use this, as with all files in the /examples directory, you will have to
+			include the file separately in your HTML.
+		</p>
+
+		<h2>Import</h2>
+
+		<p>
+			[name] is an add-on, and must be imported explicitly.
+			See [link:#manual/introduction/Installation Installation / Addons].
+		</p>
+
+		<code>
+		import { XREstimatedLight } from 'three/addons/webxr/XREstimatedLight.js';
+		</code>
+
+		<h2>Code Example</h2>
+
+		<code>
+		renderer.xr.enabled = true;
+
+		// Don't add the XREstimatedLight to the scene initially.
+		// It doesn't have any estimated lighting values until an AR session starts.
+		const xrLight = new XREstimatedLight( renderer );
+
+		xrLight.addEventListener( 'estimationstart' , () => {
+
+			scene.add( xrLight );
+
+			if ( xrLight.environment ) {
+
+				scene.environment = xrLight.environment;
+
+			}
+
+		} );
+
+		xrLight.addEventListener( 'estimationend', () => {
+
+			scene.remove( xrLight );
+
+			scene.environment = null;
+
+		} );
+
+		// In order for lighting estimation to work, 'light-estimation' must be included as either
+		// an optional or required feature.
+		document.body.appendChild( XRButton.createButton( renderer, {
+			optionalFeatures: [ 'light-estimation' ]
+		} ) );
+		</code>
+
+		<h2>Examples</h2>
+
+		<p>[example:webxr_ar_lighting webxr / light estimation]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:WebGLRenderer renderer], [param:Boolean environmentEstimation] )</h3>
+		<p>
+			[page:WebGLRenderer renderer]: (required) The renderer used to render the Scene. Mainly used to interact with WebXRManager.<br><br>
+
+			environmentEstimation: If `true`, use WebXR to estimate an environment map.
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>estimationstart</h3>
+		<p>
+			Fires when the estimated lighting values start being updated.
+		</p>
+
+		<h3>estimationend</h3>
+		<p>
+			Fires when the estimated lighting values stop being updated.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Texture environment]</h3>
+		<p>
+			The environment map estimated by WebXR. This is only available if environmentEstimation is `true`.<br><br>
+
+			It can be used as the [page:Scene.environment], for
+			[page:MeshStandardMaterial.envMap], or
+			as the [page:Scene.background].
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/XREstimatedLight.js examples/jsm/webxr/XREstimatedLight.js]
+		</p>
+	</body>
+</html>

+ 1 - 1
docs/examples/zh/objects/Lensflare.html

@@ -21,7 +21,7 @@
 		</p>
 
 		<code>
-			import { Lensflare } from 'three/addons/objects/Lensflare.js';
+			import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js';
 		</code>
 
 		<h2>代码示例</h2>

+ 3 - 1
docs/index.html

@@ -368,7 +368,9 @@
 
 		function escapeRegExp( string ) {
 
-			return string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); // https://stackoverflow.com/a/6969486/5250847
+			string = string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); // https://stackoverflow.com/a/6969486/5250847
+
+			return '(?=.*' + string.split( ' ' ).join( ')(?=.*' ) + ')'; // match all words, in any order
 
 		}
 

+ 7 - 1
docs/list.json

@@ -344,7 +344,8 @@
 				"ConvexGeometry": "examples/en/geometries/ConvexGeometry",
 				"DecalGeometry": "examples/en/geometries/DecalGeometry",
 				"ParametricGeometry": "examples/en/geometries/ParametricGeometry",
-				"TextGeometry": "examples/en/geometries/TextGeometry"
+				"TextGeometry": "examples/en/geometries/TextGeometry",
+				"SDFGeometryGenerator": "examples/en/geometries/SDFGeometryGenerator"
 			},
 
 			"Helpers": {
@@ -418,6 +419,10 @@
 				"CameraUtils": "examples/en/utils/CameraUtils",
 				"SceneUtils": "examples/en/utils/SceneUtils",
 				"SkeletonUtils": "examples/en/utils/SkeletonUtils"
+			},
+			
+			"WebXR": {
+				"XREstimatedLight": "examples/en/webxr/XREstimatedLight"
 			}
 
 		},
@@ -748,6 +753,7 @@
 				"画线": "manual/zh/introduction/Drawing-lines",
 				"创建文字": "manual/zh/introduction/Creating-text",
 				"载入3D模型": "manual/zh/introduction/Loading-3D-models",
+				"库和插件": "manual/zh/introduction/Libraries-and-Plugins",
 				"常见问题": "manual/zh/introduction/FAQ",
 				"一些有用的链接": "manual/zh/introduction/Useful-links"
 			},

+ 2 - 2
docs/manual/en/introduction/Creating-a-scene.html

@@ -105,8 +105,8 @@
 
 		<code>
 		&lt;!DOCTYPE html&gt;
-		&lt;html&gt;
-			&lt;head lang="en"&gt;
+		&lt;html lang="en"&gt;
+			&lt;head&gt;
 				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;style&gt;

+ 1 - 1
docs/manual/ko/introduction/Creating-a-scene.html

@@ -13,7 +13,7 @@
 
 		<h2>시작하기에 앞서</h2>
 
-		<p>three.js를 사용하려면, 표시할 수 있는 공간이 필요합니다. Save the following HTML to a file on your computer and open it in your browser.</p>
+		<p>three.js를 사용하려면, 표시할 수 있는 공간이 필요합니다. 다음 HTML을 컴퓨터의 파일에 저장하고 브라우저에서 여세요.</p>
 
 		<code>
 		&lt;!DOCTYPE html&gt;

+ 2 - 2
docs/manual/ko/introduction/FAQ.html

@@ -51,9 +51,9 @@ visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_f
 			<code>material.side = THREE.DoubleSide</code>
 		</p>
 
-		<h2>Why does three.js sometimes return strange results for invalid inputs?</h2>
+		<h2>three.js가 때때로 잘못된 입력에 대해 이상한 결과를 반환하는 이유는 무엇인가요?</h2>
 		<p>
-			For performance reasons, three.js doesn't validate inputs in most cases. It's your app's responsibility to make sure that all inputs are valid.
+			성능상의 이유로 three.js는 대부분의 경우 입력의 유효성을 검사하지 않습니다. 모든 입력이 유효한지 확인하는 과정은 사용자의 앱에서 책임을 가져야 합니다.
 		</p>
 	</body>
 </html>

+ 1 - 1
docs/manual/ko/introduction/How-to-update-things.html

@@ -114,7 +114,7 @@ line.geometry.computeBoundingSphere();
 			</code>
 
 			<p>
-				[link:https://jsfiddle.net/t4m85pLr/1/ Here is a fiddle] showing an animated line which you can adapt to your use case.
+				[link:https://jsfiddle.net/t4m85pLr/1/ 다음 코드]는 사용 사례에 맞게 조정할 수 있는 애니메이션 라인을 보여줍니다.
 			</p>
 
 			<h3>Examples</h3>

+ 2 - 2
docs/manual/ko/introduction/Installation.html

@@ -172,11 +172,11 @@
     <h3>Node.js</h3>
 
     <p>
-        Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.
+        Three.js는 웹 환경을 위해 만들어졌기 때문에, Node.js환경에서는 존재하지 않는 browser 객체와 DOM API에 의존적입니다. Node.js환경에서 사용한다면, 일부 문제는 [link:https://github.com/stackgl/headless-gl headless-gl]과 같은 심을 사용해서 해결하거나 [page:TextureLoader]와 같은 컴포넌트로 대안으로 사용하여 해결할 수 있습니다. 다른 DOM API는 이를 사용하는 코드와 깊게 얽혀있을 수 있으며, 해결하기가 더 어려울 수 있습니다. 우리는 Node.js환경을 지원하기 위한 간단하고 유지보수 가능한 풀리퀘스트를 환영합니다만 이슈를 먼저 열어 당신이 요청하려고하는 개선 코드에 대해 토론하는 것을 추천드립니다.
     </p>
 
     <p>
-        Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.
+        `package.json`에 `{ “type”: “module” }` 을 추가해서 노드 프로젝트에서도 ES6 모듈을 사용할 수 있도록 활성화하세요.
     </p>
 
 </body>

+ 52 - 63
docs/manual/zh/introduction/Creating-a-scene.html

@@ -9,39 +9,22 @@
 	<body>
 		<h1>创建一个场景([name])</h1>
 
-		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
+		<p>这一部分将对 three.js 来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
 
 		<h2>开始之前</h2>
 		<p>
-			在开始使用three.js之前,你需要一个地方来显示它。将下列HTML代码保存为你电脑上的一个HTML文件然后在你的浏览器中打开这个HTML文件
+			如果您还没有安装,请先阅读[link:#manual/introduction/Installation 安装]指南。我们假设你已经设置了相同的项目结构(包括 <i>index.html</i> 和 main.js),安装了 three.js,运行了构建工具,或使用了带有 CDN 和导入映射的本地服务器
 		</p>
-		<code>
-		&lt;!DOCTYPE html&gt;
-		&lt;html&gt;
-			&lt;head&gt;
-				&lt;meta charset="utf-8"&gt;
-				&lt;title&gt;My first three.js app&lt;/title&gt;
-				&lt;style&gt;
-					body { margin: 0; }
-				&lt;/style&gt;
-			&lt;/head&gt;
-			&lt;body&gt;
-				&lt;script type="module"&gt;
-					import * as THREE from 'https://unpkg.com/three/build/three.module.js';
-
-					// Our Javascript will go here.
-				&lt;/script&gt;
-			&lt;/body&gt;
-		&lt;/html&gt;
-		</code>
-
-		<p>好了,接下来的所有代码将会写入到空的&lt;script&gt;标签中。</p>
 
 		<h2>创建一个场景</h2>
 
-		<p>为了真正能够让你的场景借助three.js来进行显示,我们需要以下几个对象:场景、相机和渲染器,这样我们就能透过摄像机渲染出场景。</p>
+		<p>为了真正能够让你的场景借助 three.js 来进行显示,我们需要以下几个对象:场景(scene)、相机(camera)和渲染器(renderer),这样我们就能透过摄像机渲染出场景。</p>
+
+		<p><i>main.js —</i></p>
 
 		<code>
+		import * as THREE from 'three';
+
 		const scene = new THREE.Scene();
 		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 
@@ -52,7 +35,7 @@
 
 		<p>我们花一点点时间来解释一下这里发生了什么。我们现在建立了场景、相机和渲染器。</p>
 
-		<p>three.js里有几种不同的相机,在这里,我们使用的是<strong>PerspectiveCamera</strong>(透视摄像机)。</p>
+		<p>three.js 里有几种不同的相机,在这里,我们使用的是 <strong>PerspectiveCamera</strong>(透视摄像机)。</p>
 
 		<p>第一个参数是<strong>视野角度(FOV)</strong>。视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的单位是角度(与弧度区分开)。</p>
 
@@ -60,13 +43,13 @@
 
 		<p>接下来的两个参数是<strong>近截面</strong>(near)和<strong>远截面</strong>(far)。 当物体某些部分比摄像机的<strong>远截面</strong>远或者比<strong>近截面</strong>近的时候,该这些部分将不会被渲染到场景中。或许现在你不用担心这个值的影响,但未来为了获得更好的渲染性能,你将可以在你的应用程序里去设置它。</p>
 
-		<p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的WebGLRenderer渲染器之外,Three.js同时提供了其他几种渲染器,当用户所使用的浏览器过于老旧,或者由于其他原因不支持WebGL时,可以使用这几种渲染器进行降级。</p>
+		<p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的 WebGLRenderer 渲染器之外,Three.js 同时提供了其他几种渲染器,当用户所使用的浏览器过于老旧,或者由于其他原因不支持 WebGL 时,可以使用这几种渲染器进行降级。</p>
 
-		<p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的尺寸。比如说,我们可以使用所需要的渲染区域的宽高,来让渲染器渲染出的场景填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。对于性能比较敏感的应用程序来说,你可以使用<strong>setSize</strong>传入一个较小的值,例如<strong>window.innerWidth/2</strong>和<strong>window.innerHeight/2</strong>,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。</p>
+		<p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的尺寸。比如说,我们可以使用所需要的渲染区域的宽高,来让渲染器渲染出的场景填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。对于性能比较敏感的应用程序来说,你可以使用 <strong>setSize</strong> 传入一个较小的值,例如 <strong>window.innerWidth/2</strong>  <strong>window.innerHeight/2</strong>,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。</p>
 
-		<p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用<strong>setSize</strong>时,将<strong>updateStyle</strong>(第三个参数)设为false。例如,假设你的&lt;canvas&gt; 标签现在已经具有了100%的宽和高,调用<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>将使得你的应用程序以一半的分辨率来进行渲染。</p>
+		<p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用 <strong>setSize</strong> 时,将 <strong>updateStyle</strong>(第三个参数)设为 false。例如,假设你的 &lt;canvas&gt; 标签现在已经具有了 100% 的宽和高,调用 <strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong> 将使得你的应用程序以四分之一的大小来进行渲染。</p>
 
-		<p>最后一步很重要,我们将<strong>renderer</strong>(渲染器)的dom元素(renderer.domElement)添加到我们的HTML文档中。这就是渲染器用来显示场景给我们看的&lt;canvas&gt;元素。</p>
+		<p>最后一步很重要,我们将 <strong>renderer</strong>(渲染器)的dom元素(renderer.domElement)添加到我们的 HTML 文档中。这就是渲染器用来显示场景给我们看的 &lt;canvas&gt; 元素。</p>
 
 		<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>接下来,我们就来添加立方体。</p>
 
@@ -79,13 +62,13 @@
 		camera.position.z = 5;
 		</code>
 
-		<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面(<strong>faces</strong>)。未来我们将在这方面进行更多的探索。</p>
+		<p>要创建一个立方体,我们需要一个 <strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面(<strong>faces</strong>)。未来我们将在这方面进行更多的探索。</p>
 
-		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js自带了几种材质,在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见,我们只设置一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情,和在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)颜色格式来设置颜色的方式一致。</p>
+		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js 自带了几种材质,在这里我们使用的是 <strong>MeshBasicMaterial</strong>。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见,我们只设置一个color属性,值为 <strong>0x00ff00</strong>,也就是绿色。这里所做的事情,和在 CSS 或者 Photoshop 中使用十六进制(<strong>hex colors</strong>)颜色格式来设置颜色的方式一致。</p>
 
-		<p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
+		<p>第三步,我们需要一个 <strong>Mesh</strong>(网格)。 网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
 
-		<p>默认情况下,当我们调用<strong>scene.add()</strong>的时候,物体将会被添加到<strong>(0,0,0)</strong>坐标。但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些即可。</p>
+		<p>默认情况下,当我们调用 <strong>scene.add()</strong> 的时候,物体将会被添加到 <strong>(0,0,0)</strong> 坐标。但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些即可。</p>
 
 		<h2>渲染场景</h2>
 
@@ -99,29 +82,31 @@
 		animate();
 		</code>
 
-		<p>在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)。如果你是一个浏览器游戏开发的新手,你或许会说<em>“为什么我们不直接用setInterval来实现刷新的功能呢?”</em>当然啦,我们的确可以用setInterval,但是,<strong>requestAnimationFrame</strong>有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源,也不会损耗电池的使用寿命。</p>
+		<p>在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)。如果你是一个浏览器游戏开发的新手,你或许会说<em>“为什么我们不直接用 setInterval 来实现刷新的功能呢?”</em>当然啦,我们的确可以用 setInterval,但是,<strong>requestAnimationFrame</strong> 有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源,也不会损耗电池的使用寿命。</p>
 
 		<h2>使立方体动起来</h2>
 
-		<p>
-			在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你可以看到一个绿色的方块。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
+		<p>在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你可以看到一个绿色的方块。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
 
-		<p>将下列代码添加到animate()函数中<strong>renderer.render</strong>调用的上方:</p>
+		<p>将下列代码添加到 animate() 函数中 <strong>renderer.render</strong> 调用的上方:</p>
 
 		<code>
 		cube.rotation.x += 0.01;
 		cube.rotation.y += 0.01;
 		</code>
 
-		<p>这段代码每帧都会执行(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,你可以在这个动画循环里调用别的函数,这样你就不会写出有上百行代码的<strong>animate</strong>函数。</p>
+		<p>这段代码每帧都会执行(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,你可以在这个动画循环里调用别的函数,这样你就不会写出有上百行代码的 <strong>animate</strong> 函数。</p>
 
 		<h2>结果</h2>
-		<p>祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>
+		<p>祝贺你!你现在已经成功完成了你的第一个 three.js 应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>
+
+		<p>下面是完整的代码,可在 [link:https://jsfiddle.net/0c1oqf38/ live example] 运行、编辑;运行或者修改代码有助于你更好的理解它是如何工作的。</p>
 
-		<p>下面是完整的代码,可在[link:https://jsfiddle.net/0c1oqf38/ live example]运行、编辑;运行或者修改代码有助于你更好的理解它是如何工作的。</p>
+		<p><i>index.html —</i></p>
 
 		<code>
-		&lt;html&gt;
+		&lt;!DOCTYPE html&gt;
+		&lt;html lang="en"&gt;
 			&lt;head&gt;
 				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
@@ -130,36 +115,40 @@
 				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
-				&lt;script type="module"&gt;
-					import * as THREE from 'https://unpkg.com/three/build/three.module.js';
+				&lt;script type="module" src="/main.js"&gt;&lt;/script&gt;
+			&lt;/body&gt;
+		&lt;/html&gt;
+		</code>
 
-					const scene = new THREE.Scene();
-					const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
+		<p><i>main.js —</i></p>
 
-					const renderer = new THREE.WebGLRenderer();
-					renderer.setSize( window.innerWidth, window.innerHeight );
-					document.body.appendChild( renderer.domElement );
+		<code>
+		import * as THREE from 'three';
 
-					const geometry = new THREE.BoxGeometry( 1, 1, 1 );
-					const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-					const cube = new THREE.Mesh( geometry, material );
-					scene.add( cube );
+		const scene = new THREE.Scene();
+		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 
-					camera.position.z = 5;
+		const renderer = new THREE.WebGLRenderer();
+		renderer.setSize( window.innerWidth, window.innerHeight );
+		document.body.appendChild( renderer.domElement );
 
-					function animate() {
-						requestAnimationFrame( animate );
+		const geometry = new THREE.BoxGeometry( 1, 1, 1 );
+		const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		const cube = new THREE.Mesh( geometry, material );
+		scene.add( cube );
 
-						cube.rotation.x += 0.01;
-						cube.rotation.y += 0.01;
+		camera.position.z = 5;
 
-						renderer.render( scene, camera );
-					}
+		function animate() {
+			requestAnimationFrame( animate );
 
-					animate();
-				&lt;/script&gt;
-			&lt;/body&gt;
-		&lt;/html&gt;
+			cube.rotation.x += 0.01;
+			cube.rotation.y += 0.01;
+
+			renderer.render( scene, camera );
+		}
+
+		animate();
 		</code>
 	</body>
 </html>

+ 191 - 87
docs/manual/zh/introduction/Installation.html

@@ -9,152 +9,256 @@
 	<body>
 		<h1>安装([name])</h1>
 
-		<p>
-			你可以使用[link:https://www.npmjs.com/ npm]以及现代构建工具来安装 three.js ,也可以只需静态主机或是 CDN 来快速上手。对于大多数用户来说,从 npm 安装是最佳选择。
-		</p>
+		<h2>项目结构</h2>
 
 		<p>
-			无论你选择哪种方式,请始终保持一致,并注意从相同版本的库中导入所有文件。混合不同来源的文件可能会导致包含重复代码,甚至会以意料之外的方式破坏应用程序,
+			每个 three.js 项目至少需要一个 HTML 文件来定义网页,以及一个 JavaScript 文件来运行你的 three.js 代码。下面的结构和命名选择并非必需,但为了保持一致性,本指南将在全文中使用。
 		</p>
 
+		<ul>
+			<li>
+				<i>index.html</i>
+				<code>
+		&lt;!DOCTYPE html&gt;
+		&lt;html lang="en"&gt;
+			&lt;head&gt;
+				&lt;meta charset="utf-8"&gt;
+				&lt;title&gt;My first three.js app&lt;/title&gt;
+				&lt;style&gt;
+					body { margin: 0; }
+				&lt;/style&gt;
+			&lt;/head&gt;
+			&lt;body&gt;
+				&lt;script type="module" src="/main.js"&gt;&lt;/script&gt;
+			&lt;/body&gt;
+		&lt;/html&gt;
+				</code>
+			</li>
+			<li>
+				<i>main.js</i>
+				<code>
+import * as THREE from 'three';
+
+...
+				</code>
+			</li>
+			<li>
+				<i>public/</i>
+				<ul>
+					<li>
+						<i>public/</i> 文件夹有时也被称为 "静态(static)"文件夹,因为其中包含的文件会原封不动地推送到网站上。纹理(textures)、音频和 3D 模型通常会放在这里。
+					</li>
+				</ul>
+			</li>
+		</ul>
+
 		<p>
-			所有安装 three.js 的方式都依赖于 ES modules(参见 [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules])。ES modules使你能够在最终项目中包含所需库的一小部分。
+			现在我们已经建立了基本的项目结构,便需要一种方法在本地运行并通过浏览器访问它。我们可以使用 npm 和构建工具来完成安装和本地开发,也可以从 CDN 导入 three.js。下面将对这两种方案进行说明
 		</p>
 
-		<h2>安装自 npm</h2>
+		<h2>方案 1:使用 NPM 和构建工具进行安装</h2>
+
+		<h3>开发</h3>
 
 		<p>
-			要安装[link:https://www.npmjs.com/package/three three] 的 npm 模块,请在你的项目文件夹里打开终端窗口,并运行:
+			对于大多数用户而已,从 [link:https://www.npmjs.com/ npm 包注册表中心] 安装并使用 [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC 构建工具] 会是一个更推荐的方案。因为项目需要的依赖越多,就越有可能遇到静态托管无法轻易解决的问题。而使用构建工具,导入本地 JavaScript 文件和 npm 软件包将会是开箱即用的,无需导入映射(import maps)。
 		</p>
 
-		<code>
-		npm install three
-		</code>
+		<ol>
+			<li>
+				安装 [link:https://nodejs.org/ Node.js]。我们需要它来管理依赖项和运行构建工具。
+			</li>
+			<li>
+				<p>
+					在项目文件夹中通过 [link:https://www.joshwcomeau.com/javascript/terminal-for-js-devs/ 终端] 安装 three.js 和构建工具 [link:https://vitejs.dev/ Vite]。Vite 将在开发过程中使用,但不会被打包成为最终网页的一部分。当然,除了 Vite 你也可以使用其他支持导入 [link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC ES Modules] 的现代构建工具。
+				</p>
+				<code>
+# three.js
+npm install --save three
+
+# vite
+npm install --save-dev vite
+				</code>
+				<aside>
+					<details>
+						<summary>安装时我的项目中新增了 <i>node_modules/</i> 和 <i>package.json</i>。它们是什么?</summary>
+						<p>
+							npm 使用 <i>package.json</i> 来描述你已经安装的每个依赖项的版本。如果有其他人和你一起开发项目,他们只需运行 <i>npm install</i> 就能安装每个依赖项的原始版本。如果你在使用版本控制器(如:Git、SVN)来控制代码版本,那么 <i>package.json</i> 应当被提交。 
+						</p>
+						<p>
+							npm 将每个依赖项的代码放在 <i>node_modules/</i> 下的文件夹中。当Vite构建应用程序时,它会看到 “three” 的导入,并自动从该文件夹中提取 three.js 文件。 <i>node_modules/</i> 文件夹仅在开发过程中使用,不应上传到你的网络托管提供商或提交到版本历史记录中。
+						</p>
+					</details>
+				</aside>
+			</li>
+			<li>
+				在终端运行:
+				<code>
+					npx vite
+				</code>
+				<aside>
+					<details>
+						<summary><i>npx</i> 是什么?</summary>
+						<p>
+							npx 与 Node.js 一同安装,可运行 Vite 等命令行程序,这样你就不必自己在 <i>node_modules/</i> 中搜索正确的文件。如果你愿意,可以将 [link:https://vitejs.dev/guide/#command-line-interface Vite 的常用命令] 放入 [link:https://docs.npmjs.com/cli/v9/using-npm/scripts package.json:scripts] 列表,然后使用 <i>npm run dev</i> 代替。
+						</p>
+					</details>
+				</aside>
+			</li>
+			<li>
+				如果一切顺利,你会在终端中看到一个类似 <i>http://localhost:5173</i> 的 URL,打开该 URL 就能看到你的网络应用程序。
+			</li>
+		</ol>
 
 		<p>
-			包将会被下载并安装。然后你就可以将它导入你的代码了:
+			目前页面将会是空白的,不过你已经准备好可以开始[link:#manual/zh/introduction/Creating-a-scene 创建一个场景]了。
 		</p>
 
-		<code>
-		// 方式 1: 导入整个 three.js核心库
-		import * as THREE from 'three';
-
-		const scene = new THREE.Scene();
-
+		<p>
+			如果你想在继续之前进一步了解这些工具,请参阅:
+		</p>
 
-		// 方式 2: 仅导入你所需要的部分
-		import { Scene } from 'three';
+		<ul>
+			<li>
+				[link:https://threejs-journey.com/lessons/local-server three.js journey: Local Server]
+			</li>
+			<li>
+				[link:https://vitejs.dev/guide/cli.html Vite: Command Line Interface]
+			</li>
+			<li>
+				[link:https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management MDN: Package management basics]
+			</li>
+		</ul>
 
-		const scene = new Scene();
-		</code>
+		<h3>生产</h3>
 
 		<p>
-			从npm上进行安装的时候,几乎总是使用某种构建工具([link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC bundling tool])来将你项目中需要的所有包组合到一个独立的JavaScript软件中。虽然任何现代的 JavaScript 打包器都可以和 three.js 一起使用,但最流行的选择是 [link:https://webpack.js.org/ webpack] 。
+			之后,当你准备部署网络应用程序时,只需要让 Vite 运行生产构建 - <i>npx vite build</i>。应用程序使用的所有内容都将被编译、优化并复制到 <i>dist/</i> 文件夹中。该文件夹中的内容就可以托管到你的网站上了
 		</p>
 
+		<h2>方案 2:从 CDN 导入</h2>
+
+		<h3>开发</h3>
+
+		<p>在不使用构建工具的情况下进行安装,需要对上述项目结构进行一些修改。</p>
+
+		<ol>
+			<li>
+				<p>
+					我们在 <i>main.js</i> 中从 "three"(一个 npm 软件包)导入了代码,但网络浏览器并不知道这意味着什么。在 <i>index.html</i> 中,我们需要添加一个[link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap 导入映射](import map)来定义从哪里获取软件包。将下面的代码放在 <i>&lt;head>&lt/head></i> 标签内、样式(styles)之后。
+				</p>
+				<code>
+&lt;script type="importmap">
+  {
+    "imports": {
+      "three": "https://unpkg.com/three@&lt;version&gt;/build/three.module.js",
+      "three/addons/": "https://unpkg.com/three@&lt;version&gt;/examples/jsm/"
+    }
+  }
+&lt;/script>
+				</code>
+				<p>
+					不要忘记将上述链接中的 <i>&lt;version&gt;</i> 替换为 three.js 的实际版本,如 <i>"v0.149.0"</i>。最新版本可在 [link:https://www.npmjs.com/package/three?activeTab=versions npm 版本列表]中找到。
+				</p>
+			</li>
+			<li>
+				<p>
+					我们还需要运行一个<i>本地服务器</i>,将这些文件托管到网络浏览器可以访问的 URL 上。虽然从技术上讲,双击 HTML 文件并在浏览器中打开它是可行的,但出于安全原因,这样打开的页面无法使用我们稍后要使用的重要功能。
+				</p>
+				<p>
+					安装 [link:https://nodejs.org/ Node.js],然后运行 [link:https://www.npmjs.com/package/serve serve] 在项目目录中启动本地服务器:
+				</p>
+				<code>
+					npx serve .
+				</code>
+			</li>
+			<li>
+				如果一切顺利,你会在终端中看到一个类似 http://localhost:3000 的 URL,打开该 URL 就能看到你的网络应用程序。
+			</li>
+		</ol>
+		
 		<p>
-			并非所有功能都可以通过 <em>three</em> 模块来直接访问(也称为“裸导入”)。three.js 中其它较为流行的部分 —— 如控制器(control)、加载器(loader)以及后期处理效果(post-processing effect) —— 必须从 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 子目录下导入。了解更多信息,请参阅下方的<em>示例</em>。
+			目前页面将会是空白的,不过你已经准备好可以开始[link:#manual/zh/introduction/Creating-a-scene 创建一个场景]了
 		</p>
 
 		<p>
-			你可以从 [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent JavaScript: Installing with npm] 来了解更多有关 npm 模块的信息。
+			还有许多其他本地静态服务器可供选择——有些使用不同的语言而不是 Node.js,有些则是桌面应用程序。它们的工作方式基本相同,下文中则提供了一些替代方案
 		</p>
 
-		<h2>从CDN或静态主机安装</h2>
+		<details>
+			<summary>更多本地服务器</summary>
 
-		<p>
-			通过将文件上传到你自己的服务器,或是使用一个已存在的CDN,three.js 便可以不借助任何构建系统来进行使用。由于 three.js 依赖于ES module,因此任何引用它的script标签必须使用<em>type="module"</em>。如下所示:
-		</p>
+			<h3>命令行(Command Line)</h3>
 
-		<code>
-		&lt;script type="importmap">
-			{
-			"imports": {
-				"three": "https://unpkg.com/three@&lt;version&gt;/build/three.module.js"
-			}
-			}
-		&lt;/script>
+			<p>命令行本地服务器通过终端窗口运行。可能需要先安装相关的编程语言。</p>
 
-		&lt;script type="module">
+			<ul>
+				<li><i>npx http-server</i> (Node.js)</li>
+				<li><i>npx five-server</i> (Node.js)</li>
+				<li><i>python -m SimpleHTTPServer</i> (Python 2.x)</li>
+				<li><i>python -m http.server</i> (Python 3.x)</li>
+				<li><i>php -S localhost:8000</i> (PHP 5.4+)</li>
+			</ul>
 
-			import * as THREE from 'three';
 
-			const scene = new THREE.Scene();
+			<h3>GUI</h3>
 
-		&lt;/script>
-		</code>
+			<p>GUI 本地服务器在计算机上以应用程序窗口的形式运行,并可以有一个用户界面。</p>
 
-		<h2>Addons</h2>
+			<ul>
+				<li>[link:https://greggman.github.io/servez Servez]</li>
+			</ul>
 
-		<p>
-			three.js的核心专注于3D引擎最重要的组件。其它很多有用的组件 —— 如控制器(control)、加载器(loader)以及后期处理效果(post-processing effect) —— 是 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 目录的一部分。它们被称为“示例”,虽然你可以直接将它们拿来使用,但它们也需要重新混合以及定制。这些组件和 three.js 的核心保持同步,而 npm 上类似的第三方包则由不同的作者进行维护,可能不是最新的。
-		</p>
+			<h3>代码编辑器的插件</h3>
 
-		<p>
-			示例无需被单独地<em>安装</em>,但需要被单独地<em>导入</em>。如果 three.js 是使用 npm 来安装的,你可以使用如下代码来加载轨道控制器([page:OrbitControls]):
-		</p>
-
-
-		<code>
-		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-
-		const controls = new OrbitControls( camera, renderer.domElement );
-		</code>
-
-		<p>
-			如果 three.js 安装自一个 CDN ,请使用相同的 CDN 来安装其他组件:
-		</p>
+			<p>有些代码编辑器的插件可以按需生成一个简单的服务器。</p>
 
-		<code>
-		&lt;script type="importmap">
-			{
-			"imports": {
-				"three": "https://unpkg.com/three@&lt;version&gt;/build/three.module.js",
-				"three/addons/": "https://unpkg.com/three@&lt;version&gt;/examples/jsm/"
-			}
-			}
-		&lt;/script>
-
-		&lt;script type="module">
+			<ul>
+				<li>Visual Studio Code:[link:https://marketplace.visualstudio.com/items?itemName=yandeu.five-server Five Server]</li>
+				<li>Visual Studio Code:[link:https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Live Server]</li>
+				<li>Atom:[link:https://atom.io/packages/atom-live-server Live Server]</li>
+			</ul>
 
-			import * as THREE from 'three';
-			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 
-			const controls = new OrbitControls( camera, renderer.domElement );
+		</details>
 
-		&lt;/script>
-		</code>
+		<h3>生产</h3>
 
 		<p>
-			所有文件使用相同版本是十分重要的。请勿从不同版本导入不同的示例,也不要使用与 three.js 本身版本不一致的示例
+			当你准备部署网络应用时,只需将源文件推送给网络托管服务提供商即可,无需构建或编译任何内容。这样做的坏处是,你需要注意根据应用程序所需的依赖项(以及依赖项的依赖项!)不断更新导入映射。如果托管你的依赖项的 CDN 暂时宕机,你的网站也会停止工作
 		</p>
 
-		<h2>兼容性</h2>
-
-		<h3>CommonJS 导入</h3>
-
 		<p>
-			虽然现代的 JavaScript 打包器已经默认支持ES module,然而也有一些较旧的构建工具并不支持。对于这些情况,你或许可以对这些打包器进行配置,让它们能够理解 ES module 。例如,[link:http://browserify.org/ Browserify] 仅需 [link:https://github.com/babel/babelify babelify] 插件。
+			<i><b>重要提示:</b> 请将所有依赖项从同一版本的 three.js 导入,并从相同的 CDN 上获取。混合使用不同来源的文件可能导致包含重复代码,甚至以意想不到的方式破坏应用程序。</i>
 		</p>
 
-		<h3>Import maps</h3>
+		<h2>附加组件(Addons)</h2>
 
 		<p>
-			和从静态主机或CDN来进行安装的方式相比,从npm安装时,导入的路径有所不同。我们意识到,对于使用两种不同方式的用户群体来说,这是一个人体工程学问题。使用构建工具与打包器的开发者更喜欢仅使用单独的包说明符(如'three')而非相对路径,而<em>examples/</em>目录中的文件使用相对于 <em>three.module.js</em> 的引用并不符合这一期望。对于不使用构建工具的人(用于快速原型、学习或个人参考)来说,或许也会很反感这些相对导入。这些相对导入需要确定目录结构,并且比全局 <em>THREE.*</em> 命名空间更不宽容
+			开箱即用的 three.js 包含 3D 引擎的基本要素。而其他 three.js 组件,如控件(controls)、加载器(loaders)和后期处理效果(post-processing effects)则属于 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm addons/] 目录的一部分。附加组件无需单独<i>安装</i>,但需要单独<i>导入</i>
 		</p>
 
 		<p>
-			我们希望在 [link:https://github.com/WICG/import-maps import maps] 广泛可用时,能够移除这些相对路径,将它们替换为单独的包说明符,'three'。这更加符合构建工具对npm包的期望,且使得两种用户群体在导入文件时能够编写完全相同的代码。对于更偏向于避免使用构建工具的用户来说,一个简单的 JSON 映射即可将所有的导入都定向到一个 CDN 或是静态文件夹。通过实验,目前你可以通过一个 import map 的 polyfill,来尝试更简洁的导入,如 [link:https://glitch.com/edit/#!/three-import-map?path=index.html import map example] 示例中所示
+			下面的示例展示了如何导入 three.js 的 [page:OrbitControls] 和 [page:GLTFLoader] 附加组件。必要时每个附加组件的文档或示例中也会提及这一点
 		</p>
 
-		<h3>Node.js</h3>
+		<code>
+import * as THREE from 'three';
+import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
+
+const controls = new OrbitControls( camera, renderer.domElement );
+const loader = new GLTFLoader();
+		</code>
 
 		<p>
-			由于 three.js 是为 Web 构建的, 因此它依赖于浏览器和 DOM 的 API ,但这些 API 在 Node.js 里不一定存在。这些问题中有的可以使用 [link:https://github.com/stackgl/headless-gl headless-gl] 等 shims 来解决,或者用自定义的替代方案来替换像 [page:TextureLoader] 这样的组件。其他 DOM API 可能与使用它们的代码强相关,因此将更难以解决。我们欢迎简单且易于维护的 pull request 来改进对 Node.js 的支持,但建议先打开问题来讨论您的改进。
+			一些优秀的第三方项目也可用于 three.js。这些项目需要单独安装,请参见 [link:#manual/zh/introduction/Libraries-and-Plugins 库和插件]
 		</p>
 
+		<h2>下一步</h2>
+
 		<p>
-			确保在您的 package.json 文件中添加 { "type": "module" },以在您的 Node.js 项目中启用 ES6 模块。
+			是时候开始[link:#manual/zh/introduction/Creating-a-scene 创建一个场景]了
 		</p>
 
 	</body>

+ 110 - 0
docs/manual/zh/introduction/Libraries-and-Plugins.html

@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>库和插件([name])</h1>
+
+		<p class="desc">
+			这里列出的是由外部开发的与 three.js 相兼容的库和插件。此列表和相关软件包由社区维护,不保证是最新版本。如果您想更新此列表,请提交 PR!
+		</p>
+
+		<h3>物理引擎/效果(Physics)</h3>
+
+		<ul>
+			<li>[link:https://github.com/lo-th/Oimo.js/ Oimo.js]</li>
+			<li>[link:https://enable3d.io/ enable3d]</li>
+			<li>[link:https://github.com/kripken/ammo.js/ ammo.js]</li>
+			<li>[link:https://github.com/pmndrs/cannon-es cannon-es]</li>
+			<li>[link:https://rapier.rs/ rapier]</li>
+			
+		</ul>
+
+		<h3>后期处理(Postprocessing)</h3>
+
+		<p>
+			除了[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing 官方的 three.js 后处理特效]外,我们还可以通过外部库获得一些额外的特效和框架支持。
+		</p>
+
+		<ul>
+			<li>[link:https://github.com/vanruesc/postprocessing postprocessing]</li>
+		</ul>
+
+		<h3>光线投射性能表现(Intersection and Raycast Performance)</h3>
+
+		<ul>
+			<li>[link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]</li>
+		</ul>
+
+		<h3>轨迹追踪(Path Tracing)</h3>
+		
+		<ul>
+			<li>[link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]</li>
+		</ul>
+		
+		<h3>文件格式(File Formats)</h3>
+
+		<p>
+			除[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders 官方的 three.js 加载器]外,还可通过外部库支持其他一些格式。
+		</p>
+
+		<ul>
+			<li>[link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]</li>
+			<li>[link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]</li>
+			<li>[link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]</li>
+			<li>[link:https://github.com/IFCjs/web-ifc-three IFC.js]</li>
+		</ul>
+
+		<h3>Geometry</h3>
+
+		<ul>
+			<li>[link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]</li>
+		</ul>
+
+		<h3>3D 文字和布局(3D Text and Layout)</h3>
+
+		<ul>
+			<li>[link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]</li>
+			<li>[link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]</li>
+		</ul>
+
+		<h3>粒子系统(Particle Systems)</h3>
+
+		<ul>
+			<li>[link:https://github.com/Alchemist0823/three.quarks three.quarks]</li>
+			<li>[link:https://github.com/creativelifeform/three-nebula three-nebula]</li>
+		</ul>
+
+		<h3>逆向运动学(Inverse Kinematics)</h3>
+
+		<ul>
+			<li>[link:https://github.com/jsantell/THREE.IK THREE.IK]</li>
+			<li>[link:https://github.com/lo-th/fullik fullik]</li>
+			<li>[link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]</li>
+		</ul>
+
+		<h3>游戏人工智能(Game AI)</h3>
+
+		<ul>
+			<li>[link:https://mugen87.github.io/yuka/ yuka]</li>
+			<li>[link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]</li>
+			<li>[link:https://github.com/isaac-mason/recast-navigation-js recast-navigation-js]</li>
+		</ul>
+
+		<h3>封装器和框架(Wrappers and Frameworks)</h3>
+
+		<ul>
+			<li>[link:https://aframe.io/ A-Frame]</li>
+			<li>[link:https://lume.io/ Lume] - HTML elements for 3D graphics built on Three.</li>
+			<li>[link:https://github.com/pmndrs/react-three-fiber react-three-fiber] - React components for 3D graphics built on Three.</li>
+			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
+			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
+			<li>[link:https://needle.tools/ Needle Engine]</li>
+		</ul>
+
+	</body>
+</html>

+ 19 - 14
docs/manual/zh/introduction/WebGL-compatibility-check.html

@@ -9,23 +9,28 @@
 	<body>
 		<h1>WebGL兼容性检查([name])</h1>
 		<p>
-            虽然这个问题现在已经变得越来不明显,但不可否定的是,某些设备以及浏览器直到现在仍然不支持WebGL。<br>以下的方法可以帮助你检测当前用户所使用的环境是否支持WebGL,如果不支持,将会向用户提示一条信息。
+			虽然这个问题现在已经变得越来不明显,但不可否定的是,某些设备以及浏览器直到现在仍然不支持WebGL。
+			<br>以下的方法可以帮助你检测当前用户所使用的环境是否支持WebGL,如果不支持,将会向用户提示一条信息。
 		</p>
-
 		<p>
 			请将[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/capabilities/WebGL.js]引入到你的文件,并在尝试开始渲染之前先运行该文件。
-        	</p>
-
-<code>
-if (WebGL.isWebGLAvailable()) {
-    // Initiate function or other initializations here
-    animate();
-} else {
-    const warning = WebGL.getWebGLErrorMessage();
-    document.getElementById('container').appendChild(warning);
-}
-</code>
-
+			导入 WebGL 兼容检测模块,并在尝试渲染任何内容之前运行以下程序。
+		</p>
 
+		<code>
+			import WebGL from 'three/addons/capabilities/WebGL.js';
+	
+			if ( WebGL.isWebGLAvailable() ) {
+	
+				// Initiate function or other initializations here
+				animate();
+	
+			} else {
+	
+				const warning = WebGL.getWebGLErrorMessage();
+				document.getElementById( 'container' ).appendChild( warning );
+	
+			}
+			</code>
 	</body>
 </html>

+ 1 - 0
docs/scenes/material-browser.html

@@ -352,6 +352,7 @@
 				// folder.add( material, 'polygonOffsetFactor' );
 				// folder.add( material, 'polygonOffsetUnits' );
 				folder.add( material, 'alphaTest', 0, 1 ).step( 0.01 ).onChange( needsUpdate( material, geometry ) );
+				folder.add( material, 'alphaHash' ).onChange( needsUpdate( material, geometry ) );
 				folder.add( material, 'visible' );
 				folder.add( material, 'side', constants.side ).onChange( needsUpdate( material, geometry ) );
 

+ 2 - 0
editor/js/Editor.js

@@ -83,6 +83,7 @@ function Editor() {
 		showGridChanged: new Signal(),
 		showHelpersChanged: new Signal(),
 		refreshSidebarObject3D: new Signal(),
+		refreshSidebarEnvironment: new Signal(),
 		historyChanged: new Signal(),
 
 		viewportCameraChanged: new Signal(),
@@ -662,6 +663,7 @@ Editor.prototype = {
 		if ( json.environment === 'ModelViewer' ) {
 
 			this.signals.sceneEnvironmentChanged.dispatch( json.environment );
+			this.signals.refreshSidebarEnvironment.dispatch();
 
 		}
 

+ 0 - 65
editor/js/Menubar.Edit.js

@@ -149,71 +149,6 @@ function MenubarEdit( editor ) {
 	} );
 	options.add( option );
 
-	//
-
-	options.add( new UIHorizontalRule() );
-
-	// Set textures to sRGB. See #15903
-
-	option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/edit/fixcolormaps' ) );
-	option.onClick( function () {
-
-		editor.scene.traverse( fixColorMap );
-
-	} );
-	options.add( option );
-
-	const colorMaps = [ 'map', 'envMap', 'emissiveMap' ];
-
-	function fixColorMap( obj ) {
-
-		const material = obj.material;
-
-		if ( material !== undefined ) {
-
-			if ( Array.isArray( material ) === true ) {
-
-				for ( let i = 0; i < material.length; i ++ ) {
-
-					fixMaterial( material[ i ] );
-
-				}
-
-			} else {
-
-				fixMaterial( material );
-
-			}
-
-			editor.signals.sceneGraphChanged.dispatch();
-
-		}
-
-	}
-
-	function fixMaterial( material ) {
-
-		let needsUpdate = material.needsUpdate;
-
-		for ( let i = 0; i < colorMaps.length; i ++ ) {
-
-			const map = material[ colorMaps[ i ] ];
-
-			if ( map ) {
-
-				map.colorSpace = THREE.SRGBColorSpace;
-				needsUpdate = true;
-
-			}
-
-		}
-
-		material.needsUpdate = needsUpdate;
-
-	}
-
 	return container;
 
 }

+ 1 - 1
editor/js/Sidebar.Animation.js

@@ -82,7 +82,7 @@ function SidebarAnimation( editor ) {
 	container.add( animationsList );
 
 	const mixerTimeScaleRow = new UIRow();
-	const mixerTimeScaleNumber = new UINumber( 0.5 ).setWidth( '60px' ).setRange( - 10, 10 );
+	const mixerTimeScaleNumber = new UINumber( 1 ).setWidth( '60px' ).setRange( - 10, 10 );
 	mixerTimeScaleNumber.onChange( function () {
 
 		mixer.timeScale = mixerTimeScaleNumber.getValue();

+ 3 - 1
editor/js/Sidebar.Material.MapProperty.js

@@ -22,6 +22,8 @@ function SidebarMaterialMapProperty( editor, property, name ) {
 
 	const mapType = property.replace( 'Map', '' );
 
+	const colorMaps = [ 'map', 'emissiveMap', 'sheenColorMap', 'specularColorMap', 'envMap' ];
+
 	let intensity;
 
 	if ( property === 'aoMap' ) {
@@ -111,7 +113,7 @@ function SidebarMaterialMapProperty( editor, property, name ) {
 
 		if ( texture !== null ) {
 
-			if ( texture.isDataTexture !== true && texture.colorSpace !== THREE.SRGBColorSpace ) {
+			if ( colorMaps[ property ] !== undefined && texture.isDataTexture !== true && texture.colorSpace !== THREE.SRGBColorSpace ) {
 
 				texture.colorSpace = THREE.SRGBColorSpace;
 				material.needsUpdate = true;

+ 1 - 1
editor/js/Sidebar.Scene.js

@@ -484,7 +484,7 @@ function SidebarScene( editor ) {
 
 	signals.sceneGraphChanged.add( refreshUI );
 
-	signals.sceneEnvironmentChanged.add( refreshUI );
+	signals.refreshSidebarEnvironment.add( refreshUI );
 
 	/*
 	signals.objectChanged.add( function ( object ) {

+ 0 - 3
editor/js/Strings.js

@@ -30,7 +30,6 @@ function Strings( config ) {
 			'menubar/edit/center': 'Center',
 			'menubar/edit/clone': 'Clone',
 			'menubar/edit/delete': 'Delete (Del)',
-			'menubar/edit/fixcolormaps': 'Fix Color Maps',
 
 			'menubar/add': 'Add',
 			'menubar/add/group': 'Group',
@@ -382,7 +381,6 @@ function Strings( config ) {
 			'menubar/edit/center': 'Center',
 			'menubar/edit/clone': 'Cloner',
 			'menubar/edit/delete': 'Supprimer (Supp)',
-			'menubar/edit/fixcolormaps': 'Correction des couleurs',
 
 			'menubar/add': 'Ajouter',
 			'menubar/add/group': 'Groupe',
@@ -732,7 +730,6 @@ function Strings( config ) {
 			'menubar/edit/center': '居中',
 			'menubar/edit/clone': '拷贝',
 			'menubar/edit/delete': '删除 (Del)',
-			'menubar/edit/fixcolormaps': '修复颜色贴图',
 
 			'menubar/add': '添加',
 			'menubar/add/group': '组',

+ 7 - 0
editor/js/Viewport.js

@@ -713,6 +713,13 @@ function Viewport( editor ) {
 			mixer.update( delta );
 			needsUpdate = true;
 
+			if ( editor.selected !== null ) {
+
+				editor.selected.updateWorldMatrix( false, true ); // avoid frame late effect for certain skinned meshes (e.g. Michelle.glb)
+				selectionBox.box.setFromObject( editor.selected, true ); // selection box should reflect current animation state
+
+			}
+
 		}
 
 		// View Helper

+ 33 - 4
editor/js/libs/ui.three.js

@@ -1,5 +1,6 @@
 import * as THREE from 'three';
 
+import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
 import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
 import { TGALoader } from 'three/addons/loaders/TGALoader.js';
 
@@ -93,6 +94,34 @@ class UITexture extends UISpan {
 
 				reader.readAsDataURL( file );
 
+			} else if ( extension === 'ktx2' ) {
+
+				reader.addEventListener( 'load', function ( event ) {
+
+					const arrayBuffer = event.target.result;
+					const blobURL = URL.createObjectURL( new Blob( [ arrayBuffer ] ) );
+					const tempRenderer = new THREE.WebGLRenderer();
+					const ktx2Loader = new KTX2Loader();
+					ktx2Loader.setTranscoderPath( '../../examples/jsm/libs/basis/' );
+					ktx2Loader.detectSupport( tempRenderer );
+
+					ktx2Loader.load( blobURL, function ( texture ) {
+
+						texture.colorSpace = THREE.SRGBColorSpace;
+						texture.sourceFile = file.name;
+						texture.needsUpdate = true;
+						scope.setValue( texture );
+
+						if ( scope.onChangeCallback ) scope.onChangeCallback( texture );
+						ktx2Loader.dispose();
+						tempRenderer.dispose();
+
+					} );
+
+				} );
+
+				reader.readAsArrayBuffer( file );
+
 			} else if ( file.type.match( 'image.*' ) ) {
 
 				reader.addEventListener( 'load', function ( event ) {
@@ -155,14 +184,14 @@ class UITexture extends UISpan {
 				canvas.title = texture.sourceFile;
 				const scale = canvas.width / image.width;
 
-				if ( image.data === undefined ) {
+				if ( texture.isDataTexture || texture.isCompressedTexture ) {
 
-					context.drawImage( image, 0, 0, image.width * scale, image.height * scale );
+					const canvas2 = renderToCanvas( texture );
+					context.drawImage( canvas2, 0, 0, image.width * scale, image.height * scale );
 
 				} else {
 
-					const canvas2 = renderToCanvas( texture );
-					context.drawImage( canvas2, 0, 0, image.width * scale, image.height * scale );
+					context.drawImage( image, 0, 0, image.width * scale, image.height * scale );
 
 				}
 

+ 0 - 3
editor/sw.js

@@ -40,9 +40,6 @@ const assets = [
 	'../examples/jsm/loaders/GLTFLoader.js',
 	'../examples/jsm/loaders/KMZLoader.js',
 	'../examples/jsm/loaders/KTX2Loader.js',
-	'../examples/jsm/loaders/IFCLoader.js',
-	'../examples/jsm/loaders/ifc/web-ifc-api.js',
-	'../examples/jsm/loaders/ifc/web-ifc.wasm',
 	'../examples/jsm/loaders/MD2Loader.js',
 	'../examples/jsm/loaders/OBJLoader.js',
 	'../examples/jsm/loaders/MTLLoader.js',

+ 6 - 0
examples/files.json

@@ -34,6 +34,7 @@
 		"webgl_geometry_extrude_splines",
 		"webgl_geometry_minecraft",
 		"webgl_geometry_nurbs",
+		"webgl_geometry_sdf",
 		"webgl_geometry_shapes",
 		"webgl_geometry_spline_editor",
 		"webgl_geometry_teapot",
@@ -169,6 +170,7 @@
 		"webgl_materials_wireframe",
 		"webgl_math_obb",
 		"webgl_math_orientation_transform",
+		"webgl_mesh_batch",
 		"webgl_mirror",
 		"webgl_modifier_curve",
 		"webgl_modifier_curve_instanced",
@@ -313,6 +315,7 @@
 		"webgpu_clearcoat",
 		"webgpu_compute_audio",
 		"webgpu_compute_particles",
+		"webgpu_compute_particles_rain",
 		"webgpu_compute_points",
 		"webgpu_compute_texture",
 		"webgpu_compute_texture_pingpong",
@@ -322,6 +325,7 @@
 		"webgpu_depth_texture",
 		"webgpu_equirectangular",
 		"webgpu_instance_mesh",
+		"webgpu_instance_points",
 		"webgpu_instance_uniform",
 		"webgpu_lights_custom",
 		"webgpu_lights_ies_spotlight",
@@ -340,12 +344,14 @@
 		"webgpu_particles",
 		"webgpu_rtt",
 		"webgpu_sandbox",
+		"webgpu_shadertoy",
 		"webgpu_shadowmap",
 		"webgpu_skinning",
 		"webgpu_skinning_instancing",
 		"webgpu_skinning_points",
 		"webgpu_sprites",
 		"webgpu_tsl_editor",
+		"webgpu_tsl_transpiler",
 		"webgpu_video_panorama"
 	],
 	"webaudio": [

+ 3 - 1
examples/index.html

@@ -261,7 +261,9 @@
 
 		function escapeRegExp( string ) {
 
-			return string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); // https://stackoverflow.com/a/6969486/5250847
+			string = string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); // https://stackoverflow.com/a/6969486/5250847
+
+			return '(?=.*' + string.split( ' ' ).join( ')(?=.*' ) + ')'; // match all words, in any order
 
 		}
 

+ 290 - 0
examples/jsm/Addons.js

@@ -0,0 +1,290 @@
+export * from './animation/AnimationClipCreator.js';
+export * from './animation/CCDIKSolver.js';
+export * from './animation/MMDAnimationHelper.js';
+export * from './animation/MMDPhysics.js';
+
+export * from './cameras/CinematicCamera.js';
+
+export { default as WebGL } from './capabilities/WebGL.js';
+
+export * from './controls/ArcballControls.js';
+export * from './controls/DragControls.js';
+export * from './controls/FirstPersonControls.js';
+export * from './controls/FlyControls.js';
+export * from './controls/MapControls.js';
+export * from './controls/OrbitControls.js';
+export * from './controls/PointerLockControls.js';
+export * from './controls/TrackballControls.js';
+export * from './controls/TransformControls.js';
+
+export * from './csm/CSM.js';
+export * from './csm/CSMFrustum.js';
+export * from './csm/CSMHelper.js';
+export * from './csm/CSMShader.js';
+
+export * as Curves from './curves/CurveExtras.js';
+export * from './curves/NURBSCurve.js';
+export * from './curves/NURBSSurface.js';
+export * as NURBSUtils from './curves/NURBSUtils.js';
+
+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';
+export * from './environments/RoomEnvironment.js';
+
+export * from './exporters/DRACOExporter.js';
+export * from './exporters/EXRExporter.js';
+export * from './exporters/GLTFExporter.js';
+export * from './exporters/KTX2Exporter.js';
+export * from './exporters/MMDExporter.js';
+export * from './exporters/OBJExporter.js';
+export * from './exporters/PLYExporter.js';
+export * from './exporters/STLExporter.js';
+export * from './exporters/USDZExporter.js';
+
+export * from './geometries/BoxLineGeometry.js';
+export * from './geometries/ConvexGeometry.js';
+export * from './geometries/DecalGeometry.js';
+export * from './geometries/ParametricGeometries.js';
+export * from './geometries/ParametricGeometry.js';
+export * from './geometries/RoundedBoxGeometry.js';
+export * from './geometries/TeapotGeometry.js';
+export * from './geometries/TextGeometry.js';
+
+export * from './helpers/LightProbeHelper.js';
+export * from './helpers/OctreeHelper.js';
+export * from './helpers/PositionalAudioHelper.js';
+export * from './helpers/RectAreaLightHelper.js';
+export * from './helpers/VertexNormalsHelper.js';
+export * from './helpers/VertexTangentsHelper.js';
+export * from './helpers/ViewHelper.js';
+
+export * from './interactive/HTMLMesh.js';
+export * from './interactive/InteractiveGroup.js';
+export * from './interactive/SelectionBox.js';
+export * from './interactive/SelectionHelper.js';
+
+export { default as IESSpotLight } from './lights/IESSpotLight.js';
+export * from './lights/LightProbeGenerator.js';
+export * from './lights/RectAreaLightUniformsLib.js';
+
+export * from './lines/Line2.js';
+export * from './lines/LineGeometry.js';
+export * from './lines/LineMaterial.js';
+export * from './lines/LineSegments2.js';
+export * from './lines/LineSegmentsGeometry.js';
+export * from './lines/Wireframe.js';
+export * from './lines/WireframeGeometry2.js';
+
+export * from './loaders/3DMLoader.js';
+export * from './loaders/3MFLoader.js';
+export * from './loaders/AMFLoader.js';
+export * from './loaders/BVHLoader.js';
+export * from './loaders/ColladaLoader.js';
+export * from './loaders/DDSLoader.js';
+export * from './loaders/DRACOLoader.js';
+export * from './loaders/EXRLoader.js';
+export * from './loaders/FBXLoader.js';
+export * from './loaders/FontLoader.js';
+export * from './loaders/GCodeLoader.js';
+export * from './loaders/GLTFLoader.js';
+export * from './loaders/HDRCubeTextureLoader.js';
+export * from './loaders/IESLoader.js';
+export * from './loaders/KMZLoader.js';
+export * from './loaders/KTX2Loader.js';
+export * from './loaders/KTXLoader.js';
+export * from './loaders/LDrawLoader.js';
+export * from './loaders/LUT3dlLoader.js';
+export * from './loaders/LUTCubeLoader.js';
+export * from './loaders/LWOLoader.js';
+export * from './loaders/LogLuvLoader.js';
+export * from './loaders/LottieLoader.js';
+export * from './loaders/MD2Loader.js';
+export * from './loaders/MDDLoader.js';
+export * from './loaders/MMDLoader.js';
+export * from './loaders/MTLLoader.js';
+export * from './loaders/NRRDLoader.js';
+export * from './loaders/OBJLoader.js';
+export * from './loaders/PCDLoader.js';
+export * from './loaders/PDBLoader.js';
+export * from './loaders/PLYLoader.js';
+export * from './loaders/PVRLoader.js';
+export * from './loaders/RGBELoader.js';
+export * from './loaders/RGBMLoader.js';
+export * from './loaders/STLLoader.js';
+export * from './loaders/SVGLoader.js';
+export * from './loaders/TDSLoader.js';
+export * from './loaders/TGALoader.js';
+export * from './loaders/TIFFLoader.js';
+export * from './loaders/TTFLoader.js';
+export * from './loaders/TiltLoader.js';
+export * from './loaders/USDZLoader.js';
+export * from './loaders/VOXLoader.js';
+export * from './loaders/VRMLLoader.js';
+export * from './loaders/VTKLoader.js';
+export * from './loaders/XYZLoader.js';
+
+export * from './materials/MeshGouraudMaterial.js';
+
+export * from './math/Capsule.js';
+export * from './math/ColorConverter.js';
+export * from './math/ConvexHull.js';
+export * from './math/ImprovedNoise.js';
+export * from './math/Lut.js';
+export * from './math/MeshSurfaceSampler.js';
+export * from './math/OBB.js';
+export * from './math/Octree.js';
+export * from './math/SimplexNoise.js';
+
+export * from './misc/ConvexObjectBreaker.js';
+export * from './misc/GPUComputationRenderer.js';
+export * from './misc/Gyroscope.js';
+export * from './misc/MD2Character.js';
+export * from './misc/MD2CharacterComplex.js';
+export * from './misc/MorphAnimMesh.js';
+export * from './misc/MorphBlendMesh.js';
+export * from './misc/ProgressiveLightMap.js';
+export * from './misc/RollerCoaster.js';
+export * from './misc/TubePainter.js';
+export * from './misc/Volume.js';
+export * from './misc/VolumeSlice.js';
+
+export * from './modifiers/CurveModifier.js';
+export * from './modifiers/EdgeSplitModifier.js';
+export * from './modifiers/SimplifyModifier.js';
+export * from './modifiers/TessellateModifier.js';
+
+export * from './objects/BatchedMesh.js';
+export * from './objects/GroundProjectedSkybox.js';
+export * from './objects/Lensflare.js';
+export * from './objects/MarchingCubes.js';
+export * from './objects/Reflector.js';
+export * from './objects/ReflectorForSSRPass.js';
+export * from './objects/Refractor.js';
+export * from './objects/ShadowMesh.js';
+export * from './objects/Sky.js';
+export * from './objects/Water.js';
+export { Water as Water2 } from './objects/Water2.js';
+
+export * from './physics/AmmoPhysics.js';
+export * from './physics/RapierPhysics.js';
+
+export * from './postprocessing/AfterimagePass.js';
+export * from './postprocessing/BloomPass.js';
+export * from './postprocessing/BokehPass.js';
+export * from './postprocessing/ClearPass.js';
+export * from './postprocessing/CubeTexturePass.js';
+export * from './postprocessing/DotScreenPass.js';
+export * from './postprocessing/EffectComposer.js';
+export * from './postprocessing/FilmPass.js';
+export * from './postprocessing/GlitchPass.js';
+export * from './postprocessing/HalftonePass.js';
+export * from './postprocessing/LUTPass.js';
+export * from './postprocessing/MaskPass.js';
+export * from './postprocessing/OutlinePass.js';
+export * from './postprocessing/OutputPass.js';
+export * from './postprocessing/Pass.js';
+export * from './postprocessing/RenderPass.js';
+export * from './postprocessing/RenderPixelatedPass.js';
+export * from './postprocessing/SAOPass.js';
+export * from './postprocessing/SMAAPass.js';
+export * from './postprocessing/SSAARenderPass.js';
+export * from './postprocessing/SSAOPass.js';
+export * from './postprocessing/SSRPass.js';
+export * from './postprocessing/SavePass.js';
+export * from './postprocessing/ShaderPass.js';
+export * from './postprocessing/TAARenderPass.js';
+export * from './postprocessing/TexturePass.js';
+export * from './postprocessing/UnrealBloomPass.js';
+
+export * from './renderers/CSS2DRenderer.js';
+export * from './renderers/CSS3DRenderer.js';
+export * from './renderers/Projector.js';
+export * from './renderers/SVGRenderer.js';
+
+export * from './shaders/ACESFilmicToneMappingShader.js';
+export * from './shaders/AfterimageShader.js';
+export * from './shaders/BasicShader.js';
+export * from './shaders/BleachBypassShader.js';
+export * from './shaders/BlendShader.js';
+export * from './shaders/BokehShader.js';
+export { BokehShader as BokehShader2 } from './shaders/BokehShader2.js';
+export * from './shaders/BrightnessContrastShader.js';
+export * from './shaders/ColorCorrectionShader.js';
+export * from './shaders/ColorifyShader.js';
+export * from './shaders/ConvolutionShader.js';
+export * from './shaders/CopyShader.js';
+export * from './shaders/DOFMipMapShader.js';
+export * from './shaders/DepthLimitedBlurShader.js';
+export * from './shaders/DigitalGlitch.js';
+export * from './shaders/DotScreenShader.js';
+export * from './shaders/ExposureShader.js';
+export * from './shaders/FXAAShader.js';
+export * from './shaders/FilmShader.js';
+export * from './shaders/FocusShader.js';
+export * from './shaders/FreiChenShader.js';
+export * from './shaders/GammaCorrectionShader.js';
+export * from './shaders/GodRaysShader.js';
+export * from './shaders/HalftoneShader.js';
+export * from './shaders/HorizontalBlurShader.js';
+export * from './shaders/HorizontalTiltShiftShader.js';
+export * from './shaders/HueSaturationShader.js';
+export * from './shaders/KaleidoShader.js';
+export * from './shaders/LuminosityHighPassShader.js';
+export * from './shaders/LuminosityShader.js';
+export * from './shaders/MMDToonShader.js';
+export * from './shaders/MirrorShader.js';
+export * from './shaders/NormalMapShader.js';
+export * from './shaders/OutputShader.js';
+export * from './shaders/RGBShiftShader.js';
+export * from './shaders/SAOShader.js';
+export * from './shaders/SMAAShader.js';
+export * from './shaders/SSAOShader.js';
+export * from './shaders/SSRShader.js';
+export * from './shaders/SepiaShader.js';
+export * from './shaders/SobelOperatorShader.js';
+export * from './shaders/SubsurfaceScatteringShader.js';
+export * from './shaders/TechnicolorShader.js';
+export * from './shaders/ToonShader.js';
+export * from './shaders/TriangleBlurShader.js';
+export * from './shaders/UnpackDepthRGBAShader.js';
+export * from './shaders/VelocityShader.js';
+export * from './shaders/VerticalBlurShader.js';
+export * from './shaders/VerticalTiltShiftShader.js';
+export * from './shaders/VignetteShader.js';
+export * from './shaders/VolumeShader.js';
+export * from './shaders/WaterRefractionShader.js';
+
+export * from './textures/FlakesTexture.js';
+
+export * as BufferGeometryUtils from './utils/BufferGeometryUtils.js';
+export * as CameraUtils from './utils/CameraUtils.js';
+export * from './utils/GPUStatsPanel.js';
+export * as GeometryCompressionUtils from './utils/GeometryCompressionUtils.js';
+export * as GeometryUtils from './utils/GeometryUtils.js';
+export * from './utils/LDrawUtils.js';
+export * from './utils/PackedPhongMaterial.js';
+export * as SceneUtils from './utils/SceneUtils.js';
+export * from './utils/ShadowMapViewer.js';
+export * as SkeletonUtils from './utils/SkeletonUtils.js';
+export * from './utils/TextureUtils.js';
+export * from './utils/UVsDebug.js';
+export * from './utils/WorkerPool.js';
+
+export * from './webxr/ARButton.js';
+export * from './webxr/OculusHandModel.js';
+export * from './webxr/OculusHandPointerModel.js';
+export * from './webxr/Text2D.js';
+export * from './webxr/VRButton.js';
+export * from './webxr/XRButton.js';
+export * from './webxr/XRControllerModelFactory.js';
+export * from './webxr/XREstimatedLight.js';
+export * from './webxr/XRHandMeshModel.js';
+export * from './webxr/XRHandModelFactory.js';
+export * from './webxr/XRHandPrimitiveModel.js';
+export * from './webxr/XRPlanes.js';

+ 26 - 0
examples/jsm/controls/FlyControls.js

@@ -186,6 +186,29 @@ class FlyControls extends EventDispatcher {
 
 		};
 
+		this.pointercancel = function () {
+
+			if ( this.enabled === false ) return;
+
+			if ( this.dragToLook ) {
+
+				this.status = 0;
+
+				this.moveState.yawLeft = this.moveState.pitchDown = 0;
+
+			} else {
+
+				this.moveState.forward = 0;
+				this.moveState.back = 0;
+
+				this.updateMovementVector();
+
+			}
+
+			this.updateRotationVector();
+
+		};
+
 		this.contextMenu = function ( event ) {
 
 			if ( this.enabled === false ) return;
@@ -269,6 +292,7 @@ class FlyControls extends EventDispatcher {
 			this.domElement.removeEventListener( 'pointerdown', _pointerdown );
 			this.domElement.removeEventListener( 'pointermove', _pointermove );
 			this.domElement.removeEventListener( 'pointerup', _pointerup );
+			this.domElement.removeEventListener( 'pointercancel', _pointercancel );
 
 			window.removeEventListener( 'keydown', _keydown );
 			window.removeEventListener( 'keyup', _keyup );
@@ -279,6 +303,7 @@ class FlyControls extends EventDispatcher {
 		const _pointermove = this.pointermove.bind( this );
 		const _pointerdown = this.pointerdown.bind( this );
 		const _pointerup = this.pointerup.bind( this );
+		const _pointercancel = this.pointercancel.bind( this );
 		const _keydown = this.keydown.bind( this );
 		const _keyup = this.keyup.bind( this );
 
@@ -286,6 +311,7 @@ class FlyControls extends EventDispatcher {
 		this.domElement.addEventListener( 'pointerdown', _pointerdown );
 		this.domElement.addEventListener( 'pointermove', _pointermove );
 		this.domElement.addEventListener( 'pointerup', _pointerup );
+		this.domElement.addEventListener( 'pointercancel', _pointercancel );
 
 		window.addEventListener( 'keydown', _keydown );
 		window.addEventListener( 'keyup', _keyup );

+ 12 - 1
examples/jsm/controls/OrbitControls.js

@@ -41,6 +41,9 @@ class OrbitControls extends EventDispatcher {
 		// "target" sets the location of focus, where the object orbits around
 		this.target = new Vector3();
 
+		// Sets the 3D cursor (similar to Blender), from which the maxTargetRadius takes effect
+		this.cursor = new Vector3();
+
 		// How far you can dolly in and out ( PerspectiveCamera only )
 		this.minDistance = 0;
 		this.maxDistance = Infinity;
@@ -49,6 +52,10 @@ class OrbitControls extends EventDispatcher {
 		this.minZoom = 0;
 		this.maxZoom = Infinity;
 
+		// Limit camera target within a spherical area around the cursor
+		this.minTargetRadius = 0;
+		this.maxTargetRadius = Infinity;
+
 		// How far you can orbit vertically, upper and lower limits.
 		// Range is 0 to Math.PI radians.
 		this.minPolarAngle = 0; // radians
@@ -249,6 +256,11 @@ class OrbitControls extends EventDispatcher {
 
 				}
 
+				// Limit the target distance from the cursor to create a sphere around the center of interest
+				scope.target.sub( scope.cursor );
+				scope.target.clampLength( scope.minTargetRadius, scope.maxTargetRadius );
+				scope.target.add( scope.cursor );
+
 				// adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
 				// we adjust zoom later in these cases
 				if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {
@@ -261,7 +273,6 @@ class OrbitControls extends EventDispatcher {
 
 				}
 
-
 				offset.setFromSpherical( spherical );
 
 				// rotate offset back to "camera-up-vector-is-up" space

+ 27 - 11
examples/jsm/controls/TransformControls.js

@@ -465,17 +465,9 @@ class TransformControls extends Object3D {
 
 			const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
 
-			if ( axis === 'E' ) {
+			let _inPlaneRotation = false;
 
-				this.rotationAxis.copy( this.eye );
-				this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
-
-				this._startNorm.copy( this.pointStart ).normalize();
-				this._endNorm.copy( this.pointEnd ).normalize();
-
-				this.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );
-
-			} else if ( axis === 'XYZE' ) {
+			if ( axis === 'XYZE' ) {
 
 				this.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();
 				this.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
@@ -492,7 +484,31 @@ class TransformControls extends Object3D {
 
 				}
 
-				this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;
+				_tempVector.cross( this.eye );
+
+				// When _tempVector is 0 after cross with this.eye the vectors are parallel and should use in-plane rotation logic.
+				if ( _tempVector.length() === 0 ) {
+
+					_inPlaneRotation = true;
+
+				} else {
+
+					this.rotationAngle = this._offset.dot( _tempVector.normalize() ) * ROTATION_SPEED;
+
+				}
+
+
+			}
+
+			if ( axis === 'E' || _inPlaneRotation ) {
+
+				this.rotationAxis.copy( this.eye );
+				this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
+
+				this._startNorm.copy( this.pointStart ).normalize();
+				this._endNorm.copy( this.pointEnd ).normalize();
+
+				this.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );
 
 			}
 

+ 1 - 1
examples/jsm/csm/CSMShader.js

@@ -6,7 +6,7 @@ vec3 geometryPosition = - vViewPosition;
 vec3 geometryNormal = normal;
 vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
 
-vec3 geometryClearcoatNormal;
+vec3 geometryClearcoatNormal = vec3( 0.0 );
 
 #ifdef USE_CLEARCOAT
 

+ 72 - 2
examples/jsm/exporters/GLTFExporter.js

@@ -22,7 +22,8 @@ import {
 	Source,
 	SRGBColorSpace,
 	CompressedTexture,
-	Vector3
+	Vector3,
+	Quaternion,
 } from 'three';
 import { decompress } from './../utils/TextureUtils.js';
 
@@ -134,6 +135,12 @@ class GLTFExporter {
 
 		} );
 
+		this.register( function ( writer ) {
+
+			return new GLTFMeshGpuInstancing( writer );
+
+		} );
+
 	}
 
 	register( callback ) {
@@ -1165,7 +1172,7 @@ class GLTFWriter {
 		}
 
 		if ( start === undefined ) start = 0;
-		if ( count === undefined ) count = attribute.count;
+		if ( count === undefined || count === Infinity ) count = attribute.count;
 
 		// Skip creating an accessor if the attribute doesn't have data to export
 		if ( count === 0 ) return null;
@@ -1639,6 +1646,8 @@ class GLTFWriter {
 		const nameConversion = {
 			uv: 'TEXCOORD_0',
 			uv1: 'TEXCOORD_1',
+			uv2: 'TEXCOORD_2',
+			uv3: 'TEXCOORD_3',
 			color: 'COLOR_0',
 			skinWeight: 'WEIGHTS_0',
 			skinIndex: 'JOINTS_0'
@@ -2962,6 +2971,67 @@ class GLTFMaterialsEmissiveStrengthExtension {
 
 }
 
+/**
+ * GPU Instancing Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
+ */
+class GLTFMeshGpuInstancing {
+
+	constructor( writer ) {
+
+		this.writer = writer;
+		this.name = 'EXT_mesh_gpu_instancing';
+
+	}
+
+	writeNode( object, nodeDef ) {
+
+		if ( ! object.isInstancedMesh ) return;
+
+		const writer = this.writer;
+
+		const mesh = object;
+
+		const translationAttr = new Float32Array( mesh.count * 3 );
+		const rotationAttr = new Float32Array( mesh.count * 4 );
+		const scaleAttr = new Float32Array( mesh.count * 3 );
+
+		const matrix = new Matrix4();
+		const position = new Vector3();
+		const quaternion = new Quaternion();
+		const scale = new Vector3();
+
+		for ( let i = 0; i < mesh.count; i ++ ) {
+
+			mesh.getMatrixAt( i, matrix );
+			matrix.decompose( position, quaternion, scale );
+
+			position.toArray( translationAttr, i * 3 );
+			quaternion.toArray( rotationAttr, i * 4 );
+			scale.toArray( scaleAttr, i * 3 );
+
+		}
+
+		const attributes = {
+			TRANSLATION: writer.processAccessor( new BufferAttribute( translationAttr, 3 ) ),
+			ROTATION: writer.processAccessor( new BufferAttribute( rotationAttr, 4 ) ),
+			SCALE: writer.processAccessor( new BufferAttribute( scaleAttr, 3 ) ),
+		};
+
+		if ( mesh.instanceColor )
+			attributes._COLOR_0 = writer.processAccessor( mesh.instanceColor );
+
+		nodeDef.extensions = nodeDef.extensions || {};
+		nodeDef.extensions[ this.name ] = { attributes };
+
+		writer.extensionsUsed[ this.name ] = true;
+		writer.extensionsRequired[ this.name ] = true;
+
+	}
+
+}
+
 /**
  * Static utility functions
  */

+ 174 - 0
examples/jsm/geometries/InstancedPointsGeometry.js

@@ -0,0 +1,174 @@
+import {
+	Box3,
+	Float32BufferAttribute,
+	InstancedBufferGeometry,
+	InstancedBufferAttribute,
+	Sphere,
+	Vector3
+} from 'three';
+
+const _vector = new Vector3();
+
+class InstancedPointsGeometry extends InstancedBufferGeometry {
+
+	constructor() {
+
+		super();
+
+		this.isInstancedPointsGeometry = true;
+
+		this.type = 'InstancedPointsGeometry';
+
+		const positions = [ - 1, 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
+		const uvs = [ - 1, 1, 1, 1, - 1, - 1, 1, - 1 ];
+		const index = [ 0, 2, 1, 2, 3, 1 ];
+
+		this.setIndex( index );
+		this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
+
+	}
+
+	applyMatrix4( matrix ) {
+
+		const pos = this.attributes.instancePosition;
+
+		if ( pos !== undefined ) {
+
+			pos.applyMatrix4( matrix );
+
+			pos.needsUpdate = true;
+
+		}
+
+		if ( this.boundingBox !== null ) {
+
+			this.computeBoundingBox();
+
+		}
+
+		if ( this.boundingSphere !== null ) {
+
+			this.computeBoundingSphere();
+
+		}
+
+		return this;
+
+	}
+
+	setPositions( array ) {
+
+		let points;
+
+		if ( array instanceof Float32Array ) {
+
+			points = array;
+
+		} else if ( Array.isArray( array ) ) {
+
+			points = new Float32Array( array );
+
+		}
+
+		this.setAttribute( 'instancePosition', new InstancedBufferAttribute( points, 3 ) ); // xyz
+
+		//
+
+		this.computeBoundingBox();
+		this.computeBoundingSphere();
+
+		return this;
+
+	}
+
+	setColors( array ) {
+
+		let colors;
+
+		if ( array instanceof Float32Array ) {
+
+			colors = array;
+
+		} else if ( Array.isArray( array ) ) {
+
+			colors = new Float32Array( array );
+
+		}
+
+		this.setAttribute( 'instanceColor', new InstancedBufferAttribute( colors, 3 ) ); // rgb
+
+		return this;
+
+	}
+
+	computeBoundingBox() {
+
+		if ( this.boundingBox === null ) {
+
+			this.boundingBox = new Box3();
+
+		}
+
+		const pos = this.attributes.instancePosition;
+
+		if ( pos !== undefined ) {
+
+			this.boundingBox.setFromBufferAttribute( pos );
+
+		}
+
+	}
+
+	computeBoundingSphere() {
+
+		if ( this.boundingSphere === null ) {
+
+			this.boundingSphere = new Sphere();
+
+		}
+
+		if ( this.boundingBox === null ) {
+
+			this.computeBoundingBox();
+
+		}
+
+		const pos = this.attributes.instancePosition;
+
+		if ( pos !== undefined ) {
+
+			const center = this.boundingSphere.center;
+
+			this.boundingBox.getCenter( center );
+
+			let maxRadiusSq = 0;
+
+			for ( let i = 0, il = pos.count; i < il; i ++ ) {
+
+				_vector.fromBufferAttribute( pos, i );
+				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
+
+			}
+
+			this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+
+			if ( isNaN( this.boundingSphere.radius ) ) {
+
+				console.error( 'THREE.InstancedPointsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+
+			}
+
+		}
+
+	}
+
+	toJSON() {
+
+		// todo
+
+	}
+
+}
+
+export default InstancedPointsGeometry;

+ 144 - 0
examples/jsm/geometries/SDFGeometryGenerator.js

@@ -0,0 +1,144 @@
+/**
+ * @author santiago / @glitch_life
+ * wrapper of https://www.npmjs.com/package/isosurface by https://github.com/mikolalysenko
+ *
+ * Returns BufferGeometry from SDF
+ */
+
+import {
+	BufferAttribute,
+	BufferGeometry,
+	FloatType,
+	Mesh,
+	OrthographicCamera,
+	PlaneGeometry,
+	Scene,
+	ShaderMaterial,
+	Vector2,
+	WebGLRenderTarget
+} from 'three';
+
+import { surfaceNet } from './../libs/surfaceNet.js';
+
+class SDFGeometryGenerator {
+
+	constructor( renderer ) {
+
+		this.renderer = renderer;
+
+	}
+
+	generate( res = 64, distFunc = 'float dist( vec3 p ){ return length(p) - 0.5; }', bounds = 1 ) {
+
+		let w, h;
+		if ( res == 8 ) [ w, h ] = [ 32, 16 ];
+		else if ( res == 16 ) [ w, h ] = [ 64, 64 ];
+		else if ( res == 32 ) [ w, h ] = [ 256, 128 ];
+		else if ( res == 64 ) [ w, h ] = [ 512, 512 ];
+		else if ( res == 128 ) [ w, h ] = [ 2048, 1024 ];
+		else if ( res == 256 ) [ w, h ] = [ 4096, 4096 ];
+		else if ( res == 512 ) [ w, h ] = [ 16384, 8096 ];
+		else if ( res == 1024 ) [ w, h ] = [ 32768, 32768 ];
+		else throw new Error( 'THREE.SDFGeometryGenerator: Resolution must be in range 8 < res < 1024 and must be ^2' );
+
+		const maxTexSize = this.renderer.capabilities.maxTextureSize;
+
+		if ( w > maxTexSize || h > maxTexSize ) throw new Error( 'THREE.SDFGeometryGenerator: Your device does not support this resolution ( ' + res + ' ), decrease [res] param.' );
+
+		const [ tilesX, tilesY ] = [ ( w / res ), ( h / res ) ];
+
+		const sdfCompute = `
+			varying vec2 vUv;
+			uniform float tileNum;
+			uniform float bounds;
+			[#dist#]
+			void main()	{ gl_FragColor=vec4( ( dist( vec3( vUv, tileNum ) * 2.0 * bounds - vec3( bounds ) ) < 0.00001 ) ? 1.0 : 0.0 ); }
+		`;
+
+		const sdfRT = this.computeSDF( w, h, tilesX, tilesY, bounds, sdfCompute.replace( '[#dist#]', distFunc ) );
+
+		const read = new Float32Array( w * h * 4 );
+		this.renderer.readRenderTargetPixels( sdfRT, 0, 0, w, h, read );
+		sdfRT.dispose();
+
+		//
+
+		const mesh = surfaceNet( [ res, res, res ], ( x, y, z ) => {
+
+			x = ( x + bounds ) * ( res / ( bounds * 2 ) );
+			y = ( y + bounds ) * ( res / ( bounds * 2 ) );
+			z = ( z + bounds ) * ( res / ( bounds * 2 ) );
+			let p = ( x + ( z % tilesX ) * res ) + y * w + ( Math.floor( z / tilesX ) * res * w );
+			p *= 4;
+			return ( read[ p + 3 ] > 0 ) ? - 0.000000001 : 1;
+
+		}, [[ - bounds, - bounds, - bounds ], [ bounds, bounds, bounds ]] );
+
+		const ps = [], ids = [];
+		const geometry = new BufferGeometry();
+		mesh.positions.forEach( p => {
+
+			ps.push( p[ 0 ], p[ 1 ], p[ 2 ] );
+
+		} );
+		mesh.cells.forEach( p => ids.push( p[ 0 ], p[ 1 ], p[ 2 ] ) );
+		geometry.setAttribute( 'position', new BufferAttribute( new Float32Array( ps ), 3 ) );
+		geometry.setIndex( ids );
+
+		return geometry;
+
+	}
+
+	computeSDF( width, height, tilesX, tilesY, bounds, shader ) {
+
+		const rt = new WebGLRenderTarget( width, height, { type: FloatType } );
+		const scn = new Scene();
+		const cam = new OrthographicCamera();
+		const tiles = tilesX * tilesY;
+		let currentTile = 0;
+
+		Object.assign( cam, { left: width / - 2, right: width / 2, top: height / 2, bottom: height / - 2 } ).updateProjectionMatrix();
+		cam.position.z = 2;
+
+		const tileSize = width / tilesX;
+		const geometry = new PlaneGeometry( tileSize, tileSize );
+
+		while ( currentTile ++ < tiles ) {
+
+			const c = currentTile - 1;
+			const [ px, py ] = [ ( tileSize ) / 2 + ( c % tilesX ) * ( tileSize ) - width / 2, ( tileSize ) / 2 + Math.floor( c / tilesX ) * ( tileSize ) - height / 2 ];
+			const compPlane = new Mesh( geometry, new ShaderMaterial( {
+				uniforms: {
+					res: { value: new Vector2( width, height ) },
+					tileNum: { value: c / ( tilesX * tilesY - 1 ) },
+					bounds: { value: bounds }
+				},
+				vertexShader: 'varying vec2 vUv;void main(){vUv=uv;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}',
+				fragmentShader: shader
+			} ) );
+			compPlane.position.set( px, py, 0 );
+			scn.add( compPlane );
+
+		}
+
+		this.renderer.setRenderTarget( rt );
+		this.renderer.render( scn, cam );
+		this.renderer.setRenderTarget( null );
+
+		//
+
+		geometry.dispose();
+
+		scn.traverse( function ( object ) {
+
+			if ( object.material !== undefined ) object.material.dispose();
+
+		} );
+
+		return rt;
+
+	}
+
+}
+
+export { SDFGeometryGenerator };

+ 6 - 1
examples/jsm/libs/lottie_canvas.module.js

@@ -1,3 +1,7 @@
+const lottie = {};
+
+if (typeof document !== 'undefined') {
+
 const svgNS = 'http://www.w3.org/2000/svg';
 
 let locationHref = '';
@@ -4547,7 +4551,6 @@ const Matrix = (function () {
   };
 }());
 
-const lottie = {};
 var standalone = '__[STANDALONE]__';
 var animationData = '__[ANIMATIONDATA]__';
 var renderer = '';
@@ -14841,4 +14844,6 @@ setExpressionsPlugin(Expressions);
 initialize$1();
 initialize();
 
+}
+
 export { lottie as default };

+ 13 - 75
examples/jsm/libs/opentype.module.js

@@ -8115,30 +8115,6 @@ Substitution.prototype.add = function(feature, sub, script, language) {
     return undefined;
 };
 
-function isBrowser() {
-    return typeof window !== 'undefined';
-}
-
-function nodeBufferToArrayBuffer(buffer) {
-    var ab = new ArrayBuffer(buffer.length);
-    var view = new Uint8Array(ab);
-    for (var i = 0; i < buffer.length; ++i) {
-        view[i] = buffer[i];
-    }
-
-    return ab;
-}
-
-function arrayBufferToNodeBuffer(ab) {
-    var buffer = new Buffer(ab.byteLength);
-    var view = new Uint8Array(ab);
-    for (var i = 0; i < buffer.length; ++i) {
-        buffer[i] = view[i];
-    }
-
-    return buffer;
-}
-
 function checkArgument(expression, message) {
     if (!expression) {
         throw message;
@@ -13671,27 +13647,21 @@ Font.prototype.download = function(fileName) {
     fileName = fileName || familyName.replace(/\s/g, '') + '-' + styleName + '.otf';
     var arrayBuffer = this.toArrayBuffer();
 
-    if (isBrowser()) {
-        window.URL = window.URL || window.webkitURL;
+    window.URL = window.URL || window.webkitURL;
 
-        if (window.URL) {
-            var dataView = new DataView(arrayBuffer);
-            var blob = new Blob([dataView], {type: 'font/opentype'});
+    if (window.URL) {
+        var dataView = new DataView(arrayBuffer);
+        var blob = new Blob([dataView], {type: 'font/opentype'});
 
-            var link = document.createElement('a');
-            link.href = window.URL.createObjectURL(blob);
-            link.download = fileName;
+        var link = document.createElement('a');
+        link.href = window.URL.createObjectURL(blob);
+        link.download = fileName;
 
-            var event = document.createEvent('MouseEvents');
-            event.initEvent('click', true, false);
-            link.dispatchEvent(event);
-        } else {
-            console.warn('Font file could not be downloaded. Try using a different browser.');
-        }
+        var event = document.createEvent('MouseEvents');
+        event.initEvent('click', true, false);
+        link.dispatchEvent(event);
     } else {
-        var fs = require('fs');
-        var buffer = arrayBufferToNodeBuffer(arrayBuffer);
-        fs.writeFileSync(fileName, buffer);
+        console.warn('Font file could not be downloaded. Try using a different browser.');
     }
 };
 /**
@@ -14155,22 +14125,7 @@ var loca = { parse: parseLocaTable };
  */
 
 // File loaders /////////////////////////////////////////////////////////
-/**
- * Loads a font from a file. The callback throws an error message as the first parameter if it fails
- * and the font as an ArrayBuffer in the second parameter if it succeeds.
- * @param  {string} path - The path of the file
- * @param  {Function} callback - The function to call when the font load completes
- */
-function loadFromFile(path, callback) {
-    var fs = require('fs');
-    fs.readFile(path, function(err, buffer) {
-        if (err) {
-            return callback(err.message);
-        }
 
-        callback(null, nodeBufferToArrayBuffer(buffer));
-    });
-}
 /**
  * Loads a font from a URL. The callback throws an error message as the first parameter if it fails
  * and the font as an ArrayBuffer in the second parameter if it succeeds.
@@ -14507,11 +14462,9 @@ function parseBuffer(buffer, opt) {
  */
 function load(url, callback, opt) {
     opt = (opt === undefined || opt === null) ?  {} : opt;
-    var isNode = typeof window === 'undefined';
-    var loadFn = isNode && !opt.isUrl ? loadFromFile : loadFromUrl;
 
     return new Promise(function (resolve, reject) {
-        loadFn(url, function(err, arrayBuffer) {
+        loadFromUrl(url, function(err, arrayBuffer) {
             if (err) {
                 if (callback) {
                     return callback(err);
@@ -14538,20 +14491,6 @@ function load(url, callback, opt) {
     });
 }
 
-/**
- * Synchronously load the font from a URL or file.
- * When done, returns the font object or throws an error.
- * @alias opentype.loadSync
- * @param  {string} url - The URL of the font to load.
- * @param  {Object} opt - opt.lowMemory
- * @return {opentype.Font}
- */
-function loadSync(url, opt) {
-    var fs = require('fs');
-    var buffer = fs.readFileSync(url);
-    return parseBuffer(nodeBufferToArrayBuffer(buffer), opt);
-}
-
 var opentype = /*#__PURE__*/Object.freeze({
 	__proto__: null,
 	Font: Font,
@@ -14561,8 +14500,7 @@ var opentype = /*#__PURE__*/Object.freeze({
 	_parse: parse,
 	parse: parseBuffer,
 	load: load,
-	loadSync: loadSync
 });
 
 export default opentype;
-export { BoundingBox, Font, Glyph, Path, parse as _parse, load, loadSync, parseBuffer as parse };
+export { BoundingBox, Font, Glyph, Path, parse as _parse, load, parseBuffer as parse };

+ 201 - 0
examples/jsm/libs/surfaceNet.js

@@ -0,0 +1,201 @@
+/**
+ * SurfaceNets in JavaScript
+ *
+ * Written by Mikola Lysenko (C) 2012
+ *
+ * MIT License
+ *
+ * Based on: S.F. Gibson, 'Constrained Elastic Surface Nets'. (1998) MERL Tech Report.
+ * from https://github.com/mikolalysenko/isosurface/tree/master
+ * 
+ */
+
+let surfaceNet = ( dims, potential, bounds ) => {
+		
+	
+	//Precompute edge table, like Paul Bourke does.
+	// This saves a bit of time when computing the centroid of each boundary cell
+	var cube_edges = new Int32Array(24) , edge_table = new Int32Array(256);
+	(function() {
+
+		//Initialize the cube_edges table
+		// This is just the vertex number of each cube
+		var k = 0;
+		for(var i=0; i<8; ++i) {
+			for(var j=1; j<=4; j<<=1) {
+				var p = i^j;
+				if(i <= p) {
+					cube_edges[k++] = i;
+					cube_edges[k++] = p;
+				}
+			}
+		}
+
+		//Initialize the intersection table.
+		//  This is a 2^(cube configuration) ->  2^(edge configuration) map
+		//  There is one entry for each possible cube configuration, and the output is a 12-bit vector enumerating all edges crossing the 0-level.
+		for(var i=0; i<256; ++i) {
+			var em = 0;
+			for(var j=0; j<24; j+=2) {
+				var a = !!(i & (1<<cube_edges[j]))
+					, b = !!(i & (1<<cube_edges[j+1]));
+				em |= a !== b ? (1 << (j >> 1)) : 0;
+			}
+			edge_table[i] = em;
+		}
+	})();
+
+	//Internal buffer, this may get resized at run time
+	var buffer = new Array(4096);
+	(function() {
+		for(var i=0; i<buffer.length; ++i) {
+			buffer[i] = 0;
+		}
+	})();
+
+	if(!bounds) {
+		bounds = [[0,0,0],dims];
+	}
+	
+	var scale     = [0,0,0];
+	var shift     = [0,0,0];
+	for(var i=0; i<3; ++i) {
+		scale[i] = (bounds[1][i] - bounds[0][i]) / dims[i];
+		shift[i] = bounds[0][i];
+	}
+	
+	var vertices = []
+		, faces = []
+		, n = 0
+		, x = [0, 0, 0]
+		, R = [1, (dims[0]+1), (dims[0]+1)*(dims[1]+1)]
+		, grid = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+		, buf_no = 1;
+	
+		
+	//Resize buffer if necessary 
+	if(R[2] * 2 > buffer.length) {
+		var ol = buffer.length;
+		buffer.length = R[2] * 2;
+		while(ol < buffer.length) {
+			buffer[ol++] = 0;
+		}
+	}
+	
+	//March over the voxel grid
+	for(x[2]=0; x[2]<dims[2]-1; ++x[2], n+=dims[0], buf_no ^= 1, R[2]=-R[2]) {
+	
+		//m is the pointer into the buffer we are going to use.  
+		//This is slightly obtuse because javascript does not have good support for packed data structures, so we must use typed arrays :(
+		//The contents of the buffer will be the indices of the vertices on the previous x/y slice of the volume
+		var m = 1 + (dims[0]+1) * (1 + buf_no * (dims[1]+1));
+		
+		for(x[1]=0; x[1]<dims[1]-1; ++x[1], ++n, m+=2)
+		for(x[0]=0; x[0]<dims[0]-1; ++x[0], ++n, ++m) {
+		
+			//Read in 8 field values around this vertex and store them in an array
+			//Also calculate 8-bit mask, like in marching cubes, so we can speed up sign checks later
+			var mask = 0, g = 0;
+			for(var k=0; k<2; ++k)
+			for(var j=0; j<2; ++j)      
+			for(var i=0; i<2; ++i, ++g) {
+				var p = potential(
+					scale[0]*(x[0]+i)+shift[0],
+					scale[1]*(x[1]+j)+shift[1],
+					scale[2]*(x[2]+k)+shift[2]);
+				grid[g] = p;
+				mask |= (p < 0) ? (1<<g) : 0;
+			}
+			
+			//Check for early termination if cell does not intersect boundary
+			if(mask === 0 || mask === 0xff) {
+				continue;
+			}
+			
+			//Sum up edge intersections
+			var edge_mask = edge_table[mask]
+				, v = [0.0,0.0,0.0]
+				, e_count = 0;
+				
+			//For every edge of the cube...
+			for(var i=0; i<12; ++i) {
+			
+				//Use edge mask to check if it is crossed
+				if(!(edge_mask & (1<<i))) {
+					continue;
+				}
+				
+				//If it did, increment number of edge crossings
+				++e_count;
+				
+				//Now find the point of intersection
+				var e0 = cube_edges[ i<<1 ]       //Unpack vertices
+					, e1 = cube_edges[(i<<1)+1]
+					, g0 = grid[e0]                 //Unpack grid values
+					, g1 = grid[e1]
+					, t  = g0 - g1;                 //Compute point of intersection
+				if(Math.abs(t) > 1e-6) {
+					t = g0 / t;
+				} else {
+					continue;
+				}
+				
+				//Interpolate vertices and add up intersections (this can be done without multiplying)
+				for(var j=0, k=1; j<3; ++j, k<<=1) {
+					var a = e0 & k
+						, b = e1 & k;
+					if(a !== b) {
+						v[j] += a ? 1.0 - t : t;
+					} else {
+						v[j] += a ? 1.0 : 0;
+					}
+				}
+			}
+			
+			//Now we just average the edge intersections and add them to coordinate
+			var s = 1.0 / e_count;
+			for(var i=0; i<3; ++i) {
+				v[i] = scale[i] * (x[i] + s * v[i]) + shift[i];
+			}
+			
+			//Add vertex to buffer, store pointer to vertex index in buffer
+			buffer[m] = vertices.length;
+			vertices.push(v);
+			
+			//Now we need to add faces together, to do this we just loop over 3 basis components
+			for(var i=0; i<3; ++i) {
+				//The first three entries of the edge_mask count the crossings along the edge
+				if(!(edge_mask & (1<<i)) ) {
+					continue;
+				}
+				
+				// i = axes we are point along.  iu, iv = orthogonal axes
+				var iu = (i+1)%3
+					, iv = (i+2)%3;
+					
+				//If we are on a boundary, skip it
+				if(x[iu] === 0 || x[iv] === 0) {
+					continue;
+				}
+				
+				//Otherwise, look up adjacent edges in buffer
+				var du = R[iu]
+					, dv = R[iv];
+				
+				//Remember to flip orientation depending on the sign of the corner.
+				if(mask & 1) {
+					faces.push([buffer[m],    buffer[m-du],    buffer[m-dv]]);
+					faces.push([buffer[m-dv], buffer[m-du],    buffer[m-du-dv]]);
+				} else {
+					faces.push([buffer[m],    buffer[m-dv],    buffer[m-du]]);
+					faces.push([buffer[m-du], buffer[m-dv],    buffer[m-du-dv]]);
+				}
+			}
+		}
+	}
+	
+	//All done!  Return the result
+	return { positions: vertices, cells: faces };
+}
+
+export { surfaceNet }

+ 12 - 3
examples/jsm/loaders/GLTFLoader.js

@@ -62,7 +62,8 @@ import {
 	Vector2,
 	Vector3,
 	VectorKeyframeTrack,
-	SRGBColorSpace
+	SRGBColorSpace,
+	InstancedBufferAttribute
 } from 'three';
 import { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js';
 
@@ -361,6 +362,9 @@ class GLTFLoader extends Loader {
 		for ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {
 
 			const plugin = this.pluginCallbacks[ i ]( parser );
+
+			if ( ! plugin.name ) console.error( 'THREE.GLTFLoader: Invalid plugin found: missing name' );
+
 			plugins[ plugin.name ] = plugin;
 
 			// Workaround to avoid determining as unknown extension
@@ -942,7 +946,7 @@ class GLTFMaterialsSheenExtension {
 		if ( extension.sheenColorFactor !== undefined ) {
 
 			const colorFactor = extension.sheenColorFactor;
-			materialParams.sheenColor.setRGB( colorFactor[ 0 ], colorFactor[ 1 ], colorFactor [ 2 ], LinearSRGBColorSpace );
+			materialParams.sheenColor.setRGB( colorFactor[ 0 ], colorFactor[ 1 ], colorFactor[ 2 ], LinearSRGBColorSpace );
 
 		}
 
@@ -1679,7 +1683,12 @@ class GLTFMeshGpuInstancing {
 				// Add instance attributes to the geometry, excluding TRS.
 				for ( const attributeName in attributes ) {
 
-					if ( attributeName !== 'TRANSLATION' &&
+					if ( attributeName === '_COLOR_0' ) {
+
+						const attr = attributes[ attributeName ];
+						instancedMesh.instanceColor = new InstancedBufferAttribute( attr.array, attr.itemSize, attr.normalized );
+
+					} else if ( attributeName !== 'TRANSLATION' &&
 						 attributeName !== 'ROTATION' &&
 						 attributeName !== 'SCALE' ) {
 

+ 162 - 0
examples/jsm/loaders/LUTImageLoader.js

@@ -0,0 +1,162 @@
+import {
+	Loader,
+	TextureLoader,
+	DataTexture,
+	Data3DTexture,
+	RGBAFormat,
+	UnsignedByteType,
+	ClampToEdgeWrapping,
+	LinearFilter,
+} from 'three';
+
+export class LUTImageLoader extends Loader {
+
+	constructor( flipVertical = false ) {
+		//The NeutralLUT.png has green at the bottom for Unreal ang green at the top for Unity URP Color Lookup 
+		//post-processing. If you're using lut image strips from a Unity pipeline then pass true to the constructor
+		
+		super();
+
+		this.flip = flipVertical;
+
+	}
+
+	load( url, onLoad, onProgress, onError ) {
+
+		const loader = new TextureLoader( this.manager );
+
+		loader.setCrossOrigin( this.crossOrigin );
+
+		loader.setPath( this.path );
+		loader.load( url, texture => {
+
+			try {
+
+				let imageData;
+
+				if ( texture.image.width < texture.image.height ) {
+
+					imageData = this.getImageData( texture );
+
+				} else {
+
+					imageData = this.horz2Vert( texture );
+
+				}
+
+				onLoad( this.parse( imageData.data, Math.min( texture.image.width, texture.image.height ) ) );
+
+			} catch ( e ) {
+
+				if ( onError ) {
+
+					onError( e );
+
+				} else {
+
+					console.error( e );
+
+				}
+
+				this.manager.itemError( url );
+
+			}
+
+		}, onProgress, onError );
+
+	}
+
+	getImageData( texture ) {
+
+		const width = texture.image.width;
+		const height = texture.image.height;
+
+		const canvas = document.createElement( 'canvas' );
+		canvas.width = width;
+		canvas.height = height;
+
+		const context = canvas.getContext( '2d' );
+
+		if ( this.flip === true ) {
+
+			context.scale( 1, - 1 );
+			context.translate( 0, - height );
+
+		}
+
+		context.drawImage( texture.image, 0, 0 );
+
+		return context.getImageData( 0, 0, width, height );
+
+	}
+
+	horz2Vert( texture ) {
+
+		const width = texture.image.height;
+		const height = texture.image.width;
+
+		const canvas = document.createElement( 'canvas' );
+		canvas.width = width;
+		canvas.height = height;
+
+		const context = canvas.getContext( '2d' );
+
+		if ( this.flip === true ) {
+
+			context.scale( 1, - 1 );
+			context.translate( 0, - height );
+
+		}
+
+		for ( let i = 0; i < width; i ++ ) {
+
+			const sy = i * width;
+			const dy = ( this.flip ) ? height - i * width : i * width;
+			context.drawImage( texture.image, sy, 0, width, width, 0, dy, width, width );
+
+		}
+
+		return context.getImageData( 0, 0, width, height );
+
+	}
+
+	parse( dataArray, size ) {
+
+		const data = new Uint8Array( dataArray );
+		const texture = new DataTexture();
+		texture.image.data = data;
+		texture.image.width = size;
+		texture.image.height = size * size;
+		texture.format = RGBAFormat;
+		texture.type = UnsignedByteType;
+		texture.magFilter = LinearFilter;
+		texture.minFilter = LinearFilter;
+		texture.wrapS = ClampToEdgeWrapping;
+		texture.wrapT = ClampToEdgeWrapping;
+		texture.generateMipmaps = false;
+		texture.needsUpdate = true;
+
+		const texture3D = new Data3DTexture();
+		texture3D.image.data = data;
+		texture3D.image.width = size;
+		texture3D.image.height = size;
+		texture3D.image.depth = size;
+		texture3D.format = RGBAFormat;
+		texture3D.type = UnsignedByteType;
+		texture3D.magFilter = LinearFilter;
+		texture3D.minFilter = LinearFilter;
+		texture3D.wrapS = ClampToEdgeWrapping;
+		texture3D.wrapT = ClampToEdgeWrapping;
+		texture3D.wrapR = ClampToEdgeWrapping;
+		texture3D.generateMipmaps = false;
+		texture3D.needsUpdate = true;
+
+		return {
+			size,
+			texture,
+			texture3D,
+		};
+
+	}
+
+}

+ 89 - 93
examples/jsm/loaders/lwo/IFFParser.js

@@ -35,18 +35,16 @@
 import { LWO2Parser } from './LWO2Parser.js';
 import { LWO3Parser } from './LWO3Parser.js';
 
-function IFFParser( ) {
+class IFFParser {
 
-	this.debugger = new Debugger();
-	// this.debugger.enable(); // un-comment to log IFF hierarchy.
+	constructor() {
 
-}
-
-IFFParser.prototype = {
+		this.debugger = new Debugger();
+		// this.debugger.enable(); // un-comment to log IFF hierarchy.
 
-	constructor: IFFParser,
+	}
 
-	parse: function ( buffer ) {
+	parse( buffer ) {
 
 		this.reader = new DataViewReader( buffer );
 
@@ -82,7 +80,7 @@ IFFParser.prototype = {
 
 		return this.tree;
 
-	},
+	}
 
 	parseTopForm() {
 
@@ -120,7 +118,7 @@ IFFParser.prototype = {
 
 		return;
 
-	},
+	}
 
 
 	///
@@ -306,7 +304,7 @@ IFFParser.prototype = {
 		this.debugger.nodeID = type;
 		this.debugger.log();
 
-	},
+	}
 
 	setupForm( type, length ) {
 
@@ -331,13 +329,13 @@ IFFParser.prototype = {
 		}
 
 
-	},
+	}
 
 	skipForm( length ) {
 
 		this.reader.skip( length - 4 );
 
-	},
+	}
 
 	parseUnknownForm( type, length ) {
 
@@ -346,7 +344,7 @@ IFFParser.prototype = {
 		printBuffer( this.reader.dv.buffer, this.reader.offset, length - 4 );
 		this.reader.skip( length - 4 );
 
-	},
+	}
 
 	parseSurfaceForm( length ) {
 
@@ -370,7 +368,7 @@ IFFParser.prototype = {
 		this.currentForm = surface;
 		this.currentFormEnd = this.reader.offset + length;
 
-	},
+	}
 
 	parseSurfaceLwo2( length ) {
 
@@ -391,7 +389,7 @@ IFFParser.prototype = {
 		this.currentForm = surface;
 		this.currentFormEnd = this.reader.offset + length;
 
-	},
+	}
 
 	parseSubNode( length ) {
 
@@ -411,7 +409,7 @@ IFFParser.prototype = {
 		this.currentFormEnd = this.reader.offset + length;
 
 
-	},
+	}
 
 	// collect attributes from all nodes at the top level of a surface
 	parseConnections( length ) {
@@ -421,7 +419,7 @@ IFFParser.prototype = {
 
 		this.currentForm = this.currentSurface.connections;
 
-	},
+	}
 
 	// surface node attribute data, e.g. specular, roughness etc
 	parseEntryForm( length ) {
@@ -432,7 +430,7 @@ IFFParser.prototype = {
 
 		this.setupForm( name, length );
 
-	},
+	}
 
 	// parse values from material - doesn't match up to other LWO3 data types
 	// sub form of entry form
@@ -462,7 +460,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	// holds various data about texture node image state
 	// Data other thanmipMapLevel unknown
@@ -472,7 +470,7 @@ IFFParser.prototype = {
 
 		this.currentForm.mipMapLevel = this.reader.getFloat32();
 
-	},
+	}
 
 	// LWO2 style image data node OR LWO3 textures defined at top level in editor (not as SURF node)
 	parseImageMap( length ) {
@@ -488,7 +486,7 @@ IFFParser.prototype = {
 
 		this.reader.skip( 10 ); // unknown, could be an issue if it contains a VX
 
-	},
+	}
 
 	parseTextureNodeAttribute( type ) {
 
@@ -526,14 +524,14 @@ IFFParser.prototype = {
 		this.reader.skip( 2 ); // unknown
 
 
-	},
+	}
 
 	// ENVL forms are currently ignored
 	parseEnvelope( length ) {
 
 		this.reader.skip( length - 4 ); // skipping  entirely for now
 
-	},
+	}
 
 	///
 	// CHUNK PARSING METHODS
@@ -570,7 +568,7 @@ IFFParser.prototype = {
 		this.tree.textures.push( texture );
 		this.currentForm = texture;
 
-	},
+	}
 
 	parseClipLwo2( length ) {
 
@@ -602,14 +600,14 @@ IFFParser.prototype = {
 		this.tree.textures.push( texture );
 		this.currentForm = texture;
 
-	},
+	}
 
 	parseImage() {
 
 		this.reader.skip( 8 ); // unknown
 		this.currentForm.fileName = this.reader.getString();
 
-	},
+	}
 
 	parseXVAL( type, length ) {
 
@@ -620,7 +618,7 @@ IFFParser.prototype = {
 
 		this.reader.setOffset( endOffset ); // set end offset directly to skip optional envelope
 
-	},
+	}
 
 	parseXVAL3( type, length ) {
 
@@ -635,7 +633,7 @@ IFFParser.prototype = {
 
 		this.reader.setOffset( endOffset );
 
-	},
+	}
 
 	// Tags associated with an object
 	// OTAG { type[ID4], tag-string[S0] }
@@ -647,7 +645,7 @@ IFFParser.prototype = {
 			tagString: this.reader.getString()
 		};
 
-	},
+	}
 
 	// Signals the start of a new layer. All the data chunks which follow will be included in this layer until another layer chunk is encountered.
 	// LAYR: number[U2], flags[U2], pivot[VEC12], name[S0], parent[U2]
@@ -668,7 +666,7 @@ IFFParser.prototype = {
 		// if we have not reached then end of the layer block, there must be a parent defined
 		this.currentLayer.parent = ( parsedLength < length ) ? this.reader.getUint16() : - 1; // omitted or -1 for no parent
 
-	},
+	}
 
 	// VEC12 * ( F4 + F4 + F4 ) array of x,y,z vectors
 	// Converting from left to right handed coordinate system:
@@ -683,7 +681,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	// parse VMAP or VMAD
 	// Associates a set of floating-point vectors with a set of points.
@@ -744,7 +742,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	parseUVMapping( name, finalOffset, discontinuous ) {
 
@@ -783,7 +781,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	parseMorphTargets( name, finalOffset, type ) {
 
@@ -808,7 +806,7 @@ IFFParser.prototype = {
 			type: type,
 		};
 
-	},
+	}
 
 	// A list of polygons for the current layer.
 	// POLS { type[ID4], ( numvert+flags[U2], vert[VX] # numvert ) * }
@@ -847,7 +845,7 @@ IFFParser.prototype = {
 
 		this.currentLayer.geometry = geometryData;
 
-	},
+	}
 
 	// Lists the tag strings that can be associated with polygons by the PTAG chunk.
 	// TAGS { tag-string[S0] * }
@@ -855,7 +853,7 @@ IFFParser.prototype = {
 
 		this.tree.tags = this.reader.getStringArray( length );
 
-	},
+	}
 
 	// Associates tags of a given type with polygons in the most recent POLS chunk.
 	// PTAG { type[ID4], ( poly[VX], tag[U2] ) * }
@@ -870,7 +868,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	parseMaterialIndices( finalOffset ) {
 
@@ -886,7 +884,7 @@ IFFParser.prototype = {
 
 		}
 
-	},
+	}
 
 	parseUnknownCHUNK( blockID, length ) {
 
@@ -901,26 +899,25 @@ IFFParser.prototype = {
 
 	}
 
-};
+}
 
-function DataViewReader( buffer ) {
 
-	this.dv = new DataView( buffer );
-	this.offset = 0;
-	this._textDecoder = new TextDecoder();
-	this._bytes = new Uint8Array( buffer );
+class DataViewReader {
 
-}
+	constructor( buffer ) {
 
-DataViewReader.prototype = {
+		this.dv = new DataView( buffer );
+		this.offset = 0;
+		this._textDecoder = new TextDecoder();
+		this._bytes = new Uint8Array( buffer );
 
-	constructor: DataViewReader,
+	}
 
-	size: function () {
+	size() {
 
 		return this.dv.buffer.byteLength;
 
-	},
+	}
 
 	setOffset( offset ) {
 
@@ -934,54 +931,54 @@ DataViewReader.prototype = {
 
 		}
 
-	},
+	}
 
-	endOfFile: function () {
+	endOfFile() {
 
 		if ( this.offset >= this.size() ) return true;
 		return false;
 
-	},
+	}
 
-	skip: function ( length ) {
+	skip( length ) {
 
 		this.offset += length;
 
-	},
+	}
 
-	getUint8: function () {
+	getUint8() {
 
 		var value = this.dv.getUint8( this.offset );
 		this.offset += 1;
 		return value;
 
-	},
+	}
 
-	getUint16: function () {
+	getUint16() {
 
 		var value = this.dv.getUint16( this.offset );
 		this.offset += 2;
 		return value;
 
-	},
+	}
 
-	getInt32: function () {
+	getInt32() {
 
 		var value = this.dv.getInt32( this.offset, false );
 		this.offset += 4;
 		return value;
 
-	},
+	}
 
-	getUint32: function () {
+	getUint32() {
 
 		var value = this.dv.getUint32( this.offset, false );
 		this.offset += 4;
 		return value;
 
-	},
+	}
 
-	getUint64: function () {
+	getUint64() {
 
 		var low, high;
 
@@ -989,17 +986,17 @@ DataViewReader.prototype = {
 		low = this.getUint32();
 		return high * 0x100000000 + low;
 
-	},
+	}
 
-	getFloat32: function () {
+	getFloat32() {
 
 		var value = this.dv.getFloat32( this.offset, false );
 		this.offset += 4;
 		return value;
 
-	},
+	}
 
-	getFloat32Array: function ( size ) {
+	getFloat32Array( size ) {
 
 		var a = [];
 
@@ -1011,17 +1008,17 @@ DataViewReader.prototype = {
 
 		return a;
 
-	},
+	}
 
-	getFloat64: function () {
+	getFloat64() {
 
 		var value = this.dv.getFloat64( this.offset, this.littleEndian );
 		this.offset += 8;
 		return value;
 
-	},
+	}
 
-	getFloat64Array: function ( size ) {
+	getFloat64Array( size ) {
 
 		var a = [];
 
@@ -1033,7 +1030,7 @@ DataViewReader.prototype = {
 
 		return a;
 
-	},
+	}
 
 	// get variable-length index data type
 	// VX ::= index[U2] | (index + 0xFF000000)[U4]
@@ -1053,16 +1050,16 @@ DataViewReader.prototype = {
 
 		return firstByte * 256 + this.getUint8();
 
-	},
+	}
 
 	// An ID tag is a sequence of 4 bytes containing 7-bit ASCII values
 	getIDTag() {
 
 		return this.getString( 4 );
 
-	},
+	}
 
-	getString: function ( size ) {
+	getString( size ) {
 
 		if ( size === 0 ) return;
 
@@ -1095,9 +1092,9 @@ DataViewReader.prototype = {
 
 		return result;
 
-	},
+	}
 
-	getStringArray: function ( size ) {
+	getStringArray( size ) {
 
 		var a = this.getString( size );
 		a = a.split( '\0' );
@@ -1106,29 +1103,28 @@ DataViewReader.prototype = {
 
 	}
 
-};
+}
 
-// ************** DEBUGGER  **************
 
-function Debugger( ) {
+// ************** DEBUGGER  **************
 
-	this.active = false;
-	this.depth = 0;
-	this.formList = [];
+class Debugger {
 
-}
+	constructor() {
 
-Debugger.prototype = {
+		this.active = false;
+		this.depth = 0;
+		this.formList = [];
 
-	constructor: Debugger,
+	}
 
-	enable: function () {
+	enable() {
 
 		this.active = true;
 
-	},
+	}
 
-	log: function () {
+	log() {
 
 		if ( ! this.active ) return;
 
@@ -1169,9 +1165,9 @@ Debugger.prototype = {
 
 		this.skipped = false;
 
-	},
+	}
 
-	closeForms: function () {
+	closeForms() {
 
 		if ( ! this.active ) return;
 
@@ -1189,7 +1185,7 @@ Debugger.prototype = {
 
 	}
 
-};
+}
 
 // ************** UTILITY FUNCTIONS **************
 

+ 2 - 0
examples/jsm/materials/MeshGouraudMaterial.js

@@ -9,6 +9,8 @@ import { UniformsUtils, UniformsLib, ShaderMaterial, Color, MultiplyOperation }
 
 const GouraudShader = {
 
+	name: 'GouraudShader',
+
 	uniforms: UniformsUtils.merge( [
 		UniformsLib.common,
 		UniformsLib.specularmap,

+ 0 - 55
examples/jsm/math/Capsule.js

@@ -2,12 +2,6 @@ import {
 	Vector3
 } from 'three';
 
-const _v1 = new Vector3();
-const _v2 = new Vector3();
-const _v3 = new Vector3();
-
-const EPS = 1e-10;
-
 class Capsule {
 
 	constructor( start = new Vector3( 0, 0, 0 ), end = new Vector3( 0, 1, 0 ), radius = 1 ) {
@@ -83,55 +77,6 @@ class Capsule {
 
 	}
 
-	lineLineMinimumPoints( line1, line2 ) {
-
-		const r = _v1.copy( line1.end ).sub( line1.start );
-		const s = _v2.copy( line2.end ).sub( line2.start );
-		const w = _v3.copy( line2.start ).sub( line1.start );
-
-		const a = r.dot( s ),
-			b = r.dot( r ),
-			c = s.dot( s ),
-			d = s.dot( w ),
-			e = r.dot( w );
-
-		let t1, t2;
-		const divisor = b * c - a * a;
-
-		if ( Math.abs( divisor ) < EPS ) {
-
-			const d1 = - d / c;
-			const d2 = ( a - d ) / c;
-
-			if ( Math.abs( d1 - 0.5 ) < Math.abs( d2 - 0.5 ) ) {
-
-				t1 = 0;
-				t2 = d1;
-
-			} else {
-
-				t1 = 1;
-				t2 = d2;
-
-			}
-
-		} else {
-
-			t1 = ( d * a + e * c ) / divisor;
-			t2 = ( t1 * a - d ) / c;
-
-		}
-
-		t2 = Math.max( 0, Math.min( 1, t2 ) );
-		t1 = Math.max( 0, Math.min( 1, t1 ) );
-
-		const point1 = r.multiplyScalar( t1 ).add( line1.start );
-		const point2 = s.multiplyScalar( t2 ).add( line2.start );
-
-		return [ point1, point2 ];
-
-	}
-
 }
 
 export { Capsule };

+ 70 - 3
examples/jsm/math/Octree.js

@@ -11,12 +11,75 @@ import { Capsule } from '../math/Capsule.js';
 
 const _v1 = new Vector3();
 const _v2 = new Vector3();
+const _point1 = new Vector3();
+const _point2 = new Vector3();
 const _plane = new Plane();
 const _line1 = new Line3();
 const _line2 = new Line3();
 const _sphere = new Sphere();
 const _capsule = new Capsule();
 
+const _temp1 = new Vector3();
+const _temp2 = new Vector3();
+const _temp3 = new Vector3();
+const EPS = 1e-10;
+
+function lineToLineClosestPoints( line1, line2, target1 = null, target2 = null ) {
+
+	const r = _temp1.copy( line1.end ).sub( line1.start );
+	const s = _temp2.copy( line2.end ).sub( line2.start );
+	const w = _temp3.copy( line2.start ).sub( line1.start );
+
+	const a = r.dot( s ),
+		b = r.dot( r ),
+		c = s.dot( s ),
+		d = s.dot( w ),
+		e = r.dot( w );
+
+	let t1, t2;
+	const divisor = b * c - a * a;
+
+	if ( Math.abs( divisor ) < EPS ) {
+
+		const d1 = - d / c;
+		const d2 = ( a - d ) / c;
+
+		if ( Math.abs( d1 - 0.5 ) < Math.abs( d2 - 0.5 ) ) {
+
+			t1 = 0;
+			t2 = d1;
+
+		} else {
+
+			t1 = 1;
+			t2 = d2;
+
+		}
+
+	} else {
+
+		t1 = ( d * a + e * c ) / divisor;
+		t2 = ( t1 * a - d ) / c;
+
+	}
+
+	t2 = Math.max( 0, Math.min( 1, t2 ) );
+	t1 = Math.max( 0, Math.min( 1, t1 ) );
+
+	if ( target1 ) {
+
+		target1.copy( r ).multiplyScalar( t1 ).add( line1.start );
+
+	}
+
+	if ( target2 ) {
+
+		target2.copy( s ).multiplyScalar( t2 ).add( line2.start );
+
+	}
+
+}
+
 class Octree {
 
 
@@ -195,11 +258,15 @@ class Octree {
 
 			const line2 = _line2.set( lines[ i ][ 0 ], lines[ i ][ 1 ] );
 
-			const [ point1, point2 ] = capsule.lineLineMinimumPoints( line1, line2 );
+			lineToLineClosestPoints( line1, line2, _point1, _point2 );
 
-			if ( point1.distanceToSquared( point2 ) < r2 ) {
+			if ( _point1.distanceToSquared( _point2 ) < r2 ) {
 
-				return { normal: point1.clone().sub( point2 ).normalize(), point: point2.clone(), depth: capsule.radius - point1.distanceTo( point2 ) };
+				return {
+					normal: _point1.clone().sub( _point2 ).normalize(),
+					point: _point2.clone(),
+					depth: capsule.radius - _point1.distanceTo( _point2 )
+				};
 
 			}
 

+ 103 - 11
examples/jsm/modifiers/SimplifyModifier.js

@@ -1,7 +1,9 @@
 import {
 	BufferGeometry,
 	Float32BufferAttribute,
-	Vector3
+	Vector2,
+	Vector3,
+	Vector4
 } from 'three';
 import * as BufferGeometryUtils from '../utils/BufferGeometryUtils.js';
 
@@ -20,13 +22,17 @@ class SimplifyModifier {
 	modify( geometry, count ) {
 
 		geometry = geometry.clone();
+
+		// currently morphAttributes are not supported
+		delete geometry.morphAttributes.position;
+		delete geometry.morphAttributes.normal;
 		const attributes = geometry.attributes;
 
-		// this modifier can only process indexed and non-indexed geomtries with a position attribute
+		// this modifier can only process indexed and non-indexed geomtries with at least a position attribute
 
 		for ( const name in attributes ) {
 
-			if ( name !== 'position' ) geometry.deleteAttribute( name );
+			if ( name !== 'position' && name !== 'uv' && name !== 'normal' && name !== 'tangent' && name !== 'color' ) geometry.deleteAttribute( name );
 
 		}
 
@@ -42,12 +48,44 @@ class SimplifyModifier {
 		// add vertices
 
 		const positionAttribute = geometry.getAttribute( 'position' );
+		const uvAttribute = geometry.getAttribute( 'uv' );
+		const normalAttribute = geometry.getAttribute( 'normal' );
+		const tangentAttribute = geometry.getAttribute( 'tangent' );
+		const colorAttribute = geometry.getAttribute( 'color' );
+
+		let t = null;
+		let v2 = null;
+		let nor = null;
+		let col = null;
 
 		for ( let i = 0; i < positionAttribute.count; i ++ ) {
 
 			const v = new Vector3().fromBufferAttribute( positionAttribute, i );
+			if ( uvAttribute ) {
+
+				v2 = new Vector2().fromBufferAttribute( uvAttribute, i );
+
+			}
+
+			if ( normalAttribute ) {
+
+				nor = new Vector3().fromBufferAttribute( normalAttribute, i );
+
+			}
+
+			if ( tangentAttribute ) {
+
+				t = new Vector4().fromBufferAttribute( tangentAttribute, i );
+
+			}
 
-			const vertex = new Vertex( v );
+			if ( colorAttribute ) {
+
+				col = new THREE.Color().fromBufferAttribute( colorAttribute, i );
+
+			}
+
+			const vertex = new Vertex( v, v2, nor, t, col );
 			vertices.push( vertex );
 
 		}
@@ -115,6 +153,10 @@ class SimplifyModifier {
 
 		const simplifiedGeometry = new BufferGeometry();
 		const position = [];
+		const uv = [];
+		const normal = [];
+		const tangent = [];
+		const color = [];
 
 		index = [];
 
@@ -122,10 +164,35 @@ class SimplifyModifier {
 
 		for ( let i = 0; i < vertices.length; i ++ ) {
 
-			const vertex = vertices[ i ].position;
-			position.push( vertex.x, vertex.y, vertex.z );
+			const vertex = vertices[ i ];
+			position.push( vertex.position.x, vertex.position.y, vertex.position.z );
+			if ( vertex.uv ) {
+
+				uv.push( vertex.uv.x, vertex.uv.y );
+
+			}
+
+			if ( vertex.normal ) {
+
+				normal.push( vertex.normal.x, vertex.normal.y, vertex.normal.z );
+
+			}
+
+			if ( vertex.tangent ) {
+
+				tangent.push( vertex.tangent.x, vertex.tangent.y, vertex.tangent.z, vertex.tangent.w );
+
+			}
+
+			if ( vertex.color ) {
+
+				color.push( vertex.color.r, vertex.color.g, vertex.color.b );
+
+			}
+
+
 			// cache final index to GREATLY speed up faces reconstruction
-			vertices[ i ].id = i;
+			vertex.id = i;
 
 		}
 
@@ -138,9 +205,12 @@ class SimplifyModifier {
 
 		}
 
-		//
-
 		simplifiedGeometry.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );
+		if ( uv.length > 0 ) simplifiedGeometry.setAttribute( 'uv', new Float32BufferAttribute( uv, 2 ) );
+		if ( normal.length > 0 ) simplifiedGeometry.setAttribute( 'normal', new Float32BufferAttribute( normal, 3 ) );
+		if ( tangent.length > 0 ) simplifiedGeometry.setAttribute( 'tangent', new Float32BufferAttribute( tangent, 4 ) );
+		if ( color.length > 0 ) simplifiedGeometry.setAttribute( 'color', new Float32BufferAttribute( color, 3 ) );
+
 		simplifiedGeometry.setIndex( index );
 
 		return simplifiedGeometry;
@@ -318,7 +388,7 @@ function removeFace( f, faces ) {
 
 }
 
-function collapse( vertices, faces, u, v ) { // u and v are pointers to vertices of an edge
+function collapse( vertices, faces, u, v ) {
 
 	// Collapse the edge uv by moving vertex u onto v
 
@@ -330,6 +400,24 @@ function collapse( vertices, faces, u, v ) { // u and v are pointers to vertices
 
 	}
 
+	if ( v.uv ) {
+
+		u.uv.copy( v.uv );
+
+	}
+
+	if ( v.normal ) {
+
+		v.normal.add( u.normal ).normalize();
+
+	}
+
+	if ( v.tangent ) {
+
+		v.tangent.add( u.tangent ).normalize();
+
+	}
+
 	const tmpVertices = [];
 
 	for ( let i = 0; i < u.neighbors.length; i ++ ) {
@@ -480,9 +568,13 @@ class Triangle {
 
 class Vertex {
 
-	constructor( v ) {
+	constructor( v, uv, normal, tangent, color ) {
 
 		this.position = v;
+		this.uv = uv;
+		this.normal = normal;
+		this.tangent = tangent;
+		this.color = color;
 
 		this.id = - 1; // external use position in vertices list (for e.g. face generation)
 

+ 3 - 3
examples/jsm/modifiers/TessellateModifier.js

@@ -111,9 +111,9 @@ class TessellateModifier {
 				const c2 = cs[ b ];
 				const c3 = cs[ c ];
 
-				colors2.push( c1.x, c1.y, c1.z );
-				colors2.push( c2.x, c2.y, c2.z );
-				colors2.push( c3.x, c3.y, c3.z );
+				colors2.push( c1.r, c1.g, c1.b );
+				colors2.push( c2.r, c2.g, c2.b );
+				colors2.push( c3.r, c3.g, c3.b );
 
 			}
 

+ 6 - 6
examples/jsm/nodes/Nodes.js

@@ -6,6 +6,7 @@ export * from './core/constants.js';
 
 // core
 export { default as ArrayUniformNode /* @TODO: arrayUniform */ } from './core/ArrayUniformNode.js';
+export { default as AssignNode, assign } from './core/AssignNode.js';
 export { default as AttributeNode, attribute } from './core/AttributeNode.js';
 export { default as BypassNode, bypass } from './core/BypassNode.js';
 export { default as CacheNode, cache } from './core/CacheNode.js';
@@ -14,6 +15,7 @@ export { default as ContextNode, context, label } from './core/ContextNode.js';
 export { default as IndexNode, vertexIndex, instanceIndex } from './core/IndexNode.js';
 export { default as LightingModel } from './core/LightingModel.js';
 export { default as Node, addNodeClass, createNodeFromType } from './core/Node.js';
+export { default as VarNode, temp } from './core/VarNode.js';
 export { default as NodeAttribute } from './core/NodeAttribute.js';
 export { default as NodeBuilder } from './core/NodeBuilder.js';
 export { default as NodeCache } from './core/NodeCache.js';
@@ -24,11 +26,11 @@ export { default as NodeKeywords } from './core/NodeKeywords.js';
 export { default as NodeUniform } from './core/NodeUniform.js';
 export { default as NodeVar } from './core/NodeVar.js';
 export { default as NodeVarying } from './core/NodeVarying.js';
-export { default as PropertyNode, property, output, diffuseColor, roughness, metalness, specularColor, shininess } from './core/PropertyNode.js';
+export { default as ParameterNode, parameter } from './core/ParameterNode.js';
+export { default as PropertyNode, property, output, diffuseColor, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, shininess, dashSize, gapSize, pointWidth } from './core/PropertyNode.js';
 export { default as StackNode, stack } from './core/StackNode.js';
 export { default as TempNode } from './core/TempNode.js';
 export { default as UniformNode, uniform } from './core/UniformNode.js';
-export { default as VarNode, temp } from './core/VarNode.js';
 export { default as VaryingNode, varying } from './core/VaryingNode.js';
 export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
 
@@ -37,7 +39,7 @@ export { NodeUtils };
 
 // math
 export { default as MathNode, EPSILON, INFINITY, radians, degrees, exp, exp2, log, log2, sqrt, inverseSqrt, floor, ceil, normalize, fract, sin, cos, tan, asin, acos, atan, abs, sign, length, negate, oneMinus, dFdx, dFdy, round, reciprocal, trunc, fwidth, atan2, min, max, mod, step, reflect, distance, difference, dot, cross, pow, pow2, pow3, pow4, transformDirection, mix, clamp, saturate, refract, smoothstep, faceForward } from './math/MathNode.js';
-export { default as OperatorNode, add, sub, mul, div, remainder, equal, assign, lessThan, greaterThan, lessThanEqual, greaterThanEqual, and, or, xor, bitAnd, bitOr, bitXor, shiftLeft, shiftRight } from './math/OperatorNode.js';
+export { default as OperatorNode, add, sub, mul, div, remainder, equal, lessThan, greaterThan, lessThanEqual, greaterThanEqual, and, or, xor, bitAnd, bitOr, bitXor, shiftLeft, shiftRight } from './math/OperatorNode.js';
 export { default as CondNode, cond } from './math/CondNode.js';
 export { default as HashNode, hash } from './math/HashNode.js';
 
@@ -70,10 +72,8 @@ export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute
 export { default as BufferNode, buffer } from './accessors/BufferNode.js';
 export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar } from './accessors/CameraNode.js';
 export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
-export { default as ExtendedMaterialNode, materialNormal } from './accessors/ExtendedMaterialNode.js';
 export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
-export { default as LineMaterialNode, materialLineDashSize, materialLineDashOffset, materialLineGapSize, materialLineScale, materialLineWidth } from './accessors/LineMaterialNode.js';
-export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialReflectivity, materialRoughness, materialMetalness, materialRotation, materialSheen, materialSheenRoughness } from './accessors/MaterialNode.js';
+export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialSpecularStrength, materialReflectivity, materialRoughness, materialMetalness, materialNormal, materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialRotation, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLineScale, materialLineDashSize, materialLineGapSize, materialLineWidth, materialLineDashOffset, materialPointWidth } from './accessors/MaterialNode.js';
 export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js';
 export { default as MorphNode, morph } from './accessors/MorphNode.js';
 export { default as TextureBicubicNode, textureBicubic } from './accessors/TextureBicubicNode.js';

+ 3 - 3
examples/jsm/nodes/accessors/CubeTextureNode.js

@@ -54,7 +54,6 @@ class CubeTextureNode extends TextureNode {
 
 		} else {
 
-			const nodeType = this.getNodeType( builder );
 			const nodeData = builder.getDataFromNode( this );
 
 			let propertyName = nodeData.propertyName;
@@ -64,7 +63,7 @@ class CubeTextureNode extends TextureNode {
 				const cubeUV = vec3( uvNode.x.negate(), uvNode.yz );
 				const uvSnippet = cubeUV.build( builder, 'vec3' );
 
-				const nodeVar = builder.getVarFromNode( this, 'vec4' );
+				const nodeVar = builder.getVarFromNode( this );
 
 				propertyName = builder.getPropertyName( nodeVar );
 
@@ -94,6 +93,7 @@ class CubeTextureNode extends TextureNode {
 			}
 
 			let snippet = propertyName;
+			const nodeType = this.getNodeType( builder );
 
 			if ( builder.needsColorSpaceToLinear( this.value ) ) {
 
@@ -101,7 +101,7 @@ class CubeTextureNode extends TextureNode {
 
 			}
 
-			return builder.format( snippet, 'vec4', output );
+			return builder.format( snippet, nodeType, output );
 
 		}
 

+ 0 - 76
examples/jsm/nodes/accessors/ExtendedMaterialNode.js

@@ -1,76 +0,0 @@
-import MaterialNode from './MaterialNode.js';
-import { materialReference } from './MaterialReferenceNode.js';
-import { normalView } from './NormalNode.js';
-import { normalMap } from '../display/NormalMapNode.js';
-import { bumpMap } from '../display/BumpMapNode.js';
-import { addNodeClass } from '../core/Node.js';
-import { nodeImmutable } from '../shadernode/ShaderNode.js';
-
-class ExtendedMaterialNode extends MaterialNode {
-
-	constructor( scope ) {
-
-		super( scope );
-
-	}
-
-	getNodeType( builder ) {
-
-		const scope = this.scope;
-		let type = null;
-
-		if ( scope === ExtendedMaterialNode.NORMAL || scope === ExtendedMaterialNode.CLEARCOAT_NORMAL ) {
-
-			type = 'vec3';
-
-		}
-
-		return type || super.getNodeType( builder );
-
-	}
-
-	setup( builder ) {
-
-		const material = builder.material;
-		const scope = this.scope;
-
-		let node = null;
-
-		if ( scope === ExtendedMaterialNode.NORMAL ) {
-
-			if ( material.normalMap ) {
-
-				node = normalMap( this.getTexture( 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
-
-			} else if ( material.bumpMap ) {
-
-				// @TODO: Replace material.bumpMap to this.getTexture( 'bumpMap' )
-				node = bumpMap( material.bumpMap, materialReference( 'bumpScale', 'float' ) );
-
-			} else {
-
-				node = normalView;
-
-			}
-
-		} else if ( scope === ExtendedMaterialNode.CLEARCOAT_NORMAL ) {
-
-			node = material.clearcoatNormalMap ? normalMap( this.getTexture( 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView;
-
-		}
-
-		return node || super.setup( builder );
-
-	}
-
-}
-
-ExtendedMaterialNode.NORMAL = 'normal';
-ExtendedMaterialNode.CLEARCOAT_NORMAL = 'clearcoatNormal';
-
-export default ExtendedMaterialNode;
-
-export const materialNormal = nodeImmutable( ExtendedMaterialNode, ExtendedMaterialNode.NORMAL );
-export const materialClearcoatNormal = nodeImmutable( ExtendedMaterialNode, ExtendedMaterialNode.CLEARCOAT_NORMAL );
-
-addNodeClass( 'ExtendedMaterialNode', ExtendedMaterialNode );

+ 3 - 3
examples/jsm/nodes/accessors/InstanceNode.js

@@ -17,7 +17,7 @@ class InstanceNode extends Node {
 
 	}
 
-	setup( builder ) {
+	setup( /*builder*/ ) {
 
 		let instanceMatrixNode = this.instanceMatrixNode;
 
@@ -57,8 +57,8 @@ class InstanceNode extends Node {
 
 		// ASSIGNS
 
-		builder.stack.assign( positionLocal, instancePosition );
-		builder.stack.assign( normalLocal, instanceNormal );
+		positionLocal.assign( instancePosition );
+		normalLocal.assign( instanceNormal );
 
 	}
 

+ 21 - 0
examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js

@@ -0,0 +1,21 @@
+import MaterialNode from './MaterialNode.js';
+import { addNodeClass } from '../core/Node.js';
+import { nodeImmutable } from '../shadernode/ShaderNode.js';
+
+class InstancedPointsMaterialNode extends MaterialNode {
+
+	setup( /*builder*/ ) {
+
+		return this.getFloat( this.scope );
+
+	}
+
+}
+
+InstancedPointsMaterialNode.POINT_WIDTH = 'pointWidth';
+
+export default InstancedPointsMaterialNode;
+
+export const materialPointWidth = nodeImmutable( InstancedPointsMaterialNode, InstancedPointsMaterialNode.POINT_WIDTH );
+
+addNodeClass( 'InstancedPointsMaterialNode', InstancedPointsMaterialNode );

+ 0 - 29
examples/jsm/nodes/accessors/LineMaterialNode.js

@@ -1,29 +0,0 @@
-import MaterialNode from './MaterialNode.js';
-import { addNodeClass } from '../core/Node.js';
-import { nodeImmutable } from '../shadernode/ShaderNode.js';
-
-class LineMaterialNode extends MaterialNode {
-
-	setup( /*builder*/ ) {
-
-		return this.getFloat( this.scope );
-
-	}
-
-}
-
-LineMaterialNode.SCALE = 'scale';
-LineMaterialNode.DASH_SIZE = 'dashSize';
-LineMaterialNode.GAP_SIZE = 'gapSize';
-LineMaterialNode.LINEWIDTH = 'linewidth';
-LineMaterialNode.DASH_OFFSET = 'dashOffset';
-
-export default LineMaterialNode;
-
-export const materialLineScale = nodeImmutable( LineMaterialNode, LineMaterialNode.SCALE );
-export const materialLineDashOffset = nodeImmutable( LineMaterialNode, LineMaterialNode.DASH_OFFSET );
-export const materialLineDashSize = nodeImmutable( LineMaterialNode, LineMaterialNode.DASH_SIZE );
-export const materialLineGapSize = nodeImmutable( LineMaterialNode, LineMaterialNode.GAP_SIZE );
-export const materialLineWidth = nodeImmutable( LineMaterialNode, LineMaterialNode.LINEWIDTH );
-
-addNodeClass( 'LineMaterialNode', LineMaterialNode );

+ 68 - 31
examples/jsm/nodes/accessors/MaterialNode.js

@@ -1,6 +1,7 @@
 import Node, { addNodeClass } from '../core/Node.js';
 import { reference } from './ReferenceNode.js';
 import { materialReference } from './MaterialReferenceNode.js';
+import { normalView } from './NormalNode.js';
 import { nodeImmutable, float } from '../shadernode/ShaderNode.js';
 
 const _propertyCache = new Map();
@@ -45,7 +46,7 @@ class MaterialNode extends Node {
 
 	getTexture( property ) {
 
-		return this.getCache( property, 'texture' );
+		return this.getCache( property === 'map' ? 'map' : property + 'Map', 'texture' );
 
 	}
 
@@ -56,17 +57,9 @@ class MaterialNode extends Node {
 
 		let node = null;
 
-		if ( scope === MaterialNode.ALPHA_TEST || scope === MaterialNode.SHININESS || scope === MaterialNode.REFLECTIVITY || scope === MaterialNode.ROTATION || scope === MaterialNode.IRIDESCENCE || scope === MaterialNode.IRIDESCENCE_IOR ) {
+		if ( scope === MaterialNode.COLOR ) {
 
-			node = this.getFloat( scope );
-
-		} else if ( scope === MaterialNode.SPECULAR_COLOR ) {
-
-			node = this.getColor( 'specular' );
-
-		} else if ( scope === MaterialNode.COLOR ) {
-
-			const colorNode = this.getColor( 'color' );
+			const colorNode = this.getColor( scope );
 
 			if ( material.map && material.map.isTexture === true ) {
 
@@ -80,11 +73,11 @@ class MaterialNode extends Node {
 
 		} else if ( scope === MaterialNode.OPACITY ) {
 
-			const opacityNode = this.getFloat( 'opacity' );
+			const opacityNode = this.getFloat( scope );
 
 			if ( material.alphaMap && material.alphaMap.isTexture === true ) {
 
-				node = opacityNode.mul( this.getTexture( 'alphaMap' ) );
+				node = opacityNode.mul( this.getTexture( 'alpha' ) );
 
 			} else {
 
@@ -96,7 +89,7 @@ class MaterialNode extends Node {
 
 			if ( material.specularMap && material.specularMap.isTexture === true ) {
 
-				node = this.getTexture( 'specularMap' ).r;
+				node = this.getTexture( scope ).r;
 
 			} else {
 
@@ -104,13 +97,13 @@ class MaterialNode extends Node {
 
 			}
 
-		} else if ( scope === MaterialNode.ROUGHNESS ) {
+		} else if ( scope === MaterialNode.ROUGHNESS ) { // TODO: cleanup similar branches
 
-			const roughnessNode = this.getFloat( 'roughness' );
+			const roughnessNode = this.getFloat( scope );
 
 			if ( material.roughnessMap && material.roughnessMap.isTexture === true ) {
 
-				node = roughnessNode.mul( this.getTexture( 'roughnessMap' ).g );
+				node = roughnessNode.mul( this.getTexture( scope ).g );
 
 			} else {
 
@@ -120,11 +113,11 @@ class MaterialNode extends Node {
 
 		} else if ( scope === MaterialNode.METALNESS ) {
 
-			const metalnessNode = this.getFloat( 'metalness' );
+			const metalnessNode = this.getFloat( scope );
 
 			if ( material.metalnessMap && material.metalnessMap.isTexture === true ) {
 
-				node = metalnessNode.mul( this.getTexture( 'metalnessMap' ).b );
+				node = metalnessNode.mul( this.getTexture( scope ).b );
 
 			} else {
 
@@ -134,11 +127,11 @@ class MaterialNode extends Node {
 
 		} else if ( scope === MaterialNode.EMISSIVE ) {
 
-			const emissiveNode = this.getColor( 'emissive' );
+			const emissiveNode = this.getColor( scope );
 
 			if ( material.emissiveMap && material.emissiveMap.isTexture === true ) {
 
-				node = emissiveNode.mul( this.getTexture( 'emissiveMap' ) );
+				node = emissiveNode.mul( this.getTexture( scope ) );
 
 			} else {
 
@@ -146,13 +139,29 @@ class MaterialNode extends Node {
 
 			}
 
+		} else if ( scope === MaterialNode.NORMAL ) {
+
+			if ( material.normalMap ) {
+
+				node = this.getTexture( 'normal' ).normalMap( this.getCache( 'normalScale', 'vec2' ) );
+
+			} else if ( material.bumpMap ) {
+
+				node = this.getTexture( 'bump' ).r.bumpMap( this.getFloat( 'bumpScale' ) );
+
+			} else {
+
+				node = normalView;
+
+			}
+
 		} else if ( scope === MaterialNode.CLEARCOAT ) {
 
-			const clearcoatNode = this.getFloat( 'clearcoat' );
+			const clearcoatNode = this.getFloat( scope );
 
 			if ( material.clearcoatMap && material.clearcoatMap.isTexture === true ) {
 
-				node = clearcoatNode.mul( this.getTexture( 'clearcoatMap' ).r );
+				node = clearcoatNode.mul( this.getTexture( scope ).r );
 
 			} else {
 
@@ -162,11 +171,11 @@ class MaterialNode extends Node {
 
 		} else if ( scope === MaterialNode.CLEARCOAT_ROUGHNESS ) {
 
-			const clearcoatRoughnessNode = this.getFloat( 'clearcoatRoughness' );
+			const clearcoatRoughnessNode = this.getFloat( scope );
 
 			if ( material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true ) {
 
-				node = clearcoatRoughnessNode.mul( this.getTexture( 'clearcoatRoughnessMap' ).r );
+				node = clearcoatRoughnessNode.mul( this.getTexture( scope ).r );
 
 			} else {
 
@@ -174,13 +183,25 @@ class MaterialNode extends Node {
 
 			}
 
+		} else if ( scope === MaterialNode.CLEARCOAT_NORMAL ) {
+
+			if ( material.clearcoatNormalMap ) {
+
+				node = this.getTexture( scope ).normalMap( this.getCache( scope + 'Scale', 'vec2' ) );
+
+			} else {
+
+				node = normalView;
+
+			}
+
 		} else if ( scope === MaterialNode.SHEEN ) {
 
 			const sheenNode = this.getColor( 'sheenColor' ).mul( this.getFloat( 'sheen' ) ); // Move this mul() to CPU
 
 			if ( material.sheenColorMap && material.sheenColorMap.isTexture === true ) {
 
-				node = sheenNode.mul( this.getTexture( 'sheenColorMap' ).rgb );
+				node = sheenNode.mul( this.getTexture( 'sheenColor' ).rgb );
 
 			} else {
 
@@ -190,11 +211,11 @@ class MaterialNode extends Node {
 
 		} else if ( scope === MaterialNode.SHEEN_ROUGHNESS ) {
 
-			const sheenRoughnessNode = this.getFloat( 'sheenRoughness' );
+			const sheenRoughnessNode = this.getFloat( scope );
 
 			if ( material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true ) {
 
-				node = sheenRoughnessNode.mul( this.getTexture( 'sheenRoughnessMap' ).a );
+				node = sheenRoughnessNode.mul( this.getTexture( scope ).a );
 
 			} else {
 
@@ -212,7 +233,7 @@ class MaterialNode extends Node {
 
 				const iridescenceThicknessMinimum = reference( 0, 'float', material.iridescenceThicknessRange );
 
-				node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );
+				node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( scope ).g ).add( iridescenceThicknessMinimum );
 
 			} else {
 
@@ -224,7 +245,7 @@ class MaterialNode extends Node {
 
 			const outputType = this.getNodeType( builder );
 
-			node = materialReference( scope, outputType );
+			node = this.getCache( scope, outputType );
 
 		}
 
@@ -238,13 +259,15 @@ MaterialNode.ALPHA_TEST = 'alphaTest';
 MaterialNode.COLOR = 'color';
 MaterialNode.OPACITY = 'opacity';
 MaterialNode.SHININESS = 'shininess';
-MaterialNode.SPECULAR = 'specular';
+MaterialNode.SPECULAR_COLOR = 'specular';
 MaterialNode.SPECULAR_STRENGTH = 'specularStrength';
 MaterialNode.REFLECTIVITY = 'reflectivity';
 MaterialNode.ROUGHNESS = 'roughness';
 MaterialNode.METALNESS = 'metalness';
+MaterialNode.NORMAL = 'normal';
 MaterialNode.CLEARCOAT = 'clearcoat';
 MaterialNode.CLEARCOAT_ROUGHNESS = 'clearcoatRoughness';
+MaterialNode.CLEARCOAT_NORMAL = 'clearcoatNormal';
 MaterialNode.EMISSIVE = 'emissive';
 MaterialNode.ROTATION = 'rotation';
 MaterialNode.SHEEN = 'sheen';
@@ -252,6 +275,12 @@ MaterialNode.SHEEN_ROUGHNESS = 'sheenRoughness';
 MaterialNode.IRIDESCENCE = 'iridescence';
 MaterialNode.IRIDESCENCE_IOR = 'iridescenceIOR';
 MaterialNode.IRIDESCENCE_THICKNESS = 'iridescenceThickness';
+MaterialNode.LINE_SCALE = 'scale';
+MaterialNode.LINE_DASH_SIZE = 'dashSize';
+MaterialNode.LINE_GAP_SIZE = 'gapSize';
+MaterialNode.LINE_WIDTH = 'linewidth';
+MaterialNode.LINE_DASH_OFFSET = 'dashOffset';
+MaterialNode.POINT_WIDTH = 'pointWidth';
 
 export default MaterialNode;
 
@@ -265,13 +294,21 @@ export const materialSpecularStrength = nodeImmutable( MaterialNode, MaterialNod
 export const materialReflectivity = nodeImmutable( MaterialNode, MaterialNode.REFLECTIVITY );
 export const materialRoughness = nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS );
 export const materialMetalness = nodeImmutable( MaterialNode, MaterialNode.METALNESS );
+export const materialNormal = nodeImmutable( MaterialNode, MaterialNode.NORMAL );
 export const materialClearcoat = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT );
 export const materialClearcoatRoughness = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_ROUGHNESS );
+export const materialClearcoatNormal = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_NORMAL );
 export const materialRotation = nodeImmutable( MaterialNode, MaterialNode.ROTATION );
 export const materialSheen = nodeImmutable( MaterialNode, MaterialNode.SHEEN );
 export const materialSheenRoughness = nodeImmutable( MaterialNode, MaterialNode.SHEEN_ROUGHNESS );
 export const materialIridescence = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE );
 export const materialIridescenceIOR = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_IOR );
 export const materialIridescenceThickness = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_THICKNESS );
+export const materialLineScale = nodeImmutable( MaterialNode, MaterialNode.LINE_SCALE );
+export const materialLineDashSize = nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_SIZE );
+export const materialLineGapSize = nodeImmutable( MaterialNode, MaterialNode.LINE_GAP_SIZE );
+export const materialLineWidth = nodeImmutable( MaterialNode, MaterialNode.LINE_WIDTH );
+export const materialLineDashOffset = nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_OFFSET );
+export const materialPointWidth = nodeImmutable( MaterialNode, MaterialNode.POINT_WIDTH );
 
 addNodeClass( 'MaterialNode', MaterialNode );

+ 1 - 2
examples/jsm/nodes/accessors/ModelNode.js

@@ -1,6 +1,5 @@
 import Object3DNode from './Object3DNode.js';
 import { addNodeClass } from '../core/Node.js';
-import { label } from '../core/ContextNode.js';
 import { nodeImmutable } from '../shadernode/ShaderNode.js';
 
 class ModelNode extends Object3DNode {
@@ -24,7 +23,7 @@ class ModelNode extends Object3DNode {
 export default ModelNode;
 
 export const modelDirection = nodeImmutable( ModelNode, ModelNode.DIRECTION );
-export const modelViewMatrix = label( nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX ), 'modelViewMatrix' );
+export const modelViewMatrix = nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX ).temp( 'ModelViewMatrix' );
 export const modelNormalMatrix = nodeImmutable( ModelNode, ModelNode.NORMAL_MATRIX );
 export const modelWorldMatrix = nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX );
 export const modelPosition = nodeImmutable( ModelNode, ModelNode.POSITION );

+ 5 - 5
examples/jsm/nodes/accessors/MorphNode.js

@@ -19,12 +19,12 @@ class MorphNode extends Node {
 
 	}
 
-	setupAttribute( builder, name, assignNode = positionLocal ) {
+	setupAttribute( name, assignNode = positionLocal ) {
 
 		const mesh = this.mesh;
 		const attributes = mesh.geometry.morphAttributes[ name ];
 
-		builder.stack.assign( assignNode, assignNode.mul( this.morphBaseInfluence ) );
+		assignNode.mulAssign( this.morphBaseInfluence );
 
 		for ( let i = 0; i < attributes.length; i ++ ) {
 
@@ -33,15 +33,15 @@ class MorphNode extends Node {
 			const bufferAttrib = bufferAttribute( attribute.array, 'vec3' );
 			const influence = reference( i, 'float', mesh.morphTargetInfluences );
 
-			builder.stack.assign( assignNode, assignNode.add( bufferAttrib.mul( influence ) ) );
+			assignNode.addAssign( bufferAttrib.mul( influence ) );
 
 		}
 
 	}
 
-	setup( builder ) {
+	setup( /*builder*/ ) {
 
-		this.setupAttribute( builder, 'position' );
+		this.setupAttribute( 'position' );
 
 	}
 

+ 1 - 1
examples/jsm/nodes/accessors/NormalNode.js

@@ -86,7 +86,7 @@ NormalNode.WORLD = 'world';
 export default NormalNode;
 
 export const normalGeometry = nodeImmutable( NormalNode, NormalNode.GEOMETRY );
-export const normalLocal = nodeImmutable( NormalNode, NormalNode.LOCAL );
+export const normalLocal = nodeImmutable( NormalNode, NormalNode.LOCAL ).temp( 'Normal' );
 export const normalView = nodeImmutable( NormalNode, NormalNode.VIEW );
 export const normalWorld = nodeImmutable( NormalNode, NormalNode.WORLD );
 export const transformedNormalView = property( 'vec3', 'TransformedNormalView' );

+ 1 - 1
examples/jsm/nodes/accessors/PositionNode.js

@@ -95,7 +95,7 @@ PositionNode.VIEW_DIRECTION = 'viewDirection';
 export default PositionNode;
 
 export const positionGeometry = nodeImmutable( PositionNode, PositionNode.GEOMETRY );
-export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL );
+export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL ).temp( 'Position' );
 export const positionWorld = nodeImmutable( PositionNode, PositionNode.WORLD );
 export const positionWorldDirection = nodeImmutable( PositionNode, PositionNode.WORLD_DIRECTION );
 export const positionView = nodeImmutable( PositionNode, PositionNode.VIEW );

Some files were not shown because too many files changed in this diff