Sfoglia il codice sorgente

USDComposer: Add light support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mr.doob 2 mesi fa
parent
commit
a158b85f4e
1 ha cambiato i file con 130 aggiunte e 0 eliminazioni
  1. 130 0
      examples/jsm/loaders/usd/USDComposer.js

+ 130 - 0
examples/jsm/loaders/usd/USDComposer.js

@@ -5,8 +5,10 @@ import {
 	BufferGeometry,
 	CapsuleGeometry,
 	ClampToEdgeWrapping,
+	Color,
 	ConeGeometry,
 	CylinderGeometry,
+	DirectionalLight,
 	Euler,
 	Group,
 	Matrix4,
@@ -17,14 +19,17 @@ import {
 	Object3D,
 	OrthographicCamera,
 	PerspectiveCamera,
+	PointLight,
 	Quaternion,
 	QuaternionKeyframeTrack,
+	RectAreaLight,
 	RepeatWrapping,
 	ShapeUtils,
 	SkinnedMesh,
 	Skeleton,
 	Bone,
 	SphereGeometry,
+	SpotLight,
 	SRGBColorSpace,
 	Texture,
 	Vector2,
@@ -725,6 +730,15 @@ class USDComposer {
 				parent.add( obj );
 				this._buildHierarchy( obj, path );
 
+			} else if ( typeName === 'DistantLight' || typeName === 'SphereLight' || typeName === 'RectLight' || typeName === 'DiskLight' ) {
+
+				const obj = this._buildLight( path, typeName );
+				obj.name = name;
+				const attrs = this._getAttributes( path );
+				this.applyTransform( obj, spec.fields, attrs );
+				parent.add( obj );
+				this._buildHierarchy( obj, path );
+
 			} else if ( typeName === 'Cube' || typeName === 'Sphere' || typeName === 'Cylinder' || typeName === 'Cone' || typeName === 'Capsule' ) {
 
 				const obj = this._buildGeomPrimitive( path, spec, typeName );
@@ -1435,6 +1449,122 @@ class USDComposer {
 
 	}
 
+	/**
+	 * Build a light from a UsdLux light spec.
+	 */
+	_buildLight( path, typeName ) {
+
+		const attrs = this._getAttributes( path );
+
+		const intensity = this._parseNumber( attrs[ 'inputs:intensity' ], 1 );
+		const baseColor = attrs[ 'inputs:color' ] || [ 1, 1, 1 ];
+		const enableColorTemperature = attrs[ 'inputs:enableColorTemperature' ] === true;
+		const colorTemperature = this._parseNumber( attrs[ 'inputs:colorTemperature' ], 6500 );
+
+		const color = new Color( baseColor[ 0 ], baseColor[ 1 ], baseColor[ 2 ] );
+
+		if ( enableColorTemperature ) {
+
+			const temp = this._colorTemperature( colorTemperature );
+			color.multiply( temp );
+
+		}
+
+		let light;
+
+		switch ( typeName ) {
+
+			case 'DistantLight':
+				light = new DirectionalLight( color, intensity );
+				break;
+
+			case 'SphereLight': {
+
+				const coneAngle = this._parseNumber( attrs[ 'shaping:cone:angle' ], 0 );
+
+				if ( coneAngle > 0 ) {
+
+					const angle = coneAngle * Math.PI / 180;
+					const softness = this._parseNumber( attrs[ 'shaping:cone:softness' ], 0 );
+					light = new SpotLight( color, intensity, 0, angle, softness );
+
+				} else {
+
+					light = new PointLight( color, intensity );
+
+				}
+
+				break;
+
+			}
+
+			case 'RectLight': {
+
+				const width = this._parseNumber( attrs[ 'inputs:width' ], 1 );
+				const height = this._parseNumber( attrs[ 'inputs:height' ], 1 );
+				light = new RectAreaLight( color, intensity, width, height );
+				break;
+
+			}
+
+			case 'DiskLight': {
+
+				const radius = this._parseNumber( attrs[ 'inputs:radius' ], 0.5 );
+				const side = radius * 2;
+				light = new RectAreaLight( color, intensity, side, side );
+				break;
+
+			}
+
+		}
+
+		return light;
+
+	}
+
+	/**
+	 * Convert a color temperature in Kelvin to an RGB Color.
+	 * Based on Tanner Helland's algorithm.
+	 */
+	_colorTemperature( kelvin ) {
+
+		const temp = kelvin / 100;
+		let r, g, b;
+
+		if ( temp <= 66 ) {
+
+			r = 1;
+			g = 0.39008157876901960784 * Math.log( temp ) - 0.63184144378862745098;
+
+		} else {
+
+			r = 1.29293618606274509804 * Math.pow( temp - 60, - 0.1332047592 );
+			g = 1.12989086089529411765 * Math.pow( temp - 60, - 0.0755148492 );
+
+		}
+
+		if ( temp >= 66 ) {
+
+			b = 1;
+
+		} else if ( temp <= 19 ) {
+
+			b = 0;
+
+		} else {
+
+			b = 0.54320678911019607843 * Math.log( temp - 10 ) - 1.19625408914;
+
+		}
+
+		return new Color(
+			Math.min( Math.max( r, 0 ), 1 ),
+			Math.min( Math.max( g, 0 ), 1 ),
+			Math.min( Math.max( b, 0 ), 1 )
+		);
+
+	}
+
 	_parseNumber( value, fallback ) {
 
 		const n = Number( value );

粤ICP备19079148号