Skip to content

Commit d067dfd

Browse files
authored
LDrawLoader: Add WebGPU support. (#29752)
* LDrawLoader: Add WebGPU support. * LDrawLoader: Improve error handling. * LDrawLoader: Clean up. * Update Addons.js
1 parent 751d9ec commit d067dfd

File tree

5 files changed

+283
-142
lines changed

5 files changed

+283
-142
lines changed

examples/jsm/Addons.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export * from './loaders/VTKLoader.js';
129129
export * from './loaders/XYZLoader.js';
130130

131131
export * from './materials/MeshGouraudMaterial.js';
132+
export * from './materials/LDrawConditionalLineMaterial.js';
133+
export * from './materials/MeshPostProcessingMaterial.js';
132134

133135
export * from './math/Capsule.js';
134136
export * from './math/ColorConverter.js';

examples/jsm/loaders/LDrawLoader.js

Lines changed: 22 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ import {
1010
Matrix4,
1111
Mesh,
1212
MeshStandardMaterial,
13-
ShaderMaterial,
1413
SRGBColorSpace,
15-
UniformsLib,
16-
UniformsUtils,
1714
Vector3,
1815
Ray
1916
} from 'three';
@@ -45,140 +42,6 @@ const COLOR_SPACE_LDRAW = SRGBColorSpace;
4542
const _tempVec0 = new Vector3();
4643
const _tempVec1 = new Vector3();
4744

48-
class LDrawConditionalLineMaterial extends ShaderMaterial {
49-
50-
static get type() {
51-
52-
return 'LDrawConditionalLineMaterial';
53-
54-
}
55-
56-
constructor( parameters ) {
57-
58-
super( {
59-
60-
uniforms: UniformsUtils.merge( [
61-
UniformsLib.fog,
62-
{
63-
diffuse: {
64-
value: new Color()
65-
},
66-
opacity: {
67-
value: 1.0
68-
}
69-
}
70-
] ),
71-
72-
vertexShader: /* glsl */`
73-
attribute vec3 control0;
74-
attribute vec3 control1;
75-
attribute vec3 direction;
76-
varying float discardFlag;
77-
78-
#include <common>
79-
#include <color_pars_vertex>
80-
#include <fog_pars_vertex>
81-
#include <logdepthbuf_pars_vertex>
82-
#include <clipping_planes_pars_vertex>
83-
void main() {
84-
#include <color_vertex>
85-
86-
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
87-
gl_Position = projectionMatrix * mvPosition;
88-
89-
// Transform the line segment ends and control points into camera clip space
90-
vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
91-
vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
92-
vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
93-
vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
94-
95-
c0.xy /= c0.w;
96-
c1.xy /= c1.w;
97-
p0.xy /= p0.w;
98-
p1.xy /= p1.w;
99-
100-
// Get the direction of the segment and an orthogonal vector
101-
vec2 dir = p1.xy - p0.xy;
102-
vec2 norm = vec2( -dir.y, dir.x );
103-
104-
// Get control point directions from the line
105-
vec2 c0dir = c0.xy - p1.xy;
106-
vec2 c1dir = c1.xy - p1.xy;
107-
108-
// If the vectors to the controls points are pointed in different directions away
109-
// from the line segment then the line should not be drawn.
110-
float d0 = dot( normalize( norm ), normalize( c0dir ) );
111-
float d1 = dot( normalize( norm ), normalize( c1dir ) );
112-
discardFlag = float( sign( d0 ) != sign( d1 ) );
113-
114-
#include <logdepthbuf_vertex>
115-
#include <clipping_planes_vertex>
116-
#include <fog_vertex>
117-
}
118-
`,
119-
120-
fragmentShader: /* glsl */`
121-
uniform vec3 diffuse;
122-
uniform float opacity;
123-
varying float discardFlag;
124-
125-
#include <common>
126-
#include <color_pars_fragment>
127-
#include <fog_pars_fragment>
128-
#include <logdepthbuf_pars_fragment>
129-
#include <clipping_planes_pars_fragment>
130-
void main() {
131-
132-
if ( discardFlag > 0.5 ) discard;
133-
134-
#include <clipping_planes_fragment>
135-
vec3 outgoingLight = vec3( 0.0 );
136-
vec4 diffuseColor = vec4( diffuse, opacity );
137-
#include <logdepthbuf_fragment>
138-
#include <color_fragment>
139-
outgoingLight = diffuseColor.rgb; // simple shader
140-
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
141-
#include <tonemapping_fragment>
142-
#include <colorspace_fragment>
143-
#include <fog_fragment>
144-
#include <premultiplied_alpha_fragment>
145-
}
146-
`,
147-
148-
} );
149-
150-
Object.defineProperties( this, {
151-
152-
opacity: {
153-
get: function () {
154-
155-
return this.uniforms.opacity.value;
156-
157-
},
158-
159-
set: function ( value ) {
160-
161-
this.uniforms.opacity.value = value;
162-
163-
}
164-
},
165-
166-
color: {
167-
get: function () {
168-
169-
return this.uniforms.diffuse.value;
170-
171-
}
172-
}
173-
174-
} );
175-
176-
this.setValues( parameters );
177-
this.isLDrawConditionalLineMaterial = true;
178-
179-
}
180-
181-
}
18245

18346
class ConditionalLineSegments extends LineSegments {
18447

@@ -1903,19 +1766,19 @@ class LDrawLoader extends Loader {
19031766
// 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.
19041767
this.fileMap = {};
19051768

1906-
// Initializes the materials library with default materials
1907-
this.setMaterials( [] );
1908-
19091769
// If this flag is set to true the vertex normals will be smoothed.
19101770
this.smoothNormals = true;
19111771

19121772
// The path to load parts from the LDraw parts library from.
19131773
this.partsLibraryPath = '';
19141774

1775+
// this material type must be injected via setConditionalLineMaterial()
1776+
this.ConditionalLineMaterial = null;
1777+
19151778
// Material assigned to not available colors for meshes and edges
19161779
this.missingColorMaterial = new MeshStandardMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, color: 0xFF00FF, roughness: 0.3, metalness: 0 } );
19171780
this.missingEdgeColorMaterial = new LineBasicMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, color: 0xFF00FF } );
1918-
this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, fog: true, color: 0xFF00FF } );
1781+
this.missingConditionalEdgeColorMaterial = null;
19191782
this.edgeMaterialCache.set( this.missingColorMaterial, this.missingEdgeColorMaterial );
19201783
this.conditionalEdgeMaterialCache.set( this.missingEdgeColorMaterial, this.missingConditionalEdgeColorMaterial );
19211784

@@ -1928,6 +1791,14 @@ class LDrawLoader extends Loader {
19281791

19291792
}
19301793

1794+
setConditionalLineMaterial( type ) {
1795+
1796+
this.ConditionalLineMaterial = type;
1797+
this.missingConditionalEdgeColorMaterial = new this.ConditionalLineMaterial( { name: Loader.DEFAULT_MATERIAL_NAME, fog: true, color: 0xFF00FF } );
1798+
return this;
1799+
1800+
}
1801+
19311802
async preloadMaterials( url ) {
19321803

19331804
const fileLoader = new FileLoader( this.manager );
@@ -1964,6 +1835,9 @@ class LDrawLoader extends Loader {
19641835
fileLoader.setWithCredentials( this.withCredentials );
19651836
fileLoader.load( url, text => {
19661837

1838+
// Initializes the materials library with default materials
1839+
this.setMaterials( [] );
1840+
19671841
this.partsCache
19681842
.parseModel( text, this.materialLibrary )
19691843
.then( group => {
@@ -2390,8 +2264,14 @@ class LDrawLoader extends Loader {
23902264
edgeMaterial.userData.code = code;
23912265
edgeMaterial.name = name + ' - Edge';
23922266

2267+
if ( this.ConditionalLineMaterial === null ) {
2268+
2269+
throw new Error( 'THREE.LDrawLoader: ConditionalLineMaterial type must be specificed via .setConditionalLineMaterial().' );
2270+
2271+
}
2272+
23932273
// This is the material used for conditional edges
2394-
const conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {
2274+
const conditionalEdgeMaterial = new this.ConditionalLineMaterial( {
23952275

23962276
fog: true,
23972277
transparent: isTransparent,
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import {
2+
Color,
3+
ShaderMaterial,
4+
UniformsLib,
5+
UniformsUtils,
6+
} from 'three';
7+
8+
class LDrawConditionalLineMaterial extends ShaderMaterial {
9+
10+
static get type() {
11+
12+
return 'LDrawConditionalLineMaterial';
13+
14+
}
15+
16+
constructor( parameters ) {
17+
18+
super( {
19+
20+
uniforms: UniformsUtils.merge( [
21+
UniformsLib.fog,
22+
{
23+
diffuse: {
24+
value: new Color()
25+
},
26+
opacity: {
27+
value: 1.0
28+
}
29+
}
30+
] ),
31+
32+
vertexShader: /* glsl */`
33+
attribute vec3 control0;
34+
attribute vec3 control1;
35+
attribute vec3 direction;
36+
varying float discardFlag;
37+
38+
#include <common>
39+
#include <color_pars_vertex>
40+
#include <fog_pars_vertex>
41+
#include <logdepthbuf_pars_vertex>
42+
#include <clipping_planes_pars_vertex>
43+
void main() {
44+
#include <color_vertex>
45+
46+
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
47+
gl_Position = projectionMatrix * mvPosition;
48+
49+
// Transform the line segment ends and control points into camera clip space
50+
vec4 c0 = projectionMatrix * modelViewMatrix * vec4( control0, 1.0 );
51+
vec4 c1 = projectionMatrix * modelViewMatrix * vec4( control1, 1.0 );
52+
vec4 p0 = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
53+
vec4 p1 = projectionMatrix * modelViewMatrix * vec4( position + direction, 1.0 );
54+
55+
c0.xy /= c0.w;
56+
c1.xy /= c1.w;
57+
p0.xy /= p0.w;
58+
p1.xy /= p1.w;
59+
60+
// Get the direction of the segment and an orthogonal vector
61+
vec2 dir = p1.xy - p0.xy;
62+
vec2 norm = vec2( -dir.y, dir.x );
63+
64+
// Get control point directions from the line
65+
vec2 c0dir = c0.xy - p1.xy;
66+
vec2 c1dir = c1.xy - p1.xy;
67+
68+
// If the vectors to the controls points are pointed in different directions away
69+
// from the line segment then the line should not be drawn.
70+
float d0 = dot( normalize( norm ), normalize( c0dir ) );
71+
float d1 = dot( normalize( norm ), normalize( c1dir ) );
72+
discardFlag = float( sign( d0 ) != sign( d1 ) );
73+
74+
#include <logdepthbuf_vertex>
75+
#include <clipping_planes_vertex>
76+
#include <fog_vertex>
77+
}
78+
`,
79+
80+
fragmentShader: /* glsl */`
81+
uniform vec3 diffuse;
82+
uniform float opacity;
83+
varying float discardFlag;
84+
85+
#include <common>
86+
#include <color_pars_fragment>
87+
#include <fog_pars_fragment>
88+
#include <logdepthbuf_pars_fragment>
89+
#include <clipping_planes_pars_fragment>
90+
void main() {
91+
92+
if ( discardFlag > 0.5 ) discard;
93+
94+
#include <clipping_planes_fragment>
95+
vec3 outgoingLight = vec3( 0.0 );
96+
vec4 diffuseColor = vec4( diffuse, opacity );
97+
#include <logdepthbuf_fragment>
98+
#include <color_fragment>
99+
outgoingLight = diffuseColor.rgb; // simple shader
100+
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
101+
#include <tonemapping_fragment>
102+
#include <colorspace_fragment>
103+
#include <fog_fragment>
104+
#include <premultiplied_alpha_fragment>
105+
}
106+
`,
107+
108+
} );
109+
110+
Object.defineProperties( this, {
111+
112+
opacity: {
113+
get: function () {
114+
115+
return this.uniforms.opacity.value;
116+
117+
},
118+
119+
set: function ( value ) {
120+
121+
this.uniforms.opacity.value = value;
122+
123+
}
124+
},
125+
126+
color: {
127+
get: function () {
128+
129+
return this.uniforms.diffuse.value;
130+
131+
}
132+
}
133+
134+
} );
135+
136+
this.setValues( parameters );
137+
this.isLDrawConditionalLineMaterial = true;
138+
139+
}
140+
141+
}
142+
143+
export { LDrawConditionalLineMaterial };

0 commit comments

Comments
 (0)