@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
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var dist_exports = {};
|
|
|
22
22
|
__export(dist_exports, {
|
|
23
23
|
GLTFAnimator: () => GLTFAnimator,
|
|
24
24
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
25
|
+
getGLTFExtensionSupport: () => getGLTFExtensionSupport,
|
|
25
26
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
26
27
|
parseGLTFLights: () => parseGLTFLights,
|
|
27
28
|
parsePBRMaterial: () => parsePBRMaterial
|
|
@@ -32,6 +33,7 @@ module.exports = __toCommonJS(dist_exports);
|
|
|
32
33
|
var import_engine = require("@luma.gl/engine");
|
|
33
34
|
var import_textures = require("@loaders.gl/textures");
|
|
34
35
|
function loadPBREnvironment(device, props) {
|
|
36
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
35
37
|
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
36
38
|
id: "brdfLUT",
|
|
37
39
|
sampler: {
|
|
@@ -45,7 +47,7 @@ function loadPBREnvironment(device, props) {
|
|
|
45
47
|
});
|
|
46
48
|
const diffuseEnvSampler = makeCube(device, {
|
|
47
49
|
id: "DiffuseEnvSampler",
|
|
48
|
-
getTextureForFace: (
|
|
50
|
+
getTextureForFace: (face) => (0, import_textures.loadImageTexture)(props.getTexUrl("diffuse", FACES.indexOf(face), 0)),
|
|
49
51
|
sampler: {
|
|
50
52
|
addressModeU: "clamp-to-edge",
|
|
51
53
|
addressModeV: "clamp-to-edge",
|
|
@@ -55,12 +57,13 @@ function loadPBREnvironment(device, props) {
|
|
|
55
57
|
});
|
|
56
58
|
const specularEnvSampler = makeCube(device, {
|
|
57
59
|
id: "SpecularEnvSampler",
|
|
58
|
-
getTextureForFace: (
|
|
60
|
+
getTextureForFace: (face) => {
|
|
59
61
|
const imageArray = [];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
const direction = FACES.indexOf(face);
|
|
63
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
64
|
+
imageArray.push((0, import_textures.loadImageTexture)(props.getTexUrl("specular", direction, lod)));
|
|
62
65
|
}
|
|
63
|
-
return imageArray;
|
|
66
|
+
return Promise.all(imageArray);
|
|
64
67
|
},
|
|
65
68
|
sampler: {
|
|
66
69
|
addressModeU: "clamp-to-edge",
|
|
@@ -76,28 +79,57 @@ function loadPBREnvironment(device, props) {
|
|
|
76
79
|
specularEnvSampler
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
|
-
var FACES = [
|
|
82
|
+
var FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
80
83
|
function makeCube(device, { id, getTextureForFace, sampler }) {
|
|
81
|
-
const data = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
const data = Promise.all(FACES.map((face) => getTextureForFace(face))).then((faceDataArray) => {
|
|
85
|
+
const cubeData = {};
|
|
86
|
+
FACES.forEach((face, index) => {
|
|
87
|
+
cubeData[face] = faceDataArray[index];
|
|
88
|
+
});
|
|
89
|
+
return cubeData;
|
|
84
90
|
});
|
|
85
91
|
return new import_engine.DynamicTexture(device, {
|
|
86
92
|
id,
|
|
87
93
|
dimension: "cube",
|
|
88
94
|
mipmaps: false,
|
|
89
95
|
sampler,
|
|
90
|
-
// @ts-expect-error
|
|
91
96
|
data
|
|
92
97
|
});
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
// dist/parsers/parse-pbr-material.js
|
|
96
101
|
var import_core = require("@luma.gl/core");
|
|
97
|
-
|
|
102
|
+
|
|
103
|
+
// dist/webgl-to-webgpu/gltf-webgl-constants.js
|
|
104
|
+
var GLEnum;
|
|
105
|
+
(function(GLEnum2) {
|
|
106
|
+
GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS";
|
|
107
|
+
GLEnum2[GLEnum2["LINES"] = 1] = "LINES";
|
|
108
|
+
GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP";
|
|
109
|
+
GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP";
|
|
110
|
+
GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES";
|
|
111
|
+
GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
|
|
112
|
+
GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
|
|
113
|
+
GLEnum2[GLEnum2["ONE"] = 1] = "ONE";
|
|
114
|
+
GLEnum2[GLEnum2["SRC_ALPHA"] = 770] = "SRC_ALPHA";
|
|
115
|
+
GLEnum2[GLEnum2["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA";
|
|
116
|
+
GLEnum2[GLEnum2["FUNC_ADD"] = 32774] = "FUNC_ADD";
|
|
117
|
+
GLEnum2[GLEnum2["LINEAR"] = 9729] = "LINEAR";
|
|
118
|
+
GLEnum2[GLEnum2["NEAREST"] = 9728] = "NEAREST";
|
|
119
|
+
GLEnum2[GLEnum2["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
|
|
120
|
+
GLEnum2[GLEnum2["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
|
|
121
|
+
GLEnum2[GLEnum2["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
|
|
122
|
+
GLEnum2[GLEnum2["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";
|
|
123
|
+
GLEnum2[GLEnum2["TEXTURE_MIN_FILTER"] = 10241] = "TEXTURE_MIN_FILTER";
|
|
124
|
+
GLEnum2[GLEnum2["TEXTURE_WRAP_S"] = 10242] = "TEXTURE_WRAP_S";
|
|
125
|
+
GLEnum2[GLEnum2["TEXTURE_WRAP_T"] = 10243] = "TEXTURE_WRAP_T";
|
|
126
|
+
GLEnum2[GLEnum2["REPEAT"] = 10497] = "REPEAT";
|
|
127
|
+
GLEnum2[GLEnum2["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE";
|
|
128
|
+
GLEnum2[GLEnum2["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT";
|
|
129
|
+
GLEnum2[GLEnum2["UNPACK_FLIP_Y_WEBGL"] = 37440] = "UNPACK_FLIP_Y_WEBGL";
|
|
130
|
+
})(GLEnum || (GLEnum = {}));
|
|
98
131
|
|
|
99
132
|
// dist/webgl-to-webgpu/convert-webgl-sampler.js
|
|
100
|
-
var import_constants = require("@luma.gl/constants");
|
|
101
133
|
function convertSampler(gltfSampler) {
|
|
102
134
|
return {
|
|
103
135
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -108,11 +140,11 @@ function convertSampler(gltfSampler) {
|
|
|
108
140
|
}
|
|
109
141
|
function convertSamplerWrapMode(mode) {
|
|
110
142
|
switch (mode) {
|
|
111
|
-
case
|
|
143
|
+
case GLEnum.CLAMP_TO_EDGE:
|
|
112
144
|
return "clamp-to-edge";
|
|
113
|
-
case
|
|
145
|
+
case GLEnum.REPEAT:
|
|
114
146
|
return "repeat";
|
|
115
|
-
case
|
|
147
|
+
case GLEnum.MIRRORED_REPEAT:
|
|
116
148
|
return "mirror-repeat";
|
|
117
149
|
default:
|
|
118
150
|
return void 0;
|
|
@@ -120,9 +152,9 @@ function convertSamplerWrapMode(mode) {
|
|
|
120
152
|
}
|
|
121
153
|
function convertSamplerMagFilter(mode) {
|
|
122
154
|
switch (mode) {
|
|
123
|
-
case
|
|
155
|
+
case GLEnum.NEAREST:
|
|
124
156
|
return "nearest";
|
|
125
|
-
case
|
|
157
|
+
case GLEnum.LINEAR:
|
|
126
158
|
return "linear";
|
|
127
159
|
default:
|
|
128
160
|
return void 0;
|
|
@@ -130,17 +162,17 @@ function convertSamplerMagFilter(mode) {
|
|
|
130
162
|
}
|
|
131
163
|
function convertSamplerMinFilter(mode) {
|
|
132
164
|
switch (mode) {
|
|
133
|
-
case
|
|
165
|
+
case GLEnum.NEAREST:
|
|
134
166
|
return { minFilter: "nearest" };
|
|
135
|
-
case
|
|
167
|
+
case GLEnum.LINEAR:
|
|
136
168
|
return { minFilter: "linear" };
|
|
137
|
-
case
|
|
169
|
+
case GLEnum.NEAREST_MIPMAP_NEAREST:
|
|
138
170
|
return { minFilter: "nearest", mipmapFilter: "nearest" };
|
|
139
|
-
case
|
|
171
|
+
case GLEnum.LINEAR_MIPMAP_NEAREST:
|
|
140
172
|
return { minFilter: "linear", mipmapFilter: "nearest" };
|
|
141
|
-
case
|
|
173
|
+
case GLEnum.NEAREST_MIPMAP_LINEAR:
|
|
142
174
|
return { minFilter: "nearest", mipmapFilter: "linear" };
|
|
143
|
-
case
|
|
175
|
+
case GLEnum.LINEAR_MIPMAP_LINEAR:
|
|
144
176
|
return { minFilter: "linear", mipmapFilter: "linear" };
|
|
145
177
|
default:
|
|
146
178
|
return {};
|
|
@@ -172,7 +204,8 @@ function parsePBRMaterial(device, material, attributes, options) {
|
|
|
172
204
|
if (imageBasedLightingEnvironment) {
|
|
173
205
|
parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
174
206
|
parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
175
|
-
parsedMaterial.bindings.
|
|
207
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
208
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
176
209
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
177
210
|
}
|
|
178
211
|
if (options == null ? void 0 : options.pbrDebug) {
|
|
@@ -195,69 +228,419 @@ function parsePBRMaterial(device, material, attributes, options) {
|
|
|
195
228
|
if (options == null ? void 0 : options.lights)
|
|
196
229
|
parsedMaterial.defines["USE_LIGHTS"] = true;
|
|
197
230
|
if (material) {
|
|
198
|
-
|
|
231
|
+
if (options.validateAttributes !== false) {
|
|
232
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
233
|
+
}
|
|
234
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
199
235
|
}
|
|
200
236
|
return parsedMaterial;
|
|
201
237
|
}
|
|
202
|
-
function
|
|
203
|
-
|
|
238
|
+
function warnOnMissingExpectedAttributes(material, attributes) {
|
|
239
|
+
var _a;
|
|
240
|
+
const uvDependentTextureSlots = getUvDependentTextureSlots(material);
|
|
241
|
+
if (uvDependentTextureSlots.length > 0 && !attributes["TEXCOORD_0"]) {
|
|
242
|
+
import_core.log.warn(`glTF material uses ${uvDependentTextureSlots.join(", ")} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`)();
|
|
243
|
+
}
|
|
244
|
+
const isUnlitMaterial = Boolean(material.unlit || ((_a = material.extensions) == null ? void 0 : _a.KHR_materials_unlit));
|
|
245
|
+
if (isUnlitMaterial || attributes["NORMAL"]) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const missingNormalReason = material.normalTexture ? "lit PBR shading with normalTexture" : "lit PBR shading";
|
|
249
|
+
import_core.log.warn(`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`)();
|
|
250
|
+
}
|
|
251
|
+
function getUvDependentTextureSlots(material) {
|
|
252
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
253
|
+
const uvDependentTextureSlots = [];
|
|
254
|
+
if ((_a = material.pbrMetallicRoughness) == null ? void 0 : _a.baseColorTexture) {
|
|
255
|
+
uvDependentTextureSlots.push("baseColorTexture");
|
|
256
|
+
}
|
|
257
|
+
if ((_b = material.pbrMetallicRoughness) == null ? void 0 : _b.metallicRoughnessTexture) {
|
|
258
|
+
uvDependentTextureSlots.push("metallicRoughnessTexture");
|
|
259
|
+
}
|
|
260
|
+
if (material.normalTexture) {
|
|
261
|
+
uvDependentTextureSlots.push("normalTexture");
|
|
262
|
+
}
|
|
263
|
+
if (material.occlusionTexture) {
|
|
264
|
+
uvDependentTextureSlots.push("occlusionTexture");
|
|
265
|
+
}
|
|
266
|
+
if (material.emissiveTexture) {
|
|
267
|
+
uvDependentTextureSlots.push("emissiveTexture");
|
|
268
|
+
}
|
|
269
|
+
if ((_d = (_c = material.extensions) == null ? void 0 : _c.KHR_materials_specular) == null ? void 0 : _d.specularTexture) {
|
|
270
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularTexture");
|
|
271
|
+
}
|
|
272
|
+
if ((_f = (_e = material.extensions) == null ? void 0 : _e.KHR_materials_specular) == null ? void 0 : _f.specularColorTexture) {
|
|
273
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularColorTexture");
|
|
274
|
+
}
|
|
275
|
+
if ((_h = (_g = material.extensions) == null ? void 0 : _g.KHR_materials_transmission) == null ? void 0 : _h.transmissionTexture) {
|
|
276
|
+
uvDependentTextureSlots.push("KHR_materials_transmission.transmissionTexture");
|
|
277
|
+
}
|
|
278
|
+
if ((_j = (_i = material.extensions) == null ? void 0 : _i.KHR_materials_clearcoat) == null ? void 0 : _j.clearcoatTexture) {
|
|
279
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatTexture");
|
|
280
|
+
}
|
|
281
|
+
if ((_l = (_k = material.extensions) == null ? void 0 : _k.KHR_materials_clearcoat) == null ? void 0 : _l.clearcoatRoughnessTexture) {
|
|
282
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatRoughnessTexture");
|
|
283
|
+
}
|
|
284
|
+
if ((_n = (_m = material.extensions) == null ? void 0 : _m.KHR_materials_sheen) == null ? void 0 : _n.sheenColorTexture) {
|
|
285
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenColorTexture");
|
|
286
|
+
}
|
|
287
|
+
if ((_p = (_o = material.extensions) == null ? void 0 : _o.KHR_materials_sheen) == null ? void 0 : _p.sheenRoughnessTexture) {
|
|
288
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenRoughnessTexture");
|
|
289
|
+
}
|
|
290
|
+
if ((_r = (_q = material.extensions) == null ? void 0 : _q.KHR_materials_iridescence) == null ? void 0 : _r.iridescenceTexture) {
|
|
291
|
+
uvDependentTextureSlots.push("KHR_materials_iridescence.iridescenceTexture");
|
|
292
|
+
}
|
|
293
|
+
if ((_t = (_s = material.extensions) == null ? void 0 : _s.KHR_materials_anisotropy) == null ? void 0 : _t.anisotropyTexture) {
|
|
294
|
+
uvDependentTextureSlots.push("KHR_materials_anisotropy.anisotropyTexture");
|
|
295
|
+
}
|
|
296
|
+
return uvDependentTextureSlots;
|
|
297
|
+
}
|
|
298
|
+
function parseMaterial(device, material, parsedMaterial, gltf) {
|
|
299
|
+
var _a;
|
|
300
|
+
parsedMaterial.uniforms.unlit = Boolean(material.unlit || ((_a = material.extensions) == null ? void 0 : _a.KHR_materials_unlit));
|
|
204
301
|
if (material.pbrMetallicRoughness) {
|
|
205
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
302
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
206
303
|
}
|
|
207
304
|
if (material.normalTexture) {
|
|
208
|
-
addTexture(device, material.normalTexture, "pbr_normalSampler",
|
|
305
|
+
addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
|
|
306
|
+
featureOptions: {
|
|
307
|
+
define: "HAS_NORMALMAP",
|
|
308
|
+
enabledUniformName: "normalMapEnabled"
|
|
309
|
+
},
|
|
310
|
+
gltf
|
|
311
|
+
});
|
|
209
312
|
const { scale = 1 } = material.normalTexture;
|
|
210
313
|
parsedMaterial.uniforms.normalScale = scale;
|
|
211
314
|
}
|
|
212
315
|
if (material.occlusionTexture) {
|
|
213
|
-
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler",
|
|
316
|
+
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
|
|
317
|
+
featureOptions: {
|
|
318
|
+
define: "HAS_OCCLUSIONMAP",
|
|
319
|
+
enabledUniformName: "occlusionMapEnabled"
|
|
320
|
+
},
|
|
321
|
+
gltf
|
|
322
|
+
});
|
|
214
323
|
const { strength = 1 } = material.occlusionTexture;
|
|
215
324
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
216
325
|
}
|
|
326
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
217
327
|
if (material.emissiveTexture) {
|
|
218
|
-
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler",
|
|
219
|
-
|
|
328
|
+
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", parsedMaterial, {
|
|
329
|
+
featureOptions: {
|
|
330
|
+
define: "HAS_EMISSIVEMAP",
|
|
331
|
+
enabledUniformName: "emissiveMapEnabled"
|
|
332
|
+
},
|
|
333
|
+
gltf
|
|
334
|
+
});
|
|
220
335
|
}
|
|
221
|
-
|
|
222
|
-
|
|
336
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
337
|
+
switch (material.alphaMode || "OPAQUE") {
|
|
338
|
+
case "OPAQUE":
|
|
339
|
+
break;
|
|
340
|
+
case "MASK": {
|
|
223
341
|
const { alphaCutoff = 0.5 } = material;
|
|
224
342
|
parsedMaterial.defines["ALPHA_CUTOFF"] = true;
|
|
343
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
225
344
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
226
345
|
break;
|
|
346
|
+
}
|
|
227
347
|
case "BLEND":
|
|
228
348
|
import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
|
|
229
|
-
parsedMaterial
|
|
230
|
-
parsedMaterial.parameters.blendColorOperation = "add";
|
|
231
|
-
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
232
|
-
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
233
|
-
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
234
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
235
|
-
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
236
|
-
parsedMaterial.glParameters["blend"] = true;
|
|
237
|
-
parsedMaterial.glParameters["blendEquation"] = 32774;
|
|
238
|
-
parsedMaterial.glParameters["blendFunc"] = [
|
|
239
|
-
770,
|
|
240
|
-
771,
|
|
241
|
-
1,
|
|
242
|
-
771
|
|
243
|
-
];
|
|
349
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
244
350
|
break;
|
|
245
351
|
}
|
|
246
352
|
}
|
|
247
|
-
function
|
|
353
|
+
function applyAlphaBlendParameters(parsedMaterial) {
|
|
354
|
+
parsedMaterial.parameters.blend = true;
|
|
355
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
356
|
+
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
357
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
358
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
359
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
360
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
361
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
362
|
+
parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
|
|
363
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
364
|
+
GLEnum.SRC_ALPHA,
|
|
365
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
366
|
+
GLEnum.ONE,
|
|
367
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
368
|
+
];
|
|
369
|
+
}
|
|
370
|
+
function applyTransmissionBlendApproximation(parsedMaterial) {
|
|
371
|
+
parsedMaterial.parameters.blend = true;
|
|
372
|
+
parsedMaterial.parameters.depthWriteEnabled = false;
|
|
373
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
374
|
+
parsedMaterial.parameters.blendColorSrcFactor = "one";
|
|
375
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
376
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
377
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
378
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
379
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
380
|
+
parsedMaterial.glParameters["depthMask"] = false;
|
|
381
|
+
parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
|
|
382
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
383
|
+
GLEnum.ONE,
|
|
384
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
385
|
+
GLEnum.ONE,
|
|
386
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial, gltf) {
|
|
248
390
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
249
|
-
addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler",
|
|
391
|
+
addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler", parsedMaterial, {
|
|
392
|
+
featureOptions: {
|
|
393
|
+
define: "HAS_BASECOLORMAP",
|
|
394
|
+
enabledUniformName: "baseColorMapEnabled"
|
|
395
|
+
},
|
|
396
|
+
gltf
|
|
397
|
+
});
|
|
250
398
|
}
|
|
251
399
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
252
400
|
if (pbrMetallicRoughness.metallicRoughnessTexture) {
|
|
253
|
-
addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler",
|
|
401
|
+
addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler", parsedMaterial, {
|
|
402
|
+
featureOptions: {
|
|
403
|
+
define: "HAS_METALROUGHNESSMAP",
|
|
404
|
+
enabledUniformName: "metallicRoughnessMapEnabled"
|
|
405
|
+
},
|
|
406
|
+
gltf
|
|
407
|
+
});
|
|
254
408
|
}
|
|
255
409
|
const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
|
|
256
410
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
257
411
|
}
|
|
258
|
-
function
|
|
259
|
-
|
|
260
|
-
|
|
412
|
+
function parseMaterialExtensions(device, extensions, parsedMaterial, gltf) {
|
|
413
|
+
if (!extensions) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (hasMaterialExtensionShading(extensions)) {
|
|
417
|
+
parsedMaterial.defines["USE_MATERIAL_EXTENSIONS"] = true;
|
|
418
|
+
}
|
|
419
|
+
parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);
|
|
420
|
+
parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
|
|
421
|
+
parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);
|
|
422
|
+
parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);
|
|
423
|
+
parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);
|
|
424
|
+
parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);
|
|
425
|
+
parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);
|
|
426
|
+
parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);
|
|
427
|
+
parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
|
|
428
|
+
}
|
|
429
|
+
function hasMaterialExtensionShading(extensions) {
|
|
430
|
+
return Boolean(extensions.KHR_materials_specular || extensions.KHR_materials_ior || extensions.KHR_materials_transmission || extensions.KHR_materials_volume || extensions.KHR_materials_clearcoat || extensions.KHR_materials_sheen || extensions.KHR_materials_iridescence || extensions.KHR_materials_anisotropy);
|
|
431
|
+
}
|
|
432
|
+
function parseSpecularExtension(device, extension, parsedMaterial, gltf) {
|
|
433
|
+
if (!extension) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (extension.specularColorFactor) {
|
|
437
|
+
parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
|
|
438
|
+
}
|
|
439
|
+
if (extension.specularFactor !== void 0) {
|
|
440
|
+
parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
|
|
441
|
+
}
|
|
442
|
+
if (extension.specularColorTexture) {
|
|
443
|
+
addTexture(device, extension.specularColorTexture, "pbr_specularColorSampler", parsedMaterial, {
|
|
444
|
+
featureOptions: {
|
|
445
|
+
define: "HAS_SPECULARCOLORMAP",
|
|
446
|
+
enabledUniformName: "specularColorMapEnabled"
|
|
447
|
+
},
|
|
448
|
+
gltf
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
if (extension.specularTexture) {
|
|
452
|
+
addTexture(device, extension.specularTexture, "pbr_specularIntensitySampler", parsedMaterial, {
|
|
453
|
+
featureOptions: {
|
|
454
|
+
define: "HAS_SPECULARINTENSITYMAP",
|
|
455
|
+
enabledUniformName: "specularIntensityMapEnabled"
|
|
456
|
+
},
|
|
457
|
+
gltf
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function parseIorExtension(extension, parsedMaterial) {
|
|
462
|
+
if ((extension == null ? void 0 : extension.ior) !== void 0) {
|
|
463
|
+
parsedMaterial.uniforms.ior = extension.ior;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function parseTransmissionExtension(device, extension, parsedMaterial, gltf) {
|
|
467
|
+
if (!extension) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (extension.transmissionFactor !== void 0) {
|
|
471
|
+
parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
|
|
472
|
+
}
|
|
473
|
+
if (extension.transmissionTexture) {
|
|
474
|
+
addTexture(device, extension.transmissionTexture, "pbr_transmissionSampler", parsedMaterial, {
|
|
475
|
+
featureOptions: {
|
|
476
|
+
define: "HAS_TRANSMISSIONMAP",
|
|
477
|
+
enabledUniformName: "transmissionMapEnabled"
|
|
478
|
+
},
|
|
479
|
+
gltf
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
|
|
483
|
+
import_core.log.warn("KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting")();
|
|
484
|
+
applyTransmissionBlendApproximation(parsedMaterial);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function parseVolumeExtension(device, extension, parsedMaterial, gltf) {
|
|
488
|
+
if (!extension) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (extension.thicknessFactor !== void 0) {
|
|
492
|
+
parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
|
|
493
|
+
}
|
|
494
|
+
if (extension.thicknessTexture) {
|
|
495
|
+
addTexture(device, extension.thicknessTexture, "pbr_thicknessSampler", parsedMaterial, {
|
|
496
|
+
featureOptions: {
|
|
497
|
+
define: "HAS_THICKNESSMAP"
|
|
498
|
+
},
|
|
499
|
+
gltf
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
if (extension.attenuationDistance !== void 0) {
|
|
503
|
+
parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
|
|
504
|
+
}
|
|
505
|
+
if (extension.attenuationColor) {
|
|
506
|
+
parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function parseClearcoatExtension(device, extension, parsedMaterial, gltf) {
|
|
510
|
+
if (!extension) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (extension.clearcoatFactor !== void 0) {
|
|
514
|
+
parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
|
|
515
|
+
}
|
|
516
|
+
if (extension.clearcoatRoughnessFactor !== void 0) {
|
|
517
|
+
parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
|
|
518
|
+
}
|
|
519
|
+
if (extension.clearcoatTexture) {
|
|
520
|
+
addTexture(device, extension.clearcoatTexture, "pbr_clearcoatSampler", parsedMaterial, {
|
|
521
|
+
featureOptions: {
|
|
522
|
+
define: "HAS_CLEARCOATMAP",
|
|
523
|
+
enabledUniformName: "clearcoatMapEnabled"
|
|
524
|
+
},
|
|
525
|
+
gltf
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (extension.clearcoatRoughnessTexture) {
|
|
529
|
+
addTexture(device, extension.clearcoatRoughnessTexture, "pbr_clearcoatRoughnessSampler", parsedMaterial, {
|
|
530
|
+
featureOptions: {
|
|
531
|
+
define: "HAS_CLEARCOATROUGHNESSMAP",
|
|
532
|
+
enabledUniformName: "clearcoatRoughnessMapEnabled"
|
|
533
|
+
},
|
|
534
|
+
gltf
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
if (extension.clearcoatNormalTexture) {
|
|
538
|
+
addTexture(device, extension.clearcoatNormalTexture, "pbr_clearcoatNormalSampler", parsedMaterial, {
|
|
539
|
+
featureOptions: {
|
|
540
|
+
define: "HAS_CLEARCOATNORMALMAP"
|
|
541
|
+
},
|
|
542
|
+
gltf
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function parseSheenExtension(device, extension, parsedMaterial, gltf) {
|
|
547
|
+
if (!extension) {
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (extension.sheenColorFactor) {
|
|
551
|
+
parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
|
|
552
|
+
}
|
|
553
|
+
if (extension.sheenRoughnessFactor !== void 0) {
|
|
554
|
+
parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
|
|
555
|
+
}
|
|
556
|
+
if (extension.sheenColorTexture) {
|
|
557
|
+
addTexture(device, extension.sheenColorTexture, "pbr_sheenColorSampler", parsedMaterial, {
|
|
558
|
+
featureOptions: {
|
|
559
|
+
define: "HAS_SHEENCOLORMAP",
|
|
560
|
+
enabledUniformName: "sheenColorMapEnabled"
|
|
561
|
+
},
|
|
562
|
+
gltf
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
if (extension.sheenRoughnessTexture) {
|
|
566
|
+
addTexture(device, extension.sheenRoughnessTexture, "pbr_sheenRoughnessSampler", parsedMaterial, {
|
|
567
|
+
featureOptions: {
|
|
568
|
+
define: "HAS_SHEENROUGHNESSMAP",
|
|
569
|
+
enabledUniformName: "sheenRoughnessMapEnabled"
|
|
570
|
+
},
|
|
571
|
+
gltf
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function parseIridescenceExtension(device, extension, parsedMaterial, gltf) {
|
|
576
|
+
if (!extension) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (extension.iridescenceFactor !== void 0) {
|
|
580
|
+
parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
|
|
581
|
+
}
|
|
582
|
+
if (extension.iridescenceIor !== void 0) {
|
|
583
|
+
parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
|
|
584
|
+
}
|
|
585
|
+
if (extension.iridescenceThicknessMinimum !== void 0 || extension.iridescenceThicknessMaximum !== void 0) {
|
|
586
|
+
parsedMaterial.uniforms.iridescenceThicknessRange = [
|
|
587
|
+
extension.iridescenceThicknessMinimum ?? 100,
|
|
588
|
+
extension.iridescenceThicknessMaximum ?? 400
|
|
589
|
+
];
|
|
590
|
+
}
|
|
591
|
+
if (extension.iridescenceTexture) {
|
|
592
|
+
addTexture(device, extension.iridescenceTexture, "pbr_iridescenceSampler", parsedMaterial, {
|
|
593
|
+
featureOptions: {
|
|
594
|
+
define: "HAS_IRIDESCENCEMAP",
|
|
595
|
+
enabledUniformName: "iridescenceMapEnabled"
|
|
596
|
+
},
|
|
597
|
+
gltf
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
if (extension.iridescenceThicknessTexture) {
|
|
601
|
+
addTexture(device, extension.iridescenceThicknessTexture, "pbr_iridescenceThicknessSampler", parsedMaterial, {
|
|
602
|
+
featureOptions: {
|
|
603
|
+
define: "HAS_IRIDESCENCETHICKNESSMAP"
|
|
604
|
+
},
|
|
605
|
+
gltf
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function parseAnisotropyExtension(device, extension, parsedMaterial, gltf) {
|
|
610
|
+
if (!extension) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (extension.anisotropyStrength !== void 0) {
|
|
614
|
+
parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
|
|
615
|
+
}
|
|
616
|
+
if (extension.anisotropyRotation !== void 0) {
|
|
617
|
+
parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
|
|
618
|
+
}
|
|
619
|
+
if (extension.anisotropyTexture) {
|
|
620
|
+
addTexture(device, extension.anisotropyTexture, "pbr_anisotropySampler", parsedMaterial, {
|
|
621
|
+
featureOptions: {
|
|
622
|
+
define: "HAS_ANISOTROPYMAP",
|
|
623
|
+
enabledUniformName: "anisotropyMapEnabled"
|
|
624
|
+
},
|
|
625
|
+
gltf
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
function parseEmissiveStrengthExtension(extension, parsedMaterial) {
|
|
630
|
+
if ((extension == null ? void 0 : extension.emissiveStrength) !== void 0) {
|
|
631
|
+
parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function addTexture(device, gltfTexture, uniformName, parsedMaterial, textureParseOptions = {}) {
|
|
635
|
+
var _a, _b, _c;
|
|
636
|
+
const { featureOptions = {}, gltf } = textureParseOptions;
|
|
637
|
+
const { define, enabledUniformName } = featureOptions;
|
|
638
|
+
const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
|
|
639
|
+
const image = (_b = (_a = resolvedTextureInfo.texture) == null ? void 0 : _a.source) == null ? void 0 : _b.image;
|
|
640
|
+
if (!image) {
|
|
641
|
+
import_core.log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
261
644
|
const gltfSampler = {
|
|
262
645
|
wrapS: 10497,
|
|
263
646
|
// default REPEAT S (U) wrapping mode.
|
|
@@ -267,10 +650,10 @@ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
|
267
650
|
// default LINEAR filtering
|
|
268
651
|
magFilter: 9729,
|
|
269
652
|
// default LINEAR filtering
|
|
270
|
-
...(
|
|
653
|
+
...(_c = resolvedTextureInfo == null ? void 0 : resolvedTextureInfo.texture) == null ? void 0 : _c.sampler
|
|
271
654
|
};
|
|
272
655
|
const baseOptions = {
|
|
273
|
-
id:
|
|
656
|
+
id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
|
|
274
657
|
sampler: convertSampler(gltfSampler)
|
|
275
658
|
};
|
|
276
659
|
let texture;
|
|
@@ -288,8 +671,34 @@ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
|
288
671
|
parsedMaterial.bindings[uniformName] = texture;
|
|
289
672
|
if (define)
|
|
290
673
|
parsedMaterial.defines[define] = true;
|
|
674
|
+
if (enabledUniformName) {
|
|
675
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
676
|
+
}
|
|
291
677
|
parsedMaterial.generatedTextures.push(texture);
|
|
292
678
|
}
|
|
679
|
+
function resolveTextureInfo(gltfTexture, gltf) {
|
|
680
|
+
if (gltfTexture.texture || gltfTexture.index === void 0 || !(gltf == null ? void 0 : gltf.textures)) {
|
|
681
|
+
return gltfTexture;
|
|
682
|
+
}
|
|
683
|
+
const resolvedTextureEntry = gltf.textures[gltfTexture.index];
|
|
684
|
+
if (!resolvedTextureEntry) {
|
|
685
|
+
return gltfTexture;
|
|
686
|
+
}
|
|
687
|
+
if ("texture" in resolvedTextureEntry && resolvedTextureEntry.texture) {
|
|
688
|
+
return {
|
|
689
|
+
...resolvedTextureEntry,
|
|
690
|
+
...gltfTexture,
|
|
691
|
+
texture: resolvedTextureEntry.texture
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (!("source" in resolvedTextureEntry)) {
|
|
695
|
+
return gltfTexture;
|
|
696
|
+
}
|
|
697
|
+
return {
|
|
698
|
+
...gltfTexture,
|
|
699
|
+
texture: resolvedTextureEntry
|
|
700
|
+
};
|
|
701
|
+
}
|
|
293
702
|
function createCompressedTextureFallback(device, baseOptions) {
|
|
294
703
|
return device.createTexture({
|
|
295
704
|
...baseOptions,
|
|
@@ -383,6 +792,7 @@ function createCompressedTexture(device, image, baseOptions) {
|
|
|
383
792
|
|
|
384
793
|
// dist/parsers/parse-gltf-lights.js
|
|
385
794
|
var import_core2 = require("@math.gl/core");
|
|
795
|
+
var GLTF_COLOR_FACTOR = 255;
|
|
386
796
|
function parseGLTFLights(gltf) {
|
|
387
797
|
var _a, _b, _c, _d;
|
|
388
798
|
const lightDefs = (
|
|
@@ -393,6 +803,8 @@ function parseGLTFLights(gltf) {
|
|
|
393
803
|
return [];
|
|
394
804
|
}
|
|
395
805
|
const lights = [];
|
|
806
|
+
const parentNodeById = createParentNodeMap(gltf.nodes || []);
|
|
807
|
+
const worldMatrixByNodeId = /* @__PURE__ */ new Map();
|
|
396
808
|
for (const node of gltf.nodes || []) {
|
|
397
809
|
const lightIndex = node.light ?? ((_d = (_c = node.extensions) == null ? void 0 : _c.KHR_lights_punctual) == null ? void 0 : _d.light);
|
|
398
810
|
if (typeof lightIndex !== "number") {
|
|
@@ -402,18 +814,19 @@ function parseGLTFLights(gltf) {
|
|
|
402
814
|
if (!gltfLight) {
|
|
403
815
|
continue;
|
|
404
816
|
}
|
|
405
|
-
const color = gltfLight.color || [1, 1, 1];
|
|
817
|
+
const color = normalizeGLTFLightColor(gltfLight.color || [1, 1, 1]);
|
|
406
818
|
const intensity = gltfLight.intensity ?? 1;
|
|
407
819
|
const range = gltfLight.range;
|
|
820
|
+
const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);
|
|
408
821
|
switch (gltfLight.type) {
|
|
409
822
|
case "directional":
|
|
410
|
-
lights.push(parseDirectionalLight(
|
|
823
|
+
lights.push(parseDirectionalLight(worldMatrix, color, intensity));
|
|
411
824
|
break;
|
|
412
825
|
case "point":
|
|
413
|
-
lights.push(parsePointLight(
|
|
826
|
+
lights.push(parsePointLight(worldMatrix, color, intensity, range));
|
|
414
827
|
break;
|
|
415
828
|
case "spot":
|
|
416
|
-
lights.push(
|
|
829
|
+
lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));
|
|
417
830
|
break;
|
|
418
831
|
default:
|
|
419
832
|
break;
|
|
@@ -421,8 +834,11 @@ function parseGLTFLights(gltf) {
|
|
|
421
834
|
}
|
|
422
835
|
return lights;
|
|
423
836
|
}
|
|
424
|
-
function
|
|
425
|
-
|
|
837
|
+
function normalizeGLTFLightColor(color) {
|
|
838
|
+
return color.map((component) => component * GLTF_COLOR_FACTOR);
|
|
839
|
+
}
|
|
840
|
+
function parsePointLight(worldMatrix, color, intensity, range) {
|
|
841
|
+
const position = getLightPosition(worldMatrix);
|
|
426
842
|
let attenuation = [1, 0, 0];
|
|
427
843
|
if (range !== void 0 && range > 0) {
|
|
428
844
|
attenuation = [1, 0, 1 / (range * range)];
|
|
@@ -435,8 +851,8 @@ function parsePointLight(node, color, intensity, range) {
|
|
|
435
851
|
attenuation
|
|
436
852
|
};
|
|
437
853
|
}
|
|
438
|
-
function parseDirectionalLight(
|
|
439
|
-
const direction =
|
|
854
|
+
function parseDirectionalLight(worldMatrix, color, intensity) {
|
|
855
|
+
const direction = getLightDirection(worldMatrix);
|
|
440
856
|
return {
|
|
441
857
|
type: "directional",
|
|
442
858
|
direction,
|
|
@@ -444,39 +860,72 @@ function parseDirectionalLight(node, color, intensity) {
|
|
|
444
860
|
intensity
|
|
445
861
|
};
|
|
446
862
|
}
|
|
447
|
-
function
|
|
448
|
-
|
|
449
|
-
|
|
863
|
+
function parseSpotLight(worldMatrix, color, intensity, range, spot = {}) {
|
|
864
|
+
const position = getLightPosition(worldMatrix);
|
|
865
|
+
const direction = getLightDirection(worldMatrix);
|
|
866
|
+
let attenuation = [1, 0, 0];
|
|
867
|
+
if (range !== void 0 && range > 0) {
|
|
868
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
450
869
|
}
|
|
451
|
-
|
|
452
|
-
|
|
870
|
+
return {
|
|
871
|
+
type: "spot",
|
|
872
|
+
position,
|
|
873
|
+
direction,
|
|
874
|
+
color,
|
|
875
|
+
intensity,
|
|
876
|
+
attenuation,
|
|
877
|
+
innerConeAngle: spot.innerConeAngle ?? 0,
|
|
878
|
+
outerConeAngle: spot.outerConeAngle ?? Math.PI / 4
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
function createParentNodeMap(nodes) {
|
|
882
|
+
const parentNodeById = /* @__PURE__ */ new Map();
|
|
883
|
+
for (const node of nodes) {
|
|
884
|
+
for (const childNode of node.children || []) {
|
|
885
|
+
parentNodeById.set(childNode.id, node);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return parentNodeById;
|
|
889
|
+
}
|
|
890
|
+
function getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId) {
|
|
891
|
+
const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);
|
|
892
|
+
if (cachedWorldMatrix) {
|
|
893
|
+
return cachedWorldMatrix;
|
|
453
894
|
}
|
|
454
|
-
|
|
895
|
+
const localMatrix = getNodeLocalMatrix(node);
|
|
896
|
+
const parentNode = parentNodeById.get(node.id);
|
|
897
|
+
const worldMatrix = parentNode ? new import_core2.Matrix4(getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)).multiplyRight(localMatrix) : localMatrix;
|
|
898
|
+
worldMatrixByNodeId.set(node.id, worldMatrix);
|
|
899
|
+
return worldMatrix;
|
|
455
900
|
}
|
|
456
|
-
function
|
|
901
|
+
function getNodeLocalMatrix(node) {
|
|
457
902
|
if (node.matrix) {
|
|
458
|
-
return new import_core2.Matrix4(node.matrix)
|
|
903
|
+
return new import_core2.Matrix4(node.matrix);
|
|
904
|
+
}
|
|
905
|
+
const matrix = new import_core2.Matrix4();
|
|
906
|
+
if (node.translation) {
|
|
907
|
+
matrix.translate(node.translation);
|
|
459
908
|
}
|
|
460
909
|
if (node.rotation) {
|
|
461
|
-
|
|
910
|
+
matrix.multiplyRight(new import_core2.Matrix4().fromQuaternion(node.rotation));
|
|
911
|
+
}
|
|
912
|
+
if (node.scale) {
|
|
913
|
+
matrix.scale(node.scale);
|
|
462
914
|
}
|
|
463
|
-
return
|
|
915
|
+
return matrix;
|
|
916
|
+
}
|
|
917
|
+
function getLightPosition(worldMatrix) {
|
|
918
|
+
return worldMatrix.transformAsPoint([0, 0, 0]);
|
|
919
|
+
}
|
|
920
|
+
function getLightDirection(worldMatrix) {
|
|
921
|
+
return worldMatrix.transformDirection([0, 0, -1]);
|
|
464
922
|
}
|
|
465
923
|
|
|
466
924
|
// dist/parsers/parse-gltf.js
|
|
467
|
-
var
|
|
925
|
+
var import_engine4 = require("@luma.gl/engine");
|
|
926
|
+
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
468
927
|
|
|
469
928
|
// dist/webgl-to-webgpu/convert-webgl-topology.js
|
|
470
|
-
var GLEnum;
|
|
471
|
-
(function(GLEnum2) {
|
|
472
|
-
GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS";
|
|
473
|
-
GLEnum2[GLEnum2["LINES"] = 1] = "LINES";
|
|
474
|
-
GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP";
|
|
475
|
-
GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP";
|
|
476
|
-
GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES";
|
|
477
|
-
GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
|
|
478
|
-
GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
|
|
479
|
-
})(GLEnum || (GLEnum = {}));
|
|
480
929
|
function convertGLDrawModeToTopology(drawMode) {
|
|
481
930
|
switch (drawMode) {
|
|
482
931
|
case GLEnum.POINTS:
|
|
@@ -496,8 +945,9 @@ function convertGLDrawModeToTopology(drawMode) {
|
|
|
496
945
|
|
|
497
946
|
// dist/gltf/create-gltf-model.js
|
|
498
947
|
var import_core3 = require("@luma.gl/core");
|
|
499
|
-
var import_shadertools = require("@luma.gl/shadertools");
|
|
500
948
|
var import_engine2 = require("@luma.gl/engine");
|
|
949
|
+
var import_shadertools = require("@luma.gl/shadertools");
|
|
950
|
+
var import_engine3 = require("@luma.gl/engine");
|
|
501
951
|
var SHADER = (
|
|
502
952
|
/* WGSL */
|
|
503
953
|
`
|
|
@@ -653,6 +1103,21 @@ var fs = (
|
|
|
653
1103
|
}
|
|
654
1104
|
`
|
|
655
1105
|
);
|
|
1106
|
+
function createGLTFMaterial(device, options) {
|
|
1107
|
+
const materialFactory = options.materialFactory || new import_engine3.MaterialFactory(device, { modules: [import_shadertools.pbrMaterial] });
|
|
1108
|
+
const pbrMaterialProps = { ...options.parsedPPBRMaterial.uniforms };
|
|
1109
|
+
delete pbrMaterialProps.camera;
|
|
1110
|
+
const materialBindings = Object.fromEntries(Object.entries({
|
|
1111
|
+
...pbrMaterialProps,
|
|
1112
|
+
...options.parsedPPBRMaterial.bindings
|
|
1113
|
+
}).filter(([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)));
|
|
1114
|
+
const material = materialFactory.createMaterial({
|
|
1115
|
+
id: options.id,
|
|
1116
|
+
bindings: materialBindings
|
|
1117
|
+
});
|
|
1118
|
+
material.setProps({ pbrMaterial: pbrMaterialProps });
|
|
1119
|
+
return material;
|
|
1120
|
+
}
|
|
656
1121
|
function createGLTFModel(device, options) {
|
|
657
1122
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
658
1123
|
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
@@ -676,15 +1141,48 @@ function createGLTFModel(device, options) {
|
|
|
676
1141
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
677
1142
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
678
1143
|
};
|
|
679
|
-
const
|
|
680
|
-
|
|
1144
|
+
const material = options.material || createGLTFMaterial(device, {
|
|
1145
|
+
id: id ? `${id}-material` : void 0,
|
|
1146
|
+
parsedPPBRMaterial
|
|
1147
|
+
});
|
|
1148
|
+
modelProps.material = material;
|
|
1149
|
+
const model = new import_engine3.Model(device, modelProps);
|
|
1150
|
+
const sceneShaderInputValues = {
|
|
681
1151
|
...parsedPPBRMaterial.uniforms,
|
|
682
1152
|
...modelOptions.uniforms,
|
|
683
1153
|
...parsedPPBRMaterial.bindings,
|
|
684
1154
|
...modelOptions.bindings
|
|
685
1155
|
};
|
|
686
|
-
model.shaderInputs.
|
|
687
|
-
|
|
1156
|
+
const sceneShaderInputProps = getSceneShaderInputProps(model.shaderInputs.getModules(), material, sceneShaderInputValues);
|
|
1157
|
+
model.shaderInputs.setProps(sceneShaderInputProps);
|
|
1158
|
+
return new import_engine3.ModelNode({ managedResources, model });
|
|
1159
|
+
}
|
|
1160
|
+
function isMaterialBindingResource(value) {
|
|
1161
|
+
return value instanceof import_core3.Buffer || value instanceof import_engine2.DynamicTexture || value instanceof import_core3.Sampler || value instanceof import_core3.Texture || value instanceof import_core3.TextureView;
|
|
1162
|
+
}
|
|
1163
|
+
function getSceneShaderInputProps(modules, material, shaderInputValues) {
|
|
1164
|
+
const propertyToModuleNameMap = /* @__PURE__ */ new Map();
|
|
1165
|
+
for (const module2 of modules) {
|
|
1166
|
+
for (const uniformName of Object.keys(module2.uniformTypes || {})) {
|
|
1167
|
+
propertyToModuleNameMap.set(uniformName, module2.name);
|
|
1168
|
+
}
|
|
1169
|
+
for (const binding of module2.bindingLayout || []) {
|
|
1170
|
+
propertyToModuleNameMap.set(binding.name, module2.name);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
const sceneShaderInputProps = {};
|
|
1174
|
+
for (const [propertyName, value] of Object.entries(shaderInputValues)) {
|
|
1175
|
+
if (value === void 0) {
|
|
1176
|
+
continue;
|
|
1177
|
+
}
|
|
1178
|
+
const moduleName = propertyToModuleNameMap.get(propertyName);
|
|
1179
|
+
if (!moduleName || material.ownsModule(moduleName)) {
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
sceneShaderInputProps[moduleName] ||= {};
|
|
1183
|
+
sceneShaderInputProps[moduleName][propertyName] = value;
|
|
1184
|
+
}
|
|
1185
|
+
return sceneShaderInputProps;
|
|
688
1186
|
}
|
|
689
1187
|
|
|
690
1188
|
// dist/parsers/parse-gltf.js
|
|
@@ -697,9 +1195,23 @@ var defaultOptions = {
|
|
|
697
1195
|
};
|
|
698
1196
|
function parseGLTF(device, gltf, options = {}) {
|
|
699
1197
|
const combinedOptions = { ...defaultOptions, ...options };
|
|
1198
|
+
const materialFactory = new import_engine4.MaterialFactory(device, { modules: [import_shadertools2.pbrMaterial] });
|
|
1199
|
+
const materials = (gltf.materials || []).map((gltfMaterial, materialIndex) => createGLTFMaterial(device, {
|
|
1200
|
+
id: getGLTFMaterialId(gltfMaterial, materialIndex),
|
|
1201
|
+
parsedPPBRMaterial: parsePBRMaterial(device, gltfMaterial, {}, {
|
|
1202
|
+
...combinedOptions,
|
|
1203
|
+
gltf,
|
|
1204
|
+
validateAttributes: false
|
|
1205
|
+
}),
|
|
1206
|
+
materialFactory
|
|
1207
|
+
}));
|
|
1208
|
+
const gltfMaterialIdToMaterialMap = /* @__PURE__ */ new Map();
|
|
1209
|
+
(gltf.materials || []).forEach((gltfMaterial, materialIndex) => {
|
|
1210
|
+
gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);
|
|
1211
|
+
});
|
|
700
1212
|
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
701
1213
|
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
702
|
-
const newMesh = createNodeForGLTFMesh(device, gltfMesh, combinedOptions);
|
|
1214
|
+
const newMesh = createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, combinedOptions);
|
|
703
1215
|
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
704
1216
|
});
|
|
705
1217
|
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
@@ -731,15 +1243,15 @@ function parseGLTF(device, gltf, options = {}) {
|
|
|
731
1243
|
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
732
1244
|
return child;
|
|
733
1245
|
});
|
|
734
|
-
return new
|
|
1246
|
+
return new import_engine4.GroupNode({
|
|
735
1247
|
id: gltfScene.name || gltfScene.id,
|
|
736
1248
|
children
|
|
737
1249
|
});
|
|
738
1250
|
});
|
|
739
|
-
return { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
1251
|
+
return { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
740
1252
|
}
|
|
741
1253
|
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
742
|
-
return new
|
|
1254
|
+
return new import_engine4.GroupNode({
|
|
743
1255
|
id: gltfNode.name || gltfNode.id,
|
|
744
1256
|
children: [],
|
|
745
1257
|
matrix: gltfNode.matrix,
|
|
@@ -748,24 +1260,36 @@ function createNodeForGLTFNode(device, gltfNode, options) {
|
|
|
748
1260
|
scale: gltfNode.scale
|
|
749
1261
|
});
|
|
750
1262
|
}
|
|
751
|
-
function createNodeForGLTFMesh(device, gltfMesh, options) {
|
|
1263
|
+
function createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options) {
|
|
752
1264
|
const gltfPrimitives = gltfMesh.primitives || [];
|
|
753
|
-
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createNodeForGLTFPrimitive(
|
|
754
|
-
|
|
1265
|
+
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createNodeForGLTFPrimitive({
|
|
1266
|
+
device,
|
|
1267
|
+
gltfPrimitive,
|
|
1268
|
+
primitiveIndex: i,
|
|
1269
|
+
gltfMesh,
|
|
1270
|
+
gltf,
|
|
1271
|
+
gltfMaterialIdToMaterialMap,
|
|
1272
|
+
options
|
|
1273
|
+
}));
|
|
1274
|
+
const mesh = new import_engine4.GroupNode({
|
|
755
1275
|
id: gltfMesh.name || gltfMesh.id,
|
|
756
1276
|
children: primitives
|
|
757
1277
|
});
|
|
758
1278
|
return mesh;
|
|
759
1279
|
}
|
|
760
|
-
function createNodeForGLTFPrimitive(device, gltfPrimitive,
|
|
761
|
-
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${
|
|
1280
|
+
function createNodeForGLTFPrimitive({ device, gltfPrimitive, primitiveIndex, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options }) {
|
|
1281
|
+
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;
|
|
762
1282
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
763
1283
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
764
1284
|
const geometry = createGeometry(id, gltfPrimitive, topology);
|
|
765
|
-
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes,
|
|
1285
|
+
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {
|
|
1286
|
+
...options,
|
|
1287
|
+
gltf
|
|
1288
|
+
});
|
|
766
1289
|
const modelNode = createGLTFModel(device, {
|
|
767
1290
|
id,
|
|
768
1291
|
geometry: createGeometry(id, gltfPrimitive, topology),
|
|
1292
|
+
material: gltfPrimitive.material ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null : null,
|
|
769
1293
|
parsedPPBRMaterial,
|
|
770
1294
|
modelOptions: options.modelOptions,
|
|
771
1295
|
vertexCount
|
|
@@ -782,13 +1306,16 @@ function createGeometry(id, gltfPrimitive, topology) {
|
|
|
782
1306
|
const { components, size, value } = attribute;
|
|
783
1307
|
attributes[attributeName] = { size: size ?? components, value };
|
|
784
1308
|
}
|
|
785
|
-
return new
|
|
1309
|
+
return new import_engine4.Geometry({
|
|
786
1310
|
id,
|
|
787
1311
|
topology,
|
|
788
1312
|
indices: gltfPrimitive.indices.value,
|
|
789
1313
|
attributes
|
|
790
1314
|
});
|
|
791
1315
|
}
|
|
1316
|
+
function getGLTFMaterialId(gltfMaterial, materialIndex) {
|
|
1317
|
+
return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;
|
|
1318
|
+
}
|
|
792
1319
|
|
|
793
1320
|
// dist/gltf/gltf-animator.js
|
|
794
1321
|
var import_core6 = require("@luma.gl/core");
|
|
@@ -929,6 +1456,9 @@ var GLTFAnimator = class {
|
|
|
929
1456
|
}
|
|
930
1457
|
};
|
|
931
1458
|
|
|
1459
|
+
// dist/parsers/parse-gltf-animations.js
|
|
1460
|
+
var import_core7 = require("@luma.gl/core");
|
|
1461
|
+
|
|
932
1462
|
// dist/webgl-to-webgpu/convert-webgl-attribute.js
|
|
933
1463
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
934
1464
|
SCALAR: 1,
|
|
@@ -962,27 +1492,48 @@ function parseGLTFAnimations(gltf) {
|
|
|
962
1492
|
const gltfAnimations = gltf.animations || [];
|
|
963
1493
|
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
964
1494
|
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
965
|
-
return gltfAnimations.
|
|
1495
|
+
return gltfAnimations.flatMap((animation, index) => {
|
|
966
1496
|
const name = animation.name || `Animation-${index}`;
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1497
|
+
const samplerCache = /* @__PURE__ */ new Map();
|
|
1498
|
+
const channels = animation.channels.flatMap(({ sampler, target }) => {
|
|
1499
|
+
const path = getSupportedAnimationPath(target.path);
|
|
1500
|
+
if (!path) {
|
|
1501
|
+
return [];
|
|
1502
|
+
}
|
|
973
1503
|
const targetNode = gltf.nodes[target.node ?? 0];
|
|
974
1504
|
if (!targetNode) {
|
|
975
1505
|
throw new Error(`Cannot find animation target ${target.node}`);
|
|
976
1506
|
}
|
|
1507
|
+
let parsedSampler = samplerCache.get(sampler);
|
|
1508
|
+
if (!parsedSampler) {
|
|
1509
|
+
const gltfSampler = animation.samplers[sampler];
|
|
1510
|
+
if (!gltfSampler) {
|
|
1511
|
+
throw new Error(`Cannot find animation sampler ${sampler}`);
|
|
1512
|
+
}
|
|
1513
|
+
const { input, interpolation = "LINEAR", output } = gltfSampler;
|
|
1514
|
+
parsedSampler = {
|
|
1515
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
1516
|
+
interpolation,
|
|
1517
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
1518
|
+
};
|
|
1519
|
+
samplerCache.set(sampler, parsedSampler);
|
|
1520
|
+
}
|
|
977
1521
|
return {
|
|
978
|
-
sampler:
|
|
1522
|
+
sampler: parsedSampler,
|
|
979
1523
|
targetNodeId: targetNode.id,
|
|
980
|
-
path
|
|
1524
|
+
path
|
|
981
1525
|
};
|
|
982
1526
|
});
|
|
983
|
-
return { name, channels };
|
|
1527
|
+
return channels.length ? [{ name, channels }] : [];
|
|
984
1528
|
});
|
|
985
1529
|
}
|
|
1530
|
+
function getSupportedAnimationPath(path) {
|
|
1531
|
+
if (path === "pointer") {
|
|
1532
|
+
import_core7.log.warn("KHR_animation_pointer channels are not supported and will be skipped")();
|
|
1533
|
+
return null;
|
|
1534
|
+
}
|
|
1535
|
+
return path;
|
|
1536
|
+
}
|
|
986
1537
|
function accessorToJsArray1D(accessor, accessorCache) {
|
|
987
1538
|
if (accessorCache.has(accessor)) {
|
|
988
1539
|
return accessorCache.get(accessor);
|
|
@@ -998,7 +1549,7 @@ function accessorToJsArray2D(accessor, accessorCache) {
|
|
|
998
1549
|
return accessorCache.get(accessor);
|
|
999
1550
|
}
|
|
1000
1551
|
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
1001
|
-
assert(components
|
|
1552
|
+
assert(components >= 1, "accessorToJsArray2D must have at least 1 component");
|
|
1002
1553
|
const result = [];
|
|
1003
1554
|
for (let i = 0; i < array.length; i += components) {
|
|
1004
1555
|
result.push(Array.from(array.slice(i, i + components)));
|
|
@@ -1012,20 +1563,254 @@ function assert(condition, message) {
|
|
|
1012
1563
|
}
|
|
1013
1564
|
}
|
|
1014
1565
|
|
|
1566
|
+
// dist/gltf/gltf-extension-support.js
|
|
1567
|
+
var UNKNOWN_EXTENSION_SUPPORT = {
|
|
1568
|
+
supportLevel: "none",
|
|
1569
|
+
comment: "Not currently listed in the luma.gl glTF extension support registry."
|
|
1570
|
+
};
|
|
1571
|
+
var GLTF_EXTENSION_SUPPORT_REGISTRY = {
|
|
1572
|
+
KHR_draco_mesh_compression: {
|
|
1573
|
+
supportLevel: "built-in",
|
|
1574
|
+
comment: "Decoded by loaders.gl before luma.gl builds the scenegraph."
|
|
1575
|
+
},
|
|
1576
|
+
EXT_meshopt_compression: {
|
|
1577
|
+
supportLevel: "built-in",
|
|
1578
|
+
comment: "Meshopt-compressed primitives are decoded during load."
|
|
1579
|
+
},
|
|
1580
|
+
KHR_mesh_quantization: {
|
|
1581
|
+
supportLevel: "built-in",
|
|
1582
|
+
comment: "Quantized accessors are unpacked before geometry creation."
|
|
1583
|
+
},
|
|
1584
|
+
KHR_lights_punctual: {
|
|
1585
|
+
supportLevel: "built-in",
|
|
1586
|
+
comment: "Parsed into luma.gl Light objects."
|
|
1587
|
+
},
|
|
1588
|
+
KHR_materials_unlit: {
|
|
1589
|
+
supportLevel: "built-in",
|
|
1590
|
+
comment: "Unlit materials bypass the default lighting path."
|
|
1591
|
+
},
|
|
1592
|
+
KHR_materials_emissive_strength: {
|
|
1593
|
+
supportLevel: "built-in",
|
|
1594
|
+
comment: "Applied by the stock PBR shader."
|
|
1595
|
+
},
|
|
1596
|
+
KHR_texture_basisu: {
|
|
1597
|
+
supportLevel: "built-in",
|
|
1598
|
+
comment: "BasisU / KTX2 textures pass through when the device supports them."
|
|
1599
|
+
},
|
|
1600
|
+
KHR_texture_transform: {
|
|
1601
|
+
supportLevel: "built-in",
|
|
1602
|
+
comment: "UV transforms are applied during load."
|
|
1603
|
+
},
|
|
1604
|
+
EXT_texture_webp: {
|
|
1605
|
+
supportLevel: "loader-only",
|
|
1606
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
1607
|
+
},
|
|
1608
|
+
EXT_texture_avif: {
|
|
1609
|
+
supportLevel: "loader-only",
|
|
1610
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
1611
|
+
},
|
|
1612
|
+
KHR_materials_specular: {
|
|
1613
|
+
supportLevel: "built-in",
|
|
1614
|
+
comment: "The stock shader now applies specular factors and textures to the dielectric F0 term."
|
|
1615
|
+
},
|
|
1616
|
+
KHR_materials_ior: {
|
|
1617
|
+
supportLevel: "built-in",
|
|
1618
|
+
comment: "The stock shader now drives dielectric reflectance from the glTF IOR value."
|
|
1619
|
+
},
|
|
1620
|
+
KHR_materials_transmission: {
|
|
1621
|
+
supportLevel: "built-in",
|
|
1622
|
+
comment: "The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer."
|
|
1623
|
+
},
|
|
1624
|
+
KHR_materials_volume: {
|
|
1625
|
+
supportLevel: "built-in",
|
|
1626
|
+
comment: "Thickness and attenuation now tint transmitted light in the stock shader."
|
|
1627
|
+
},
|
|
1628
|
+
KHR_materials_clearcoat: {
|
|
1629
|
+
supportLevel: "built-in",
|
|
1630
|
+
comment: "The stock shader now adds a secondary clearcoat specular lobe."
|
|
1631
|
+
},
|
|
1632
|
+
KHR_materials_sheen: {
|
|
1633
|
+
supportLevel: "built-in",
|
|
1634
|
+
comment: "The stock shader now adds a sheen lobe for cloth-like materials."
|
|
1635
|
+
},
|
|
1636
|
+
KHR_materials_iridescence: {
|
|
1637
|
+
supportLevel: "built-in",
|
|
1638
|
+
comment: "The stock shader now tints specular response with a view-dependent thin-film iridescence approximation."
|
|
1639
|
+
},
|
|
1640
|
+
KHR_materials_anisotropy: {
|
|
1641
|
+
supportLevel: "built-in",
|
|
1642
|
+
comment: "The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation."
|
|
1643
|
+
},
|
|
1644
|
+
KHR_materials_pbrSpecularGlossiness: {
|
|
1645
|
+
supportLevel: "loader-only",
|
|
1646
|
+
comment: "Extension data can be loaded, but it is not translated into the default metallic-roughness material path."
|
|
1647
|
+
},
|
|
1648
|
+
KHR_materials_variants: {
|
|
1649
|
+
supportLevel: "loader-only",
|
|
1650
|
+
comment: "Variant metadata can be loaded, but applications must choose and apply variants."
|
|
1651
|
+
},
|
|
1652
|
+
EXT_mesh_gpu_instancing: {
|
|
1653
|
+
supportLevel: "none",
|
|
1654
|
+
comment: "GPU instancing data is not yet converted into luma.gl instanced draw setup."
|
|
1655
|
+
},
|
|
1656
|
+
KHR_node_visibility: {
|
|
1657
|
+
supportLevel: "none",
|
|
1658
|
+
comment: "Node-visibility animations and toggles are not mapped onto runtime scenegraph state."
|
|
1659
|
+
},
|
|
1660
|
+
KHR_animation_pointer: {
|
|
1661
|
+
supportLevel: "none",
|
|
1662
|
+
comment: "Animation pointers are not mapped onto runtime scenegraph updates."
|
|
1663
|
+
},
|
|
1664
|
+
KHR_materials_diffuse_transmission: {
|
|
1665
|
+
supportLevel: "none",
|
|
1666
|
+
comment: "Diffuse-transmission shading is not implemented in the stock PBR shader."
|
|
1667
|
+
},
|
|
1668
|
+
KHR_materials_dispersion: {
|
|
1669
|
+
supportLevel: "none",
|
|
1670
|
+
comment: "Chromatic dispersion is not implemented in the stock PBR shader."
|
|
1671
|
+
},
|
|
1672
|
+
KHR_materials_volume_scatter: {
|
|
1673
|
+
supportLevel: "none",
|
|
1674
|
+
comment: "Volume scattering is not implemented in the stock PBR shader."
|
|
1675
|
+
},
|
|
1676
|
+
KHR_xmp: {
|
|
1677
|
+
supportLevel: "none",
|
|
1678
|
+
comment: "Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them."
|
|
1679
|
+
},
|
|
1680
|
+
KHR_xmp_json_ld: {
|
|
1681
|
+
supportLevel: "none",
|
|
1682
|
+
comment: "Metadata is preserved in the glTF, but luma.gl does not interpret it."
|
|
1683
|
+
},
|
|
1684
|
+
EXT_lights_image_based: {
|
|
1685
|
+
supportLevel: "none",
|
|
1686
|
+
comment: "Use loadPBREnvironment() or custom environment setup instead."
|
|
1687
|
+
},
|
|
1688
|
+
EXT_texture_video: {
|
|
1689
|
+
supportLevel: "none",
|
|
1690
|
+
comment: "Video textures are not created automatically by the stock pipeline."
|
|
1691
|
+
},
|
|
1692
|
+
MSFT_lod: {
|
|
1693
|
+
supportLevel: "none",
|
|
1694
|
+
comment: "Level-of-detail switching is not implemented in the stock scenegraph loader."
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
function getGLTFExtensionSupport(gltf) {
|
|
1698
|
+
const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();
|
|
1699
|
+
const extensionSupportEntries = extensionNames.map((extensionName) => {
|
|
1700
|
+
const extensionSupportDefinition = GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;
|
|
1701
|
+
return [
|
|
1702
|
+
extensionName,
|
|
1703
|
+
{
|
|
1704
|
+
extensionName,
|
|
1705
|
+
supported: extensionSupportDefinition.supportLevel === "built-in",
|
|
1706
|
+
supportLevel: extensionSupportDefinition.supportLevel,
|
|
1707
|
+
comment: extensionSupportDefinition.comment
|
|
1708
|
+
}
|
|
1709
|
+
];
|
|
1710
|
+
});
|
|
1711
|
+
return new Map(extensionSupportEntries);
|
|
1712
|
+
}
|
|
1713
|
+
function collectGLTFExtensionNames(gltf) {
|
|
1714
|
+
var _a;
|
|
1715
|
+
const gltfWithRemovedExtensions = gltf;
|
|
1716
|
+
const extensionNames = /* @__PURE__ */ new Set();
|
|
1717
|
+
addExtensionNames(extensionNames, gltf.extensionsUsed);
|
|
1718
|
+
addExtensionNames(extensionNames, gltf.extensionsRequired);
|
|
1719
|
+
addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);
|
|
1720
|
+
addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));
|
|
1721
|
+
if (((_a = gltfWithRemovedExtensions.lights) == null ? void 0 : _a.length) || gltf.nodes.some((node) => "light" in node)) {
|
|
1722
|
+
extensionNames.add("KHR_lights_punctual");
|
|
1723
|
+
}
|
|
1724
|
+
if (gltf.materials.some((material) => {
|
|
1725
|
+
var _a2;
|
|
1726
|
+
const gltfMaterial = material;
|
|
1727
|
+
return gltfMaterial.unlit || ((_a2 = gltfMaterial.extensions) == null ? void 0 : _a2.KHR_materials_unlit);
|
|
1728
|
+
})) {
|
|
1729
|
+
extensionNames.add("KHR_materials_unlit");
|
|
1730
|
+
}
|
|
1731
|
+
return extensionNames;
|
|
1732
|
+
}
|
|
1733
|
+
function addExtensionNames(extensionNames, newExtensionNames = []) {
|
|
1734
|
+
for (const extensionName of newExtensionNames) {
|
|
1735
|
+
extensionNames.add(extensionName);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1015
1739
|
// dist/gltf/create-scenegraph-from-gltf.js
|
|
1016
1740
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
1017
|
-
const { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
1741
|
+
const { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
1018
1742
|
const animations = parseGLTFAnimations(gltf);
|
|
1019
1743
|
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
1020
1744
|
const lights = parseGLTFLights(gltf);
|
|
1745
|
+
const extensionSupport = getGLTFExtensionSupport(gltf);
|
|
1746
|
+
const sceneBounds = scenes.map((scene) => getScenegraphBounds(scene.getBounds()));
|
|
1747
|
+
const modelBounds = getCombinedScenegraphBounds(sceneBounds);
|
|
1021
1748
|
return {
|
|
1022
1749
|
scenes,
|
|
1750
|
+
materials,
|
|
1023
1751
|
animator,
|
|
1024
1752
|
lights,
|
|
1753
|
+
extensionSupport,
|
|
1754
|
+
sceneBounds,
|
|
1755
|
+
modelBounds,
|
|
1025
1756
|
gltfMeshIdToNodeMap,
|
|
1026
1757
|
gltfNodeIdToNodeMap,
|
|
1027
1758
|
gltfNodeIndexToNodeMap,
|
|
1028
1759
|
gltf
|
|
1029
1760
|
};
|
|
1030
1761
|
}
|
|
1762
|
+
function getScenegraphBounds(bounds) {
|
|
1763
|
+
if (!bounds) {
|
|
1764
|
+
return {
|
|
1765
|
+
bounds: null,
|
|
1766
|
+
center: [0, 0, 0],
|
|
1767
|
+
size: [0, 0, 0],
|
|
1768
|
+
radius: 0.5,
|
|
1769
|
+
recommendedOrbitDistance: 1
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
const normalizedBounds = [
|
|
1773
|
+
[bounds[0][0], bounds[0][1], bounds[0][2]],
|
|
1774
|
+
[bounds[1][0], bounds[1][1], bounds[1][2]]
|
|
1775
|
+
];
|
|
1776
|
+
const size = [
|
|
1777
|
+
normalizedBounds[1][0] - normalizedBounds[0][0],
|
|
1778
|
+
normalizedBounds[1][1] - normalizedBounds[0][1],
|
|
1779
|
+
normalizedBounds[1][2] - normalizedBounds[0][2]
|
|
1780
|
+
];
|
|
1781
|
+
const center = [
|
|
1782
|
+
normalizedBounds[0][0] + size[0] * 0.5,
|
|
1783
|
+
normalizedBounds[0][1] + size[1] * 0.5,
|
|
1784
|
+
normalizedBounds[0][2] + size[2] * 0.5
|
|
1785
|
+
];
|
|
1786
|
+
const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;
|
|
1787
|
+
const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 1e-3);
|
|
1788
|
+
return {
|
|
1789
|
+
bounds: normalizedBounds,
|
|
1790
|
+
center,
|
|
1791
|
+
size,
|
|
1792
|
+
radius,
|
|
1793
|
+
recommendedOrbitDistance: Math.max(Math.max(maxHalfExtent, 1e-3) / Math.tan(Math.PI / 6) * 1.15, radius * 1.1)
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
function getCombinedScenegraphBounds(sceneBounds) {
|
|
1797
|
+
let combinedBounds = null;
|
|
1798
|
+
for (const sceneBoundInfo of sceneBounds) {
|
|
1799
|
+
if (!sceneBoundInfo.bounds) {
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
if (!combinedBounds) {
|
|
1803
|
+
combinedBounds = [
|
|
1804
|
+
[...sceneBoundInfo.bounds[0]],
|
|
1805
|
+
[...sceneBoundInfo.bounds[1]]
|
|
1806
|
+
];
|
|
1807
|
+
continue;
|
|
1808
|
+
}
|
|
1809
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
1810
|
+
combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);
|
|
1811
|
+
combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
return getScenegraphBounds(combinedBounds);
|
|
1815
|
+
}
|
|
1031
1816
|
//# sourceMappingURL=index.cjs.map
|