Browse Source

Updated examples builds.

Mr.doob 3 years ago
parent
commit
766ffc58de

+ 26 - 1
examples/js/interactive/SelectionBox.js

@@ -34,6 +34,12 @@
 
 	const _vectemp3 = new THREE.Vector3();
 
+	const _matrix = new THREE.Matrix4();
+
+	const _quaternion = new THREE.Quaternion();
+
+	const _scale = new THREE.Vector3();
+
 	class SelectionBox {
 
 		constructor( camera, scene, deep = Number.MAX_VALUE ) {
@@ -43,6 +49,7 @@
 			this.startPoint = new THREE.Vector3();
 			this.endPoint = new THREE.Vector3();
 			this.collection = [];
+			this.instances = {};
 			this.deep = deep;
 
 		}
@@ -198,7 +205,25 @@
 
 			if ( object.isMesh || object.isLine || object.isPoints ) {
 
-				if ( object.material !== undefined ) {
+				if ( object.isInstancedMesh ) {
+
+					this.instances[ object.uuid ] = [];
+
+					for ( let instanceId = 0; instanceId < object.count; instanceId ++ ) {
+
+						object.getMatrixAt( instanceId, _matrix );
+
+						_matrix.decompose( _center, _quaternion, _scale );
+
+						if ( frustum.containsPoint( _center ) ) {
+
+							this.instances[ object.uuid ].push( instanceId );
+
+						}
+
+					}
+
+				} else {
 
 					if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere();
 

+ 207 - 57
examples/js/lines/LineMaterial.js

@@ -7,13 +7,14 @@
  *  dashed: <boolean>,
  *  dashScale: <float>,
  *  dashSize: <float>,
- *  dashOffset: <float>,
  *  gapSize: <float>,
  *  resolution: <Vector2>, // to be set by renderer
  * }
  */
-
 	THREE.UniformsLib.line = {
+		worldUnits: {
+			value: 1
+		},
 		linewidth: {
 			value: 1
 		},
@@ -26,16 +27,10 @@
 		dashSize: {
 			value: 1
 		},
-		dashOffset: {
-			value: 0
-		},
 		gapSize: {
 			value: 1
-		},
-		// todo FIX - maybe change to totalSize
-		opacity: {
-			value: 1
-		}
+		} // todo FIX - maybe change to totalSize
+
 	};
 	THREE.ShaderLib[ 'line' ] = {
 		uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.fog, THREE.UniformsLib.line ] ),
@@ -58,6 +53,9 @@
 		attribute vec3 instanceColorEnd;
 
 		varying vec2 vUv;
+		varying vec4 worldPos;
+		varying vec3 worldStart;
+		varying vec3 worldEnd;
 
 		#ifdef USE_DASH
 
@@ -105,6 +103,9 @@
 			vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
 			vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
 
+			worldStart = start.xyz;
+			worldEnd = end.xyz;
+
 			// special case for perspective projection, and segments that terminate either in, or behind, the camera plane
 			// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
 			// but we need to perform ndc-space calculations in the shader, so we must address this issue directly
@@ -131,50 +132,108 @@
 			vec4 clipEnd = projectionMatrix * end;
 
 			// ndc space
-			vec2 ndcStart = clipStart.xy / clipStart.w;
-			vec2 ndcEnd = clipEnd.xy / clipEnd.w;
+			vec3 ndcStart = clipStart.xyz / clipStart.w;
+			vec3 ndcEnd = clipEnd.xyz / clipEnd.w;
 
 			// direction
-			vec2 dir = ndcEnd - ndcStart;
+			vec2 dir = ndcEnd.xy - ndcStart.xy;
 
 			// account for clip-space aspect ratio
 			dir.x *= aspect;
 			dir = normalize( dir );
 
-			// perpendicular to dir
-			vec2 offset = vec2( dir.y, - dir.x );
+			#ifdef WORLD_UNITS
 
-			// undo aspect ratio adjustment
-			dir.x /= aspect;
-			offset.x /= aspect;
+				// get the offset direction as perpendicular to the view vector
+				vec3 worldDir = normalize( end.xyz - start.xyz );
+				vec3 offset;
+				if ( position.y < 0.5 ) {
 
-			// sign flip
-			if ( position.x < 0.0 ) offset *= - 1.0;
+					offset = normalize( cross( start.xyz, worldDir ) );
 
-			// endcaps
-			if ( position.y < 0.0 ) {
+				} else {
 
-				offset += - dir;
+					offset = normalize( cross( end.xyz, worldDir ) );
 
-			} else if ( position.y > 1.0 ) {
+				}
 
-				offset += dir;
+				// sign flip
+				if ( position.x < 0.0 ) offset *= - 1.0;
 
-			}
+				float forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );
 
-			// adjust for linewidth
-			offset *= linewidth;
+				// don't extend the line if we're rendering dashes because we
+				// won't be rendering the endcaps
+				#ifndef USE_DASH
 
-			// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
-			offset /= resolution.y;
+					// extend the line bounds to encompass  endcaps
+					start.xyz += - worldDir * linewidth * 0.5;
+					end.xyz += worldDir * linewidth * 0.5;
 
-			// select end
-			vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
+					// shift the position of the quad so it hugs the forward edge of the line
+					offset.xy -= dir * forwardOffset;
+					offset.z += 0.5;
+
+				#endif
+
+				// endcaps
+				if ( position.y > 1.0 || position.y < 0.0 ) {
+
+					offset.xy += dir * 2.0 * forwardOffset;
+
+				}
+
+				// adjust for linewidth
+				offset *= linewidth * 0.5;
+
+				// set the world position
+				worldPos = ( position.y < 0.5 ) ? start : end;
+				worldPos.xyz += offset;
+
+				// project the worldpos
+				vec4 clip = projectionMatrix * worldPos;
+
+				// shift the depth of the projected points so the line
+				// segements overlap neatly
+				vec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;
+				clip.z = clipPose.z * clip.w;
+
+			#else
 
-			// back to clip space
-			offset *= clip.w;
+				vec2 offset = vec2( dir.y, - dir.x );
+				// undo aspect ratio adjustment
+				dir.x /= aspect;
+				offset.x /= aspect;
 
-			clip.xy += offset;
+				// sign flip
+				if ( position.x < 0.0 ) offset *= - 1.0;
+
+				// endcaps
+				if ( position.y < 0.0 ) {
+
+					offset += - dir;
+
+				} else if ( position.y > 1.0 ) {
+
+					offset += dir;
+
+				}
+
+				// adjust for linewidth
+				offset *= linewidth;
+
+				// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
+				offset /= resolution.y;
+
+				// select end
+				vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
+
+				// back to clip space
+				offset *= clip.w;
+
+				clip.xy += offset;
+
+			#endif
 
 			gl_Position = clip;
 
@@ -184,22 +243,26 @@
 			#include <clipping_planes_vertex>
 			#include <fog_vertex>
 
-		}`,
+		}
+		`,
 		fragmentShader:
   /* glsl */
   `
 		uniform vec3 diffuse;
 		uniform float opacity;
+		uniform float linewidth;
 
 		#ifdef USE_DASH
 
 			uniform float dashSize;
-			uniform float dashOffset;
 			uniform float gapSize;
 
 		#endif
 
 		varying float vLineDistance;
+		varying vec4 worldPos;
+		varying vec3 worldStart;
+		varying vec3 worldEnd;
 
 		#include <common>
 		#include <color_pars_fragment>
@@ -209,6 +272,35 @@
 
 		varying vec2 vUv;
 
+		vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
+
+			float mua;
+			float mub;
+
+			vec3 p13 = p1 - p3;
+			vec3 p43 = p4 - p3;
+
+			vec3 p21 = p2 - p1;
+
+			float d1343 = dot( p13, p43 );
+			float d4321 = dot( p43, p21 );
+			float d1321 = dot( p13, p21 );
+			float d4343 = dot( p43, p43 );
+			float d2121 = dot( p21, p21 );
+
+			float denom = d2121 * d4343 - d4321 * d4321;
+
+			float numer = d1343 * d4321 - d1321 * d4343;
+
+			mua = numer / denom;
+			mua = clamp( mua, 0.0, 1.0 );
+			mub = ( d1343 + d4321 * ( mua ) ) / d4343;
+			mub = clamp( mub, 0.0, 1.0 );
+
+			return vec2( mua, mub );
+
+		}
+
 		void main() {
 
 			#include <clipping_planes_fragment>
@@ -217,53 +309,90 @@
 
 				if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
 
-				if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
+				if ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
 
 			#endif
 
-			float alpha = 1.0;
+			float alpha = opacity;
 
-			#ifdef ALPHA_TO_COVERAGE
+			#ifdef WORLD_UNITS
 
-			// artifacts appear on some hardware if a derivative is taken within a conditional
-			float a = vUv.x;
-			float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
-			float len2 = a * a + b * b;
-			float dlen = fwidth( len2 );
+				// Find the closest points on the view ray and the line segment
+				vec3 rayEnd = normalize( worldPos.xyz ) * 1e5;
+				vec3 lineDir = worldEnd - worldStart;
+				vec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );
 
-			if ( abs( vUv.y ) > 1.0 ) {
+				vec3 p1 = worldStart + lineDir * params.x;
+				vec3 p2 = rayEnd * params.y;
+				vec3 delta = p1 - p2;
+				float len = length( delta );
+				float norm = len / linewidth;
 
-				alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
+				#ifndef USE_DASH
 
-			}
+					#ifdef ALPHA_TO_COVERAGE
+
+						float dnorm = fwidth( norm );
+						alpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );
+
+					#else
+
+						if ( norm > 0.5 ) {
+
+							discard;
+
+						}
+
+					#endif
+
+				#endif
 
 			#else
 
-			if ( abs( vUv.y ) > 1.0 ) {
+				#ifdef ALPHA_TO_COVERAGE
 
-				float a = vUv.x;
-				float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
-				float len2 = a * a + b * b;
+					// artifacts appear on some hardware if a derivative is taken within a conditional
+					float a = vUv.x;
+					float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
+					float len2 = a * a + b * b;
+					float dlen = fwidth( len2 );
 
-				if ( len2 > 1.0 ) discard;
+					if ( abs( vUv.y ) > 1.0 ) {
 
-			}
+						alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
+
+					}
+
+				#else
+
+					if ( abs( vUv.y ) > 1.0 ) {
+
+						float a = vUv.x;
+						float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
+						float len2 = a * a + b * b;
+
+						if ( len2 > 1.0 ) discard;
+
+					}
+
+				#endif
 
 			#endif
 
-			vec4 diffuseColor = vec4( diffuse, opacity * alpha );
+			vec4 diffuseColor = vec4( diffuse, alpha );
 
 			#include <logdepthbuf_fragment>
 			#include <color_fragment>
 
-			gl_FragColor = diffuseColor;
+			gl_FragColor = vec4( diffuseColor.rgb, alpha );
 
 			#include <tonemapping_fragment>
 			#include <encodings_fragment>
 			#include <fog_fragment>
 			#include <premultiplied_alpha_fragment>
 
-		}`
+		}
+		`
 	};
 
 	class LineMaterial extends THREE.ShaderMaterial {
@@ -292,6 +421,27 @@
 
 					}
 				},
+				worldUnits: {
+					enumerable: true,
+					get: function () {
+
+						return 'WORLD_UNITS' in this.defines;
+
+					},
+					set: function ( value ) {
+
+						if ( value === true ) {
+
+							this.defines.WORLD_UNITS = '';
+
+						} else {
+
+							delete this.defines.WORLD_UNITS;
+
+						}
+
+					}
+				},
 				linewidth: {
 					enumerable: true,
 					get: function () {

+ 1 - 0
examples/js/loaders/GLTFLoader.js

@@ -2819,6 +2819,7 @@
 
 			} else {
 
+				materialParams.format = THREE.RGBFormat;
 				materialParams.transparent = false;
 
 				if ( alphaMode === ALPHA_MODES.MASK ) {