Browse Source

Raycaster: Add Interpolated Normals (#25566)

* Add Interpolated Normals to Raycast

* Restore getUV as an alias for getInterpolation

* Update src/math/Triangle.js

Co-authored-by: Levi Pesin <[email protected]>

* Make calling pattern consistent

* Deprecate getUV

* What do we think of this?

---------

Co-authored-by: Levi Pesin <[email protected]>
Johnathon Selstad 2 years ago
parent
commit
efb62812c5

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

@@ -177,6 +177,7 @@
 			[page:Object3D object] – the intersected object<br />
 			[page:Object3D object] – the intersected object<br />
 			[page:Vector2 uv] - U,V coordinates at point of intersection<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<br />
 			[page:Vector2 uv2] - Second set of U,V coordinates at point of intersection<br />
+			[page:Vector3 normal] - interpolated normal vector at point of intersection<br />
 			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 		</p>
 		</p>
 		<p>
 		<p>

+ 6 - 6
docs/api/en/math/Triangle.html

@@ -113,15 +113,15 @@
 		Calculate a [page:Plane plane] based on the triangle. .
 		Calculate a [page:Plane plane] based on the triangle. .
 		</p>
 		</p>
 
 
-		<h3>[method:Vector2 getUV]( [param:Vector3 point], [param:Vector2 uv1], [param:Vector2 uv2], [param:Vector2 uv3], [param:Vector2 target] )</h3>
+		<h3>[method:Vector2 getInterpolation]( [param:Vector3 point], [param:Vector2 v1] | [param:Vector3 v1] | [param:Vector4 v1], [param:Vector2 v2] | [param:Vector3 v2] | [param:Vector4 v3], [param:Vector2 v3] | [param:Vector3 v3] | [param:Vector4 v3], [param:Vector2 target] )</h3>
 		<p>
 		<p>
 		[page:Vector3 point] - The point on the triangle.<br />
 		[page:Vector3 point] - The point on the triangle.<br />
-		[page:Vector2 uv1] - The uv coordinate of the triangle's first vertex.<br />
-		[page:Vector2 uv2] - The uv coordinate of the triangle's second vertex.<br />
-		[page:Vector2 uv3] - The uv coordinate of the triangle's third vertex.<br />
-		[page:Vector2 target] — the result will be copied into this Vector2.<br /><br />
+		[page:Vector2 v1] - The value of the triangle's first vertex.<br />
+		[page:Vector2 v2] - The value of the triangle's second vertex.<br />
+		[page:Vector2 v3] - The value of the triangle's third vertex.<br />
+		[page:Vector2 target] — the result will be copied into this Vector.<br /><br />
 
 
-		Returns the uv coordinates for the given point on the triangle.
+		Returns the value barycentrically interpolated for the given point on the triangle.
 		</p>
 		</p>
 
 
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>

+ 1 - 0
docs/api/it/core/Raycaster.html

@@ -179,6 +179,7 @@
 			[page:Object3D object] – l'oggetto intersecato<br />
 			[page:Object3D object] – l'oggetto intersecato<br />
 			[page:Vector2 uv] - le coordinate U,V nel punto di intersezione<br />
 			[page:Vector2 uv] - le coordinate U,V nel punto di intersezione<br />
 			[page:Vector2 uv2] - Secondo insieme delle coordinate U,V nel punto di intersezione<br />
 			[page:Vector2 uv2] - Secondo insieme delle coordinate U,V nel punto di intersezione<br />
+			[page:Vector3 normal] - vettore normale interpolato nel punto di intersezione<br />
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 		</p>
 		</p>
 		<p>
 		<p>

+ 6 - 6
docs/api/it/math/Triangle.html

@@ -111,15 +111,15 @@
 		Calcola il [page:Plane piano] in base al triangolo.
 		Calcola il [page:Plane piano] in base al triangolo.
 		</p>
 		</p>
 
 
-		<h3>[method:Vector2 getUV]( [param:Vector3 point], [param:Vector2 uv1], [param:Vector2 uv2], [param:Vector2 uv3], [param:Vector2 target] )</h3>
+		<h3>[method:Vector2 getInterpolation]( [param:Vector3 point], [param:Vector2 v1] | [param:Vector3 v1] | [param:Vector4 v1], [param:Vector2 v2] | [param:Vector3 v2] | [param:Vector4 v3], [param:Vector2 v3] | [param:Vector3 v3] | [param:Vector4 v3], [param:Vector2 target] )</h3>
 		<p>
 		<p>
 		[page:Vector3 point] - Il punto sul triangolo.<br />
 		[page:Vector3 point] - Il punto sul triangolo.<br />
-		[page:Vector2 uv1] - La coordinata uv del primo vertice del triangolo.<br />
-		[page:Vector2 uv2] - La coordinata uv del secondo vertice del triangolo.<br />
-		[page:Vector2 uv3] - La coordinata uv del terzo vertice del triangolo.<br />
-		[page:Vector2 target] — il risultato sarà copiato in questo Vector2.<br /><br />
+		[page:Vector2 v1] - La valore del primo vertice del triangolo.<br />
+		[page:Vector2 v2] - La valore del secondo vertice del triangolo.<br />
+		[page:Vector2 v3] - La valore del terzo vertice del triangolo.<br />
+		[page:Vector2 target] — il risultato sarà copiato in questo Vector.<br /><br />
 
 
-		Restituisce le coordinate uv per il punto specificato sul triangolo.
+		Restituisce le valore interpolato baricentricamente per il punto specificato sul triangolo.
 		</p>
 		</p>
 
 
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>

+ 1 - 0
docs/api/ko/core/Raycaster.html

@@ -175,6 +175,7 @@
 			[page:Object3D object] – 교차된 객체<br />
 			[page:Object3D object] – 교차된 객체<br />
 			[page:Vector2 uv] - 교차점의 U,V 좌표<br />
 			[page:Vector2 uv] - 교차점의 U,V 좌표<br />
 			[page:Vector2 uv2] - 교차점의 U,V 2차 좌표<br />
 			[page:Vector2 uv2] - 교차점의 U,V 2차 좌표<br />
+			[page:Vector3 normal] - 교차점에서 보간된 법선 벡터<br />
 			[page:Integer instanceId] – InstancedMesh에 교차하는 레이의 인스턴스 인덱스 넘버입니다.
 			[page:Integer instanceId] – InstancedMesh에 교차하는 레이의 인스턴스 인덱스 넘버입니다.
 		</p>
 		</p>
 		<p>
 		<p>

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

@@ -180,6 +180,7 @@
 			[page:Object3D object] —— 相交的物体<br />
 			[page:Object3D object] —— 相交的物体<br />
 			[page:Vector2 uv] —— 相交部分的点的UV坐标。<br />
 			[page:Vector2 uv] —— 相交部分的点的UV坐标。<br />
 			[page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection<br />
 			[page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection<br />
+			[page:Vector3 normal] - 交点处的内插法向量<br />
 			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 			[page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh
 		</p>
 		</p>
 		<p>
 		<p>

+ 21 - 5
src/math/Triangle.js

@@ -83,12 +83,20 @@ class Triangle {
 
 
 	static getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) {
 	static getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) {
 
 
+		console.warn( 'THREE.Triangle.getUV() has been renamed to THREE.Triangle.getInterpolation().' );
+
+		return this.getInterpolation( point, p1, p2, p3, uv1, uv2, uv3, target );
+
+	}
+
+	static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) {
+
 		this.getBarycoord( point, p1, p2, p3, _v3 );
 		this.getBarycoord( point, p1, p2, p3, _v3 );
 
 
-		target.set( 0, 0 );
-		target.addScaledVector( uv1, _v3.x );
-		target.addScaledVector( uv2, _v3.y );
-		target.addScaledVector( uv3, _v3.z );
+		target.setScalar( 0 );
+		target.addScaledVector( v1, _v3.x );
+		target.addScaledVector( v2, _v3.y );
+		target.addScaledVector( v3, _v3.z );
 
 
 		return target;
 		return target;
 
 
@@ -185,7 +193,15 @@ class Triangle {
 
 
 	getUV( point, uv1, uv2, uv3, target ) {
 	getUV( point, uv1, uv2, uv3, target ) {
 
 
-		return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
+		console.warn( 'Triangle.getUV() has been renamed to Triangle.getInterpolation().' );
+
+		return Triangle.getInterpolation( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
+
+	}
+
+	getInterpolation( point, v1, v2, v3, target ) {
+
+		return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target );
 
 
 	}
 	}
 
 

+ 28 - 7
src/objects/Mesh.js

@@ -25,6 +25,10 @@ const _uvA = /*@__PURE__*/ new Vector2();
 const _uvB = /*@__PURE__*/ new Vector2();
 const _uvB = /*@__PURE__*/ new Vector2();
 const _uvC = /*@__PURE__*/ new Vector2();
 const _uvC = /*@__PURE__*/ new Vector2();
 
 
+const _normalA = /*@__PURE__*/ new Vector3();
+const _normalB = /*@__PURE__*/ new Vector3();
+const _normalC = /*@__PURE__*/ new Vector3();
+
 const _intersectionPoint = /*@__PURE__*/ new Vector3();
 const _intersectionPoint = /*@__PURE__*/ new Vector3();
 const _intersectionPointWorld = /*@__PURE__*/ new Vector3();
 const _intersectionPointWorld = /*@__PURE__*/ new Vector3();
 
 
@@ -193,6 +197,7 @@ class Mesh extends Object3D {
 		const position = geometry.attributes.position;
 		const position = geometry.attributes.position;
 		const uv = geometry.attributes.uv;
 		const uv = geometry.attributes.uv;
 		const uv2 = geometry.attributes.uv2;
 		const uv2 = geometry.attributes.uv2;
+		const normal = geometry.attributes.normal;
 		const groups = geometry.groups;
 		const groups = geometry.groups;
 		const drawRange = geometry.drawRange;
 		const drawRange = geometry.drawRange;
 
 
@@ -216,7 +221,7 @@ class Mesh extends Object3D {
 						const b = index.getX( j + 1 );
 						const b = index.getX( j + 1 );
 						const c = index.getX( j + 2 );
 						const c = index.getX( j + 2 );
 
 
-						intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv2, a, b, c );
+						intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv2, normal, a, b, c );
 
 
 						if ( intersection ) {
 						if ( intersection ) {
 
 
@@ -241,7 +246,7 @@ class Mesh extends Object3D {
 					const b = index.getX( i + 1 );
 					const b = index.getX( i + 1 );
 					const c = index.getX( i + 2 );
 					const c = index.getX( i + 2 );
 
 
-					intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, uv, uv2, a, b, c );
+					intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, uv, uv2, normal, a, b, c );
 
 
 					if ( intersection ) {
 					if ( intersection ) {
 
 
@@ -274,7 +279,7 @@ class Mesh extends Object3D {
 						const b = j + 1;
 						const b = j + 1;
 						const c = j + 2;
 						const c = j + 2;
 
 
-						intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv2, a, b, c );
+						intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv2, normal, a, b, c );
 
 
 						if ( intersection ) {
 						if ( intersection ) {
 
 
@@ -299,7 +304,7 @@ class Mesh extends Object3D {
 					const b = i + 1;
 					const b = i + 1;
 					const c = i + 2;
 					const c = i + 2;
 
 
-					intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, uv, uv2, a, b, c );
+					intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, uv, uv2, normal, a, b, c );
 
 
 					if ( intersection ) {
 					if ( intersection ) {
 
 
@@ -349,7 +354,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point
 
 
 }
 }
 
 
-function checkBufferGeometryIntersection( object, material, raycaster, ray, uv, uv2, a, b, c ) {
+function checkBufferGeometryIntersection( object, material, raycaster, ray, uv, uv2, normal, a, b, c ) {
 
 
 	object.getVertexPosition( a, _vA );
 	object.getVertexPosition( a, _vA );
 	object.getVertexPosition( b, _vB );
 	object.getVertexPosition( b, _vB );
@@ -365,7 +370,7 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, uv,
 			_uvB.fromBufferAttribute( uv, b );
 			_uvB.fromBufferAttribute( uv, b );
 			_uvC.fromBufferAttribute( uv, c );
 			_uvC.fromBufferAttribute( uv, c );
 
 
-			intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
+			intersection.uv = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
 
 
 		}
 		}
 
 
@@ -375,7 +380,23 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, uv,
 			_uvB.fromBufferAttribute( uv2, b );
 			_uvB.fromBufferAttribute( uv2, b );
 			_uvC.fromBufferAttribute( uv2, c );
 			_uvC.fromBufferAttribute( uv2, c );
 
 
-			intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
+			intersection.uv2 = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
+
+		}
+
+		if ( normal ) {
+
+			_normalA.fromBufferAttribute( normal, a );
+			_normalB.fromBufferAttribute( normal, b );
+			_normalC.fromBufferAttribute( normal, c );
+
+			intersection.normal = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, new Vector3() );
+
+			if ( intersection.normal.dot( ray.direction ) > 0 ) {
+
+				intersection.normal.multiplyScalar( - 1 );
+
+			}
 
 
 		}
 		}
 
 

+ 1 - 1
src/objects/Sprite.js

@@ -129,7 +129,7 @@ class Sprite extends Object3D {
 
 
 			distance: distance,
 			distance: distance,
 			point: _intersectPoint.clone(),
 			point: _intersectPoint.clone(),
-			uv: Triangle.getUV( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ),
+			uv: Triangle.getInterpolation( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ),
 			face: null,
 			face: null,
 			object: this
 			object: this