@luma.gl/gltf 9.2.6 → 9.3.0-alpha.2
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 +78 -13
- package/dist/dist.min.js +4 -4
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +2 -0
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +3 -1
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/index.cjs +83 -16
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- 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-lights.d.ts +5 -0
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -0
- package/dist/parsers/parse-gltf-lights.js +69 -0
- package/dist/parsers/parse-gltf-lights.js.map +1 -0
- package/dist/pbr/pbr-environment.d.ts +4 -4
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +3 -3
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/package.json +6 -6
- package/src/gltf/create-scenegraph-from-gltf.ts +5 -1
- package/src/index.ts +1 -0
- package/src/parsers/parse-gltf-lights.ts +91 -0
- package/src/pbr/pbr-environment.ts +7 -7
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(dist_exports, {
|
|
|
23
23
|
GLTFAnimator: () => GLTFAnimator,
|
|
24
24
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
25
25
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
26
|
+
parseGLTFLights: () => parseGLTFLights,
|
|
26
27
|
parsePBRMaterial: () => parsePBRMaterial
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(dist_exports);
|
|
@@ -31,7 +32,7 @@ module.exports = __toCommonJS(dist_exports);
|
|
|
31
32
|
var import_engine = require("@luma.gl/engine");
|
|
32
33
|
var import_textures = require("@loaders.gl/textures");
|
|
33
34
|
function loadPBREnvironment(device, props) {
|
|
34
|
-
const brdfLutTexture = new import_engine.
|
|
35
|
+
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
35
36
|
id: "brdfLUT",
|
|
36
37
|
sampler: {
|
|
37
38
|
addressModeU: "clamp-to-edge",
|
|
@@ -81,7 +82,7 @@ function makeCube(device, { id, getTextureForFace, sampler }) {
|
|
|
81
82
|
FACES.forEach((face) => {
|
|
82
83
|
data[String(face)] = getTextureForFace(face);
|
|
83
84
|
});
|
|
84
|
-
return new import_engine.
|
|
85
|
+
return new import_engine.DynamicTexture(device, {
|
|
85
86
|
id,
|
|
86
87
|
dimension: "cube",
|
|
87
88
|
mipmaps: false,
|
|
@@ -277,9 +278,74 @@ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
|
277
278
|
parsedMaterial.generatedTextures.push(texture);
|
|
278
279
|
}
|
|
279
280
|
|
|
281
|
+
// dist/parsers/parse-gltf-lights.js
|
|
282
|
+
var import_core2 = require("@math.gl/core");
|
|
283
|
+
function parseGLTFLights(gltf) {
|
|
284
|
+
var _a, _b, _c;
|
|
285
|
+
const lightDefs = (_b = (_a = gltf.extensions) == null ? void 0 : _a["KHR_lights_punctual"]) == null ? void 0 : _b["lights"];
|
|
286
|
+
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
287
|
+
return [];
|
|
288
|
+
}
|
|
289
|
+
const lights = [];
|
|
290
|
+
for (const node of gltf.nodes || []) {
|
|
291
|
+
const nodeLight = (_c = node.extensions) == null ? void 0 : _c.KHR_lights_punctual;
|
|
292
|
+
if (!nodeLight || typeof nodeLight.light !== "number") {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const gltfLight = lightDefs[nodeLight.light];
|
|
296
|
+
if (!gltfLight) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const color = gltfLight.color || [1, 1, 1];
|
|
300
|
+
const intensity = gltfLight.intensity ?? 1;
|
|
301
|
+
const range = gltfLight.range;
|
|
302
|
+
switch (gltfLight.type) {
|
|
303
|
+
case "directional":
|
|
304
|
+
lights.push(parseDirectionalLight(node, color, intensity));
|
|
305
|
+
break;
|
|
306
|
+
case "point":
|
|
307
|
+
lights.push(parsePointLight(node, color, intensity, range));
|
|
308
|
+
break;
|
|
309
|
+
case "spot":
|
|
310
|
+
lights.push(parsePointLight(node, color, intensity, range));
|
|
311
|
+
break;
|
|
312
|
+
default:
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return lights;
|
|
317
|
+
}
|
|
318
|
+
function parsePointLight(node, color, intensity, range) {
|
|
319
|
+
const position = node.translation ? [...node.translation] : [0, 0, 0];
|
|
320
|
+
let attenuation = [1, 0, 0];
|
|
321
|
+
if (range !== void 0 && range > 0) {
|
|
322
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
type: "point",
|
|
326
|
+
position,
|
|
327
|
+
color,
|
|
328
|
+
intensity,
|
|
329
|
+
attenuation
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function parseDirectionalLight(node, color, intensity) {
|
|
333
|
+
let direction = [0, 0, -1];
|
|
334
|
+
if (node.rotation) {
|
|
335
|
+
const orientation = new import_core2.Matrix4().fromQuaternion(node.rotation);
|
|
336
|
+
direction = orientation.transformDirection([0, 0, -1]);
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
type: "directional",
|
|
340
|
+
direction,
|
|
341
|
+
color,
|
|
342
|
+
intensity
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
280
346
|
// dist/parsers/parse-gltf.js
|
|
281
347
|
var import_engine3 = require("@luma.gl/engine");
|
|
282
|
-
var
|
|
348
|
+
var import_core4 = require("@math.gl/core");
|
|
283
349
|
|
|
284
350
|
// dist/webgl-to-webgpu/convert-webgl-topology.js
|
|
285
351
|
var GLEnum;
|
|
@@ -310,7 +376,7 @@ function convertGLDrawModeToTopology(drawMode) {
|
|
|
310
376
|
}
|
|
311
377
|
|
|
312
378
|
// dist/gltf/create-gltf-model.js
|
|
313
|
-
var
|
|
379
|
+
var import_core3 = require("@luma.gl/core");
|
|
314
380
|
var import_shadertools = require("@luma.gl/shadertools");
|
|
315
381
|
var import_engine2 = require("@luma.gl/engine");
|
|
316
382
|
var SHADER = (
|
|
@@ -418,7 +484,7 @@ var fs = (
|
|
|
418
484
|
);
|
|
419
485
|
function createGLTFModel(device, options) {
|
|
420
486
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
421
|
-
|
|
487
|
+
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
422
488
|
const managedResources = [];
|
|
423
489
|
const parameters = {
|
|
424
490
|
depthWriteEnabled: true,
|
|
@@ -491,7 +557,7 @@ function createNode(device, gltfNode, gltfNodes, options) {
|
|
|
491
557
|
node.matrix.translate(gltfNode.translation);
|
|
492
558
|
}
|
|
493
559
|
if (gltfNode.rotation) {
|
|
494
|
-
const rotationMatrix = new
|
|
560
|
+
const rotationMatrix = new import_core4.Matrix4().fromQuaternion(gltfNode.rotation);
|
|
495
561
|
node.matrix.multiplyRight(rotationMatrix);
|
|
496
562
|
}
|
|
497
563
|
if (gltfNode.scale) {
|
|
@@ -550,13 +616,13 @@ function createGeometry(id, gltfPrimitive, topology) {
|
|
|
550
616
|
}
|
|
551
617
|
|
|
552
618
|
// dist/gltf/gltf-animator.js
|
|
553
|
-
var
|
|
554
|
-
var
|
|
619
|
+
var import_core7 = require("@luma.gl/core");
|
|
620
|
+
var import_core8 = require("@math.gl/core");
|
|
555
621
|
|
|
556
622
|
// dist/gltf/animations/interpolate.js
|
|
557
|
-
var
|
|
558
|
-
var
|
|
559
|
-
var scratchQuaternion = new
|
|
623
|
+
var import_core5 = require("@luma.gl/core");
|
|
624
|
+
var import_core6 = require("@math.gl/core");
|
|
625
|
+
var scratchQuaternion = new import_core6.Quaternion();
|
|
560
626
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
561
627
|
const maxTime = input[input.length - 1];
|
|
562
628
|
const animationTime = time % maxTime;
|
|
@@ -574,7 +640,7 @@ function interpolate(time, { input, interpolation, output }, target, path) {
|
|
|
574
640
|
target[path] = [1, 1, 1];
|
|
575
641
|
break;
|
|
576
642
|
default:
|
|
577
|
-
|
|
643
|
+
import_core5.log.warn(`Bad animation path ${path}`)();
|
|
578
644
|
}
|
|
579
645
|
}
|
|
580
646
|
const previousTime = input[previousIndex];
|
|
@@ -601,7 +667,7 @@ function interpolate(time, { input, interpolation, output }, target, path) {
|
|
|
601
667
|
}
|
|
602
668
|
break;
|
|
603
669
|
default:
|
|
604
|
-
|
|
670
|
+
import_core5.log.warn(`Interpolation ${interpolation} not supported`)();
|
|
605
671
|
break;
|
|
606
672
|
}
|
|
607
673
|
}
|
|
@@ -674,7 +740,7 @@ var GLTFAnimator = class {
|
|
|
674
740
|
}
|
|
675
741
|
/** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
|
|
676
742
|
animate(time) {
|
|
677
|
-
|
|
743
|
+
import_core7.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
678
744
|
this.setTime(time);
|
|
679
745
|
}
|
|
680
746
|
setTime(time) {
|
|
@@ -684,7 +750,7 @@ var GLTFAnimator = class {
|
|
|
684
750
|
return this.animations;
|
|
685
751
|
}
|
|
686
752
|
};
|
|
687
|
-
var scratchMatrix = new
|
|
753
|
+
var scratchMatrix = new import_core8.Matrix4();
|
|
688
754
|
function applyTranslationRotationScale(gltfNode, node) {
|
|
689
755
|
node.matrix.identity();
|
|
690
756
|
if (gltfNode.translation) {
|
|
@@ -785,6 +851,7 @@ function createScenegraphsFromGLTF(device, gltf, options) {
|
|
|
785
851
|
const scenes = parseGLTF(device, gltf, options);
|
|
786
852
|
const animations = parseGLTFAnimations(gltf);
|
|
787
853
|
const animator = new GLTFAnimator({ animations });
|
|
788
|
-
|
|
854
|
+
const lights = parseGLTFLights(gltf);
|
|
855
|
+
return { scenes, animator, lights };
|
|
789
856
|
}
|
|
790
857
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/parsers/parse-gltf-animations.ts", "../src/utils/deep-copy.ts", "../src/gltf/create-scenegraph-from-gltf.ts"],
|
|
4
|
-
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {} from './pbr/pbr-environment';\n\n// glTF Scenegraph Instantiator\nexport {createScenegraphsFromGLTF} from './gltf/create-scenegraph-from-gltf';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {AsyncTexture} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: AsyncTexture;\n diffuseEnvSampler: AsyncTexture;\n specularEnvSampler: AsyncTexture;\n};\n\nexport type PBREnvironmentProps = {\n brdfLutUrl: string;\n getTexUrl: (name: string, dir: number, level: number) => string;\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const brdfLutTexture = new AsyncTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(props.brdfLutUrl)\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: dir => loadImageTexture(props.getTexUrl('diffuse', dir, 0)),\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (dir: number) => {\n const imageArray: Promise<any>[] = [];\n // @ts-ignore\n for (let lod = 0; lod <= props.specularMipLevels - 1; lod++) {\n imageArray.push(loadImageTexture(props.getTexUrl('specular', dir, lod)));\n }\n return imageArray;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES = [0, 1, 2, 3, 4, 5];\n\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n id: string;\n getTextureForFace: (dir: number) => Promise<any> | Promise<any>[];\n sampler: SamplerProps;\n }\n): AsyncTexture {\n const data = {};\n FACES.forEach(face => {\n // @ts-ignore TODO\n data[String(face)] = getTextureForFace(face);\n });\n return new AsyncTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n // @ts-expect-error\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, Texture} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\nimport {log} from '@luma.gl/core';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'MASK' | 'BLEND';\n alphaCutoff?: number;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n parseMaterial(device, material, parsedMaterial);\n }\n\n return parsedMaterial;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial\n): void {\n parsedMaterial.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);\n }\n if (material.normalTexture) {\n addTexture(\n device,\n material.normalTexture,\n 'pbr_normalSampler',\n 'HAS_NORMALMAP',\n parsedMaterial\n );\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(\n device,\n material.occlusionTexture,\n 'pbr_occlusionSampler',\n 'HAS_OCCLUSIONMAP',\n parsedMaterial\n );\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n addTexture(\n device,\n material.emissiveTexture,\n 'pbr_emissiveSampler',\n 'HAS_EMISSIVEMAP',\n parsedMaterial\n );\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n\n switch (material.alphaMode || 'MASK') {\n case 'MASK':\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n\n // WebGPU style parameters\n parsedMaterial.parameters.blend = true;\n\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n // GL parameters\n // TODO - remove in favor of parameters\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GL.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GL.SRC_ALPHA,\n GL.ONE_MINUS_SRC_ALPHA,\n GL.ONE,\n GL.ONE_MINUS_SRC_ALPHA\n ];\n\n break;\n }\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP',\n parsedMaterial\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP',\n parsedMaterial\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n define: string,\n parsedMaterial: ParsedPBRMaterial\n): void {\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n\n if (image.compressed) {\n textureOptions = image;\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n ...gltfTexture?.texture?.sampler\n } as any;\n\n const texture: Texture = device.createTexture({\n id: gltfTexture.uniformName || gltfTexture.id,\n sampler: convertSampler(gltfSampler),\n ...textureOptions\n });\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n parsedMaterial.generatedTextures.push(texture);\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GL.FUNC_ADD,\n blendFunc: [GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GL.TEXTURE_MIN_FILTER]: image.data.length > 1 ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GL.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\ntype GLTFSampler = {\n wrapS?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n wrapT?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n magFilter?: GL.NEAREST | GL.LINEAR;\n minFilter?:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR;\n};\n\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\nfunction convertSamplerWrapMode(\n mode: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GL.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GL.REPEAT:\n return 'repeat';\n case GL.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMagFilter(\n mode: GL.NEAREST | GL.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GL.NEAREST:\n return 'nearest';\n case GL.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMinFilter(\n mode:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GL.NEAREST:\n return {minFilter: 'nearest'};\n case GL.LINEAR:\n return {minFilter: 'linear'};\n case GL.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GL.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GL.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GL.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {Geometry, GeometryAttribute, GroupNode, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {type GLTFScenePostprocessed} from '@loaders.gl/gltf/dist/lib/types/gltf-postprocessed-schema';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\nexport type ParseGLTFOptions = {\n modelOptions?: Partial<ModelProps>;\n pbrDebug?: boolean;\n imageBasedLightingEnvironment?: PBREnvironment;\n lights?: boolean;\n useTangents?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options_: ParseGLTFOptions = {}\n): GroupNode[] {\n const options = {...defaultOptions, ...options_};\n const sceneNodes = gltf.scenes.map(gltfScene =>\n createScene(device, gltfScene, gltf.nodes, options)\n );\n return sceneNodes;\n}\n\nfunction createScene(\n device: Device,\n gltfScene: GLTFScenePostprocessed,\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfSceneNodes = gltfScene.nodes || [];\n const nodes = gltfSceneNodes.map(node => createNode(device, node, gltfNodes, options));\n const sceneNode = new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children: nodes\n });\n return sceneNode;\n}\n\nfunction createNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed & {_node?: GroupNode},\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n if (!gltfNode._node) {\n const gltfChildren = gltfNode.children || [];\n const children = gltfChildren.map(child => createNode(device, child, gltfNodes, options));\n\n // Node can have children nodes and meshes at the same time\n if (gltfNode.mesh) {\n children.push(createMesh(device, gltfNode.mesh, options));\n }\n\n const node = new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children\n });\n\n if (gltfNode.matrix) {\n node.setMatrix(gltfNode.matrix);\n } else {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n }\n gltfNode._node = node;\n }\n\n // Copy _node so that gltf-animator can access\n const topLevelNode = gltfNodes.find(node => node.id === gltfNode.id) as any;\n topLevelNode._node = gltfNode._node;\n\n return gltfNode._node;\n}\n\nfunction createMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed & {_mesh?: GroupNode},\n options: Required<ParseGLTFOptions>\n): GroupNode {\n // TODO: avoid changing the gltf\n if (!gltfMesh._mesh) {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createPrimitive(device, gltfPrimitive, i, gltfMesh, options)\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n gltfMesh._mesh = mesh;\n }\n\n return gltfMesh._mesh;\n}\n\nfunction createPrimitive(\n device: Device,\n gltfPrimitive: any,\n i: number,\n gltfMesh: GLTFMeshPostprocessed,\n options: Required<ParseGLTFOptions>\n): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(\n device,\n gltfPrimitive.material,\n geometry.attributes,\n options\n );\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry: createGeometry(id, gltfPrimitive, topology),\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\nfunction getVertexCount(attributes: any) {\n throw new Error('getVertexCount not implemented');\n}\n\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices.value,\n attributes\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\n\n// NOTE: Modules other than `@luma.gl/webgl` should not import `GL` from\n// `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid\n// conflicts with the `babel-plugin-inline-webgl-constants` plugin.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6\n}\n\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // prettier-ignore\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type RenderPipelineParameters, log} from '@luma.gl/core';\nimport {pbrMaterial, ShaderModule} from '@luma.gl/shadertools';\nimport {Geometry, Model, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nlayout(0) positions: vec4; // in vec4 POSITION;\n\n #ifdef HAS_NORMALS\n in vec4 normals; // in vec4 NORMAL;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n@vertex\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = u_MVPMatrix * positions;\n }\n\n@fragment\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = pbrProjection.modelViewProjectionMatrix * positions;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\nexport type CreateGLTFModelOptions = {\n id?: string;\n vertexCount?: number;\n geometry: Geometry;\n parsedPPBRMaterial: ParsedPBRMaterial;\n modelOptions?: Partial<ModelProps>;\n};\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial as unknown as ShaderModule],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const model = new Model(device, modelProps);\n\n const {camera, ...pbrMaterialProps} = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n\n model.shaderInputs.setProps({pbrMaterial: pbrMaterialProps, pbrProjection: {camera}});\n return new ModelNode({managedResources, model});\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {GLTFAnimation} from './animations/animations';\nimport {interpolate} from './animations/interpolate';\n\ntype GLTFSingleAnimatorProps = {\n animation: GLTFAnimation;\n startTime?: number;\n playing?: boolean;\n speed?: number;\n};\n\nclass GLTFSingleAnimator {\n animation: GLTFAnimation;\n startTime: number = 0;\n playing: boolean = true;\n speed: number = 1;\n\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n }\n\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(({sampler, target, path}) => {\n interpolate(time, sampler, target, path);\n applyTranslationRotationScale(target, (target as any)._node as GroupNode);\n });\n }\n}\n\nexport type GLTFAnimatorProps = {\n animations: GLTFAnimation[];\n};\n\nexport class GLTFAnimator {\n animations: GLTFSingleAnimator[];\n\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n getAnimations() {\n return this.animations;\n }\n}\n\n// TODO: share with GLTFInstantiator\nconst scratchMatrix = new Matrix4();\n\nfunction applyTranslationRotationScale(gltfNode: GLTFNodePostprocessed, node: GroupNode) {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n}\n", "import {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationChannel, GLTFAnimationSampler} from './animations';\n\nconst scratchQuaternion = new Quaternion();\n\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path']\n) {\n const maxTime = input[input.length - 1];\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n const previousIndex = Math.max(0, nextIndex - 1);\n\n if (!Array.isArray(target[path])) {\n switch (path) {\n case 'translation':\n target[path] = [0, 0, 0];\n break;\n\n case 'rotation':\n target[path] = [0, 0, 0, 1];\n break;\n\n case 'scale':\n target[path] = [1, 1, 1];\n break;\n\n default:\n log.warn(`Bad animation path ${path}`)();\n }\n }\n\n // assert(target[path].length === output[previousIndex].length);\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n stepInterpolate(target, path, output[previousIndex] as number[]);\n break;\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n linearInterpolate(\n target,\n path,\n output[previousIndex] as number[],\n output[nextIndex] as number[],\n ratio\n );\n }\n break;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1] as number[];\n const outTangent0 = output[3 * previousIndex + 2] as number[];\n const inTangent1 = output[3 * nextIndex + 0] as number[];\n const p1 = output[3 * nextIndex + 1] as number[];\n\n cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n break;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n break;\n }\n}\n\nfunction linearInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n start: number[],\n stop: number[],\n ratio: number\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n if (path === 'rotation') {\n // SLERP when path is rotation\n scratchQuaternion.slerp({start, target: stop, ratio});\n for (let i = 0; i < scratchQuaternion.length; i++) {\n target[path][i] = scratchQuaternion[i];\n }\n } else {\n // regular interpolation\n for (let i = 0; i < start.length; i++) {\n target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n }\n}\n\nfunction cubicsplineInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n {\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n }: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n }\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n // TODO: Quaternion might need normalization\n for (let i = 0; i < target[path].length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n target[path][i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n}\n\nfunction stepInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n value: number[]\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n for (let i = 0; i < value.length; i++) {\n target[path][i] = value[i];\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\ntype GLTFAccessor = {\n componentType: number;\n type: string;\n count: number;\n bufferView?: {data: {buffer: ArrayBuffer; byteOffset?: number}};\n byteOffset?: number;\n};\n\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n typedArray: TypedArray;\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFAnimationSampler\n} from '../gltf/animations/animations';\n\nimport {accessorToTypedArray} from '..//webgl-to-webgpu/convert-webgl-attribute';\n\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n return gltfAnimations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplers: GLTFAnimationSampler[] = animation.samplers.map(\n ({input, interpolation = 'LINEAR', output}) => ({\n input: accessorToJsArray(gltf.accessors[input]) as number[],\n interpolation,\n output: accessorToJsArray(gltf.accessors[output])\n })\n );\n const channels: GLTFAnimationChannel[] = animation.channels.map(({sampler, target}) => ({\n sampler: samplers[sampler],\n target: gltf.nodes[target.node ?? 0],\n path: target.path as GLTFAnimationChannel['path']\n }));\n return {name, channels};\n });\n}\n\n//\n\nfunction accessorToJsArray(\n accessor: GLTFAccessorPostprocessed & {_animation?: number[] | number[][]}\n): number[] | number[][] {\n if (!accessor._animation) {\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n\n if (components === 1) {\n accessor._animation = Array.from(array);\n } else {\n // Slice array\n const slicedArray: number[][] = [];\n for (let i = 0; i < array.length; i += components) {\n slicedArray.push(Array.from(array.slice(i, i + components)));\n }\n accessor._animation = slicedArray;\n }\n }\n\n return accessor._animation;\n}\n", "/** Deeply copies a JS data structure */\nexport function deepCopy(object: any): any {\n // don't copy binary data\n if (\n ArrayBuffer.isView(object) ||\n object instanceof ArrayBuffer ||\n object instanceof ImageBitmap\n ) {\n return object;\n }\n if (Array.isArray(object)) {\n return object.map(deepCopy);\n }\n if (object && typeof object === 'object') {\n const result: typeof object = {};\n for (const key in object) {\n result[key] = deepCopy(object[key]);\n }\n return result;\n }\n return object;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {deepCopy} from '../utils/deep-copy';\n\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): {\n scenes: GroupNode[];\n animator: GLTFAnimator;\n} {\n gltf = deepCopy(gltf);\n const scenes = parseGLTF(device, gltf, options);\n // Note: There is a nasty dependency on injected nodes in the glTF\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations});\n return {scenes, animator};\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_constants", "import_engine", "import_core", "GLEnum", "import_core", "import_engine", "import_core", "import_core"]
|
|
3
|
+
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/parsers/parse-gltf-lights.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/parsers/parse-gltf-animations.ts", "../src/utils/deep-copy.ts", "../src/gltf/create-scenegraph-from-gltf.ts"],
|
|
4
|
+
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {} from './pbr/pbr-environment';\nexport {parseGLTFLights} from './parsers/parse-gltf-lights';\n\n// glTF Scenegraph Instantiator\nexport {createScenegraphsFromGLTF} from './gltf/create-scenegraph-from-gltf';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {DynamicTexture} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: DynamicTexture;\n diffuseEnvSampler: DynamicTexture;\n specularEnvSampler: DynamicTexture;\n};\n\nexport type PBREnvironmentProps = {\n brdfLutUrl: string;\n getTexUrl: (name: string, dir: number, level: number) => string;\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const brdfLutTexture = new DynamicTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(props.brdfLutUrl)\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: dir => loadImageTexture(props.getTexUrl('diffuse', dir, 0)),\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (dir: number) => {\n const imageArray: Promise<any>[] = [];\n // @ts-ignore\n for (let lod = 0; lod <= props.specularMipLevels - 1; lod++) {\n imageArray.push(loadImageTexture(props.getTexUrl('specular', dir, lod)));\n }\n return imageArray;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES = [0, 1, 2, 3, 4, 5];\n\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n id: string;\n getTextureForFace: (dir: number) => Promise<any> | Promise<any>[];\n sampler: SamplerProps;\n }\n): DynamicTexture {\n const data = {};\n FACES.forEach(face => {\n // @ts-ignore TODO\n data[String(face)] = getTextureForFace(face);\n });\n return new DynamicTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n // @ts-expect-error\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, Texture} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\nimport {log} from '@luma.gl/core';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'MASK' | 'BLEND';\n alphaCutoff?: number;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n parseMaterial(device, material, parsedMaterial);\n }\n\n return parsedMaterial;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial\n): void {\n parsedMaterial.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);\n }\n if (material.normalTexture) {\n addTexture(\n device,\n material.normalTexture,\n 'pbr_normalSampler',\n 'HAS_NORMALMAP',\n parsedMaterial\n );\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(\n device,\n material.occlusionTexture,\n 'pbr_occlusionSampler',\n 'HAS_OCCLUSIONMAP',\n parsedMaterial\n );\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n addTexture(\n device,\n material.emissiveTexture,\n 'pbr_emissiveSampler',\n 'HAS_EMISSIVEMAP',\n parsedMaterial\n );\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n\n switch (material.alphaMode || 'MASK') {\n case 'MASK':\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n\n // WebGPU style parameters\n parsedMaterial.parameters.blend = true;\n\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n // GL parameters\n // TODO - remove in favor of parameters\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GL.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GL.SRC_ALPHA,\n GL.ONE_MINUS_SRC_ALPHA,\n GL.ONE,\n GL.ONE_MINUS_SRC_ALPHA\n ];\n\n break;\n }\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP',\n parsedMaterial\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP',\n parsedMaterial\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n define: string,\n parsedMaterial: ParsedPBRMaterial\n): void {\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n\n if (image.compressed) {\n textureOptions = image;\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n ...gltfTexture?.texture?.sampler\n } as any;\n\n const texture: Texture = device.createTexture({\n id: gltfTexture.uniformName || gltfTexture.id,\n sampler: convertSampler(gltfSampler),\n ...textureOptions\n });\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n parsedMaterial.generatedTextures.push(texture);\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GL.FUNC_ADD,\n blendFunc: [GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GL.TEXTURE_MIN_FILTER]: image.data.length > 1 ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GL.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\ntype GLTFSampler = {\n wrapS?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n wrapT?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n magFilter?: GL.NEAREST | GL.LINEAR;\n minFilter?:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR;\n};\n\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\nfunction convertSamplerWrapMode(\n mode: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GL.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GL.REPEAT:\n return 'repeat';\n case GL.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMagFilter(\n mode: GL.NEAREST | GL.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GL.NEAREST:\n return 'nearest';\n case GL.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMinFilter(\n mode:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GL.NEAREST:\n return {minFilter: 'nearest'};\n case GL.LINEAR:\n return {minFilter: 'linear'};\n case GL.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GL.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GL.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GL.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "import {Matrix4} from '@math.gl/core';\nimport type {GLTFNodePostprocessed, GLTFPostprocessed} from '@loaders.gl/gltf';\nimport type {DirectionalLight, Light, PointLight} from '@luma.gl/shadertools';\n\n/** Parse KHR_lights_punctual extension into luma.gl light definitions */\nexport function parseGLTFLights(gltf: GLTFPostprocessed): Light[] {\n const lightDefs = gltf.extensions?.['KHR_lights_punctual']?.['lights'];\n if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {\n return [];\n }\n\n const lights: Light[] = [];\n\n for (const node of gltf.nodes || []) {\n const nodeLight = node.extensions?.KHR_lights_punctual;\n if (!nodeLight || typeof nodeLight.light !== 'number') {\n // eslint-disable-next-line no-continue\n continue;\n }\n const gltfLight = lightDefs[nodeLight.light];\n if (!gltfLight) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const color = (gltfLight.color || [1, 1, 1]) as [number, number, number];\n const intensity = gltfLight.intensity ?? 1;\n const range = gltfLight.range;\n\n switch (gltfLight.type) {\n case 'directional':\n lights.push(parseDirectionalLight(node, color, intensity));\n break;\n case 'point':\n lights.push(parsePointLight(node, color, intensity, range));\n break;\n case 'spot':\n lights.push(parsePointLight(node, color, intensity, range));\n break;\n default:\n // Unsupported light type\n break;\n }\n }\n\n return lights;\n}\n\nfunction parsePointLight(\n node: GLTFNodePostprocessed,\n color: [number, number, number],\n intensity: number,\n range?: number\n): PointLight {\n const position: Readonly<[number, number, number]> = node.translation\n ? ([...node.translation] as [number, number, number])\n : ([0, 0, 0] as [number, number, number]);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'point',\n position,\n color,\n intensity,\n attenuation\n };\n}\n\nfunction parseDirectionalLight(\n node: GLTFNodePostprocessed,\n color: [number, number, number],\n intensity: number\n): DirectionalLight {\n let direction: [number, number, number] = [0, 0, -1];\n\n if (node.rotation) {\n const orientation = new Matrix4().fromQuaternion(node.rotation);\n direction = orientation.transformDirection([0, 0, -1]) as [number, number, number];\n }\n\n return {\n type: 'directional',\n direction,\n color,\n intensity\n };\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {Geometry, GeometryAttribute, GroupNode, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {type GLTFScenePostprocessed} from '@loaders.gl/gltf/dist/lib/types/gltf-postprocessed-schema';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\nexport type ParseGLTFOptions = {\n modelOptions?: Partial<ModelProps>;\n pbrDebug?: boolean;\n imageBasedLightingEnvironment?: PBREnvironment;\n lights?: boolean;\n useTangents?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options_: ParseGLTFOptions = {}\n): GroupNode[] {\n const options = {...defaultOptions, ...options_};\n const sceneNodes = gltf.scenes.map(gltfScene =>\n createScene(device, gltfScene, gltf.nodes, options)\n );\n return sceneNodes;\n}\n\nfunction createScene(\n device: Device,\n gltfScene: GLTFScenePostprocessed,\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfSceneNodes = gltfScene.nodes || [];\n const nodes = gltfSceneNodes.map(node => createNode(device, node, gltfNodes, options));\n const sceneNode = new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children: nodes\n });\n return sceneNode;\n}\n\nfunction createNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed & {_node?: GroupNode},\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n if (!gltfNode._node) {\n const gltfChildren = gltfNode.children || [];\n const children = gltfChildren.map(child => createNode(device, child, gltfNodes, options));\n\n // Node can have children nodes and meshes at the same time\n if (gltfNode.mesh) {\n children.push(createMesh(device, gltfNode.mesh, options));\n }\n\n const node = new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children\n });\n\n if (gltfNode.matrix) {\n node.setMatrix(gltfNode.matrix);\n } else {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n }\n gltfNode._node = node;\n }\n\n // Copy _node so that gltf-animator can access\n const topLevelNode = gltfNodes.find(node => node.id === gltfNode.id) as any;\n topLevelNode._node = gltfNode._node;\n\n return gltfNode._node;\n}\n\nfunction createMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed & {_mesh?: GroupNode},\n options: Required<ParseGLTFOptions>\n): GroupNode {\n // TODO: avoid changing the gltf\n if (!gltfMesh._mesh) {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createPrimitive(device, gltfPrimitive, i, gltfMesh, options)\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n gltfMesh._mesh = mesh;\n }\n\n return gltfMesh._mesh;\n}\n\nfunction createPrimitive(\n device: Device,\n gltfPrimitive: any,\n i: number,\n gltfMesh: GLTFMeshPostprocessed,\n options: Required<ParseGLTFOptions>\n): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(\n device,\n gltfPrimitive.material,\n geometry.attributes,\n options\n );\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry: createGeometry(id, gltfPrimitive, topology),\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\nfunction getVertexCount(attributes: any) {\n throw new Error('getVertexCount not implemented');\n}\n\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices.value,\n attributes\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\n\n// NOTE: Modules other than `@luma.gl/webgl` should not import `GL` from\n// `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid\n// conflicts with the `babel-plugin-inline-webgl-constants` plugin.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6\n}\n\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // prettier-ignore\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type RenderPipelineParameters, log} from '@luma.gl/core';\nimport {pbrMaterial, ShaderModule} from '@luma.gl/shadertools';\nimport {Geometry, Model, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nlayout(0) positions: vec4; // in vec4 POSITION;\n\n #ifdef HAS_NORMALS\n in vec4 normals; // in vec4 NORMAL;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n@vertex\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = u_MVPMatrix * positions;\n }\n\n@fragment\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = pbrProjection.modelViewProjectionMatrix * positions;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\nexport type CreateGLTFModelOptions = {\n id?: string;\n vertexCount?: number;\n geometry: Geometry;\n parsedPPBRMaterial: ParsedPBRMaterial;\n modelOptions?: Partial<ModelProps>;\n};\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial as unknown as ShaderModule],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const model = new Model(device, modelProps);\n\n const {camera, ...pbrMaterialProps} = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n\n model.shaderInputs.setProps({pbrMaterial: pbrMaterialProps, pbrProjection: {camera}});\n return new ModelNode({managedResources, model});\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {GLTFAnimation} from './animations/animations';\nimport {interpolate} from './animations/interpolate';\n\ntype GLTFSingleAnimatorProps = {\n animation: GLTFAnimation;\n startTime?: number;\n playing?: boolean;\n speed?: number;\n};\n\nclass GLTFSingleAnimator {\n animation: GLTFAnimation;\n startTime: number = 0;\n playing: boolean = true;\n speed: number = 1;\n\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n }\n\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(({sampler, target, path}) => {\n interpolate(time, sampler, target, path);\n applyTranslationRotationScale(target, (target as any)._node as GroupNode);\n });\n }\n}\n\nexport type GLTFAnimatorProps = {\n animations: GLTFAnimation[];\n};\n\nexport class GLTFAnimator {\n animations: GLTFSingleAnimator[];\n\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n getAnimations() {\n return this.animations;\n }\n}\n\n// TODO: share with GLTFInstantiator\nconst scratchMatrix = new Matrix4();\n\nfunction applyTranslationRotationScale(gltfNode: GLTFNodePostprocessed, node: GroupNode) {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n}\n", "import {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationChannel, GLTFAnimationSampler} from './animations';\n\nconst scratchQuaternion = new Quaternion();\n\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path']\n) {\n const maxTime = input[input.length - 1];\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n const previousIndex = Math.max(0, nextIndex - 1);\n\n if (!Array.isArray(target[path])) {\n switch (path) {\n case 'translation':\n target[path] = [0, 0, 0];\n break;\n\n case 'rotation':\n target[path] = [0, 0, 0, 1];\n break;\n\n case 'scale':\n target[path] = [1, 1, 1];\n break;\n\n default:\n log.warn(`Bad animation path ${path}`)();\n }\n }\n\n // assert(target[path].length === output[previousIndex].length);\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n stepInterpolate(target, path, output[previousIndex] as number[]);\n break;\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n linearInterpolate(\n target,\n path,\n output[previousIndex] as number[],\n output[nextIndex] as number[],\n ratio\n );\n }\n break;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1] as number[];\n const outTangent0 = output[3 * previousIndex + 2] as number[];\n const inTangent1 = output[3 * nextIndex + 0] as number[];\n const p1 = output[3 * nextIndex + 1] as number[];\n\n cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n break;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n break;\n }\n}\n\nfunction linearInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n start: number[],\n stop: number[],\n ratio: number\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n if (path === 'rotation') {\n // SLERP when path is rotation\n scratchQuaternion.slerp({start, target: stop, ratio});\n for (let i = 0; i < scratchQuaternion.length; i++) {\n target[path][i] = scratchQuaternion[i];\n }\n } else {\n // regular interpolation\n for (let i = 0; i < start.length; i++) {\n target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n }\n}\n\nfunction cubicsplineInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n {\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n }: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n }\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n // TODO: Quaternion might need normalization\n for (let i = 0; i < target[path].length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n target[path][i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n}\n\nfunction stepInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n value: number[]\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n for (let i = 0; i < value.length; i++) {\n target[path][i] = value[i];\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\ntype GLTFAccessor = {\n componentType: number;\n type: string;\n count: number;\n bufferView?: {data: {buffer: ArrayBuffer; byteOffset?: number}};\n byteOffset?: number;\n};\n\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n typedArray: TypedArray;\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFAnimationSampler\n} from '../gltf/animations/animations';\n\nimport {accessorToTypedArray} from '..//webgl-to-webgpu/convert-webgl-attribute';\n\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n return gltfAnimations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplers: GLTFAnimationSampler[] = animation.samplers.map(\n ({input, interpolation = 'LINEAR', output}) => ({\n input: accessorToJsArray(gltf.accessors[input]) as number[],\n interpolation,\n output: accessorToJsArray(gltf.accessors[output])\n })\n );\n const channels: GLTFAnimationChannel[] = animation.channels.map(({sampler, target}) => ({\n sampler: samplers[sampler],\n target: gltf.nodes[target.node ?? 0],\n path: target.path as GLTFAnimationChannel['path']\n }));\n return {name, channels};\n });\n}\n\n//\n\nfunction accessorToJsArray(\n accessor: GLTFAccessorPostprocessed & {_animation?: number[] | number[][]}\n): number[] | number[][] {\n if (!accessor._animation) {\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n\n if (components === 1) {\n accessor._animation = Array.from(array);\n } else {\n // Slice array\n const slicedArray: number[][] = [];\n for (let i = 0; i < array.length; i += components) {\n slicedArray.push(Array.from(array.slice(i, i + components)));\n }\n accessor._animation = slicedArray;\n }\n }\n\n return accessor._animation;\n}\n", "/** Deeply copies a JS data structure */\nexport function deepCopy(object: any): any {\n // don't copy binary data\n if (\n ArrayBuffer.isView(object) ||\n object instanceof ArrayBuffer ||\n object instanceof ImageBitmap\n ) {\n return object;\n }\n if (Array.isArray(object)) {\n return object.map(deepCopy);\n }\n if (object && typeof object === 'object') {\n const result: typeof object = {};\n for (const key in object) {\n result[key] = deepCopy(object[key]);\n }\n return result;\n }\n return object;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {Light} from '@luma.gl/shadertools';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {parseGLTFLights} from '../parsers/parse-gltf-lights';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {deepCopy} from '../utils/deep-copy';\n\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): {\n scenes: GroupNode[];\n animator: GLTFAnimator;\n lights: Light[];\n} {\n gltf = deepCopy(gltf);\n const scenes = parseGLTF(device, gltf, options);\n // Note: There is a nasty dependency on injected nodes in the glTF\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations});\n const lights = parseGLTFLights(gltf);\n return {scenes, animator, lights};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_constants", "import_core", "import_engine", "import_core", "GLEnum", "import_core", "import_engine", "import_core", "import_core"]
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { loadPBREnvironment, type PBREnvironment } from "./pbr/pbr-environment.j
|
|
|
2
2
|
export { type ParsedPBRMaterial } from "./pbr/pbr-material.js";
|
|
3
3
|
export { parsePBRMaterial, type ParsePBRMaterialOptions } from "./parsers/parse-pbr-material.js";
|
|
4
4
|
export {} from "./pbr/pbr-environment.js";
|
|
5
|
+
export { parseGLTFLights } from "./parsers/parse-gltf-lights.js";
|
|
5
6
|
export { createScenegraphsFromGLTF } from "./gltf/create-scenegraph-from-gltf.js";
|
|
6
7
|
export { GLTFAnimator } from "./gltf/gltf-animator.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAE,KAAK,cAAc,EAAC,iCAA8B;AAC9E,OAAO,EAAC,KAAK,iBAAiB,EAAC,8BAA2B;AAC1D,OAAO,EAAC,gBAAgB,EAAE,KAAK,uBAAuB,EAAC,wCAAqC;AAC5F,OAAO,EAAE,iCAA8B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAE,KAAK,cAAc,EAAC,iCAA8B;AAC9E,OAAO,EAAC,KAAK,iBAAiB,EAAC,8BAA2B;AAC1D,OAAO,EAAC,gBAAgB,EAAE,KAAK,uBAAuB,EAAC,wCAAqC;AAC5F,OAAO,EAAE,iCAA8B;AACvC,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAG5D,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
2
|
export { loadPBREnvironment } from "./pbr/pbr-environment.js";
|
|
3
3
|
export { parsePBRMaterial } from "./parsers/parse-pbr-material.js";
|
|
4
|
+
export { parseGLTFLights } from "./parsers/parse-gltf-lights.js";
|
|
4
5
|
// glTF Scenegraph Instantiator
|
|
5
6
|
export { createScenegraphsFromGLTF } from "./gltf/create-scenegraph-from-gltf.js";
|
|
6
7
|
export { GLTFAnimator } from "./gltf/gltf-animator.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAC,kBAAkB,EAAsB,iCAA8B;AAE9E,OAAO,EAAC,gBAAgB,EAA+B,wCAAqC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAC,kBAAkB,EAAsB,iCAA8B;AAE9E,OAAO,EAAC,gBAAgB,EAA+B,wCAAqC;AAE5F,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAE5D,+BAA+B;AAC/B,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GLTFPostprocessed } from '@loaders.gl/gltf';
|
|
2
|
+
import type { Light } from '@luma.gl/shadertools';
|
|
3
|
+
/** Parse KHR_lights_punctual extension into luma.gl light definitions */
|
|
4
|
+
export declare function parseGLTFLights(gltf: GLTFPostprocessed): Light[];
|
|
5
|
+
//# sourceMappingURL=parse-gltf-lights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-gltf-lights.d.ts","sourceRoot":"","sources":["../../src/parsers/parse-gltf-lights.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,KAAK,EAAmB,KAAK,EAAa,MAAM,sBAAsB,CAAC;AAE9E,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,KAAK,EAAE,CAyChE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Matrix4 } from '@math.gl/core';
|
|
2
|
+
/** Parse KHR_lights_punctual extension into luma.gl light definitions */
|
|
3
|
+
export function parseGLTFLights(gltf) {
|
|
4
|
+
const lightDefs = gltf.extensions?.['KHR_lights_punctual']?.['lights'];
|
|
5
|
+
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
const lights = [];
|
|
9
|
+
for (const node of gltf.nodes || []) {
|
|
10
|
+
const nodeLight = node.extensions?.KHR_lights_punctual;
|
|
11
|
+
if (!nodeLight || typeof nodeLight.light !== 'number') {
|
|
12
|
+
// eslint-disable-next-line no-continue
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
const gltfLight = lightDefs[nodeLight.light];
|
|
16
|
+
if (!gltfLight) {
|
|
17
|
+
// eslint-disable-next-line no-continue
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const color = (gltfLight.color || [1, 1, 1]);
|
|
21
|
+
const intensity = gltfLight.intensity ?? 1;
|
|
22
|
+
const range = gltfLight.range;
|
|
23
|
+
switch (gltfLight.type) {
|
|
24
|
+
case 'directional':
|
|
25
|
+
lights.push(parseDirectionalLight(node, color, intensity));
|
|
26
|
+
break;
|
|
27
|
+
case 'point':
|
|
28
|
+
lights.push(parsePointLight(node, color, intensity, range));
|
|
29
|
+
break;
|
|
30
|
+
case 'spot':
|
|
31
|
+
lights.push(parsePointLight(node, color, intensity, range));
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
// Unsupported light type
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return lights;
|
|
39
|
+
}
|
|
40
|
+
function parsePointLight(node, color, intensity, range) {
|
|
41
|
+
const position = node.translation
|
|
42
|
+
? [...node.translation]
|
|
43
|
+
: [0, 0, 0];
|
|
44
|
+
let attenuation = [1, 0, 0];
|
|
45
|
+
if (range !== undefined && range > 0) {
|
|
46
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
type: 'point',
|
|
50
|
+
position,
|
|
51
|
+
color,
|
|
52
|
+
intensity,
|
|
53
|
+
attenuation
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function parseDirectionalLight(node, color, intensity) {
|
|
57
|
+
let direction = [0, 0, -1];
|
|
58
|
+
if (node.rotation) {
|
|
59
|
+
const orientation = new Matrix4().fromQuaternion(node.rotation);
|
|
60
|
+
direction = orientation.transformDirection([0, 0, -1]);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
type: 'directional',
|
|
64
|
+
direction,
|
|
65
|
+
color,
|
|
66
|
+
intensity
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=parse-gltf-lights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-gltf-lights.js","sourceRoot":"","sources":["../../src/parsers/parse-gltf-lights.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Device } from '@luma.gl/core';
|
|
2
|
-
import {
|
|
2
|
+
import { DynamicTexture } from '@luma.gl/engine';
|
|
3
3
|
/** Environment textures for PBR module */
|
|
4
4
|
export type PBREnvironment = {
|
|
5
5
|
/** Bi-directional Reflectance Distribution Function (BRDF) lookup table */
|
|
6
|
-
brdfLutTexture:
|
|
7
|
-
diffuseEnvSampler:
|
|
8
|
-
specularEnvSampler:
|
|
6
|
+
brdfLutTexture: DynamicTexture;
|
|
7
|
+
diffuseEnvSampler: DynamicTexture;
|
|
8
|
+
specularEnvSampler: DynamicTexture;
|
|
9
9
|
};
|
|
10
10
|
export type PBREnvironmentProps = {
|
|
11
11
|
brdfLutUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbr-environment.d.ts","sourceRoot":"","sources":["../../src/pbr/pbr-environment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAe,MAAM,eAAe,CAAC;AACnD,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"pbr-environment.d.ts","sourceRoot":"","sources":["../../src/pbr/pbr-environment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAe,MAAM,eAAe,CAAC;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG;IAC3B,2EAA2E;IAC3E,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,cAAc,CAAC;IAClC,kBAAkB,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,yCAAyC;AACzC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,cAAc,CA+C7F"}
|