Просмотр исходного кода

LDrawLoader: Add WebGPU support. (#29752)

* LDrawLoader: Add WebGPU support.

* LDrawLoader: Improve error handling.

* LDrawLoader: Clean up.

* Update Addons.js
Michael Herzog 1 год назад
Родитель
Сommit
d067dfd7f5

+ 2 - 0
examples/jsm/Addons.js

@@ -129,6 +129,8 @@ export * from './loaders/VTKLoader.js';
 export * from './loaders/XYZLoader.js';
 
 export * from './materials/MeshGouraudMaterial.js';
+export * from './materials/LDrawConditionalLineMaterial.js';
+export * from './materials/MeshPostProcessingMaterial.js';
 
 export * from './math/Capsule.js';
 export * from './math/ColorConverter.js';

+ 22 - 142
examples/jsm/loaders/LDrawLoader.js

@@ -10,10 +10,7 @@ import {
 	Matrix4,
 	Mesh,
 	MeshStandardMaterial,
-	ShaderMaterial,
 	SRGBColorSpace,
-	UniformsLib,
-	UniformsUtils,
 	Vector3,
 	Ray
 } from 'three';
@@ -45,140 +42,6 @@ const COLOR_SPACE_LDRAW = SRGBColorSpace;
 const _tempVec0 = new Vector3();
 const _tempVec1 = new Vector3();
 
-class LDrawConditionalLineMaterial extends ShaderMaterial {
-
-	static get type() {
-
-		return 'LDrawConditionalLineMaterial';
-
-	}
-
-	constructor( parameters ) {
-
-		super( {
-
-			uniforms: UniformsUtils.merge( [
-				UniformsLib.fog,
-				{
-					diffuse: {
-						value: new Color()
-					},
-					opacity: {
-						value: 1.0
-					}
-				}
-			] ),
-
-			vertexShader: /* glsl */`
-				attribute vec3 control0;
-				attribute vec3 control1;
-				attribute vec3 direction;
-				varying float discardFlag;
-
-				#include <common>
-				#include <color_pars_vertex>
-				#include <fog_pars_vertex>
-				#include <logdepthbuf_pars_vertex>
-				#include <clipping_planes_pars_vertex>
-				void main() {
-					#include <color_vertex>
-
-					vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
-					gl_Position = projectionMatrix * mvPosition;
-
-					// Transform the line segment ends and control points into camera clip space
-					vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
-					vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
-					vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-					vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
-
-					c0.xy /= c0.w;
-					c1.xy /= c1.w;
-					p0.xy /= p0.w;
-					p1.xy /= p1.w;
-
-					// Get the direction of the segment and an orthogonal vector
-					vec2 dir = p1.xy - p0.xy;
-					vec2 norm = vec2( -dir.y, dir.x );
-
-					// Get control point directions from the line
-					vec2 c0dir = c0.xy - p1.xy;
-					vec2 c1dir = c1.xy - p1.xy;
-
-					// If the vectors to the controls points are pointed in different directions away
-					// from the line segment then the line should not be drawn.
-					float d0 = dot( normalize( norm ), normalize( c0dir ) );
-					float d1 = dot( normalize( norm ), normalize( c1dir ) );
-					discardFlag = float( sign( d0 ) != sign( d1 ) );
-
-					#include <logdepthbuf_vertex>
-					#include <clipping_planes_vertex>
-					#include <fog_vertex>
-				}
-			`,
-
-			fragmentShader: /* glsl */`
-			uniform vec3 diffuse;
-			uniform float opacity;
-			varying float discardFlag;
-
-			#include <common>
-			#include <color_pars_fragment>
-			#include <fog_pars_fragment>
-			#include <logdepthbuf_pars_fragment>
-			#include <clipping_planes_pars_fragment>
-			void main() {
-
-				if ( discardFlag > 0.5 ) discard;
-
-				#include <clipping_planes_fragment>
-				vec3 outgoingLight = vec3( 0.0 );
-				vec4 diffuseColor = vec4( diffuse, opacity );
-				#include <logdepthbuf_fragment>
-				#include <color_fragment>
-				outgoingLight = diffuseColor.rgb; // simple shader
-				gl_FragColor = vec4( outgoingLight, diffuseColor.a );
-				#include <tonemapping_fragment>
-				#include <colorspace_fragment>
-				#include <fog_fragment>
-				#include <premultiplied_alpha_fragment>
-			}
-			`,
-
-		} );
-
-		Object.defineProperties( this, {
-
-			opacity: {
-				get: function () {
-
-					return this.uniforms.opacity.value;
-
-				},
-
-				set: function ( value ) {
-
-					this.uniforms.opacity.value = value;
-
-				}
-			},
-
-			color: {
-				get: function () {
-
-					return this.uniforms.diffuse.value;
-
-				}
-			}
-
-		} );
-
-		this.setValues( parameters );
-		this.isLDrawConditionalLineMaterial = true;
-
-	}
-
-}
 
 class ConditionalLineSegments extends LineSegments {
 
@@ -1903,19 +1766,19 @@ class LDrawLoader extends Loader {
 		// This object is a map from file names to paths. It agilizes the paths search. If it is not set then files will be searched by trial and error.
 		this.fileMap = {};
 
-		// Initializes the materials library with default materials
-		this.setMaterials( [] );
-
 		// If this flag is set to true the vertex normals will be smoothed.
 		this.smoothNormals = true;
 
 		// The path to load parts from the LDraw parts library from.
 		this.partsLibraryPath = '';
 
+		// this material type must be injected via setConditionalLineMaterial()
+		this.ConditionalLineMaterial = null;
+
 		// Material assigned to not available colors for meshes and edges
 		this.missingColorMaterial = new MeshStandardMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, color: 0xFF00FF, roughness: 0.3, metalness: 0 } );
 		this.missingEdgeColorMaterial = new LineBasicMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, color: 0xFF00FF } );
-		this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, fog: true, color: 0xFF00FF } );
+		this.missingConditionalEdgeColorMaterial = null;
 		this.edgeMaterialCache.set( this.missingColorMaterial, this.missingEdgeColorMaterial );
 		this.conditionalEdgeMaterialCache.set( this.missingEdgeColorMaterial, this.missingConditionalEdgeColorMaterial );
 
@@ -1928,6 +1791,14 @@ class LDrawLoader extends Loader {
 
 	}
 
+	setConditionalLineMaterial( type ) {
+
+		this.ConditionalLineMaterial = type;
+		this.missingConditionalEdgeColorMaterial = new this.ConditionalLineMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, fog: true, color: 0xFF00FF } );
+		return this;
+
+	}
+
 	async preloadMaterials( url ) {
 
 		const fileLoader = new FileLoader( this.manager );
@@ -1964,6 +1835,9 @@ class LDrawLoader extends Loader {
 		fileLoader.setWithCredentials( this.withCredentials );
 		fileLoader.load( url, text => {
 
+			// Initializes the materials library with default materials
+			this.setMaterials( [] );
+
 			this.partsCache
 				.parseModel( text, this.materialLibrary )
 				.then( group => {
@@ -2390,8 +2264,14 @@ class LDrawLoader extends Loader {
 			edgeMaterial.userData.code = code;
 			edgeMaterial.name = name + ' - Edge';
 
+			if ( this.ConditionalLineMaterial === null ) {
+
+				throw new Error( 'THREE.LDrawLoader: ConditionalLineMaterial type must be specificed via .setConditionalLineMaterial().' );
+
+			}
+
 			// This is the material used for conditional edges
-			const conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {
+			const conditionalEdgeMaterial = new this.ConditionalLineMaterial( {
 
 				fog: true,
 				transparent: isTransparent,

+ 143 - 0
examples/jsm/materials/LDrawConditionalLineMaterial.js

@@ -0,0 +1,143 @@
+import {
+	Color,
+	ShaderMaterial,
+	UniformsLib,
+	UniformsUtils,
+} from 'three';
+
+class LDrawConditionalLineMaterial extends ShaderMaterial {
+
+	static get type() {
+
+		return 'LDrawConditionalLineMaterial';
+
+	}
+
+	constructor( parameters ) {
+
+		super( {
+
+			uniforms: UniformsUtils.merge( [
+				UniformsLib.fog,
+				{
+					diffuse: {
+						value: new Color()
+					},
+					opacity: {
+						value: 1.0
+					}
+				}
+			] ),
+
+			vertexShader: /* glsl */`
+				attribute vec3 control0;
+				attribute vec3 control1;
+				attribute vec3 direction;
+				varying float discardFlag;
+
+				#include <common>
+				#include <color_pars_vertex>
+				#include <fog_pars_vertex>
+				#include <logdepthbuf_pars_vertex>
+				#include <clipping_planes_pars_vertex>
+				void main() {
+					#include <color_vertex>
+
+					vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+					gl_Position = projectionMatrix * mvPosition;
+
+					// Transform the line segment ends and control points into camera clip space
+					vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
+					vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
+					vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+					vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
+
+					c0.xy /= c0.w;
+					c1.xy /= c1.w;
+					p0.xy /= p0.w;
+					p1.xy /= p1.w;
+
+					// Get the direction of the segment and an orthogonal vector
+					vec2 dir = p1.xy - p0.xy;
+					vec2 norm = vec2( -dir.y, dir.x );
+
+					// Get control point directions from the line
+					vec2 c0dir = c0.xy - p1.xy;
+					vec2 c1dir = c1.xy - p1.xy;
+
+					// If the vectors to the controls points are pointed in different directions away
+					// from the line segment then the line should not be drawn.
+					float d0 = dot( normalize( norm ), normalize( c0dir ) );
+					float d1 = dot( normalize( norm ), normalize( c1dir ) );
+					discardFlag = float( sign( d0 ) != sign( d1 ) );
+
+					#include <logdepthbuf_vertex>
+					#include <clipping_planes_vertex>
+					#include <fog_vertex>
+				}
+			`,
+
+			fragmentShader: /* glsl */`
+			uniform vec3 diffuse;
+			uniform float opacity;
+			varying float discardFlag;
+
+			#include <common>
+			#include <color_pars_fragment>
+			#include <fog_pars_fragment>
+			#include <logdepthbuf_pars_fragment>
+			#include <clipping_planes_pars_fragment>
+			void main() {
+
+				if ( discardFlag > 0.5 ) discard;
+
+				#include <clipping_planes_fragment>
+				vec3 outgoingLight = vec3( 0.0 );
+				vec4 diffuseColor = vec4( diffuse, opacity );
+				#include <logdepthbuf_fragment>
+				#include <color_fragment>
+				outgoingLight = diffuseColor.rgb; // simple shader
+				gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+				#include <tonemapping_fragment>
+				#include <colorspace_fragment>
+				#include <fog_fragment>
+				#include <premultiplied_alpha_fragment>
+			}
+			`,
+
+		} );
+
+		Object.defineProperties( this, {
+
+			opacity: {
+				get: function () {
+
+					return this.uniforms.opacity.value;
+
+				},
+
+				set: function ( value ) {
+
+					this.uniforms.opacity.value = value;
+
+				}
+			},
+
+			color: {
+				get: function () {
+
+					return this.uniforms.diffuse.value;
+
+				}
+			}
+
+		} );
+
+		this.setValues( parameters );
+		this.isLDrawConditionalLineMaterial = true;
+
+	}
+
+}
+
+export { LDrawConditionalLineMaterial };

+ 114 - 0
examples/jsm/materials/LDrawConditionalLineNodeMaterial.js

@@ -0,0 +1,114 @@
+import { Color } from 'three';
+import { attribute, cameraProjectionMatrix, dot, float, Fn, modelViewMatrix, modelViewProjection, NodeMaterial, normalize, positionGeometry, sign, uniform, varyingProperty, vec2, vec4 } from 'three/tsl';
+
+class LDrawConditionalLineMaterial extends NodeMaterial {
+
+	static get type() {
+
+		return 'LDrawConditionalLineMaterial';
+
+	}
+
+	constructor( parameters ) {
+
+		super();
+
+		const vertexNode = /*@__PURE__*/ Fn( () => {
+
+			const control0 = attribute( 'control0', 'vec3' );
+			const control1 = attribute( 'control1', 'vec3' );
+			const direction = attribute( 'direction', 'vec3' );
+
+			const mvp = cameraProjectionMatrix.mul( modelViewMatrix );
+
+			// Transform the line segment ends and control points into camera clip space
+
+			const c0 = mvp.mul( vec4( control0, 1 ) ).toVar();
+			const c1 = mvp.mul( vec4( control1, 1 ) ).toVar();
+			const p0 = mvp.mul( vec4( positionGeometry, 1 ) ).toVar();
+			const p1 = mvp.mul( vec4( positionGeometry.add( direction ), 1 ) ).toVar();
+
+			c0.xy.divAssign( c0.w );
+			c1.xy.divAssign( c1.w );
+			p0.xy.divAssign( p0.w );
+			p1.xy.divAssign( p1.w );
+
+			// Get the direction of the segment and an orthogonal vector
+
+			const dir = p1.xy.sub( p0.xy ).toVar();
+			const norm = vec2( dir.y.negate(), dir.x ).toVar();
+
+			// Get control point directions from the line
+			const c0dir = c0.xy.sub( p1.xy ).toVar();
+			const c1dir = c1.xy.sub( p1.xy ).toVar();
+
+			// If the vectors to the controls points are pointed in different directions away
+			// from the line segment then the line should not be drawn.
+			const d0 = dot( normalize( norm ), normalize( c0dir ) ).toVar();
+			const d1 = dot( normalize( norm ), normalize( c1dir ) ).toVar();
+			const discardFlag = sign( d0 ).notEqual( sign( d1 ) ).select( float( 1 ), float( 0 ) );
+
+			varyingProperty( 'float', 'discardFlag' ).assign( discardFlag );
+
+			return modelViewProjection();
+
+		} )();
+
+		const fragmentNode = /*@__PURE__*/ Fn( () => {
+
+			const discardFlag = varyingProperty( 'float', 'discardFlag' );
+
+			discardFlag.greaterThan( float( 0.5 ) ).discard();
+
+			return vec4( this._diffuseUniform, this._opacityUniform );
+
+		} )();
+
+		this.vertexNode = vertexNode;
+		this.fragmentNode = fragmentNode;
+
+		this._diffuseUniform = uniform( new Color() );
+		this._opacityUniform = uniform( 1 );
+
+		//
+
+		Object.defineProperties( this, {
+
+			opacity: {
+				get: function () {
+
+					return this._opacityUniform.value;
+
+				},
+
+				set: function ( value ) {
+
+					this._opacityUniform.value = value;
+
+				}
+			},
+
+			color: {
+				get: function () {
+
+					return this._diffuseUniform.value;
+
+				},
+
+				set: function ( value ) {
+
+					this._diffuseUniform.value.copy( value );
+
+				}
+			}
+
+		} );
+
+		this.setValues( parameters );
+		this.isLDrawConditionalLineMaterial = true;
+
+	}
+
+}
+
+export { LDrawConditionalLineMaterial };

+ 2 - 0
examples/webgl_loader_ldraw.html

@@ -40,6 +40,7 @@
 
 			import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';
 			import { LDrawUtils } from 'three/addons/utils/LDrawUtils.js';
+			import { LDrawConditionalLineMaterial } from 'three/addons/materials/LDrawConditionalLineMaterial.js';
 
 			let container, progressBarDiv;
 
@@ -172,6 +173,7 @@
 
 				// only smooth when not rendering with flat colors to improve processing time
 				const lDrawLoader = new LDrawLoader();
+				lDrawLoader.setConditionalLineMaterial( LDrawConditionalLineMaterial );
 				lDrawLoader.smoothNormals = guiData.smoothNormals && ! guiData.flatColors;
 				lDrawLoader
 					.setPath( ldrawPath )

粤ICP备19079148号