@luma.gl/gltf 9.3.0-alpha.6 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +942 -141
- package/dist/dist.min.js +4 -4
- package/dist/gltf/create-gltf-model.d.ts +9 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +58 -4
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +22 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +63 -1
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +899 -114
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +34 -12
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-lights.js +86 -20
- package/dist/parsers/parse-gltf-lights.js.map +1 -1
- package/dist/parsers/parse-gltf.d.ts +3 -1
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +41 -9
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +69 -1
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +429 -42
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +14 -12
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +8 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +5 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +12 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +1 -10
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +1 -15
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +5 -6
- package/src/gltf/create-gltf-model.ts +113 -5
- package/src/gltf/create-scenegraph-from-gltf.ts +97 -6
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +10 -1
- package/src/parsers/parse-gltf-animations.ts +39 -15
- package/src/parsers/parse-gltf-lights.ts +114 -25
- package/src/parsers/parse-gltf.ts +86 -19
- package/src/parsers/parse-pbr-material.ts +664 -69
- package/src/pbr/pbr-environment.ts +29 -16
- package/src/pbr/pbr-material.ts +13 -3
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +29 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +1 -15
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import type {Device, SamplerProps, TextureFormat, TypedArray} from '@luma.gl/core';
|
|
6
6
|
import {Texture, log, textureFormatDecoder} from '@luma.gl/core';
|
|
7
|
-
import type {GLTFSampler} from '@loaders.gl/gltf';
|
|
8
|
-
import {GL} from '@luma.gl/constants';
|
|
7
|
+
import type {GLTFPostprocessed, GLTFSampler} from '@loaders.gl/gltf';
|
|
9
8
|
|
|
10
9
|
import {type ParsedPBRMaterial} from '../pbr/pbr-material';
|
|
11
10
|
import {type PBREnvironment} from '../pbr/pbr-environment';
|
|
12
11
|
import {type PBRMaterialBindings} from '@luma.gl/shadertools';
|
|
12
|
+
import {GLEnum} from '../webgl-to-webgpu/gltf-webgl-constants';
|
|
13
13
|
import {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';
|
|
14
14
|
|
|
15
15
|
// TODO - synchronize the GLTF... types with loaders.gl
|
|
@@ -19,6 +19,7 @@ import {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';
|
|
|
19
19
|
|
|
20
20
|
type GLTFTexture = {
|
|
21
21
|
id: string;
|
|
22
|
+
index?: number;
|
|
22
23
|
texture: {source: {image: any}; sampler: {parameters: any}};
|
|
23
24
|
uniformName?: string;
|
|
24
25
|
// is this on all textures?
|
|
@@ -36,16 +37,114 @@ type GLTFPBRMetallicRoughness = {
|
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
type GLTFPBRMaterial = {
|
|
40
|
+
extensions?: GLTFMaterialExtensions;
|
|
39
41
|
unlit?: boolean;
|
|
40
42
|
pbrMetallicRoughness?: GLTFPBRMetallicRoughness;
|
|
41
43
|
normalTexture?: GLTFTexture;
|
|
42
44
|
occlusionTexture?: GLTFTexture;
|
|
43
45
|
emissiveTexture?: GLTFTexture;
|
|
44
46
|
emissiveFactor?: [number, number, number];
|
|
45
|
-
alphaMode?: 'MASK' | 'BLEND';
|
|
47
|
+
alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';
|
|
48
|
+
doubleSided?: boolean;
|
|
46
49
|
alphaCutoff?: number;
|
|
47
50
|
};
|
|
48
51
|
|
|
52
|
+
type GLTFMaterialSpecularExtension = {
|
|
53
|
+
specularFactor?: number;
|
|
54
|
+
specularTexture?: GLTFTexture;
|
|
55
|
+
specularColorFactor?: [number, number, number];
|
|
56
|
+
specularColorTexture?: GLTFTexture;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
type GLTFMaterialIorExtension = {
|
|
60
|
+
ior?: number;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type GLTFMaterialTransmissionExtension = {
|
|
64
|
+
transmissionFactor?: number;
|
|
65
|
+
transmissionTexture?: GLTFTexture;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type GLTFMaterialVolumeExtension = {
|
|
69
|
+
thicknessFactor?: number;
|
|
70
|
+
thicknessTexture?: GLTFTexture;
|
|
71
|
+
attenuationDistance?: number;
|
|
72
|
+
attenuationColor?: [number, number, number];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type GLTFMaterialClearcoatExtension = {
|
|
76
|
+
clearcoatFactor?: number;
|
|
77
|
+
clearcoatTexture?: GLTFTexture;
|
|
78
|
+
clearcoatRoughnessFactor?: number;
|
|
79
|
+
clearcoatRoughnessTexture?: GLTFTexture;
|
|
80
|
+
clearcoatNormalTexture?: GLTFTexture;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
type GLTFMaterialSheenExtension = {
|
|
84
|
+
sheenColorFactor?: [number, number, number];
|
|
85
|
+
sheenColorTexture?: GLTFTexture;
|
|
86
|
+
sheenRoughnessFactor?: number;
|
|
87
|
+
sheenRoughnessTexture?: GLTFTexture;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
type GLTFMaterialIridescenceExtension = {
|
|
91
|
+
iridescenceFactor?: number;
|
|
92
|
+
iridescenceTexture?: GLTFTexture;
|
|
93
|
+
iridescenceIor?: number;
|
|
94
|
+
iridescenceThicknessMinimum?: number;
|
|
95
|
+
iridescenceThicknessMaximum?: number;
|
|
96
|
+
iridescenceThicknessTexture?: GLTFTexture;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
type GLTFMaterialAnisotropyExtension = {
|
|
100
|
+
anisotropyStrength?: number;
|
|
101
|
+
anisotropyRotation?: number;
|
|
102
|
+
anisotropyTexture?: GLTFTexture;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
type GLTFMaterialEmissiveStrengthExtension = {
|
|
106
|
+
emissiveStrength?: number;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type GLTFMaterialExtensions = {
|
|
110
|
+
KHR_materials_unlit?: Record<string, never>;
|
|
111
|
+
KHR_materials_specular?: GLTFMaterialSpecularExtension;
|
|
112
|
+
KHR_materials_ior?: GLTFMaterialIorExtension;
|
|
113
|
+
KHR_materials_transmission?: GLTFMaterialTransmissionExtension;
|
|
114
|
+
KHR_materials_volume?: GLTFMaterialVolumeExtension;
|
|
115
|
+
KHR_materials_clearcoat?: GLTFMaterialClearcoatExtension;
|
|
116
|
+
KHR_materials_sheen?: GLTFMaterialSheenExtension;
|
|
117
|
+
KHR_materials_iridescence?: GLTFMaterialIridescenceExtension;
|
|
118
|
+
KHR_materials_anisotropy?: GLTFMaterialAnisotropyExtension;
|
|
119
|
+
KHR_materials_emissive_strength?: GLTFMaterialEmissiveStrengthExtension;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
type TextureEnabledUniformName =
|
|
123
|
+
| 'baseColorMapEnabled'
|
|
124
|
+
| 'normalMapEnabled'
|
|
125
|
+
| 'emissiveMapEnabled'
|
|
126
|
+
| 'metallicRoughnessMapEnabled'
|
|
127
|
+
| 'occlusionMapEnabled'
|
|
128
|
+
| 'specularColorMapEnabled'
|
|
129
|
+
| 'specularIntensityMapEnabled'
|
|
130
|
+
| 'transmissionMapEnabled'
|
|
131
|
+
| 'clearcoatMapEnabled'
|
|
132
|
+
| 'clearcoatRoughnessMapEnabled'
|
|
133
|
+
| 'sheenColorMapEnabled'
|
|
134
|
+
| 'sheenRoughnessMapEnabled'
|
|
135
|
+
| 'iridescenceMapEnabled'
|
|
136
|
+
| 'anisotropyMapEnabled';
|
|
137
|
+
|
|
138
|
+
type TextureFeatureOptions = {
|
|
139
|
+
define?: string;
|
|
140
|
+
enabledUniformName?: TextureEnabledUniformName;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
type TextureParseOptions = {
|
|
144
|
+
featureOptions?: TextureFeatureOptions;
|
|
145
|
+
gltf?: GLTFPostprocessed;
|
|
146
|
+
};
|
|
147
|
+
|
|
49
148
|
export type ParsePBRMaterialOptions = {
|
|
50
149
|
/** Debug PBR shader */
|
|
51
150
|
pbrDebug?: boolean;
|
|
@@ -55,6 +154,10 @@ export type ParsePBRMaterialOptions = {
|
|
|
55
154
|
useTangents?: boolean;
|
|
56
155
|
/** provide an image based (texture cube) lighting environment */
|
|
57
156
|
imageBasedLightingEnvironment?: PBREnvironment;
|
|
157
|
+
/** parent post-processed glTF, used to resolve extension texture infos */
|
|
158
|
+
gltf?: GLTFPostprocessed;
|
|
159
|
+
/** run primitive-attribute diagnostics such as missing TEXCOORD_0 / NORMAL */
|
|
160
|
+
validateAttributes?: boolean;
|
|
58
161
|
};
|
|
59
162
|
|
|
60
163
|
/**
|
|
@@ -93,7 +196,8 @@ export function parsePBRMaterial(
|
|
|
93
196
|
imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
94
197
|
parsedMaterial.bindings.pbr_specularEnvSampler =
|
|
95
198
|
imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
96
|
-
parsedMaterial.bindings.
|
|
199
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
200
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
97
201
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
98
202
|
}
|
|
99
203
|
|
|
@@ -114,106 +218,217 @@ export function parsePBRMaterial(
|
|
|
114
218
|
if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;
|
|
115
219
|
|
|
116
220
|
if (material) {
|
|
117
|
-
|
|
221
|
+
if (options.validateAttributes !== false) {
|
|
222
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
223
|
+
}
|
|
224
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
118
225
|
}
|
|
119
226
|
|
|
120
227
|
return parsedMaterial;
|
|
121
228
|
}
|
|
122
229
|
|
|
230
|
+
function warnOnMissingExpectedAttributes(
|
|
231
|
+
material: GLTFPBRMaterial,
|
|
232
|
+
attributes: Record<string, any>
|
|
233
|
+
): void {
|
|
234
|
+
const uvDependentTextureSlots = getUvDependentTextureSlots(material);
|
|
235
|
+
if (uvDependentTextureSlots.length > 0 && !attributes['TEXCOORD_0']) {
|
|
236
|
+
log.warn(
|
|
237
|
+
`glTF material uses ${uvDependentTextureSlots.join(', ')} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`
|
|
238
|
+
)();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);
|
|
242
|
+
if (isUnlitMaterial || attributes['NORMAL']) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const missingNormalReason = material.normalTexture
|
|
247
|
+
? 'lit PBR shading with normalTexture'
|
|
248
|
+
: 'lit PBR shading';
|
|
249
|
+
log.warn(
|
|
250
|
+
`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`
|
|
251
|
+
)();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function getUvDependentTextureSlots(material: GLTFPBRMaterial): string[] {
|
|
255
|
+
const uvDependentTextureSlots: string[] = [];
|
|
256
|
+
|
|
257
|
+
if (material.pbrMetallicRoughness?.baseColorTexture) {
|
|
258
|
+
uvDependentTextureSlots.push('baseColorTexture');
|
|
259
|
+
}
|
|
260
|
+
if (material.pbrMetallicRoughness?.metallicRoughnessTexture) {
|
|
261
|
+
uvDependentTextureSlots.push('metallicRoughnessTexture');
|
|
262
|
+
}
|
|
263
|
+
if (material.normalTexture) {
|
|
264
|
+
uvDependentTextureSlots.push('normalTexture');
|
|
265
|
+
}
|
|
266
|
+
if (material.occlusionTexture) {
|
|
267
|
+
uvDependentTextureSlots.push('occlusionTexture');
|
|
268
|
+
}
|
|
269
|
+
if (material.emissiveTexture) {
|
|
270
|
+
uvDependentTextureSlots.push('emissiveTexture');
|
|
271
|
+
}
|
|
272
|
+
if (material.extensions?.KHR_materials_specular?.specularTexture) {
|
|
273
|
+
uvDependentTextureSlots.push('KHR_materials_specular.specularTexture');
|
|
274
|
+
}
|
|
275
|
+
if (material.extensions?.KHR_materials_specular?.specularColorTexture) {
|
|
276
|
+
uvDependentTextureSlots.push('KHR_materials_specular.specularColorTexture');
|
|
277
|
+
}
|
|
278
|
+
if (material.extensions?.KHR_materials_transmission?.transmissionTexture) {
|
|
279
|
+
uvDependentTextureSlots.push('KHR_materials_transmission.transmissionTexture');
|
|
280
|
+
}
|
|
281
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatTexture) {
|
|
282
|
+
uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatTexture');
|
|
283
|
+
}
|
|
284
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatRoughnessTexture) {
|
|
285
|
+
uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatRoughnessTexture');
|
|
286
|
+
}
|
|
287
|
+
if (material.extensions?.KHR_materials_sheen?.sheenColorTexture) {
|
|
288
|
+
uvDependentTextureSlots.push('KHR_materials_sheen.sheenColorTexture');
|
|
289
|
+
}
|
|
290
|
+
if (material.extensions?.KHR_materials_sheen?.sheenRoughnessTexture) {
|
|
291
|
+
uvDependentTextureSlots.push('KHR_materials_sheen.sheenRoughnessTexture');
|
|
292
|
+
}
|
|
293
|
+
if (material.extensions?.KHR_materials_iridescence?.iridescenceTexture) {
|
|
294
|
+
uvDependentTextureSlots.push('KHR_materials_iridescence.iridescenceTexture');
|
|
295
|
+
}
|
|
296
|
+
if (material.extensions?.KHR_materials_anisotropy?.anisotropyTexture) {
|
|
297
|
+
uvDependentTextureSlots.push('KHR_materials_anisotropy.anisotropyTexture');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return uvDependentTextureSlots;
|
|
301
|
+
}
|
|
302
|
+
|
|
123
303
|
/** Parse GLTF material record */
|
|
124
304
|
function parseMaterial(
|
|
125
305
|
device: Device,
|
|
126
306
|
material: GLTFPBRMaterial,
|
|
127
|
-
parsedMaterial: ParsedPBRMaterial
|
|
307
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
308
|
+
gltf?: GLTFPostprocessed
|
|
128
309
|
): void {
|
|
129
|
-
parsedMaterial.uniforms.unlit = Boolean(
|
|
310
|
+
parsedMaterial.uniforms.unlit = Boolean(
|
|
311
|
+
material.unlit || material.extensions?.KHR_materials_unlit
|
|
312
|
+
);
|
|
130
313
|
|
|
131
314
|
if (material.pbrMetallicRoughness) {
|
|
132
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
315
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
133
316
|
}
|
|
134
317
|
if (material.normalTexture) {
|
|
135
|
-
addTexture(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
);
|
|
318
|
+
addTexture(device, material.normalTexture, 'pbr_normalSampler', parsedMaterial, {
|
|
319
|
+
featureOptions: {
|
|
320
|
+
define: 'HAS_NORMALMAP',
|
|
321
|
+
enabledUniformName: 'normalMapEnabled'
|
|
322
|
+
},
|
|
323
|
+
gltf
|
|
324
|
+
});
|
|
142
325
|
|
|
143
326
|
const {scale = 1} = material.normalTexture;
|
|
144
327
|
parsedMaterial.uniforms.normalScale = scale;
|
|
145
328
|
}
|
|
146
329
|
if (material.occlusionTexture) {
|
|
147
|
-
addTexture(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
);
|
|
330
|
+
addTexture(device, material.occlusionTexture, 'pbr_occlusionSampler', parsedMaterial, {
|
|
331
|
+
featureOptions: {
|
|
332
|
+
define: 'HAS_OCCLUSIONMAP',
|
|
333
|
+
enabledUniformName: 'occlusionMapEnabled'
|
|
334
|
+
},
|
|
335
|
+
gltf
|
|
336
|
+
});
|
|
154
337
|
|
|
155
338
|
const {strength = 1} = material.occlusionTexture;
|
|
156
339
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
157
340
|
}
|
|
341
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
158
342
|
if (material.emissiveTexture) {
|
|
159
|
-
addTexture(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
);
|
|
166
|
-
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
343
|
+
addTexture(device, material.emissiveTexture, 'pbr_emissiveSampler', parsedMaterial, {
|
|
344
|
+
featureOptions: {
|
|
345
|
+
define: 'HAS_EMISSIVEMAP',
|
|
346
|
+
enabledUniformName: 'emissiveMapEnabled'
|
|
347
|
+
},
|
|
348
|
+
gltf
|
|
349
|
+
});
|
|
167
350
|
}
|
|
168
351
|
|
|
169
|
-
|
|
170
|
-
|
|
352
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
353
|
+
|
|
354
|
+
switch (material.alphaMode || 'OPAQUE') {
|
|
355
|
+
case 'OPAQUE':
|
|
356
|
+
break;
|
|
357
|
+
case 'MASK': {
|
|
171
358
|
const {alphaCutoff = 0.5} = material;
|
|
172
359
|
parsedMaterial.defines['ALPHA_CUTOFF'] = true;
|
|
360
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
173
361
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
174
362
|
break;
|
|
363
|
+
}
|
|
175
364
|
case 'BLEND':
|
|
176
365
|
log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();
|
|
177
|
-
|
|
178
|
-
// WebGPU style parameters
|
|
179
|
-
parsedMaterial.parameters.blend = true;
|
|
180
|
-
|
|
181
|
-
parsedMaterial.parameters.blendColorOperation = 'add';
|
|
182
|
-
parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';
|
|
183
|
-
parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';
|
|
184
|
-
|
|
185
|
-
parsedMaterial.parameters.blendAlphaOperation = 'add';
|
|
186
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = 'one';
|
|
187
|
-
parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';
|
|
188
|
-
|
|
189
|
-
// GL parameters
|
|
190
|
-
// TODO - remove in favor of parameters
|
|
191
|
-
parsedMaterial.glParameters['blend'] = true;
|
|
192
|
-
parsedMaterial.glParameters['blendEquation'] = GL.FUNC_ADD;
|
|
193
|
-
parsedMaterial.glParameters['blendFunc'] = [
|
|
194
|
-
GL.SRC_ALPHA,
|
|
195
|
-
GL.ONE_MINUS_SRC_ALPHA,
|
|
196
|
-
GL.ONE,
|
|
197
|
-
GL.ONE_MINUS_SRC_ALPHA
|
|
198
|
-
];
|
|
366
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
199
367
|
|
|
200
368
|
break;
|
|
201
369
|
}
|
|
202
370
|
}
|
|
203
371
|
|
|
372
|
+
function applyAlphaBlendParameters(parsedMaterial: ParsedPBRMaterial): void {
|
|
373
|
+
parsedMaterial.parameters.blend = true;
|
|
374
|
+
parsedMaterial.parameters.blendColorOperation = 'add';
|
|
375
|
+
parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';
|
|
376
|
+
parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';
|
|
377
|
+
parsedMaterial.parameters.blendAlphaOperation = 'add';
|
|
378
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = 'one';
|
|
379
|
+
parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';
|
|
380
|
+
|
|
381
|
+
parsedMaterial.glParameters['blend'] = true;
|
|
382
|
+
parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;
|
|
383
|
+
parsedMaterial.glParameters['blendFunc'] = [
|
|
384
|
+
GLEnum.SRC_ALPHA,
|
|
385
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
386
|
+
GLEnum.ONE,
|
|
387
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
388
|
+
];
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function applyTransmissionBlendApproximation(parsedMaterial: ParsedPBRMaterial): void {
|
|
392
|
+
parsedMaterial.parameters.blend = true;
|
|
393
|
+
parsedMaterial.parameters.depthWriteEnabled = false;
|
|
394
|
+
parsedMaterial.parameters.blendColorOperation = 'add';
|
|
395
|
+
parsedMaterial.parameters.blendColorSrcFactor = 'one';
|
|
396
|
+
parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';
|
|
397
|
+
parsedMaterial.parameters.blendAlphaOperation = 'add';
|
|
398
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = 'one';
|
|
399
|
+
parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';
|
|
400
|
+
|
|
401
|
+
parsedMaterial.glParameters['blend'] = true;
|
|
402
|
+
parsedMaterial.glParameters['depthMask'] = false;
|
|
403
|
+
parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;
|
|
404
|
+
parsedMaterial.glParameters['blendFunc'] = [
|
|
405
|
+
GLEnum.ONE,
|
|
406
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
407
|
+
GLEnum.ONE,
|
|
408
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
409
|
+
];
|
|
410
|
+
}
|
|
411
|
+
|
|
204
412
|
/** Parse GLTF material sub record */
|
|
205
413
|
function parsePbrMetallicRoughness(
|
|
206
414
|
device: Device,
|
|
207
415
|
pbrMetallicRoughness: GLTFPBRMetallicRoughness,
|
|
208
|
-
parsedMaterial: ParsedPBRMaterial
|
|
416
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
417
|
+
gltf?: GLTFPostprocessed
|
|
209
418
|
): void {
|
|
210
419
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
211
420
|
addTexture(
|
|
212
421
|
device,
|
|
213
422
|
pbrMetallicRoughness.baseColorTexture,
|
|
214
423
|
'pbr_baseColorSampler',
|
|
215
|
-
|
|
216
|
-
|
|
424
|
+
parsedMaterial,
|
|
425
|
+
{
|
|
426
|
+
featureOptions: {
|
|
427
|
+
define: 'HAS_BASECOLORMAP',
|
|
428
|
+
enabledUniformName: 'baseColorMapEnabled'
|
|
429
|
+
},
|
|
430
|
+
gltf
|
|
431
|
+
}
|
|
217
432
|
);
|
|
218
433
|
}
|
|
219
434
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
@@ -223,34 +438,374 @@ function parsePbrMetallicRoughness(
|
|
|
223
438
|
device,
|
|
224
439
|
pbrMetallicRoughness.metallicRoughnessTexture,
|
|
225
440
|
'pbr_metallicRoughnessSampler',
|
|
226
|
-
|
|
227
|
-
|
|
441
|
+
parsedMaterial,
|
|
442
|
+
{
|
|
443
|
+
featureOptions: {
|
|
444
|
+
define: 'HAS_METALROUGHNESSMAP',
|
|
445
|
+
enabledUniformName: 'metallicRoughnessMapEnabled'
|
|
446
|
+
},
|
|
447
|
+
gltf
|
|
448
|
+
}
|
|
228
449
|
);
|
|
229
450
|
}
|
|
230
451
|
const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;
|
|
231
452
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
232
453
|
}
|
|
233
454
|
|
|
455
|
+
function parseMaterialExtensions(
|
|
456
|
+
device: Device,
|
|
457
|
+
extensions: GLTFMaterialExtensions | undefined,
|
|
458
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
459
|
+
gltf?: GLTFPostprocessed
|
|
460
|
+
): void {
|
|
461
|
+
if (!extensions) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (hasMaterialExtensionShading(extensions)) {
|
|
466
|
+
parsedMaterial.defines['USE_MATERIAL_EXTENSIONS'] = true;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);
|
|
470
|
+
parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
|
|
471
|
+
parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);
|
|
472
|
+
parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);
|
|
473
|
+
parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);
|
|
474
|
+
parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);
|
|
475
|
+
parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);
|
|
476
|
+
parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);
|
|
477
|
+
parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function hasMaterialExtensionShading(extensions: GLTFMaterialExtensions): boolean {
|
|
481
|
+
return Boolean(
|
|
482
|
+
extensions.KHR_materials_specular ||
|
|
483
|
+
extensions.KHR_materials_ior ||
|
|
484
|
+
extensions.KHR_materials_transmission ||
|
|
485
|
+
extensions.KHR_materials_volume ||
|
|
486
|
+
extensions.KHR_materials_clearcoat ||
|
|
487
|
+
extensions.KHR_materials_sheen ||
|
|
488
|
+
extensions.KHR_materials_iridescence ||
|
|
489
|
+
extensions.KHR_materials_anisotropy
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function parseSpecularExtension(
|
|
494
|
+
device: Device,
|
|
495
|
+
extension: GLTFMaterialSpecularExtension | undefined,
|
|
496
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
497
|
+
gltf?: GLTFPostprocessed
|
|
498
|
+
): void {
|
|
499
|
+
if (!extension) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (extension.specularColorFactor) {
|
|
504
|
+
parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
|
|
505
|
+
}
|
|
506
|
+
if (extension.specularFactor !== undefined) {
|
|
507
|
+
parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
|
|
508
|
+
}
|
|
509
|
+
if (extension.specularColorTexture) {
|
|
510
|
+
addTexture(device, extension.specularColorTexture, 'pbr_specularColorSampler', parsedMaterial, {
|
|
511
|
+
featureOptions: {
|
|
512
|
+
define: 'HAS_SPECULARCOLORMAP',
|
|
513
|
+
enabledUniformName: 'specularColorMapEnabled'
|
|
514
|
+
},
|
|
515
|
+
gltf
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
if (extension.specularTexture) {
|
|
519
|
+
addTexture(device, extension.specularTexture, 'pbr_specularIntensitySampler', parsedMaterial, {
|
|
520
|
+
featureOptions: {
|
|
521
|
+
define: 'HAS_SPECULARINTENSITYMAP',
|
|
522
|
+
enabledUniformName: 'specularIntensityMapEnabled'
|
|
523
|
+
},
|
|
524
|
+
gltf
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function parseIorExtension(
|
|
530
|
+
extension: GLTFMaterialIorExtension | undefined,
|
|
531
|
+
parsedMaterial: ParsedPBRMaterial
|
|
532
|
+
): void {
|
|
533
|
+
if (extension?.ior !== undefined) {
|
|
534
|
+
parsedMaterial.uniforms.ior = extension.ior;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function parseTransmissionExtension(
|
|
539
|
+
device: Device,
|
|
540
|
+
extension: GLTFMaterialTransmissionExtension | undefined,
|
|
541
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
542
|
+
gltf?: GLTFPostprocessed
|
|
543
|
+
): void {
|
|
544
|
+
if (!extension) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (extension.transmissionFactor !== undefined) {
|
|
549
|
+
parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
|
|
550
|
+
}
|
|
551
|
+
if (extension.transmissionTexture) {
|
|
552
|
+
addTexture(device, extension.transmissionTexture, 'pbr_transmissionSampler', parsedMaterial, {
|
|
553
|
+
featureOptions: {
|
|
554
|
+
define: 'HAS_TRANSMISSIONMAP',
|
|
555
|
+
enabledUniformName: 'transmissionMapEnabled'
|
|
556
|
+
},
|
|
557
|
+
gltf
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
|
|
562
|
+
log.warn(
|
|
563
|
+
'KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting'
|
|
564
|
+
)();
|
|
565
|
+
applyTransmissionBlendApproximation(parsedMaterial);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function parseVolumeExtension(
|
|
570
|
+
device: Device,
|
|
571
|
+
extension: GLTFMaterialVolumeExtension | undefined,
|
|
572
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
573
|
+
gltf?: GLTFPostprocessed
|
|
574
|
+
): void {
|
|
575
|
+
if (!extension) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (extension.thicknessFactor !== undefined) {
|
|
580
|
+
parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
|
|
581
|
+
}
|
|
582
|
+
if (extension.thicknessTexture) {
|
|
583
|
+
addTexture(device, extension.thicknessTexture, 'pbr_thicknessSampler', parsedMaterial, {
|
|
584
|
+
featureOptions: {
|
|
585
|
+
define: 'HAS_THICKNESSMAP'
|
|
586
|
+
},
|
|
587
|
+
gltf
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
if (extension.attenuationDistance !== undefined) {
|
|
591
|
+
parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
|
|
592
|
+
}
|
|
593
|
+
if (extension.attenuationColor) {
|
|
594
|
+
parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function parseClearcoatExtension(
|
|
599
|
+
device: Device,
|
|
600
|
+
extension: GLTFMaterialClearcoatExtension | undefined,
|
|
601
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
602
|
+
gltf?: GLTFPostprocessed
|
|
603
|
+
): void {
|
|
604
|
+
if (!extension) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (extension.clearcoatFactor !== undefined) {
|
|
609
|
+
parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
|
|
610
|
+
}
|
|
611
|
+
if (extension.clearcoatRoughnessFactor !== undefined) {
|
|
612
|
+
parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
|
|
613
|
+
}
|
|
614
|
+
if (extension.clearcoatTexture) {
|
|
615
|
+
addTexture(device, extension.clearcoatTexture, 'pbr_clearcoatSampler', parsedMaterial, {
|
|
616
|
+
featureOptions: {
|
|
617
|
+
define: 'HAS_CLEARCOATMAP',
|
|
618
|
+
enabledUniformName: 'clearcoatMapEnabled'
|
|
619
|
+
},
|
|
620
|
+
gltf
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
if (extension.clearcoatRoughnessTexture) {
|
|
624
|
+
addTexture(
|
|
625
|
+
device,
|
|
626
|
+
extension.clearcoatRoughnessTexture,
|
|
627
|
+
'pbr_clearcoatRoughnessSampler',
|
|
628
|
+
parsedMaterial,
|
|
629
|
+
{
|
|
630
|
+
featureOptions: {
|
|
631
|
+
define: 'HAS_CLEARCOATROUGHNESSMAP',
|
|
632
|
+
enabledUniformName: 'clearcoatRoughnessMapEnabled'
|
|
633
|
+
},
|
|
634
|
+
gltf
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
if (extension.clearcoatNormalTexture) {
|
|
639
|
+
addTexture(
|
|
640
|
+
device,
|
|
641
|
+
extension.clearcoatNormalTexture,
|
|
642
|
+
'pbr_clearcoatNormalSampler',
|
|
643
|
+
parsedMaterial,
|
|
644
|
+
{
|
|
645
|
+
featureOptions: {
|
|
646
|
+
define: 'HAS_CLEARCOATNORMALMAP'
|
|
647
|
+
},
|
|
648
|
+
gltf
|
|
649
|
+
}
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
function parseSheenExtension(
|
|
655
|
+
device: Device,
|
|
656
|
+
extension: GLTFMaterialSheenExtension | undefined,
|
|
657
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
658
|
+
gltf?: GLTFPostprocessed
|
|
659
|
+
): void {
|
|
660
|
+
if (!extension) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (extension.sheenColorFactor) {
|
|
665
|
+
parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
|
|
666
|
+
}
|
|
667
|
+
if (extension.sheenRoughnessFactor !== undefined) {
|
|
668
|
+
parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
|
|
669
|
+
}
|
|
670
|
+
if (extension.sheenColorTexture) {
|
|
671
|
+
addTexture(device, extension.sheenColorTexture, 'pbr_sheenColorSampler', parsedMaterial, {
|
|
672
|
+
featureOptions: {
|
|
673
|
+
define: 'HAS_SHEENCOLORMAP',
|
|
674
|
+
enabledUniformName: 'sheenColorMapEnabled'
|
|
675
|
+
},
|
|
676
|
+
gltf
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
if (extension.sheenRoughnessTexture) {
|
|
680
|
+
addTexture(
|
|
681
|
+
device,
|
|
682
|
+
extension.sheenRoughnessTexture,
|
|
683
|
+
'pbr_sheenRoughnessSampler',
|
|
684
|
+
parsedMaterial,
|
|
685
|
+
{
|
|
686
|
+
featureOptions: {
|
|
687
|
+
define: 'HAS_SHEENROUGHNESSMAP',
|
|
688
|
+
enabledUniformName: 'sheenRoughnessMapEnabled'
|
|
689
|
+
},
|
|
690
|
+
gltf
|
|
691
|
+
}
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function parseIridescenceExtension(
|
|
697
|
+
device: Device,
|
|
698
|
+
extension: GLTFMaterialIridescenceExtension | undefined,
|
|
699
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
700
|
+
gltf?: GLTFPostprocessed
|
|
701
|
+
): void {
|
|
702
|
+
if (!extension) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (extension.iridescenceFactor !== undefined) {
|
|
707
|
+
parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
|
|
708
|
+
}
|
|
709
|
+
if (extension.iridescenceIor !== undefined) {
|
|
710
|
+
parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
|
|
711
|
+
}
|
|
712
|
+
if (
|
|
713
|
+
extension.iridescenceThicknessMinimum !== undefined ||
|
|
714
|
+
extension.iridescenceThicknessMaximum !== undefined
|
|
715
|
+
) {
|
|
716
|
+
parsedMaterial.uniforms.iridescenceThicknessRange = [
|
|
717
|
+
extension.iridescenceThicknessMinimum ?? 100,
|
|
718
|
+
extension.iridescenceThicknessMaximum ?? 400
|
|
719
|
+
];
|
|
720
|
+
}
|
|
721
|
+
if (extension.iridescenceTexture) {
|
|
722
|
+
addTexture(device, extension.iridescenceTexture, 'pbr_iridescenceSampler', parsedMaterial, {
|
|
723
|
+
featureOptions: {
|
|
724
|
+
define: 'HAS_IRIDESCENCEMAP',
|
|
725
|
+
enabledUniformName: 'iridescenceMapEnabled'
|
|
726
|
+
},
|
|
727
|
+
gltf
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
if (extension.iridescenceThicknessTexture) {
|
|
731
|
+
addTexture(
|
|
732
|
+
device,
|
|
733
|
+
extension.iridescenceThicknessTexture,
|
|
734
|
+
'pbr_iridescenceThicknessSampler',
|
|
735
|
+
parsedMaterial,
|
|
736
|
+
{
|
|
737
|
+
featureOptions: {
|
|
738
|
+
define: 'HAS_IRIDESCENCETHICKNESSMAP'
|
|
739
|
+
},
|
|
740
|
+
gltf
|
|
741
|
+
}
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
function parseAnisotropyExtension(
|
|
747
|
+
device: Device,
|
|
748
|
+
extension: GLTFMaterialAnisotropyExtension | undefined,
|
|
749
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
750
|
+
gltf?: GLTFPostprocessed
|
|
751
|
+
): void {
|
|
752
|
+
if (!extension) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (extension.anisotropyStrength !== undefined) {
|
|
757
|
+
parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
|
|
758
|
+
}
|
|
759
|
+
if (extension.anisotropyRotation !== undefined) {
|
|
760
|
+
parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
|
|
761
|
+
}
|
|
762
|
+
if (extension.anisotropyTexture) {
|
|
763
|
+
addTexture(device, extension.anisotropyTexture, 'pbr_anisotropySampler', parsedMaterial, {
|
|
764
|
+
featureOptions: {
|
|
765
|
+
define: 'HAS_ANISOTROPYMAP',
|
|
766
|
+
enabledUniformName: 'anisotropyMapEnabled'
|
|
767
|
+
},
|
|
768
|
+
gltf
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
function parseEmissiveStrengthExtension(
|
|
774
|
+
extension: GLTFMaterialEmissiveStrengthExtension | undefined,
|
|
775
|
+
parsedMaterial: ParsedPBRMaterial
|
|
776
|
+
): void {
|
|
777
|
+
if (extension?.emissiveStrength !== undefined) {
|
|
778
|
+
parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
234
782
|
/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */
|
|
235
783
|
function addTexture(
|
|
236
784
|
device: Device,
|
|
237
785
|
gltfTexture: GLTFTexture,
|
|
238
786
|
uniformName: keyof PBRMaterialBindings,
|
|
239
|
-
|
|
240
|
-
|
|
787
|
+
parsedMaterial: ParsedPBRMaterial,
|
|
788
|
+
textureParseOptions: TextureParseOptions = {}
|
|
241
789
|
): void {
|
|
242
|
-
const
|
|
790
|
+
const {featureOptions = {}, gltf} = textureParseOptions;
|
|
791
|
+
const {define, enabledUniformName} = featureOptions;
|
|
792
|
+
const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
|
|
793
|
+
const image = resolvedTextureInfo.texture?.source?.image;
|
|
794
|
+
if (!image) {
|
|
795
|
+
log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
243
798
|
|
|
244
799
|
const gltfSampler = {
|
|
245
800
|
wrapS: 10497, // default REPEAT S (U) wrapping mode.
|
|
246
801
|
wrapT: 10497, // default REPEAT T (V) wrapping mode.
|
|
247
802
|
minFilter: 9729, // default LINEAR filtering
|
|
248
803
|
magFilter: 9729, // default LINEAR filtering
|
|
249
|
-
...
|
|
804
|
+
...resolvedTextureInfo?.texture?.sampler
|
|
250
805
|
} as GLTFSampler;
|
|
251
806
|
|
|
252
807
|
const baseOptions = {
|
|
253
|
-
id:
|
|
808
|
+
id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
|
|
254
809
|
sampler: convertSampler(gltfSampler)
|
|
255
810
|
};
|
|
256
811
|
|
|
@@ -270,9 +825,43 @@ function addTexture(
|
|
|
270
825
|
|
|
271
826
|
parsedMaterial.bindings[uniformName] = texture;
|
|
272
827
|
if (define) parsedMaterial.defines[define] = true;
|
|
828
|
+
if (enabledUniformName) {
|
|
829
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
830
|
+
}
|
|
273
831
|
parsedMaterial.generatedTextures.push(texture);
|
|
274
832
|
}
|
|
275
833
|
|
|
834
|
+
function resolveTextureInfo(gltfTexture: GLTFTexture, gltf?: GLTFPostprocessed): GLTFTexture {
|
|
835
|
+
if (gltfTexture.texture || gltfTexture.index === undefined || !gltf?.textures) {
|
|
836
|
+
return gltfTexture;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
const resolvedTextureEntry = gltf.textures[gltfTexture.index] as
|
|
840
|
+
| Partial<GLTFTexture>
|
|
841
|
+
| GLTFTexture['texture']
|
|
842
|
+
| undefined;
|
|
843
|
+
if (!resolvedTextureEntry) {
|
|
844
|
+
return gltfTexture;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if ('texture' in resolvedTextureEntry && resolvedTextureEntry.texture) {
|
|
848
|
+
return {
|
|
849
|
+
...resolvedTextureEntry,
|
|
850
|
+
...gltfTexture,
|
|
851
|
+
texture: resolvedTextureEntry.texture
|
|
852
|
+
} as GLTFTexture;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
if (!('source' in resolvedTextureEntry)) {
|
|
856
|
+
return gltfTexture;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
return {
|
|
860
|
+
...gltfTexture,
|
|
861
|
+
texture: resolvedTextureEntry
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
|
|
276
865
|
/** One mip level as produced by loaders.gl compressed texture parsers */
|
|
277
866
|
export type CompressedMipLevel = {
|
|
278
867
|
data: TypedArray;
|
|
@@ -502,7 +1091,7 @@ export class PBRMaterialParser {
|
|
|
502
1091
|
if (imageBasedLightingEnvironment) {
|
|
503
1092
|
this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();
|
|
504
1093
|
this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();
|
|
505
|
-
this.bindings.
|
|
1094
|
+
this.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.getBrdfTexture();
|
|
506
1095
|
this.uniforms.scaleIBLAmbient = [1, 1];
|
|
507
1096
|
}
|
|
508
1097
|
|
|
@@ -572,8 +1161,13 @@ export class PBRMaterialParser {
|
|
|
572
1161
|
log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();
|
|
573
1162
|
Object.assign(this.parameters, {
|
|
574
1163
|
blend: true,
|
|
575
|
-
blendEquation:
|
|
576
|
-
blendFunc: [
|
|
1164
|
+
blendEquation: GLEnum.FUNC_ADD,
|
|
1165
|
+
blendFunc: [
|
|
1166
|
+
GLEnum.SRC_ALPHA,
|
|
1167
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
1168
|
+
GLEnum.ONE,
|
|
1169
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
1170
|
+
]
|
|
577
1171
|
});
|
|
578
1172
|
}
|
|
579
1173
|
}
|
|
@@ -610,7 +1204,8 @@ export class PBRMaterialParser {
|
|
|
610
1204
|
if (image.compressed) {
|
|
611
1205
|
textureOptions = image;
|
|
612
1206
|
specialTextureParameters = {
|
|
613
|
-
[
|
|
1207
|
+
[GLEnum.TEXTURE_MIN_FILTER]:
|
|
1208
|
+
image.data.length > 1 ? GLEnum.LINEAR_MIPMAP_NEAREST : GLEnum.LINEAR
|
|
614
1209
|
};
|
|
615
1210
|
} else {
|
|
616
1211
|
// Texture2D accepts a promise that returns an image as data (Async Textures)
|
|
@@ -624,7 +1219,7 @@ export class PBRMaterialParser {
|
|
|
624
1219
|
...specialTextureParameters
|
|
625
1220
|
},
|
|
626
1221
|
pixelStore: {
|
|
627
|
-
[
|
|
1222
|
+
[GLEnum.UNPACK_FLIP_Y_WEBGL]: false
|
|
628
1223
|
},
|
|
629
1224
|
...textureOptions
|
|
630
1225
|
});
|