Kaynağa Gözat

merging dev

Emmett Lalish 5 yıl önce
ebeveyn
işleme
8e22e12e41
60 değiştirilmiş dosya ile 1208 ekleme ve 868 silme
  1. 125 37
      build/three.js
  2. 133 303
      build/three.min.js
  3. 125 37
      build/three.module.js
  4. 3 1
      docs/api/en/core/Raycaster.html
  5. 6 2
      docs/api/en/materials/Material.html
  6. 11 0
      docs/api/en/objects/InstancedMesh.html
  7. 3 1
      docs/api/zh/core/Raycaster.html
  8. 6 2
      docs/api/zh/materials/Material.html
  9. 11 0
      docs/api/zh/objects/InstancedMesh.html
  10. 8 0
      docs/examples/en/loaders/DRACOLoader.html
  11. 1 1
      docs/examples/en/loaders/MTLLoader.html
  12. 8 0
      docs/examples/zh/loaders/DRACOLoader.html
  13. 3 2
      examples/files.js
  14. 95 105
      examples/js/effects/OutlineEffect.js
  15. 1 1
      examples/js/exporters/OBJExporter.js
  16. 2 2
      examples/js/exporters/PLYExporter.js
  17. 8 0
      examples/js/loaders/DRACOLoader.js
  18. 9 0
      examples/js/loaders/OBJLoader.js
  19. 1 1
      examples/js/renderers/SVGRenderer.js
  20. 98 107
      examples/jsm/effects/OutlineEffect.js
  21. 1 1
      examples/jsm/exporters/OBJExporter.js
  22. 2 2
      examples/jsm/exporters/PLYExporter.js
  23. 1 0
      examples/jsm/loaders/DRACOLoader.d.ts
  24. 8 0
      examples/jsm/loaders/DRACOLoader.js
  25. 9 0
      examples/jsm/loaders/OBJLoader.js
  26. 4 3
      examples/jsm/nodes/materials/NodeMaterial.js
  27. 1 1
      examples/jsm/renderers/SVGRenderer.js
  28. 30 24
      examples/webgl2_multisampled_renderbuffers.html
  29. 146 0
      examples/webgl_instancing_raycast.html
  30. 0 138
      examples/webvr_6dof_panorama.html
  31. 1 0
      examples/webvr_ballshooter.html
  32. 1 0
      examples/webvr_cubes.html
  33. 1 0
      examples/webvr_dragging.html
  34. 1 0
      examples/webvr_lorenzattractor.html
  35. 1 0
      examples/webvr_multiview.html
  36. 1 0
      examples/webvr_paint.html
  37. 1 0
      examples/webvr_panorama.html
  38. 136 0
      examples/webvr_panorama_depth.html
  39. 1 0
      examples/webvr_sandbox.html
  40. 1 0
      examples/webvr_sculpt.html
  41. 1 0
      examples/webvr_video.html
  42. 1 0
      examples/webvr_vive_paint.html
  43. 1 0
      examples/webvr_vive_sculpt.html
  44. 28 22
      src/core/BufferAttribute.d.ts
  45. 5 7
      src/core/InterleavedBufferAttribute.d.ts
  46. 2 2
      src/loaders/AnimationLoader.d.ts
  47. 3 3
      src/loaders/AudioLoader.d.ts
  48. 5 4
      src/loaders/BufferGeometryLoader.d.ts
  49. 1 1
      src/loaders/ImageBitmapLoader.d.ts
  50. 5 0
      src/materials/Material.d.ts
  51. 10 1
      src/materials/Material.js
  52. 3 0
      src/objects/InstancedMesh.d.ts
  53. 57 3
      src/objects/InstancedMesh.js
  54. 12 4
      src/renderers/WebGLRenderer.js
  55. 2 13
      src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl.js
  56. 11 3
      src/renderers/webgl/WebGLAttributes.d.ts
  57. 11 4
      src/renderers/webgl/WebGLGeometries.d.ts
  58. 1 1
      src/renderers/webgl/WebGLInfo.d.ts
  59. 28 9
      src/renderers/webvr/WebVRManager.js
  60. 17 20
      src/renderers/webvr/WebXRManager.js

Dosya farkı çok büyük olduğundan ihmal edildi
+ 125 - 37
build/three.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 133 - 303
build/three.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 125 - 37
build/three.module.js


+ 3 - 1
docs/api/en/core/Raycaster.html

@@ -58,6 +58,7 @@
 			Examples: [example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
 			[example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry]<br />
+			[example:webgl_instancing_raycast Raycasting to a InstancedMesh]<br />
 			[example:webgl_interactive_lines Raycasting to a Line]<br />
 			[example:webgl_interactive_raycasting_points Raycasting to Points]<br />
 			[example:webgl_geometry_terrain_raycast Terrain raycasting]<br />
@@ -170,7 +171,8 @@
 			[page:Integer faceIndex] – index of the intersected face<br />
 			[page:Object3D object] – the intersected object<br />
 			[page:Vector2 uv] - U,V coordinates at point of intersection<br />
-			[page:Vector2 uv2] - Second set of U,V coordinates at point of intersection
+			[page:Vector2 uv2] - Second set of U,V coordinates at point of intersection<br />
+			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 		</p>
 		<p>
 		*Raycaster* delegates to the [page:Object3D.raycast raycast] method of the passed object, when evaluating whether the ray intersects the object or not. This allows [page:Mesh meshes] to respond differently to ray casting than [page:Line lines] and [page:Points pointclouds].

+ 6 - 2
docs/api/en/materials/Material.html

@@ -186,8 +186,7 @@
 
 		<h3>[property:Boolean needsUpdate]</h3>
 		<p>
-		Specifies that the material needs to be recompiled.<br />
-		This property is automatically set to *true* when instancing a new material.
+		Specifies that the material needs to be recompiled.
 		</p>
 
 		<h3>[property:Float opacity]</h3>
@@ -296,6 +295,11 @@
 		This gets automatically assigned, so this shouldn't be edited.
 		</p>
 
+		<h3>[property:Integer version]</h3>
+		<p>
+		This starts at *0* and counts how many times [property:Boolean needsUpdate] is set to *true*.
+		</p>
+
 		<h3>[property:Integer vertexColors]</h3>
 		<p>
 		Defines whether vertex coloring is used.

+ 11 - 0
docs/api/en/objects/InstancedMesh.html

@@ -53,6 +53,17 @@
 		<h2>Methods</h2>
 		<p>See the base [page:Mesh] class for common methods.</p>
 
+		<h3>[method:null getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the range [0, count].
+		</p>
+		<p>
+			[page:Matrix4 matrix]: This 4x4 matrix will be set to the local transformation matrix of the defined instance.
+		</p>
+		<p>
+			Get the local transformation matrix of the defined instance.
+		</p>
+
 		<h3>[method:null setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )</h3>
 		<p>
 			[page:Integer index]: The index of an instance. Values have to be in the range [0, count].

+ 3 - 1
docs/api/zh/core/Raycaster.html

@@ -56,6 +56,7 @@
 			其它示例:<br>[example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
 			[example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry]<br />
+			[example:webgl_instancing_raycast Raycasting to a InstancedMesh]<br />
 			[example:webgl_interactive_lines Raycasting to a Line]<br />
 			[example:webgl_interactive_raycasting_points Raycasting to Points]<br />
 			[example:webgl_geometry_terrain_raycast Terrain raycasting]<br />
@@ -170,7 +171,8 @@
 			[page:Integer faceIndex] —— 相交的面的索引<br />
 			[page:Object3D object] —— 相交的物体<br />
 			[page:Vector2 uv] —— 相交部分的点的UV坐标。<br />
-			[page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection
+			[page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection<br />
+			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 		</p>
 		<p>
 			当计算这条射线是否和物体相交的时候,*Raycaster*将传入的对象委托给[page:Object3D.raycast raycast]方法。

+ 6 - 2
docs/api/zh/materials/Material.html

@@ -163,8 +163,7 @@ Which stencil operation to perform when the comparison function returns true and
 <p>对象的可选名称(不必是唯一的)。默认值为空字符串。</p>
 
 <h3>[property:Boolean needsUpdate]</h3>
-<p>指定需要重新编译材质。<br/>
-	实例化新材质时,此属性自动设置为true。
+<p>指定需要重新编译材质。
 </p>
 
 <h3>[property:Float opacity]</h3>
@@ -255,6 +254,11 @@ Defines whether this material is tone mapped according to the renderer's [page:W
 <p> 此材质实例的[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID],会自动分配,不应该被更改。
 </p>
 
+<h3>[property:Integer version]</h3>
+<p>
+This starts at *0* and counts how many times [property:Boolean needsUpdate] is set to *true*.
+</p>
+
 <h3>[property:Integer vertexColors]</h3>
 <p> 是否使用顶点着色。默认值为[page:Materials THREE.NoColors]。
 	其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。

+ 11 - 0
docs/api/zh/objects/InstancedMesh.html

@@ -53,6 +53,17 @@
 		<h2>Methods</h2>
 		<p>See the base [page:Mesh] class for common methods.</p>
 
+		<h3>[method:null getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the range [0, count].
+		</p>
+		<p>
+			[page:Matrix4 matrix]: This 4x4 matrix will be set to the local transformation matrix of the defined instance.
+		</p>
+		<p>
+			Get the local transformation matrix of the defined instance.
+		</p>
+
 		<h3>[method:null setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )</h3>
 		<p>
 			[page:Integer index]: The index of an instance. Values have to be in the range [0, count].

+ 8 - 0
docs/examples/en/loaders/DRACOLoader.html

@@ -36,6 +36,9 @@
 		// Specify path to a folder containing WASM/JS decoding libraries.
 		loader.setDecoderPath( '/examples/js/libs/draco/' );
 
+		// Optional: Pre-fetch Draco WASM/JS module.
+		loader.preload();
+
 		// Load a Draco geometry
 		loader.load(
 			// resource URL
@@ -128,6 +131,11 @@
 		in the application.
 		</p>
 
+		<h3>[method:this preload]()</h3>
+		<p>
+		Requests the decoder libraries, if not already loaded.
+		</p>
+
 		<h3>[method:this dispose]()</h3>
 		<p>
 		Disposes of the decoder resources and deallocates memory. The decoder

+ 1 - 1
docs/examples/en/loaders/MTLLoader.html

@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<p class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJLoader].<br />
+		<p class="desc">A loader for loading an <em>.mtl</em> resource, used internally by [page:OBJLoader].<br />
 		The Material Template Library format (MTL) or .MTL File Format is a companion file format to .OBJ that describes surface shading
 		(material) properties of objects within one or more .OBJ files.
 		</p>

+ 8 - 0
docs/examples/zh/loaders/DRACOLoader.html

@@ -36,6 +36,9 @@
 		// Specify path to a folder containing WASM/JS decoding libraries.
 		loader.setDecoderPath( '/examples/js/libs/draco/' );
 
+		// Optional: Pre-fetch Draco WASM/JS module.
+		loader.preload();
+
 		// Load a Draco geometry
 		loader.load(
 			// resource URL
@@ -128,6 +131,11 @@
 		in the application.
 		</p>
 
+		<h3>[method:this preload]()</h3>
+		<p>
+		Requests the decoder libraries, if not already loaded.
+		</p>
+
 		<h3>[method:this dispose]()</h3>
 		<p>
 		Disposes of the decoder resources and deallocates memory. The decoder

+ 3 - 2
examples/files.js

@@ -48,6 +48,7 @@ var files = {
 		"webgl_geometry_text_stroke",
 		"webgl_helpers",
 		"webgl_instancing_suzanne",
+		"webgl_instancing_raycast",
 		"webgl_interactive_buffergeometry",
 		"webgl_interactive_cubes",
 		"webgl_interactive_cubes_gpu",
@@ -328,14 +329,14 @@ var files = {
 		"webvr_lorenzattractor",
 		"webvr_multiview",
 		"webvr_panorama",
+		"webvr_panorama_depth",
 		"webvr_paint",
 		"webvr_rollercoaster",
 		"webvr_sandbox",
 		"webvr_sculpt",
 		"webvr_video",
 		"webvr_vive_paint",
-		"webvr_vive_sculpt",
-		"webvr_6dof_panorama"
+		"webvr_vive_sculpt"
 	],
 	"physics": [
 		"webgl_physics_cloth",

+ 95 - 105
examples/js/effects/OutlineEffect.js

@@ -54,9 +54,6 @@
  * 	visible: true,
  * 	keepAlive: true
  * };
- *
- * TODO
- *  - support shader material without objectNormal in its vertexShader
  */
 
 THREE.OutlineEffect = function ( renderer, parameters ) {
@@ -90,58 +87,57 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	//this.cache = cache;  // for debug
 
-	// copied from WebGLPrograms and removed some materials
-	var shaderIDs = {
-		MeshBasicMaterial: 'basic',
-		MeshLambertMaterial: 'lambert',
-		MeshPhongMaterial: 'phong',
-		MeshToonMaterial: 'phong',
-		MeshStandardMaterial: 'physical',
-		MeshPhysicalMaterial: 'physical'
-	};
-
-	var uniformsChunk = {
+	var uniformsOutline = {
 		outlineThickness: { value: defaultThickness },
 		outlineColor: { value: defaultColor },
 		outlineAlpha: { value: defaultAlpha }
 	};
 
-	var vertexShaderChunk = [
+	var vertexShader = [
+		"#include <common>",
+		"#include <uv_pars_vertex>",
+		"#include <displacementmap_pars_vertex>",
+		"#include <fog_pars_vertex>",
+		"#include <morphtarget_pars_vertex>",
+		"#include <skinning_pars_vertex>",
+		"#include <logdepthbuf_pars_vertex>",
+		"#include <clipping_planes_pars_vertex>",
 
 		"uniform float outlineThickness;",
 
-		"vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {",
-
+		"vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {",
 		"	float thickness = outlineThickness;",
 		"	const float ratio = 1.0;", // TODO: support outline thickness ratio for each vertex
-		"	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );",
+		"	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );",
 		// NOTE: subtract pos2 from pos because BackSide objectNormal is negative
 		"	vec4 norm = normalize( pos - pos2 );",
 		"	return pos + norm * thickness * pos.w * ratio;",
+		"}",
 
-		"}"
+		"void main() {",
 
-	].join( "\n" );
+		"	#include <uv_vertex>",
 
-	var vertexShaderChunk2 = [
+		"	#include <beginnormal_vertex>",
+		"	#include <morphnormal_vertex>",
+		"	#include <skinbase_vertex>",
+		"	#include <skinnormal_vertex>",
 
-		"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( STANDARD )",
-		"	#ifndef USE_ENVMAP",
-		"		vec3 objectNormal = normalize( normal );",
-		"	#endif",
-		"#endif",
+		"	#include <begin_vertex>",
+		"	#include <morphtarget_vertex>",
+		"	#include <skinning_vertex>",
+		"	#include <displacementmap_vertex>",
+		"	#include <project_vertex>",
 
-		"#ifdef FLIP_SIDED",
-		"	objectNormal = -objectNormal;",
-		"#endif",
+		"	vec3 outlineNormal = - objectNormal;", // the outline material is always rendered with THREE.BackSide
 
-		"#ifdef DECLARE_TRANSFORMED",
-		"	vec3 transformed = vec3( position );",
-		"#endif",
+		"	gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );",
 
-		"gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
+		"	#include <logdepthbuf_vertex>",
+		"	#include <clipping_planes_vertex>",
+		"	#include <fog_vertex>",
 
-		"#include <fog_vertex>"
+		"}",
 
 	].join( "\n" );
 
@@ -149,92 +145,40 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		"#include <common>",
 		"#include <fog_pars_fragment>",
+		"#include <logdepthbuf_pars_fragment>",
+		"#include <clipping_planes_pars_fragment>",
 
 		"uniform vec3 outlineColor;",
 		"uniform float outlineAlpha;",
 
 		"void main() {",
 
+		"	#include <clipping_planes_fragment>",
+		"	#include <logdepthbuf_fragment>",
+
 		"	gl_FragColor = vec4( outlineColor, outlineAlpha );",
 
+		"	#include <premultiplied_alpha_fragment>",
+		"	#include <tonemapping_fragment>",
+		"	#include <encodings_fragment>",
 		"	#include <fog_fragment>",
 
 		"}"
 
 	].join( "\n" );
 
-	function createInvisibleMaterial() {
-
-		return new THREE.ShaderMaterial( { name: 'invisible', visible: false } );
-
-	}
-
-	function createMaterial( originalMaterial ) {
-
-		var shaderID = shaderIDs[ originalMaterial.type ];
-		var originalUniforms, originalVertexShader;
-
-		if ( shaderID !== undefined ) {
-
-			var shader = THREE.ShaderLib[ shaderID ];
-			originalUniforms = shader.uniforms;
-			originalVertexShader = shader.vertexShader;
-
-		} else if ( originalMaterial.isRawShaderMaterial === true ) {
-
-			originalUniforms = originalMaterial.uniforms;
-			originalVertexShader = originalMaterial.vertexShader;
-
-			if ( ! /attribute\s+vec3\s+position\s*;/.test( originalVertexShader ) ||
-			     ! /attribute\s+vec3\s+normal\s*;/.test( originalVertexShader ) ) {
-
-				console.warn( 'THREE.OutlineEffect requires both vec3 position and normal attributes in vertex shader, ' +
-				              'does not draw outline for ' + originalMaterial.name + '(uuid:' + originalMaterial.uuid + ') material.' );
-
-				return createInvisibleMaterial();
-
-			}
-
-		} else if ( originalMaterial.isShaderMaterial === true ) {
-
-			originalUniforms = originalMaterial.uniforms;
-			originalVertexShader = originalMaterial.vertexShader;
-
-		} else {
-
-			return createInvisibleMaterial();
-
-		}
-
-		var uniforms = Object.assign( {}, originalUniforms, uniformsChunk );
-
-		var vertexShader = originalVertexShader
-			// put vertexShaderChunk right before "void main() {...}"
-			.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
-			// put vertexShaderChunk2 the end of "void main() {...}"
-			// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
-			.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
-			// remove any light related lines
-			// Note: here is very sensitive to originalVertexShader
-			// TODO: consider safer way
-			.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
-
-		var defines = {};
-
-		if ( ! /vec3\s+transformed\s*=/.test( originalVertexShader ) &&
-		     ! /#include\s+<begin_vertex>/.test( originalVertexShader ) ) defines.DECLARE_TRANSFORMED = true;
+	function createMaterial() {
 
 		return new THREE.ShaderMaterial( {
-			defines: defines,
-			uniforms: uniforms,
+			type: 'OutlineEffect',
+			uniforms: THREE.UniformsUtils.merge( [
+				THREE.UniformsLib[ 'fog' ],
+				THREE.UniformsLib[ 'displacementmap' ],
+				uniformsOutline
+			] ),
 			vertexShader: vertexShader,
 			fragmentShader: fragmentShader,
-			side: THREE.BackSide,
-			//wireframe: true,
-			skinning: false,
-			morphTargets: false,
-			morphNormals: false,
-			fog: false
+			side: THREE.BackSide
 		} );
 
 	}
@@ -246,7 +190,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		if ( data === undefined ) {
 
 			data = {
-				material: createMaterial( originalMaterial ),
+				material: createMaterial(),
 				used: true,
 				keepAlive: defaultKeepAlive,
 				count: 0
@@ -274,9 +218,32 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
+	function isCompatible( object ) {
+
+		var geometry = object.geometry;
+		var hasNormals = false;
+
+		if ( object.geometry !== undefined ) {
+
+			if ( geometry.isBufferGeometry ) {
+
+				hasNormals = geometry.attributes.normal !== undefined;
+
+			} else {
+
+				hasNormals = true; // the renderer always produces a normal attribute for Geometry
+
+			}
+
+		}
+
+		return ( object.isMesh === true && object.material !== undefined && hasNormals === true );
+
+	}
+
 	function setOutlineMaterial( object ) {
 
-		if ( object.material === undefined ) return;
+		if ( isCompatible( object ) === false ) return;
 
 		if ( Array.isArray( object.material ) ) {
 
@@ -299,7 +266,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	function restoreOriginalMaterial( object ) {
 
-		if ( object.material === undefined ) return;
+		if ( isCompatible( object ) === false ) return;
 
 		if ( Array.isArray( object.material ) ) {
 
@@ -344,6 +311,14 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		}
 
+		if ( originalMaterial.displacementMap ) {
+
+			material.uniforms.displacementMap.value = originalMaterial.displacementMap;
+			material.uniforms.displacementScale.value = originalMaterial.displacementScale;
+			material.uniforms.displacementBias.value = originalMaterial.displacementBias;
+
+		}
+
 	}
 
 	function updateOutlineMaterial( material, originalMaterial ) {
@@ -356,6 +331,9 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		material.morphTargets = originalMaterial.morphTargets;
 		material.morphNormals = originalMaterial.morphNormals;
 		material.fog = originalMaterial.fog;
+		material.toneMapped = originalMaterial.toneMapped;
+		material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
+		material.displacementMap = originalMaterial.displacementMap;
 
 		if ( outlineParameters !== undefined ) {
 
@@ -382,6 +360,18 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
 
+		if ( originalMaterial.clippingPlanes ) {
+
+			material.clipping = true;
+
+			material.clippingPlanes = originalMaterial.clippingPlanes;
+			material.clipIntersection = originalMaterial.clipIntersection;
+			material.clipShadows = originalMaterial.clipShadows;
+
+		}
+
+		material.version = originalMaterial.version; // update outline material if necessary
+
 	}
 
 	function cleanupCache() {

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

@@ -105,7 +105,7 @@ THREE.OBJExporter.prototype = {
 						normal.z = normals.getZ( i );
 
 						// transfrom the normal to world space
-						normal.applyMatrix3( normalMatrixWorld );
+						normal.applyMatrix3( normalMatrixWorld ).normalize();
 
 						// transform the normal to export format
 						output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

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

@@ -276,7 +276,7 @@ THREE.PLYExporter.prototype = {
 							vertex.y = normals.getY( i );
 							vertex.z = normals.getZ( i );
 
-							vertex.applyMatrix3( normalMatrixWorld );
+							vertex.applyMatrix3( normalMatrixWorld ).normalize();
 
 							output.setFloat32( vOffset, vertex.x );
 							vOffset += 4;
@@ -452,7 +452,7 @@ THREE.PLYExporter.prototype = {
 							vertex.y = normals.getY( i );
 							vertex.z = normals.getZ( i );
 
-							vertex.applyMatrix3( normalMatrixWorld );
+							vertex.applyMatrix3( normalMatrixWorld ).normalize();
 
 							line += ' ' +
 								vertex.x + ' ' +

+ 8 - 0
examples/js/loaders/DRACOLoader.js

@@ -220,6 +220,14 @@ THREE.DRACOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototy
 
 	},
 
+	preload: function () {
+
+		this._initDecoder();
+
+		return this;
+
+	},
+
 	_initDecoder: function () {
 
 		if ( this.decoderPending ) return this.decoderPending;

+ 9 - 0
examples/js/loaders/OBJLoader.js

@@ -10,6 +10,8 @@ THREE.OBJLoader = ( function () {
 	var material_library_pattern = /^mtllib /;
 	// usemtl material_name
 	var material_use_pattern = /^usemtl /;
+	// usemap map_name
+	var map_use_pattern = /^usemap /;
 
 	function ParserState() {
 
@@ -570,6 +572,13 @@ THREE.OBJLoader = ( function () {
 
 					state.materialLibraries.push( line.substring( 7 ).trim() );
 
+				} else if ( map_use_pattern.test( line ) ) {
+
+					// the line is parsed but ignored since the loader assumes textures are defined MTL files
+					// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)
+
+					console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
+
 				} else if ( lineFirstChar === 's' ) {
 
 					result = line.split( ' ' );

+ 1 - 1
examples/js/renderers/SVGRenderer.js

@@ -439,7 +439,7 @@ THREE.SVGRenderer = function () {
 
 		} else if ( material.isMeshNormalMaterial ) {
 
-			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix );
+			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
 
 			_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 

+ 98 - 107
examples/jsm/effects/OutlineEffect.js

@@ -54,16 +54,14 @@
  * 	visible: true,
  * 	keepAlive: true
  * };
- *
- * TODO
- *  - support shader material without objectNormal in its vertexShader
  */
 
 import {
 	BackSide,
 	Color,
-	ShaderLib,
-	ShaderMaterial
+	ShaderMaterial,
+	UniformsLib,
+	UniformsUtils
 } from "../../../build/three.module.js";
 
 var OutlineEffect = function ( renderer, parameters ) {
@@ -97,58 +95,57 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 	//this.cache = cache;  // for debug
 
-	// copied from WebGLPrograms and removed some materials
-	var shaderIDs = {
-		MeshBasicMaterial: 'basic',
-		MeshLambertMaterial: 'lambert',
-		MeshPhongMaterial: 'phong',
-		MeshToonMaterial: 'phong',
-		MeshStandardMaterial: 'physical',
-		MeshPhysicalMaterial: 'physical'
-	};
-
-	var uniformsChunk = {
+	var uniformsOutline = {
 		outlineThickness: { value: defaultThickness },
 		outlineColor: { value: defaultColor },
 		outlineAlpha: { value: defaultAlpha }
 	};
 
-	var vertexShaderChunk = [
+	var vertexShader = [
+		"#include <common>",
+		"#include <uv_pars_vertex>",
+		"#include <displacementmap_pars_vertex>",
+		"#include <fog_pars_vertex>",
+		"#include <morphtarget_pars_vertex>",
+		"#include <skinning_pars_vertex>",
+		"#include <logdepthbuf_pars_vertex>",
+		"#include <clipping_planes_pars_vertex>",
 
 		"uniform float outlineThickness;",
 
-		"vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {",
-
+		"vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {",
 		"	float thickness = outlineThickness;",
 		"	const float ratio = 1.0;", // TODO: support outline thickness ratio for each vertex
-		"	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );",
+		"	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );",
 		// NOTE: subtract pos2 from pos because BackSide objectNormal is negative
 		"	vec4 norm = normalize( pos - pos2 );",
 		"	return pos + norm * thickness * pos.w * ratio;",
+		"}",
 
-		"}"
+		"void main() {",
 
-	].join( "\n" );
+		"	#include <uv_vertex>",
 
-	var vertexShaderChunk2 = [
+		"	#include <beginnormal_vertex>",
+		"	#include <morphnormal_vertex>",
+		"	#include <skinbase_vertex>",
+		"	#include <skinnormal_vertex>",
 
-		"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( STANDARD )",
-		"	#ifndef USE_ENVMAP",
-		"		vec3 objectNormal = normalize( normal );",
-		"	#endif",
-		"#endif",
+		"	#include <begin_vertex>",
+		"	#include <morphtarget_vertex>",
+		"	#include <skinning_vertex>",
+		"	#include <displacementmap_vertex>",
+		"	#include <project_vertex>",
 
-		"#ifdef FLIP_SIDED",
-		"	objectNormal = -objectNormal;",
-		"#endif",
+		"	vec3 outlineNormal = - objectNormal;", // the outline material is always rendered with BackSide
 
-		"#ifdef DECLARE_TRANSFORMED",
-		"	vec3 transformed = vec3( position );",
-		"#endif",
+		"	gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );",
 
-		"gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
+		"	#include <logdepthbuf_vertex>",
+		"	#include <clipping_planes_vertex>",
+		"	#include <fog_vertex>",
 
-		"#include <fog_vertex>"
+		"}",
 
 	].join( "\n" );
 
@@ -156,92 +153,40 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 		"#include <common>",
 		"#include <fog_pars_fragment>",
+		"#include <logdepthbuf_pars_fragment>",
+		"#include <clipping_planes_pars_fragment>",
 
 		"uniform vec3 outlineColor;",
 		"uniform float outlineAlpha;",
 
 		"void main() {",
 
+		"	#include <clipping_planes_fragment>",
+		"	#include <logdepthbuf_fragment>",
+
 		"	gl_FragColor = vec4( outlineColor, outlineAlpha );",
 
+		"	#include <premultiplied_alpha_fragment>",
+		"	#include <tonemapping_fragment>",
+		"	#include <encodings_fragment>",
 		"	#include <fog_fragment>",
 
 		"}"
 
 	].join( "\n" );
 
-	function createInvisibleMaterial() {
-
-		return new ShaderMaterial( { name: 'invisible', visible: false } );
-
-	}
-
-	function createMaterial( originalMaterial ) {
-
-		var shaderID = shaderIDs[ originalMaterial.type ];
-		var originalUniforms, originalVertexShader;
-
-		if ( shaderID !== undefined ) {
-
-			var shader = ShaderLib[ shaderID ];
-			originalUniforms = shader.uniforms;
-			originalVertexShader = shader.vertexShader;
-
-		} else if ( originalMaterial.isRawShaderMaterial === true ) {
-
-			originalUniforms = originalMaterial.uniforms;
-			originalVertexShader = originalMaterial.vertexShader;
-
-			if ( ! /attribute\s+vec3\s+position\s*;/.test( originalVertexShader ) ||
-			     ! /attribute\s+vec3\s+normal\s*;/.test( originalVertexShader ) ) {
-
-				console.warn( 'THREE.OutlineEffect requires both vec3 position and normal attributes in vertex shader, ' +
-				              'does not draw outline for ' + originalMaterial.name + '(uuid:' + originalMaterial.uuid + ') material.' );
-
-				return createInvisibleMaterial();
-
-			}
-
-		} else if ( originalMaterial.isShaderMaterial === true ) {
-
-			originalUniforms = originalMaterial.uniforms;
-			originalVertexShader = originalMaterial.vertexShader;
-
-		} else {
-
-			return createInvisibleMaterial();
-
-		}
-
-		var uniforms = Object.assign( {}, originalUniforms, uniformsChunk );
-
-		var vertexShader = originalVertexShader
-			// put vertexShaderChunk right before "void main() {...}"
-			.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
-			// put vertexShaderChunk2 the end of "void main() {...}"
-			// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
-			.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
-			// remove any light related lines
-			// Note: here is very sensitive to originalVertexShader
-			// TODO: consider safer way
-			.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
-
-		var defines = {};
-
-		if ( ! /vec3\s+transformed\s*=/.test( originalVertexShader ) &&
-		     ! /#include\s+<begin_vertex>/.test( originalVertexShader ) ) defines.DECLARE_TRANSFORMED = true;
+	function createMaterial() {
 
 		return new ShaderMaterial( {
-			defines: defines,
-			uniforms: uniforms,
+			type: 'OutlineEffect',
+			uniforms: UniformsUtils.merge( [
+				UniformsLib[ 'fog' ],
+				UniformsLib[ 'displacementmap' ],
+				uniformsOutline
+			] ),
 			vertexShader: vertexShader,
 			fragmentShader: fragmentShader,
-			side: BackSide,
-			//wireframe: true,
-			skinning: false,
-			morphTargets: false,
-			morphNormals: false,
-			fog: false
+			side: BackSide
 		} );
 
 	}
@@ -253,7 +198,7 @@ var OutlineEffect = function ( renderer, parameters ) {
 		if ( data === undefined ) {
 
 			data = {
-				material: createMaterial( originalMaterial ),
+				material: createMaterial(),
 				used: true,
 				keepAlive: defaultKeepAlive,
 				count: 0
@@ -281,9 +226,32 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
+	function isCompatible( object ) {
+
+		var geometry = object.geometry;
+		var hasNormals = false;
+
+		if ( object.geometry !== undefined ) {
+
+			if ( geometry.isBufferGeometry ) {
+
+				hasNormals = geometry.attributes.normal !== undefined;
+
+			} else {
+
+				hasNormals = true; // the renderer always produces a normal attribute for Geometry
+
+			}
+
+		}
+
+		return ( object.isMesh === true && object.material !== undefined && hasNormals === true );
+
+	}
+
 	function setOutlineMaterial( object ) {
 
-		if ( object.material === undefined ) return;
+		if ( isCompatible( object ) === false ) return;
 
 		if ( Array.isArray( object.material ) ) {
 
@@ -306,7 +274,7 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 	function restoreOriginalMaterial( object ) {
 
-		if ( object.material === undefined ) return;
+		if ( isCompatible( object ) === false ) return;
 
 		if ( Array.isArray( object.material ) ) {
 
@@ -351,6 +319,14 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 		}
 
+		if ( originalMaterial.displacementMap ) {
+
+			material.uniforms.displacementMap.value = originalMaterial.displacementMap;
+			material.uniforms.displacementScale.value = originalMaterial.displacementScale;
+			material.uniforms.displacementBias.value = originalMaterial.displacementBias;
+
+		}
+
 	}
 
 	function updateOutlineMaterial( material, originalMaterial ) {
@@ -363,6 +339,9 @@ var OutlineEffect = function ( renderer, parameters ) {
 		material.morphTargets = originalMaterial.morphTargets;
 		material.morphNormals = originalMaterial.morphNormals;
 		material.fog = originalMaterial.fog;
+		material.toneMapped = originalMaterial.toneMapped;
+		material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
+		material.displacementMap = originalMaterial.displacementMap;
 
 		if ( outlineParameters !== undefined ) {
 
@@ -389,6 +368,18 @@ var OutlineEffect = function ( renderer, parameters ) {
 
 		if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
 
+		if ( originalMaterial.clippingPlanes ) {
+
+			material.clipping = true;
+
+			material.clippingPlanes = originalMaterial.clippingPlanes;
+			material.clipIntersection = originalMaterial.clipIntersection;
+			material.clipShadows = originalMaterial.clipShadows;
+
+		}
+
+		material.version = originalMaterial.version; // update outline material if necessary
+
 	}
 
 	function cleanupCache() {

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

@@ -115,7 +115,7 @@ OBJExporter.prototype = {
 						normal.z = normals.getZ( i );
 
 						// transfrom the normal to world space
-						normal.applyMatrix3( normalMatrixWorld );
+						normal.applyMatrix3( normalMatrixWorld ).normalize();
 
 						// transform the normal to export format
 						output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

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

@@ -282,7 +282,7 @@ PLYExporter.prototype = {
 							vertex.y = normals.getY( i );
 							vertex.z = normals.getZ( i );
 
-							vertex.applyMatrix3( normalMatrixWorld );
+							vertex.applyMatrix3( normalMatrixWorld ).normalize();
 
 							output.setFloat32( vOffset, vertex.x );
 							vOffset += 4;
@@ -458,7 +458,7 @@ PLYExporter.prototype = {
 							vertex.y = normals.getY( i );
 							vertex.z = normals.getZ( i );
 
-							vertex.applyMatrix3( normalMatrixWorld );
+							vertex.applyMatrix3( normalMatrixWorld ).normalize();
 
 							line += ' ' +
 								vertex.x + ' ' +

+ 1 - 0
examples/jsm/loaders/DRACOLoader.d.ts

@@ -12,6 +12,7 @@ export class DRACOLoader extends Loader {
 	setDecoderPath( path: string ): DRACOLoader;
 	setDecoderConfig( config: object ): DRACOLoader;
 	setWorkerLimit( workerLimit: number ): DRACOLoader;
+	preload(): DRACOLoader;
 	dispose(): DRACOLoader;
 
 }

+ 8 - 0
examples/jsm/loaders/DRACOLoader.js

@@ -227,6 +227,14 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 	},
 
+	preload: function () {
+
+		this._initDecoder();
+
+		return this;
+
+	},
+
 	_initDecoder: function () {
 
 		if ( this.decoderPending ) return this.decoderPending;

+ 9 - 0
examples/jsm/loaders/OBJLoader.js

@@ -27,6 +27,8 @@ var OBJLoader = ( function () {
 	var material_library_pattern = /^mtllib /;
 	// usemtl material_name
 	var material_use_pattern = /^usemtl /;
+	// usemap map_name
+	var map_use_pattern = /^usemap /;
 
 	function ParserState() {
 
@@ -587,6 +589,13 @@ var OBJLoader = ( function () {
 
 					state.materialLibraries.push( line.substring( 7 ).trim() );
 
+				} else if ( map_use_pattern.test( line ) ) {
+
+					// the line is parsed but ignored since the loader assumes textures are defined MTL files
+					// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)
+
+					console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
+
 				} else if ( lineFirstChar === 's' ) {
 
 					result = line.split( ' ' );

+ 4 - 3
examples/jsm/nodes/materials/NodeMaterial.js

@@ -30,7 +30,9 @@ function NodeMaterial( vertex, fragment ) {
 
 	this.onBeforeCompile = function ( shader, renderer ) {
 
-		if ( this.needsUpdate ) {
+		var materialProperties = renderer.properties.get( this );
+
+		if ( this.version !== materialProperties.__version ) {
 
 			this.build( { renderer: renderer } );
 
@@ -74,6 +76,7 @@ Object.defineProperties( NodeMaterial.prototype, {
 
 		set: function ( value ) {
 
+			if ( value === true ) this.version ++;
 			this.needsCompile = value;
 
 		},
@@ -120,8 +123,6 @@ NodeMaterial.prototype.build = function ( params ) {
 
 	this.transparent = builder.requires.transparent || this.blending > NormalBlending;
 
-	this.needsUpdate = false;
-
 	return this;
 
 };

+ 1 - 1
examples/jsm/renderers/SVGRenderer.js

@@ -455,7 +455,7 @@ var SVGRenderer = function () {
 
 		} else if ( material.isMeshNormalMaterial ) {
 
-			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix );
+			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
 
 			_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 

+ 30 - 24
examples/webgl2_multisampled_renderbuffers.html

@@ -17,7 +17,7 @@
 
 			#container {
 				position: absolute;
-				top: 80px;
+				top: 70px;
 				width: 100%;
 				bottom: 0px;
 			}
@@ -28,7 +28,7 @@
 
 		<div id="info">
 			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Multisampled Renderbuffers<br />
-			Left: WebGLMultisampleRenderTarget, Right: WebGLRenderTarget.
+			Left: WebGLRenderTarget, Right: WebGLMultisampleRenderTarget.
 		</div>
 		<div id="container">
 		</div>
@@ -60,7 +60,7 @@
 
 				container = document.getElementById( 'container' );
 
-				camera = new THREE.PerspectiveCamera( 45, ( container.offsetWidth * 0.5 ) / container.offsetHeight, 1, 2000 );
+				camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 2000 );
 				camera.position.z = 500;
 
 				scene = new THREE.Scene();
@@ -71,30 +71,35 @@
 
 				//
 
-				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
-				hemiLight.position.set( 0, 1000, 0 );
+				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x222222, 1.5 );
+				hemiLight.position.set( 1, 1, 1 );
 				scene.add( hemiLight );
 
-				var dirLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
-				dirLight.position.set( - 3000, 1000, - 1000 );
-				scene.add( dirLight );
-
 				//
 
 				group = new THREE.Group();
 
-				var geometry = new THREE.IcosahedronBufferGeometry( 10, 2 );
-				var material = new THREE.MeshStandardMaterial( { color: 0xee0808, flatShading: true } );
+				var geometry = new THREE.SphereBufferGeometry( 10, 64, 40 );
+				var material = new THREE.MeshLambertMaterial( { color: 0xee0808 } );
+				var material2 = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
 
-				for ( var i = 0; i < 100; i ++ ) {
+				for ( var i = 0; i < 10; i ++ ) {
 
 					var mesh = new THREE.Mesh( geometry, material );
-					mesh.position.x = Math.random() * 500 - 250;
-					mesh.position.y = Math.random() * 500 - 250;
-					mesh.position.z = Math.random() * 500 - 250;
-					mesh.scale.setScalar( Math.random() * 2 + 1 );
+					mesh.position.x = Math.random() * 600 - 300;
+					mesh.position.y = Math.random() * 600 - 300;
+					mesh.position.z = Math.random() * 600 - 300;
+					mesh.rotation.x = Math.random();
+					mesh.rotation.z = Math.random();
+					mesh.scale.setScalar( Math.random() * 5 + 5 );
 					group.add( mesh );
 
+					var mesh2 = new THREE.Mesh( geometry, material2 );
+					mesh2.position.copy( mesh.position );
+					mesh2.rotation.copy( mesh.rotation );
+					mesh2.scale.copy( mesh.scale );
+					group.add( mesh2 );
+
 				}
 
 				scene.add( group );
@@ -102,12 +107,11 @@
 				//
 
 				var canvas = document.createElement( 'canvas' );
-				canvas.style.imageRendering = 'pixelated'; // disable browser interpolation
-
 				var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } );
 
 				renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
 				renderer.autoClear = false;
+				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( container.offsetWidth, container.offsetHeight );
 				container.appendChild( renderer.domElement );
 
@@ -126,13 +130,13 @@
 
 				//
 
-				composer1 = new EffectComposer( renderer, renderTarget );
+				composer1 = new EffectComposer( renderer );
 				composer1.addPass( renderPass );
 				composer1.addPass( copyPass );
 
 				//
 
-				composer2 = new EffectComposer( renderer );
+				composer2 = new EffectComposer( renderer, renderTarget );
 				composer2.addPass( renderPass );
 				composer2.addPass( copyPass );
 
@@ -144,7 +148,7 @@
 
 			function onWindowResize() {
 
-				camera.aspect = ( container.offsetWidth * 0.5 ) / container.offsetHeight;
+				camera.aspect = container.offsetWidth / container.offsetHeight;
 				camera.updateProjectionMatrix();
 
 				renderer.setSize( container.offsetWidth, container.offsetHeight );
@@ -161,14 +165,16 @@
 
 				group.rotation.y += clock.getDelta() * 0.1;
 
-				renderer.setViewport( 0, 0, halfWidth, container.offsetHeight );
+				renderer.setScissorTest( true );
 
+				renderer.setScissor( 0, 0, halfWidth - 1, container.offsetHeight );
 				composer1.render();
 
-				renderer.setViewport( halfWidth, 0, halfWidth, container.offsetHeight );
-
+				renderer.setScissor( halfWidth, 0, halfWidth, container.offsetHeight );
 				composer2.render();
 
+				renderer.setScissorTest( false );
+
 			}
 
 		</script>

+ 146 - 0
examples/webgl_instancing_raycast.html

@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<title>three.js webgl - instancing - raycast</title>
+	<meta charset="utf-8">
+	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+	<link type="text/css" rel="stylesheet" href="main.css">
+</head>
+<body>
+<script type="module">
+
+	import * as THREE from '../build/three.module.js';
+
+	import Stats from './jsm/libs/stats.module.js';
+	import { GUI } from './jsm/libs/dat.gui.module.js';
+	import { OrbitControls } from "./jsm/controls/OrbitControls.js";
+
+	var camera, scene, renderer, stats;
+
+	var mesh, geometry;
+	var amount = parseInt( window.location.search.substr( 1 ) ) || 3;
+	var count = Math.pow( amount, 3 );
+	var object = new THREE.Object3D();
+
+	var intersection;
+	var raycaster = new THREE.Raycaster();
+	var mouse = new THREE.Vector2( 1, 1 );
+
+	var rotationTheta = 0.1;
+	var rotationMatrix = new THREE.Matrix4().makeRotationY( rotationTheta );
+	var instanceMatrix = new THREE.Matrix4();
+	var matrix = new THREE.Matrix4();
+
+	init();
+	animate();
+
+	function init() {
+
+		camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
+		camera.position.set( amount, amount, amount );
+		camera.lookAt( 0, 0, 0 );
+
+		scene = new THREE.Scene();
+
+		geometry = new THREE.TorusKnotBufferGeometry( 0.5, 0.2, 16, 4, 2, 3 );
+		geometry.scale( 0.5, 0.5, 0.5 );
+
+		var material = new THREE.MeshNormalMaterial( { flatShading: true } );
+
+		mesh = new THREE.InstancedMesh( geometry, material, count );
+
+		var i = 0;
+		var offset = amount / 2;
+
+		for ( var x = 0; x < amount; x ++ ) {
+
+			for ( var y = 0; y < amount; y ++ ) {
+
+				for ( var z = 0; z < amount; z ++ ) {
+
+					object.position.set( offset - x, offset - y, offset - z );
+
+					object.updateMatrix();
+
+					mesh.setMatrixAt( i ++, object.matrix );
+
+				}
+
+			}
+
+		}
+
+		scene.add( mesh );
+
+		//
+
+		var gui = new GUI();
+		gui.add( mesh, 'count', 0, count );
+
+		renderer = new THREE.WebGLRenderer( { antialias: true } );
+		renderer.setPixelRatio( window.devicePixelRatio );
+		renderer.setSize( window.innerWidth, window.innerHeight );
+		document.body.appendChild( renderer.domElement );
+
+		var orbitControls = new OrbitControls( camera, renderer.domElement );
+
+		stats = new Stats();
+		document.body.appendChild( stats.dom );
+
+		window.addEventListener( 'resize', onWindowResize, false );
+		document.addEventListener( 'mousemove', onMouseMove, false );
+
+	}
+
+	function onWindowResize() {
+
+		camera.aspect = window.innerWidth / window.innerHeight;
+		camera.updateProjectionMatrix();
+
+		renderer.setSize( window.innerWidth, window.innerHeight );
+
+	}
+
+	function onMouseMove( event ) {
+
+		event.preventDefault();
+
+		mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+		mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+	}
+
+	function animate() {
+
+		requestAnimationFrame( animate );
+
+		render();
+
+	}
+
+	function render() {
+
+		raycaster.setFromCamera( mouse, camera );
+
+		intersection = raycaster.intersectObjects( scene.children );
+
+		if ( intersection.length > 0 ) {
+
+			mesh.getMatrixAt( intersection[ 0 ].instanceId, instanceMatrix );
+			matrix.multiplyMatrices( instanceMatrix, rotationMatrix );
+
+			mesh.setMatrixAt( intersection[ 0 ].instanceId, matrix );
+			mesh.instanceMatrix.needsUpdate = true;
+
+		}
+
+		renderer.render( scene, camera );
+
+		stats.update();
+
+	}
+
+</script>
+
+</body>
+</html>

+ 0 - 138
examples/webvr_6dof_panorama.html

@@ -1,138 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webvr - 360 6DOF panorama</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<link type="text/css" rel="stylesheet" href="main.css">
-		<!-- WebXR Device API (For Chrome M76+), expires 12/04/2019 -->
-		<meta http-equiv="origin-trial" content="Aq9LklhCLNUveuCr7QTpGpqwCPG817cYHdVyQuJPOZYk47iRB390lUKa5edVmgS1pZSl8HPspElEC/91Fz55dwIAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU3NTQxNzU5OX0=">
-	</head>
-	<body>
-		<div id="container"></div>
-
-		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webvr - 360 6DOF panorama<br />
-			Created by <a href="https://orfleisher.com" target="_blank" rel="noopener">@juniorxsound</a>. Panorama from <a href="https://krpano.com/examples/?depthmap" target="_blank" rel="noopener">krpano</a>.
-        </div>
-
-		<script src="js/vr/HelioWebXRPolyfill.js"></script>
-
-		<script type="module">
-
-            import * as THREE from '../build/three.module.js';
-            import { WEBVR } from './jsm/vr/WebVR.js';
-
-            var camera, scene, renderer, sphere, clock;
-
-            init();
-            animate();
-
-            function init() {
-
-                var container = document.getElementById( 'container' );
-
-                clock = new THREE.Clock();
-
-                scene = new THREE.Scene();
-                scene.background = new THREE.Color( 0x101010 );
-
-                var light = new THREE.AmbientLight( 0x404040, 10 );
-                scene.add( light );
-
-                camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
-                var cameraRig = new THREE.Object3D();
-                cameraRig.position.y = - 1.6;
-                cameraRig.add( camera );
-                scene.add( cameraRig );
-
-                // Create the panoramic sphere geometery
-                var panoSphereGeo = new THREE.SphereBufferGeometry( 6, 256, 256 );
-
-                // Create the panoramic sphere material
-                var panoSphereMat = new THREE.MeshStandardMaterial( {
-                    side: THREE.BackSide,
-                    displacementScale: - 4.0
-                } );
-
-                // Create the panoramic sphere mesh
-                sphere = new THREE.Mesh( panoSphereGeo, panoSphereMat );
-
-                // Load and assign the texture and depth map
-                var manager = new THREE.LoadingManager();
-                var loader = new THREE.TextureLoader( manager );
-
-                loader.load( './textures/kandao3.jpg', function ( texture ) {
-
-                    texture.minFilter = THREE.NearestFilter;
-                    texture.format = THREE.RGBFormat;
-                    texture.generateMipmaps = false;
-                    sphere.material.map = texture;
-
-                } );
-
-                loader.load( './textures/kandao3_depthmap.jpg', function ( depth ) {
-
-                    depth.minFilter = THREE.NearestFilter;
-                    depth.format = THREE.RGBFormat;
-                    depth.generateMipmaps = false;
-                    sphere.material.displacementMap = depth;
-
-                } );
-
-                // On load complete add the panoramic sphere to the scene
-                manager.onLoad = function () {
-
-                    scene.add( sphere );
-
-                };
-
-                renderer = new THREE.WebGLRenderer();
-                renderer.setPixelRatio( window.devicePixelRatio );
-                renderer.setSize( window.innerWidth, window.innerHeight );
-                renderer.vr.enabled = true;
-                container.appendChild( renderer.domElement );
-
-                document.body.appendChild( WEBVR.createButton( renderer ) );
-
-                //
-
-                window.addEventListener( 'resize', onWindowResize, false );
-
-            }
-
-            function onWindowResize() {
-
-                camera.aspect = window.innerWidth / window.innerHeight;
-                camera.updateProjectionMatrix();
-
-                renderer.setSize( window.innerWidth, window.innerHeight );
-
-            }
-
-            function animate() {
-
-                renderer.setAnimationLoop( render );
-
-            }
-
-            function render() {
-
-                // If we are not presenting move the camera a little so the effect is visible
-                if ( ! renderer.vr.isPresenting() ) {
-
-                    var time = clock.getElapsedTime();
-
-                    sphere.rotation.y += 0.001;
-                    sphere.position.x = Math.sin( time ) * 0.2;
-                    sphere.position.z = Math.cos( time ) * 0.2;
-
-                }
-
-                renderer.render( scene, camera );
-
-            }
-
-		</script>
-	</body>
-</html>

+ 1 - 0
examples/webvr_ballshooter.html

@@ -44,6 +44,7 @@
 				scene.background = new THREE.Color( 0x505050 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 
 				room = new THREE.LineSegments(
 					new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ),

+ 1 - 0
examples/webvr_cubes.html

@@ -46,6 +46,7 @@
 				scene.background = new THREE.Color( 0x505050 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 				scene.add( camera );
 
 				crosshair = new THREE.Mesh(

+ 1 - 0
examples/webvr_dragging.html

@@ -42,6 +42,7 @@
 				scene.background = new THREE.Color( 0x808080 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.PlaneBufferGeometry( 4, 4 );
 				var material = new THREE.MeshStandardMaterial( {

+ 1 - 0
examples/webvr_lorenzattractor.html

@@ -82,6 +82,7 @@
 				scene = new THREE.Scene();
 
 				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 
 				//
 

+ 1 - 0
examples/webvr_multiview.html

@@ -82,6 +82,7 @@
 				scene.background = new THREE.Color( 0x505050 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 
 				room = new THREE.LineSegments(
 					new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ),

+ 1 - 0
examples/webvr_paint.html

@@ -48,6 +48,7 @@
 				scene.background = new THREE.Color( 0x222222 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 50 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.BoxBufferGeometry( 0.5, 0.8, 0.5 );
 				var material = new THREE.MeshStandardMaterial( {

+ 1 - 0
examples/webvr_panorama.html

@@ -39,6 +39,7 @@
 
 				camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 1, 1000 );
 				camera.layers.enable( 1 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 				geometry.scale( 1, 1, - 1 );

+ 136 - 0
examples/webvr_panorama_depth.html

@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webvr - panorama with depth</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
+		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 12/04/2019 -->
+		<meta http-equiv="origin-trial" content="Aq9LklhCLNUveuCr7QTpGpqwCPG817cYHdVyQuJPOZYk47iRB390lUKa5edVmgS1pZSl8HPspElEC/91Fz55dwIAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU3NTQxNzU5OX0=">
+	</head>
+	<body>
+		<div id="container"></div>
+
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webvr - panorama with depth<br />
+			Created by <a href="https://orfleisher.com" target="_blank" rel="noopener">@juniorxsound</a>. Panorama from <a href="https://krpano.com/examples/?depthmap" target="_blank" rel="noopener">krpano</a>.
+		</div>
+
+		<script src="js/vr/HelioWebXRPolyfill.js"></script>
+
+		<script type="module">
+
+			import * as THREE from '../build/three.module.js';
+			import { WEBVR } from './jsm/vr/WebVR.js';
+
+			var camera, scene, renderer, sphere, clock;
+
+			init();
+			animate();
+
+			function init() {
+
+				var container = document.getElementById( 'container' );
+
+				clock = new THREE.Clock();
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0x101010 );
+
+				var light = new THREE.AmbientLight( 0x404040, 10 );
+				scene.add( light );
+
+				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
+				scene.add( camera );
+
+				// Create the panoramic sphere geometery
+				var panoSphereGeo = new THREE.SphereBufferGeometry( 6, 256, 256 );
+
+				// Create the panoramic sphere material
+				var panoSphereMat = new THREE.MeshStandardMaterial( {
+					side: THREE.BackSide,
+					displacementScale: - 4.0
+				} );
+
+				// Create the panoramic sphere mesh
+				sphere = new THREE.Mesh( panoSphereGeo, panoSphereMat );
+
+				// Load and assign the texture and depth map
+				var manager = new THREE.LoadingManager();
+				var loader = new THREE.TextureLoader( manager );
+
+				loader.load( './textures/kandao3.jpg', function ( texture ) {
+
+					texture.minFilter = THREE.NearestFilter;
+					texture.format = THREE.RGBFormat;
+					texture.generateMipmaps = false;
+					sphere.material.map = texture;
+
+				} );
+
+				loader.load( './textures/kandao3_depthmap.jpg', function ( depth ) {
+
+					depth.minFilter = THREE.NearestFilter;
+					depth.format = THREE.RGBFormat;
+					depth.generateMipmaps = false;
+					sphere.material.displacementMap = depth;
+
+				} );
+
+				// On load complete add the panoramic sphere to the scene
+				manager.onLoad = function () {
+
+					scene.add( sphere );
+
+				};
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.vr.enabled = true;
+				container.appendChild( renderer.domElement );
+
+				document.body.appendChild( WEBVR.createButton( renderer, { referenceSpaceType: 'local' } ) );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				renderer.setAnimationLoop( render );
+
+			}
+
+			function render() {
+
+				// If we are not presenting move the camera a little so the effect is visible
+
+				if ( renderer.vr.isPresenting() === false ) {
+
+					var time = clock.getElapsedTime();
+
+					sphere.rotation.y += 0.001;
+					sphere.position.x = Math.sin( time ) * 0.2;
+					sphere.position.z = Math.cos( time ) * 0.2;
+
+				}
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 1 - 0
examples/webvr_sandbox.html

@@ -38,6 +38,7 @@
 				scene.background = background;
 
 				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.TorusKnotBufferGeometry( 0.4, 0.15, 150, 20 );
 				var material = new THREE.MeshStandardMaterial( { roughness: 0.01, metalness: 0.2, envMap: background } );

+ 1 - 0
examples/webvr_sculpt.html

@@ -44,6 +44,7 @@
 				scene.background = new THREE.Color( 0x222222 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.02, 50 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.BoxBufferGeometry( 0.5, 0.8, 0.5 );
 				var material = new THREE.MeshStandardMaterial( {

+ 1 - 0
examples/webvr_video.html

@@ -44,6 +44,7 @@
 
 				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.layers.enable( 1 ); // render left view when no stereo available
+				camera.position.set( 0, 1.6, 0 );
 
 				// video
 

+ 1 - 0
examples/webvr_vive_paint.html

@@ -51,6 +51,7 @@
 				scene.background = new THREE.Color( 0x222222 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 50 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.BoxBufferGeometry( 0.5, 0.8, 0.5 );
 				var material = new THREE.MeshStandardMaterial( {

+ 1 - 0
examples/webvr_vive_sculpt.html

@@ -46,6 +46,7 @@
 				scene.background = new THREE.Color( 0x222222 );
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 50 );
+				camera.position.set( 0, 1.6, 0 );
 
 				var geometry = new THREE.BoxBufferGeometry( 0.5, 0.8, 0.5 );
 				var material = new THREE.MeshStandardMaterial( {

+ 28 - 22
src/core/BufferAttribute.d.ts

@@ -16,54 +16,60 @@ export class BufferAttribute {
 	updateRange: { offset: number; count: number };
 	version: number;
 	normalized: boolean;
-	needsUpdate: boolean;
 	count: number;
-	onUpload: Function;
 
-	setUsage( usage: Usage ): BufferAttribute;
-	clone(): this;
+	set needsUpdate( value: boolean );
+
+	isBufferAttribute: true;
+
+	onUploadCallback: () => void;
+	onUpload( callback: () => void ): this;
+	setUsage( usage: Usage ): this;
+	clone(): BufferAttribute;
 	copy( source: BufferAttribute ): this;
 	copyAt(
 		index1: number,
 		attribute: BufferAttribute,
 		index2: number
-	): BufferAttribute;
-	copyArray( array: ArrayLike<number> ): BufferAttribute;
+	): this;
+	copyArray( array: ArrayLike<number> ): this;
 	copyColorsArray(
 		colors: { r: number; g: number; b: number }[]
-	): BufferAttribute;
-	copyVector2sArray( vectors: { x: number; y: number }[] ): BufferAttribute;
+	): this;
+	copyVector2sArray( vectors: { x: number; y: number }[] ): this;
 	copyVector3sArray(
 		vectors: { x: number; y: number; z: number }[]
-	): BufferAttribute;
+	): this;
 	copyVector4sArray(
 		vectors: { x: number; y: number; z: number; w: number }[]
-	): BufferAttribute;
+	): this;
 	set(
 		value: ArrayLike<number> | ArrayBufferView,
 		offset?: number
-	): BufferAttribute;
+	): this;
 	getX( index: number ): number;
-	setX( index: number, x: number ): BufferAttribute;
+	setX( index: number, x: number ): this;
 	getY( index: number ): number;
-	setY( index: number, y: number ): BufferAttribute;
+	setY( index: number, y: number ): this;
 	getZ( index: number ): number;
-	setZ( index: number, z: number ): BufferAttribute;
+	setZ( index: number, z: number ): this;
 	getW( index: number ): number;
-	setW( index: number, z: number ): BufferAttribute;
-	setXY( index: number, x: number, y: number ): BufferAttribute;
-	setXYZ( index: number, x: number, y: number, z: number ): BufferAttribute;
+	setW( index: number, z: number ): this;
+	setXY( index: number, x: number, y: number ): this;
+	setXYZ( index: number, x: number, y: number, z: number ): this;
 	setXYZW(
 		index: number,
 		x: number,
 		y: number,
 		z: number,
 		w: number
-	): BufferAttribute;
-	/**
-	 * @deprecated Use {@link BufferAttribute#count .count} instead.
-	 */
-	length: number;
+	): this;
+	toJSON(): {
+		itemSize: number,
+		type: string,
+		array: number[],
+		normalized: boolean
+	};
 
 }
 

+ 5 - 7
src/core/InterleavedBufferAttribute.d.ts

@@ -11,13 +11,15 @@ export class InterleavedBufferAttribute {
 		normalized?: boolean
 	);
 
-	uuid: string;
 	data: InterleavedBuffer;
 	itemSize: number;
 	offset: number;
-	count: number;
 	normalized: boolean;
-	array: any[];
+
+	get count(): number;
+	get array(): ArrayLike<number>;
+
+	isInterleavedBufferAttribute: true;
 
 	getX( index: number ): number;
 	setX( index: number, x: number ): InterleavedBufferAttribute;
@@ -41,9 +43,5 @@ export class InterleavedBufferAttribute {
 		z: number,
 		w: number
 	): InterleavedBufferAttribute;
-	/**
-	 * @deprecated Use {@link InterleavedBufferAttribute#count .count} instead.
-	 */
-	length: number;
 
 }

+ 2 - 2
src/loaders/AnimationLoader.d.ts

@@ -8,10 +8,10 @@ export class AnimationLoader extends Loader {
 
 	load(
 		url: string,
-		onLoad?: ( response: string | ArrayBuffer ) => void,
+		onLoad: ( response: AnimationClip[] ) => void,
 		onProgress?: ( request: ProgressEvent ) => void,
 		onError?: ( event: ErrorEvent ) => void
-	): any;
+	): void;
 	parse( json: any ): AnimationClip[];
 
 }

+ 3 - 3
src/loaders/AudioLoader.d.ts

@@ -7,9 +7,9 @@ export class AudioLoader extends Loader {
 
 	load(
 		url: string,
-		onLoad: Function,
-		onPrgress: Function,
-		onError: Function
+		onLoad: ( audioBuffer: AudioBuffer ) => void,
+		onProgress?: ( request: ProgressEvent ) => void,
+		onError?: ( event: ErrorEvent ) => void
 	): void;
 
 }

+ 5 - 4
src/loaders/BufferGeometryLoader.d.ts

@@ -1,6 +1,7 @@
 import { Loader } from './Loader';
 import { LoadingManager } from './LoadingManager';
 import { BufferGeometry } from './../core/BufferGeometry';
+import { InstancedBufferGeometry } from '../core/InstancedBufferGeometry';
 
 export class BufferGeometryLoader extends Loader {
 
@@ -8,10 +9,10 @@ export class BufferGeometryLoader extends Loader {
 
 	load(
 		url: string,
-		onLoad: ( bufferGeometry: BufferGeometry ) => void,
-		onProgress?: ( event: any ) => void,
-		onError?: ( event: any ) => void
+		onLoad: ( bufferGeometry: InstancedBufferGeometry | BufferGeometry ) => void,
+		onProgress?: ( request: ProgressEvent ) => void,
+		onError?: ( event: ErrorEvent ) => void
 	): void;
-	parse( json: any ): BufferGeometry;
+	parse( json: any ): InstancedBufferGeometry | BufferGeometry;
 
 }

+ 1 - 1
src/loaders/ImageBitmapLoader.d.ts

@@ -10,7 +10,7 @@ export class ImageBitmapLoader extends Loader {
 	setOptions( options: object ): ImageBitmapLoader;
 	load(
 		url: string,
-		onLoad?: ( response: string | ArrayBuffer ) => void,
+		onLoad?: ( response: ImageBitmap ) => void,
 		onProgress?: ( request: ProgressEvent ) => void,
 		onError?: ( event: ErrorEvent ) => void
 	): any;

+ 5 - 0
src/materials/Material.d.ts

@@ -293,6 +293,11 @@ export class Material extends EventDispatcher {
 	 */
 	userData: any;
 
+	/**
+	 * This starts at 0 and counts how many times .needsUpdate is set to true.
+	 */
+	version: number;
+
 	/**
 	 * Return a new material with the same parameters as this material.
 	 */

+ 10 - 1
src/materials/Material.js

@@ -74,7 +74,7 @@ function Material() {
 
 	this.userData = {};
 
-	this.needsUpdate = true;
+	this.version = 0;
 
 }
 
@@ -422,5 +422,14 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 } );
 
+Object.defineProperty( Material.prototype, 'needsUpdate', {
+
+	set: function ( value ) {
+
+		if ( value === true ) this.version ++;
+
+	}
+
+} );
 
 export { Material };

+ 3 - 0
src/objects/InstancedMesh.d.ts

@@ -17,6 +17,9 @@ export class InstancedMesh extends Mesh {
 	instanceMatrix: BufferAttribute;
 	isInstancedMesh: true;
 
+	getMatrixAt( index: number, matrix: Matrix4 ): void;
 	setMatrixAt( index: number, matrix: Matrix4 ): void;
 
+
+
 }

+ 57 - 3
src/objects/InstancedMesh.js

@@ -1,9 +1,16 @@
 /**
  * @author mrdoob / http://mrdoob.com/
  */
-
 import { BufferAttribute } from '../core/BufferAttribute.js';
 import { Mesh } from './Mesh.js';
+import { Matrix4 } from '../math/Matrix4.js';
+
+var _instanceLocalMatrix = new Matrix4();
+var _instanceWorldMatrix = new Matrix4();
+
+var _instanceIntersects = [];
+
+var _mesh = new Mesh();
 
 function InstancedMesh( geometry, material, count ) {
 
@@ -21,7 +28,52 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	isInstancedMesh: true,
 
-	raycast: function () {},
+	getMatrixAt: function ( index, matrix ) {
+
+		matrix.fromArray( this.instanceMatrix.array, index * 16 );
+
+	},
+
+	raycast: function ( raycaster, intersects ) {
+
+		var matrixWorld = this.matrixWorld;
+		var raycastTimes = this.count;
+
+		_mesh.geometry = this.geometry;
+		_mesh.material = this.material;
+
+		if ( _mesh.material === undefined ) return;
+
+		for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {
+
+			// calculate the world matrix for each instance
+
+			this.getMatrixAt( instanceId, _instanceLocalMatrix );
+
+			_instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );
+
+			// the mesh represents this single instance
+
+			_mesh.matrixWorld = _instanceWorldMatrix;
+
+			_mesh.raycast( raycaster, _instanceIntersects );
+
+			// process the result of raycast
+
+			if ( _instanceIntersects.length > 0 ) {
+
+				_instanceIntersects[ 0 ].instanceId = instanceId;
+				_instanceIntersects[ 0 ].object = this;
+
+				intersects.push( _instanceIntersects[ 0 ] );
+
+				_instanceIntersects.length = 0;
+
+			}
+
+		}
+
+	},
 
 	setMatrixAt: function ( index, matrix ) {
 
@@ -29,7 +81,9 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	},
 
-	updateMorphTargets: function () {}
+	updateMorphTargets: function () {
+
+	}
 
 } );
 

+ 12 - 4
src/renderers/WebGLRenderer.js

@@ -742,6 +742,14 @@ function WebGLRenderer( parameters ) {
 
 		var index = geometry.index;
 		var position = geometry.attributes.position;
+
+		//
+
+		if ( index !== null && index.count === 0 ) return;
+		if ( position === undefined || position.count === 0 ) return;
+
+		//
+
 		var rangeFactor = 1;
 
 		if ( material.wireframe === true ) {
@@ -1145,7 +1153,7 @@ function WebGLRenderer( parameters ) {
 
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 
-		if ( vr.enabled ) {
+		if ( vr.enabled && vr.isPresenting() ) {
 
 			camera = vr.getCamera( camera );
 
@@ -1675,7 +1683,7 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		if ( material.needsUpdate === false ) {
+		if ( material.version === materialProperties.__version ) {
 
 			if ( materialProperties.program === undefined ) {
 
@@ -1699,10 +1707,10 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		if ( material.needsUpdate ) {
+		if ( material.version !== materialProperties.__version ) {
 
 			initMaterial( material, fog, object );
-			material.needsUpdate = false;
+			materialProperties.__version = material.version;
 
 		}
 

+ 2 - 13
src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl.js

@@ -32,21 +32,10 @@ export default /* glsl */`
 		vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );
 		vec3 N = normalize( surf_norm );
 
-		#ifdef DOUBLE_SIDED
-
-			// Workaround for Adreno GPUs gl_FrontFacing bug. See #15850 and #10331
-
-			bool frontFacing = dot( cross( S, T ), N ) > 0.0;
-
-			mapN.xy *= ( float( frontFacing ) * 2.0 - 1.0 );
-
-		#else
-
-			mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
+		mat3 tsn = mat3( S, T, N );
 
-		#endif
+		mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
 
-		mat3 tsn = mat3( S, T, N );
 		return normalize( tsn * mapN );
 
 	}

+ 11 - 3
src/renderers/webgl/WebGLAttributes.d.ts

@@ -1,11 +1,19 @@
+import { BufferAttribute } from "../../core/BufferAttribute";
+import { InterleavedBufferAttribute } from "../../core/InterleavedBufferAttribute";
+
 export class WebGLAttributes {
 
 	constructor( gl: WebGLRenderingContext | WebGL2RenderingContext );
 
-	get( attribute: any ): any;
+	get( attribute: BufferAttribute | InterleavedBufferAttribute ): {
+		buffer: WebGLBuffer,
+		type: GLenum,
+		bytesPerElement: number,
+		version: number
+	};
 
-	remove( attribute: any ): void;
+	remove( attribute: BufferAttribute | InterleavedBufferAttribute ): void;
 
-	update( attribute: any, bufferType: Array<any> ): void;
+	update( attribute: BufferAttribute | InterleavedBufferAttribute, bufferType: GLenum ): void;
 
 }

+ 11 - 4
src/renderers/webgl/WebGLGeometries.d.ts

@@ -1,9 +1,16 @@
+import { WebGLAttributes } from './WebGLAttributes';
+import { WebGLInfo } from './WebGLInfo';
+import { BufferAttribute } from '../../core/BufferAttribute';
+import { BufferGeometry } from '../../core/BufferGeometry';
+import { Geometry } from '../../core/Geometry';
+import { Object3D } from '../../core/Object3D';
+
 export class WebGLGeometries {
 
-	constructor( gl: WebGLRenderingContext, attributes: any, info: any );
+	constructor( gl: WebGLRenderingContext, attributes: WebGLAttributes, info: WebGLInfo );
 
-	get( object: any, geometry: any ): any;
-	update( geometry: any ): any;
-	getWireframeAttribute( geometry: any ): any;
+	get( object: Object3D, geometry: Geometry | BufferGeometry ): BufferGeometry;
+	update( geometry: Geometry | BufferGeometry ): void;
+	getWireframeAttribute( geometry: Geometry | BufferGeometry ): BufferAttribute;
 
 }

+ 1 - 1
src/renderers/webgl/WebGLInfo.d.ts

@@ -20,7 +20,7 @@ export class WebGLInfo {
 		points: number;
 		triangles: number;
 	};
-	update( count: any, mode: any, instanceCount: any ): void;
+	update( count: number, mode: GLenum, instanceCount: number ): void;
 	reset(): void;
 
 }

+ 28 - 9
src/renderers/webvr/WebVRManager.js

@@ -104,6 +104,7 @@ function WebVRManager( renderer ) {
 	//
 
 	var triggers = [];
+	var grips = [];
 
 	function findGamepad( id ) {
 
@@ -179,6 +180,33 @@ function WebVRManager( renderer ) {
 
 				}
 
+				// Grip
+				buttonId = 2;
+
+				if ( grips[ i ] === undefined ) grips[ i ] = false;
+
+				// Skip if the grip button doesn't exist on this controller
+				if ( gamepad.buttons[ buttonId ] !== undefined ) {
+
+					if ( grips[ i ] !== gamepad.buttons[ buttonId ].pressed ) {
+
+						grips[ i ] = gamepad.buttons[ buttonId ].pressed;
+
+						if ( grips[ i ] === true ) {
+
+							controller.dispatchEvent( { type: 'squeezestart' } );
+
+						} else {
+
+							controller.dispatchEvent( { type: 'squeezeend' } );
+							controller.dispatchEvent( { type: 'squeeze' } );
+
+						}
+
+					}
+
+				}
+
 			} else {
 
 				controller.visible = false;
@@ -257,15 +285,6 @@ function WebVRManager( renderer ) {
 
 		var userHeight = referenceSpaceType === 'local-floor' ? 1.6 : 0;
 
-		if ( isPresenting() === false ) {
-
-			camera.position.set( 0, userHeight, 0 );
-			camera.rotation.set( 0, 0, 0 );
-
-			return camera;
-
-		}
-
 		device.depthNear = camera.near;
 		device.depthFar = camera.far;
 

+ 17 - 20
src/renderers/webvr/WebXRManager.js

@@ -133,6 +133,9 @@ function WebXRManager( renderer, gl ) {
 			session.addEventListener( 'select', onSessionEvent );
 			session.addEventListener( 'selectstart', onSessionEvent );
 			session.addEventListener( 'selectend', onSessionEvent );
+			session.addEventListener( 'squeeze', onSessionEvent );
+			session.addEventListener( 'squeezestart', onSessionEvent );
+			session.addEventListener( 'squeezeend', onSessionEvent );
 			session.addEventListener( 'end', onSessionEnd );
 
 			// eslint-disable-next-line no-undef
@@ -196,38 +199,32 @@ function WebXRManager( renderer, gl ) {
 
 	this.getCamera = function ( camera ) {
 
-		if ( isPresenting() ) {
+		var parent = camera.parent;
+		var cameras = cameraVR.cameras;
 
-			var parent = camera.parent;
-			var cameras = cameraVR.cameras;
+		updateCamera( cameraVR, parent );
 
-			updateCamera( cameraVR, parent );
+		for ( var i = 0; i < cameras.length; i ++ ) {
 
-			for ( var i = 0; i < cameras.length; i ++ ) {
+			updateCamera( cameras[ i ], parent );
 
-				updateCamera( cameras[ i ], parent );
-
-			}
-
-			// update camera and its children
-
-			camera.matrixWorld.copy( cameraVR.matrixWorld );
-
-			var children = camera.children;
+		}
 
-			for ( var i = 0, l = children.length; i < l; i ++ ) {
+		// update camera and its children
 
-				children[ i ].updateMatrixWorld( true );
+		camera.matrixWorld.copy( cameraVR.matrixWorld );
 
-			}
+		var children = camera.children;
 
-			setProjectionFromUnion( cameraVR, cameraL, cameraR );
+		for ( var i = 0, l = children.length; i < l; i ++ ) {
 
-			return cameraVR;
+			children[ i ].updateMatrixWorld( true );
 
 		}
 
-		return camera;
+		setProjectionFromUnion( cameraVR, cameraL, cameraR );
+
+		return cameraVR;
 
 	};
 

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor