@luma.gl/gltf 9.3.0-alpha.6 → 9.3.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +942 -141
- package/dist/dist.min.js +4 -4
- package/dist/gltf/create-gltf-model.d.ts +9 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +58 -4
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +22 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +63 -1
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +899 -114
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +34 -12
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-lights.js +86 -20
- package/dist/parsers/parse-gltf-lights.js.map +1 -1
- package/dist/parsers/parse-gltf.d.ts +3 -1
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +41 -9
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +69 -1
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +429 -42
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +14 -12
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +8 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +5 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +12 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +1 -10
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +1 -15
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +5 -6
- package/src/gltf/create-gltf-model.ts +113 -5
- package/src/gltf/create-scenegraph-from-gltf.ts +97 -6
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +10 -1
- package/src/parsers/parse-gltf-animations.ts +39 -15
- package/src/parsers/parse-gltf-lights.ts +114 -25
- package/src/parsers/parse-gltf.ts +86 -19
- package/src/parsers/parse-pbr-material.ts +664 -69
- package/src/pbr/pbr-environment.ts +29 -16
- package/src/pbr/pbr-material.ts +13 -3
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +29 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +1 -15
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
package/dist/dist.dev.js
CHANGED
|
@@ -52,13 +52,6 @@ var __exports__ = (() => {
|
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
// external-global-plugin:@luma.gl/constants
|
|
56
|
-
var require_constants = __commonJS({
|
|
57
|
-
"external-global-plugin:@luma.gl/constants"(exports, module) {
|
|
58
|
-
module.exports = globalThis.luma;
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
55
|
// external-global-plugin:@luma.gl/shadertools
|
|
63
56
|
var require_shadertools = __commonJS({
|
|
64
57
|
"external-global-plugin:@luma.gl/shadertools"(exports, module) {
|
|
@@ -71,6 +64,7 @@ var __exports__ = (() => {
|
|
|
71
64
|
__export(bundle_exports, {
|
|
72
65
|
GLTFAnimator: () => GLTFAnimator,
|
|
73
66
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
67
|
+
getGLTFExtensionSupport: () => getGLTFExtensionSupport,
|
|
74
68
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
75
69
|
parseGLTFLights: () => parseGLTFLights,
|
|
76
70
|
parsePBRMaterial: () => parsePBRMaterial
|
|
@@ -620,6 +614,7 @@ var __exports__ = (() => {
|
|
|
620
614
|
|
|
621
615
|
// src/pbr/pbr-environment.ts
|
|
622
616
|
function loadPBREnvironment(device, props) {
|
|
617
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
623
618
|
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
624
619
|
id: "brdfLUT",
|
|
625
620
|
sampler: {
|
|
@@ -633,7 +628,9 @@ var __exports__ = (() => {
|
|
|
633
628
|
});
|
|
634
629
|
const diffuseEnvSampler = makeCube(device, {
|
|
635
630
|
id: "DiffuseEnvSampler",
|
|
636
|
-
getTextureForFace: (
|
|
631
|
+
getTextureForFace: (face) => loadImageTexture(
|
|
632
|
+
props.getTexUrl("diffuse", FACES.indexOf(face), 0)
|
|
633
|
+
),
|
|
637
634
|
sampler: {
|
|
638
635
|
addressModeU: "clamp-to-edge",
|
|
639
636
|
addressModeV: "clamp-to-edge",
|
|
@@ -643,12 +640,13 @@ var __exports__ = (() => {
|
|
|
643
640
|
});
|
|
644
641
|
const specularEnvSampler = makeCube(device, {
|
|
645
642
|
id: "SpecularEnvSampler",
|
|
646
|
-
getTextureForFace: (
|
|
643
|
+
getTextureForFace: (face) => {
|
|
647
644
|
const imageArray = [];
|
|
648
|
-
|
|
649
|
-
|
|
645
|
+
const direction = FACES.indexOf(face);
|
|
646
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
647
|
+
imageArray.push(loadImageTexture(props.getTexUrl("specular", direction, lod)));
|
|
650
648
|
}
|
|
651
|
-
return imageArray;
|
|
649
|
+
return Promise.all(imageArray);
|
|
652
650
|
},
|
|
653
651
|
sampler: {
|
|
654
652
|
addressModeU: "clamp-to-edge",
|
|
@@ -664,32 +662,34 @@ var __exports__ = (() => {
|
|
|
664
662
|
specularEnvSampler
|
|
665
663
|
};
|
|
666
664
|
}
|
|
667
|
-
var FACES = [
|
|
665
|
+
var FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
668
666
|
function makeCube(device, {
|
|
669
667
|
id,
|
|
670
668
|
getTextureForFace,
|
|
671
669
|
sampler
|
|
672
670
|
}) {
|
|
673
|
-
const data =
|
|
674
|
-
|
|
675
|
-
|
|
671
|
+
const data = Promise.all(
|
|
672
|
+
FACES.map((face) => getTextureForFace(face))
|
|
673
|
+
).then((faceDataArray) => {
|
|
674
|
+
const cubeData = {};
|
|
675
|
+
FACES.forEach((face, index) => {
|
|
676
|
+
cubeData[face] = faceDataArray[index];
|
|
677
|
+
});
|
|
678
|
+
return cubeData;
|
|
676
679
|
});
|
|
677
680
|
return new import_engine.DynamicTexture(device, {
|
|
678
681
|
id,
|
|
679
682
|
dimension: "cube",
|
|
680
683
|
mipmaps: false,
|
|
681
684
|
sampler,
|
|
682
|
-
// @ts-expect-error
|
|
683
685
|
data
|
|
684
686
|
});
|
|
685
687
|
}
|
|
686
688
|
|
|
687
689
|
// src/parsers/parse-pbr-material.ts
|
|
688
690
|
var import_core = __toESM(require_core(), 1);
|
|
689
|
-
var import_constants2 = __toESM(require_constants(), 1);
|
|
690
691
|
|
|
691
692
|
// src/webgl-to-webgpu/convert-webgl-sampler.ts
|
|
692
|
-
var import_constants = __toESM(require_constants(), 1);
|
|
693
693
|
function convertSampler(gltfSampler) {
|
|
694
694
|
return {
|
|
695
695
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -700,11 +700,11 @@ var __exports__ = (() => {
|
|
|
700
700
|
}
|
|
701
701
|
function convertSamplerWrapMode(mode) {
|
|
702
702
|
switch (mode) {
|
|
703
|
-
case
|
|
703
|
+
case 33071 /* CLAMP_TO_EDGE */:
|
|
704
704
|
return "clamp-to-edge";
|
|
705
|
-
case
|
|
705
|
+
case 10497 /* REPEAT */:
|
|
706
706
|
return "repeat";
|
|
707
|
-
case
|
|
707
|
+
case 33648 /* MIRRORED_REPEAT */:
|
|
708
708
|
return "mirror-repeat";
|
|
709
709
|
default:
|
|
710
710
|
return void 0;
|
|
@@ -712,9 +712,9 @@ var __exports__ = (() => {
|
|
|
712
712
|
}
|
|
713
713
|
function convertSamplerMagFilter(mode) {
|
|
714
714
|
switch (mode) {
|
|
715
|
-
case
|
|
715
|
+
case 9728 /* NEAREST */:
|
|
716
716
|
return "nearest";
|
|
717
|
-
case
|
|
717
|
+
case 9729 /* LINEAR */:
|
|
718
718
|
return "linear";
|
|
719
719
|
default:
|
|
720
720
|
return void 0;
|
|
@@ -722,17 +722,17 @@ var __exports__ = (() => {
|
|
|
722
722
|
}
|
|
723
723
|
function convertSamplerMinFilter(mode) {
|
|
724
724
|
switch (mode) {
|
|
725
|
-
case
|
|
725
|
+
case 9728 /* NEAREST */:
|
|
726
726
|
return { minFilter: "nearest" };
|
|
727
|
-
case
|
|
727
|
+
case 9729 /* LINEAR */:
|
|
728
728
|
return { minFilter: "linear" };
|
|
729
|
-
case
|
|
729
|
+
case 9984 /* NEAREST_MIPMAP_NEAREST */:
|
|
730
730
|
return { minFilter: "nearest", mipmapFilter: "nearest" };
|
|
731
|
-
case
|
|
731
|
+
case 9985 /* LINEAR_MIPMAP_NEAREST */:
|
|
732
732
|
return { minFilter: "linear", mipmapFilter: "nearest" };
|
|
733
|
-
case
|
|
733
|
+
case 9986 /* NEAREST_MIPMAP_LINEAR */:
|
|
734
734
|
return { minFilter: "nearest", mipmapFilter: "linear" };
|
|
735
|
-
case
|
|
735
|
+
case 9987 /* LINEAR_MIPMAP_LINEAR */:
|
|
736
736
|
return { minFilter: "linear", mipmapFilter: "linear" };
|
|
737
737
|
default:
|
|
738
738
|
return {};
|
|
@@ -764,7 +764,8 @@ var __exports__ = (() => {
|
|
|
764
764
|
if (imageBasedLightingEnvironment) {
|
|
765
765
|
parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
766
766
|
parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
767
|
-
parsedMaterial.bindings.
|
|
767
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
768
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
768
769
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
769
770
|
}
|
|
770
771
|
if (options?.pbrDebug) {
|
|
@@ -787,81 +788,181 @@ var __exports__ = (() => {
|
|
|
787
788
|
if (options?.lights)
|
|
788
789
|
parsedMaterial.defines["USE_LIGHTS"] = true;
|
|
789
790
|
if (material) {
|
|
790
|
-
|
|
791
|
+
if (options.validateAttributes !== false) {
|
|
792
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
793
|
+
}
|
|
794
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
791
795
|
}
|
|
792
796
|
return parsedMaterial;
|
|
793
797
|
}
|
|
794
|
-
function
|
|
795
|
-
|
|
798
|
+
function warnOnMissingExpectedAttributes(material, attributes) {
|
|
799
|
+
const uvDependentTextureSlots = getUvDependentTextureSlots(material);
|
|
800
|
+
if (uvDependentTextureSlots.length > 0 && !attributes["TEXCOORD_0"]) {
|
|
801
|
+
import_core.log.warn(
|
|
802
|
+
`glTF material uses ${uvDependentTextureSlots.join(", ")} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`
|
|
803
|
+
)();
|
|
804
|
+
}
|
|
805
|
+
const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);
|
|
806
|
+
if (isUnlitMaterial || attributes["NORMAL"]) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
const missingNormalReason = material.normalTexture ? "lit PBR shading with normalTexture" : "lit PBR shading";
|
|
810
|
+
import_core.log.warn(
|
|
811
|
+
`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`
|
|
812
|
+
)();
|
|
813
|
+
}
|
|
814
|
+
function getUvDependentTextureSlots(material) {
|
|
815
|
+
const uvDependentTextureSlots = [];
|
|
816
|
+
if (material.pbrMetallicRoughness?.baseColorTexture) {
|
|
817
|
+
uvDependentTextureSlots.push("baseColorTexture");
|
|
818
|
+
}
|
|
819
|
+
if (material.pbrMetallicRoughness?.metallicRoughnessTexture) {
|
|
820
|
+
uvDependentTextureSlots.push("metallicRoughnessTexture");
|
|
821
|
+
}
|
|
822
|
+
if (material.normalTexture) {
|
|
823
|
+
uvDependentTextureSlots.push("normalTexture");
|
|
824
|
+
}
|
|
825
|
+
if (material.occlusionTexture) {
|
|
826
|
+
uvDependentTextureSlots.push("occlusionTexture");
|
|
827
|
+
}
|
|
828
|
+
if (material.emissiveTexture) {
|
|
829
|
+
uvDependentTextureSlots.push("emissiveTexture");
|
|
830
|
+
}
|
|
831
|
+
if (material.extensions?.KHR_materials_specular?.specularTexture) {
|
|
832
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularTexture");
|
|
833
|
+
}
|
|
834
|
+
if (material.extensions?.KHR_materials_specular?.specularColorTexture) {
|
|
835
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularColorTexture");
|
|
836
|
+
}
|
|
837
|
+
if (material.extensions?.KHR_materials_transmission?.transmissionTexture) {
|
|
838
|
+
uvDependentTextureSlots.push("KHR_materials_transmission.transmissionTexture");
|
|
839
|
+
}
|
|
840
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatTexture) {
|
|
841
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatTexture");
|
|
842
|
+
}
|
|
843
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatRoughnessTexture) {
|
|
844
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatRoughnessTexture");
|
|
845
|
+
}
|
|
846
|
+
if (material.extensions?.KHR_materials_sheen?.sheenColorTexture) {
|
|
847
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenColorTexture");
|
|
848
|
+
}
|
|
849
|
+
if (material.extensions?.KHR_materials_sheen?.sheenRoughnessTexture) {
|
|
850
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenRoughnessTexture");
|
|
851
|
+
}
|
|
852
|
+
if (material.extensions?.KHR_materials_iridescence?.iridescenceTexture) {
|
|
853
|
+
uvDependentTextureSlots.push("KHR_materials_iridescence.iridescenceTexture");
|
|
854
|
+
}
|
|
855
|
+
if (material.extensions?.KHR_materials_anisotropy?.anisotropyTexture) {
|
|
856
|
+
uvDependentTextureSlots.push("KHR_materials_anisotropy.anisotropyTexture");
|
|
857
|
+
}
|
|
858
|
+
return uvDependentTextureSlots;
|
|
859
|
+
}
|
|
860
|
+
function parseMaterial(device, material, parsedMaterial, gltf) {
|
|
861
|
+
parsedMaterial.uniforms.unlit = Boolean(
|
|
862
|
+
material.unlit || material.extensions?.KHR_materials_unlit
|
|
863
|
+
);
|
|
796
864
|
if (material.pbrMetallicRoughness) {
|
|
797
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
865
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
798
866
|
}
|
|
799
867
|
if (material.normalTexture) {
|
|
800
|
-
addTexture(
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
);
|
|
868
|
+
addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
|
|
869
|
+
featureOptions: {
|
|
870
|
+
define: "HAS_NORMALMAP",
|
|
871
|
+
enabledUniformName: "normalMapEnabled"
|
|
872
|
+
},
|
|
873
|
+
gltf
|
|
874
|
+
});
|
|
807
875
|
const { scale: scale4 = 1 } = material.normalTexture;
|
|
808
876
|
parsedMaterial.uniforms.normalScale = scale4;
|
|
809
877
|
}
|
|
810
878
|
if (material.occlusionTexture) {
|
|
811
|
-
addTexture(
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
);
|
|
879
|
+
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
|
|
880
|
+
featureOptions: {
|
|
881
|
+
define: "HAS_OCCLUSIONMAP",
|
|
882
|
+
enabledUniformName: "occlusionMapEnabled"
|
|
883
|
+
},
|
|
884
|
+
gltf
|
|
885
|
+
});
|
|
818
886
|
const { strength = 1 } = material.occlusionTexture;
|
|
819
887
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
820
888
|
}
|
|
889
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
821
890
|
if (material.emissiveTexture) {
|
|
822
|
-
addTexture(
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
);
|
|
829
|
-
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
891
|
+
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", parsedMaterial, {
|
|
892
|
+
featureOptions: {
|
|
893
|
+
define: "HAS_EMISSIVEMAP",
|
|
894
|
+
enabledUniformName: "emissiveMapEnabled"
|
|
895
|
+
},
|
|
896
|
+
gltf
|
|
897
|
+
});
|
|
830
898
|
}
|
|
831
|
-
|
|
832
|
-
|
|
899
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
900
|
+
switch (material.alphaMode || "OPAQUE") {
|
|
901
|
+
case "OPAQUE":
|
|
902
|
+
break;
|
|
903
|
+
case "MASK": {
|
|
833
904
|
const { alphaCutoff = 0.5 } = material;
|
|
834
905
|
parsedMaterial.defines["ALPHA_CUTOFF"] = true;
|
|
906
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
835
907
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
836
908
|
break;
|
|
909
|
+
}
|
|
837
910
|
case "BLEND":
|
|
838
911
|
import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
|
|
839
|
-
parsedMaterial
|
|
840
|
-
parsedMaterial.parameters.blendColorOperation = "add";
|
|
841
|
-
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
842
|
-
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
843
|
-
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
844
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
845
|
-
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
846
|
-
parsedMaterial.glParameters["blend"] = true;
|
|
847
|
-
parsedMaterial.glParameters["blendEquation"] = import_constants2.GL.FUNC_ADD;
|
|
848
|
-
parsedMaterial.glParameters["blendFunc"] = [
|
|
849
|
-
import_constants2.GL.SRC_ALPHA,
|
|
850
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA,
|
|
851
|
-
import_constants2.GL.ONE,
|
|
852
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA
|
|
853
|
-
];
|
|
912
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
854
913
|
break;
|
|
855
914
|
}
|
|
856
915
|
}
|
|
857
|
-
function
|
|
916
|
+
function applyAlphaBlendParameters(parsedMaterial) {
|
|
917
|
+
parsedMaterial.parameters.blend = true;
|
|
918
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
919
|
+
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
920
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
921
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
922
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
923
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
924
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
925
|
+
parsedMaterial.glParameters["blendEquation"] = 32774 /* FUNC_ADD */;
|
|
926
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
927
|
+
770 /* SRC_ALPHA */,
|
|
928
|
+
771 /* ONE_MINUS_SRC_ALPHA */,
|
|
929
|
+
1 /* ONE */,
|
|
930
|
+
771 /* ONE_MINUS_SRC_ALPHA */
|
|
931
|
+
];
|
|
932
|
+
}
|
|
933
|
+
function applyTransmissionBlendApproximation(parsedMaterial) {
|
|
934
|
+
parsedMaterial.parameters.blend = true;
|
|
935
|
+
parsedMaterial.parameters.depthWriteEnabled = false;
|
|
936
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
937
|
+
parsedMaterial.parameters.blendColorSrcFactor = "one";
|
|
938
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
939
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
940
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
941
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
942
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
943
|
+
parsedMaterial.glParameters["depthMask"] = false;
|
|
944
|
+
parsedMaterial.glParameters["blendEquation"] = 32774 /* FUNC_ADD */;
|
|
945
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
946
|
+
1 /* ONE */,
|
|
947
|
+
771 /* ONE_MINUS_SRC_ALPHA */,
|
|
948
|
+
1 /* ONE */,
|
|
949
|
+
771 /* ONE_MINUS_SRC_ALPHA */
|
|
950
|
+
];
|
|
951
|
+
}
|
|
952
|
+
function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial, gltf) {
|
|
858
953
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
859
954
|
addTexture(
|
|
860
955
|
device,
|
|
861
956
|
pbrMetallicRoughness.baseColorTexture,
|
|
862
957
|
"pbr_baseColorSampler",
|
|
863
|
-
|
|
864
|
-
|
|
958
|
+
parsedMaterial,
|
|
959
|
+
{
|
|
960
|
+
featureOptions: {
|
|
961
|
+
define: "HAS_BASECOLORMAP",
|
|
962
|
+
enabledUniformName: "baseColorMapEnabled"
|
|
963
|
+
},
|
|
964
|
+
gltf
|
|
965
|
+
}
|
|
865
966
|
);
|
|
866
967
|
}
|
|
867
968
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
@@ -870,15 +971,278 @@ var __exports__ = (() => {
|
|
|
870
971
|
device,
|
|
871
972
|
pbrMetallicRoughness.metallicRoughnessTexture,
|
|
872
973
|
"pbr_metallicRoughnessSampler",
|
|
873
|
-
|
|
874
|
-
|
|
974
|
+
parsedMaterial,
|
|
975
|
+
{
|
|
976
|
+
featureOptions: {
|
|
977
|
+
define: "HAS_METALROUGHNESSMAP",
|
|
978
|
+
enabledUniformName: "metallicRoughnessMapEnabled"
|
|
979
|
+
},
|
|
980
|
+
gltf
|
|
981
|
+
}
|
|
875
982
|
);
|
|
876
983
|
}
|
|
877
984
|
const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
|
|
878
985
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
879
986
|
}
|
|
880
|
-
function
|
|
881
|
-
|
|
987
|
+
function parseMaterialExtensions(device, extensions, parsedMaterial, gltf) {
|
|
988
|
+
if (!extensions) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (hasMaterialExtensionShading(extensions)) {
|
|
992
|
+
parsedMaterial.defines["USE_MATERIAL_EXTENSIONS"] = true;
|
|
993
|
+
}
|
|
994
|
+
parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);
|
|
995
|
+
parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
|
|
996
|
+
parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);
|
|
997
|
+
parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);
|
|
998
|
+
parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);
|
|
999
|
+
parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);
|
|
1000
|
+
parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);
|
|
1001
|
+
parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);
|
|
1002
|
+
parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
|
|
1003
|
+
}
|
|
1004
|
+
function hasMaterialExtensionShading(extensions) {
|
|
1005
|
+
return Boolean(
|
|
1006
|
+
extensions.KHR_materials_specular || extensions.KHR_materials_ior || extensions.KHR_materials_transmission || extensions.KHR_materials_volume || extensions.KHR_materials_clearcoat || extensions.KHR_materials_sheen || extensions.KHR_materials_iridescence || extensions.KHR_materials_anisotropy
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
function parseSpecularExtension(device, extension, parsedMaterial, gltf) {
|
|
1010
|
+
if (!extension) {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
if (extension.specularColorFactor) {
|
|
1014
|
+
parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
|
|
1015
|
+
}
|
|
1016
|
+
if (extension.specularFactor !== void 0) {
|
|
1017
|
+
parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
|
|
1018
|
+
}
|
|
1019
|
+
if (extension.specularColorTexture) {
|
|
1020
|
+
addTexture(device, extension.specularColorTexture, "pbr_specularColorSampler", parsedMaterial, {
|
|
1021
|
+
featureOptions: {
|
|
1022
|
+
define: "HAS_SPECULARCOLORMAP",
|
|
1023
|
+
enabledUniformName: "specularColorMapEnabled"
|
|
1024
|
+
},
|
|
1025
|
+
gltf
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
if (extension.specularTexture) {
|
|
1029
|
+
addTexture(device, extension.specularTexture, "pbr_specularIntensitySampler", parsedMaterial, {
|
|
1030
|
+
featureOptions: {
|
|
1031
|
+
define: "HAS_SPECULARINTENSITYMAP",
|
|
1032
|
+
enabledUniformName: "specularIntensityMapEnabled"
|
|
1033
|
+
},
|
|
1034
|
+
gltf
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function parseIorExtension(extension, parsedMaterial) {
|
|
1039
|
+
if (extension?.ior !== void 0) {
|
|
1040
|
+
parsedMaterial.uniforms.ior = extension.ior;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function parseTransmissionExtension(device, extension, parsedMaterial, gltf) {
|
|
1044
|
+
if (!extension) {
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (extension.transmissionFactor !== void 0) {
|
|
1048
|
+
parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
|
|
1049
|
+
}
|
|
1050
|
+
if (extension.transmissionTexture) {
|
|
1051
|
+
addTexture(device, extension.transmissionTexture, "pbr_transmissionSampler", parsedMaterial, {
|
|
1052
|
+
featureOptions: {
|
|
1053
|
+
define: "HAS_TRANSMISSIONMAP",
|
|
1054
|
+
enabledUniformName: "transmissionMapEnabled"
|
|
1055
|
+
},
|
|
1056
|
+
gltf
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
|
|
1060
|
+
import_core.log.warn(
|
|
1061
|
+
"KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting"
|
|
1062
|
+
)();
|
|
1063
|
+
applyTransmissionBlendApproximation(parsedMaterial);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function parseVolumeExtension(device, extension, parsedMaterial, gltf) {
|
|
1067
|
+
if (!extension) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
if (extension.thicknessFactor !== void 0) {
|
|
1071
|
+
parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
|
|
1072
|
+
}
|
|
1073
|
+
if (extension.thicknessTexture) {
|
|
1074
|
+
addTexture(device, extension.thicknessTexture, "pbr_thicknessSampler", parsedMaterial, {
|
|
1075
|
+
featureOptions: {
|
|
1076
|
+
define: "HAS_THICKNESSMAP"
|
|
1077
|
+
},
|
|
1078
|
+
gltf
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
if (extension.attenuationDistance !== void 0) {
|
|
1082
|
+
parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
|
|
1083
|
+
}
|
|
1084
|
+
if (extension.attenuationColor) {
|
|
1085
|
+
parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function parseClearcoatExtension(device, extension, parsedMaterial, gltf) {
|
|
1089
|
+
if (!extension) {
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
if (extension.clearcoatFactor !== void 0) {
|
|
1093
|
+
parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
|
|
1094
|
+
}
|
|
1095
|
+
if (extension.clearcoatRoughnessFactor !== void 0) {
|
|
1096
|
+
parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
|
|
1097
|
+
}
|
|
1098
|
+
if (extension.clearcoatTexture) {
|
|
1099
|
+
addTexture(device, extension.clearcoatTexture, "pbr_clearcoatSampler", parsedMaterial, {
|
|
1100
|
+
featureOptions: {
|
|
1101
|
+
define: "HAS_CLEARCOATMAP",
|
|
1102
|
+
enabledUniformName: "clearcoatMapEnabled"
|
|
1103
|
+
},
|
|
1104
|
+
gltf
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
if (extension.clearcoatRoughnessTexture) {
|
|
1108
|
+
addTexture(
|
|
1109
|
+
device,
|
|
1110
|
+
extension.clearcoatRoughnessTexture,
|
|
1111
|
+
"pbr_clearcoatRoughnessSampler",
|
|
1112
|
+
parsedMaterial,
|
|
1113
|
+
{
|
|
1114
|
+
featureOptions: {
|
|
1115
|
+
define: "HAS_CLEARCOATROUGHNESSMAP",
|
|
1116
|
+
enabledUniformName: "clearcoatRoughnessMapEnabled"
|
|
1117
|
+
},
|
|
1118
|
+
gltf
|
|
1119
|
+
}
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
if (extension.clearcoatNormalTexture) {
|
|
1123
|
+
addTexture(
|
|
1124
|
+
device,
|
|
1125
|
+
extension.clearcoatNormalTexture,
|
|
1126
|
+
"pbr_clearcoatNormalSampler",
|
|
1127
|
+
parsedMaterial,
|
|
1128
|
+
{
|
|
1129
|
+
featureOptions: {
|
|
1130
|
+
define: "HAS_CLEARCOATNORMALMAP"
|
|
1131
|
+
},
|
|
1132
|
+
gltf
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function parseSheenExtension(device, extension, parsedMaterial, gltf) {
|
|
1138
|
+
if (!extension) {
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
if (extension.sheenColorFactor) {
|
|
1142
|
+
parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
|
|
1143
|
+
}
|
|
1144
|
+
if (extension.sheenRoughnessFactor !== void 0) {
|
|
1145
|
+
parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
|
|
1146
|
+
}
|
|
1147
|
+
if (extension.sheenColorTexture) {
|
|
1148
|
+
addTexture(device, extension.sheenColorTexture, "pbr_sheenColorSampler", parsedMaterial, {
|
|
1149
|
+
featureOptions: {
|
|
1150
|
+
define: "HAS_SHEENCOLORMAP",
|
|
1151
|
+
enabledUniformName: "sheenColorMapEnabled"
|
|
1152
|
+
},
|
|
1153
|
+
gltf
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
if (extension.sheenRoughnessTexture) {
|
|
1157
|
+
addTexture(
|
|
1158
|
+
device,
|
|
1159
|
+
extension.sheenRoughnessTexture,
|
|
1160
|
+
"pbr_sheenRoughnessSampler",
|
|
1161
|
+
parsedMaterial,
|
|
1162
|
+
{
|
|
1163
|
+
featureOptions: {
|
|
1164
|
+
define: "HAS_SHEENROUGHNESSMAP",
|
|
1165
|
+
enabledUniformName: "sheenRoughnessMapEnabled"
|
|
1166
|
+
},
|
|
1167
|
+
gltf
|
|
1168
|
+
}
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
function parseIridescenceExtension(device, extension, parsedMaterial, gltf) {
|
|
1173
|
+
if (!extension) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (extension.iridescenceFactor !== void 0) {
|
|
1177
|
+
parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
|
|
1178
|
+
}
|
|
1179
|
+
if (extension.iridescenceIor !== void 0) {
|
|
1180
|
+
parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
|
|
1181
|
+
}
|
|
1182
|
+
if (extension.iridescenceThicknessMinimum !== void 0 || extension.iridescenceThicknessMaximum !== void 0) {
|
|
1183
|
+
parsedMaterial.uniforms.iridescenceThicknessRange = [
|
|
1184
|
+
extension.iridescenceThicknessMinimum ?? 100,
|
|
1185
|
+
extension.iridescenceThicknessMaximum ?? 400
|
|
1186
|
+
];
|
|
1187
|
+
}
|
|
1188
|
+
if (extension.iridescenceTexture) {
|
|
1189
|
+
addTexture(device, extension.iridescenceTexture, "pbr_iridescenceSampler", parsedMaterial, {
|
|
1190
|
+
featureOptions: {
|
|
1191
|
+
define: "HAS_IRIDESCENCEMAP",
|
|
1192
|
+
enabledUniformName: "iridescenceMapEnabled"
|
|
1193
|
+
},
|
|
1194
|
+
gltf
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
if (extension.iridescenceThicknessTexture) {
|
|
1198
|
+
addTexture(
|
|
1199
|
+
device,
|
|
1200
|
+
extension.iridescenceThicknessTexture,
|
|
1201
|
+
"pbr_iridescenceThicknessSampler",
|
|
1202
|
+
parsedMaterial,
|
|
1203
|
+
{
|
|
1204
|
+
featureOptions: {
|
|
1205
|
+
define: "HAS_IRIDESCENCETHICKNESSMAP"
|
|
1206
|
+
},
|
|
1207
|
+
gltf
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
function parseAnisotropyExtension(device, extension, parsedMaterial, gltf) {
|
|
1213
|
+
if (!extension) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
if (extension.anisotropyStrength !== void 0) {
|
|
1217
|
+
parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
|
|
1218
|
+
}
|
|
1219
|
+
if (extension.anisotropyRotation !== void 0) {
|
|
1220
|
+
parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
|
|
1221
|
+
}
|
|
1222
|
+
if (extension.anisotropyTexture) {
|
|
1223
|
+
addTexture(device, extension.anisotropyTexture, "pbr_anisotropySampler", parsedMaterial, {
|
|
1224
|
+
featureOptions: {
|
|
1225
|
+
define: "HAS_ANISOTROPYMAP",
|
|
1226
|
+
enabledUniformName: "anisotropyMapEnabled"
|
|
1227
|
+
},
|
|
1228
|
+
gltf
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
function parseEmissiveStrengthExtension(extension, parsedMaterial) {
|
|
1233
|
+
if (extension?.emissiveStrength !== void 0) {
|
|
1234
|
+
parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
function addTexture(device, gltfTexture, uniformName, parsedMaterial, textureParseOptions = {}) {
|
|
1238
|
+
const { featureOptions = {}, gltf } = textureParseOptions;
|
|
1239
|
+
const { define, enabledUniformName } = featureOptions;
|
|
1240
|
+
const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
|
|
1241
|
+
const image = resolvedTextureInfo.texture?.source?.image;
|
|
1242
|
+
if (!image) {
|
|
1243
|
+
import_core.log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
882
1246
|
const gltfSampler = {
|
|
883
1247
|
wrapS: 10497,
|
|
884
1248
|
// default REPEAT S (U) wrapping mode.
|
|
@@ -888,10 +1252,10 @@ var __exports__ = (() => {
|
|
|
888
1252
|
// default LINEAR filtering
|
|
889
1253
|
magFilter: 9729,
|
|
890
1254
|
// default LINEAR filtering
|
|
891
|
-
...
|
|
1255
|
+
...resolvedTextureInfo?.texture?.sampler
|
|
892
1256
|
};
|
|
893
1257
|
const baseOptions = {
|
|
894
|
-
id:
|
|
1258
|
+
id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
|
|
895
1259
|
sampler: convertSampler(gltfSampler)
|
|
896
1260
|
};
|
|
897
1261
|
let texture;
|
|
@@ -909,8 +1273,34 @@ var __exports__ = (() => {
|
|
|
909
1273
|
parsedMaterial.bindings[uniformName] = texture;
|
|
910
1274
|
if (define)
|
|
911
1275
|
parsedMaterial.defines[define] = true;
|
|
1276
|
+
if (enabledUniformName) {
|
|
1277
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
1278
|
+
}
|
|
912
1279
|
parsedMaterial.generatedTextures.push(texture);
|
|
913
1280
|
}
|
|
1281
|
+
function resolveTextureInfo(gltfTexture, gltf) {
|
|
1282
|
+
if (gltfTexture.texture || gltfTexture.index === void 0 || !gltf?.textures) {
|
|
1283
|
+
return gltfTexture;
|
|
1284
|
+
}
|
|
1285
|
+
const resolvedTextureEntry = gltf.textures[gltfTexture.index];
|
|
1286
|
+
if (!resolvedTextureEntry) {
|
|
1287
|
+
return gltfTexture;
|
|
1288
|
+
}
|
|
1289
|
+
if ("texture" in resolvedTextureEntry && resolvedTextureEntry.texture) {
|
|
1290
|
+
return {
|
|
1291
|
+
...resolvedTextureEntry,
|
|
1292
|
+
...gltfTexture,
|
|
1293
|
+
texture: resolvedTextureEntry.texture
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
if (!("source" in resolvedTextureEntry)) {
|
|
1297
|
+
return gltfTexture;
|
|
1298
|
+
}
|
|
1299
|
+
return {
|
|
1300
|
+
...gltfTexture,
|
|
1301
|
+
texture: resolvedTextureEntry
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
914
1304
|
function createCompressedTextureFallback(device, baseOptions) {
|
|
915
1305
|
return device.createTexture({
|
|
916
1306
|
...baseOptions,
|
|
@@ -3579,6 +3969,7 @@ var __exports__ = (() => {
|
|
|
3579
3969
|
};
|
|
3580
3970
|
|
|
3581
3971
|
// src/parsers/parse-gltf-lights.ts
|
|
3972
|
+
var GLTF_COLOR_FACTOR = 255;
|
|
3582
3973
|
function parseGLTFLights(gltf) {
|
|
3583
3974
|
const lightDefs = (
|
|
3584
3975
|
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
@@ -3588,6 +3979,8 @@ var __exports__ = (() => {
|
|
|
3588
3979
|
return [];
|
|
3589
3980
|
}
|
|
3590
3981
|
const lights = [];
|
|
3982
|
+
const parentNodeById = createParentNodeMap(gltf.nodes || []);
|
|
3983
|
+
const worldMatrixByNodeId = /* @__PURE__ */ new Map();
|
|
3591
3984
|
for (const node of gltf.nodes || []) {
|
|
3592
3985
|
const lightIndex = node.light ?? node.extensions?.KHR_lights_punctual?.light;
|
|
3593
3986
|
if (typeof lightIndex !== "number") {
|
|
@@ -3597,18 +3990,21 @@ var __exports__ = (() => {
|
|
|
3597
3990
|
if (!gltfLight) {
|
|
3598
3991
|
continue;
|
|
3599
3992
|
}
|
|
3600
|
-
const color =
|
|
3993
|
+
const color = normalizeGLTFLightColor(
|
|
3994
|
+
gltfLight.color || [1, 1, 1]
|
|
3995
|
+
);
|
|
3601
3996
|
const intensity = gltfLight.intensity ?? 1;
|
|
3602
3997
|
const range = gltfLight.range;
|
|
3998
|
+
const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);
|
|
3603
3999
|
switch (gltfLight.type) {
|
|
3604
4000
|
case "directional":
|
|
3605
|
-
lights.push(parseDirectionalLight(
|
|
4001
|
+
lights.push(parseDirectionalLight(worldMatrix, color, intensity));
|
|
3606
4002
|
break;
|
|
3607
4003
|
case "point":
|
|
3608
|
-
lights.push(parsePointLight(
|
|
4004
|
+
lights.push(parsePointLight(worldMatrix, color, intensity, range));
|
|
3609
4005
|
break;
|
|
3610
4006
|
case "spot":
|
|
3611
|
-
lights.push(
|
|
4007
|
+
lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));
|
|
3612
4008
|
break;
|
|
3613
4009
|
default:
|
|
3614
4010
|
break;
|
|
@@ -3616,8 +4012,11 @@ var __exports__ = (() => {
|
|
|
3616
4012
|
}
|
|
3617
4013
|
return lights;
|
|
3618
4014
|
}
|
|
3619
|
-
function
|
|
3620
|
-
|
|
4015
|
+
function normalizeGLTFLightColor(color) {
|
|
4016
|
+
return color.map((component) => component * GLTF_COLOR_FACTOR);
|
|
4017
|
+
}
|
|
4018
|
+
function parsePointLight(worldMatrix, color, intensity, range) {
|
|
4019
|
+
const position = getLightPosition(worldMatrix);
|
|
3621
4020
|
let attenuation = [1, 0, 0];
|
|
3622
4021
|
if (range !== void 0 && range > 0) {
|
|
3623
4022
|
attenuation = [1, 0, 1 / (range * range)];
|
|
@@ -3630,8 +4029,8 @@ var __exports__ = (() => {
|
|
|
3630
4029
|
attenuation
|
|
3631
4030
|
};
|
|
3632
4031
|
}
|
|
3633
|
-
function parseDirectionalLight(
|
|
3634
|
-
const direction =
|
|
4032
|
+
function parseDirectionalLight(worldMatrix, color, intensity) {
|
|
4033
|
+
const direction = getLightDirection(worldMatrix);
|
|
3635
4034
|
return {
|
|
3636
4035
|
type: "directional",
|
|
3637
4036
|
direction,
|
|
@@ -3639,27 +4038,72 @@ var __exports__ = (() => {
|
|
|
3639
4038
|
intensity
|
|
3640
4039
|
};
|
|
3641
4040
|
}
|
|
3642
|
-
function
|
|
3643
|
-
|
|
3644
|
-
|
|
4041
|
+
function parseSpotLight(worldMatrix, color, intensity, range, spot = {}) {
|
|
4042
|
+
const position = getLightPosition(worldMatrix);
|
|
4043
|
+
const direction = getLightDirection(worldMatrix);
|
|
4044
|
+
let attenuation = [1, 0, 0];
|
|
4045
|
+
if (range !== void 0 && range > 0) {
|
|
4046
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
3645
4047
|
}
|
|
3646
|
-
|
|
3647
|
-
|
|
4048
|
+
return {
|
|
4049
|
+
type: "spot",
|
|
4050
|
+
position,
|
|
4051
|
+
direction,
|
|
4052
|
+
color,
|
|
4053
|
+
intensity,
|
|
4054
|
+
attenuation,
|
|
4055
|
+
innerConeAngle: spot.innerConeAngle ?? 0,
|
|
4056
|
+
outerConeAngle: spot.outerConeAngle ?? Math.PI / 4
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
4059
|
+
function createParentNodeMap(nodes) {
|
|
4060
|
+
const parentNodeById = /* @__PURE__ */ new Map();
|
|
4061
|
+
for (const node of nodes) {
|
|
4062
|
+
for (const childNode of node.children || []) {
|
|
4063
|
+
parentNodeById.set(childNode.id, node);
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
return parentNodeById;
|
|
4067
|
+
}
|
|
4068
|
+
function getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId) {
|
|
4069
|
+
const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);
|
|
4070
|
+
if (cachedWorldMatrix) {
|
|
4071
|
+
return cachedWorldMatrix;
|
|
3648
4072
|
}
|
|
3649
|
-
|
|
4073
|
+
const localMatrix = getNodeLocalMatrix(node);
|
|
4074
|
+
const parentNode = parentNodeById.get(node.id);
|
|
4075
|
+
const worldMatrix = parentNode ? new Matrix4(
|
|
4076
|
+
getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)
|
|
4077
|
+
).multiplyRight(localMatrix) : localMatrix;
|
|
4078
|
+
worldMatrixByNodeId.set(node.id, worldMatrix);
|
|
4079
|
+
return worldMatrix;
|
|
3650
4080
|
}
|
|
3651
|
-
function
|
|
4081
|
+
function getNodeLocalMatrix(node) {
|
|
3652
4082
|
if (node.matrix) {
|
|
3653
|
-
return new Matrix4(node.matrix)
|
|
4083
|
+
return new Matrix4(node.matrix);
|
|
4084
|
+
}
|
|
4085
|
+
const matrix = new Matrix4();
|
|
4086
|
+
if (node.translation) {
|
|
4087
|
+
matrix.translate(node.translation);
|
|
3654
4088
|
}
|
|
3655
4089
|
if (node.rotation) {
|
|
3656
|
-
|
|
4090
|
+
matrix.multiplyRight(new Matrix4().fromQuaternion(node.rotation));
|
|
4091
|
+
}
|
|
4092
|
+
if (node.scale) {
|
|
4093
|
+
matrix.scale(node.scale);
|
|
3657
4094
|
}
|
|
3658
|
-
return
|
|
4095
|
+
return matrix;
|
|
4096
|
+
}
|
|
4097
|
+
function getLightPosition(worldMatrix) {
|
|
4098
|
+
return worldMatrix.transformAsPoint([0, 0, 0]);
|
|
4099
|
+
}
|
|
4100
|
+
function getLightDirection(worldMatrix) {
|
|
4101
|
+
return worldMatrix.transformDirection([0, 0, -1]);
|
|
3659
4102
|
}
|
|
3660
4103
|
|
|
3661
4104
|
// src/parsers/parse-gltf.ts
|
|
3662
|
-
var
|
|
4105
|
+
var import_engine4 = __toESM(require_engine(), 1);
|
|
4106
|
+
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
3663
4107
|
|
|
3664
4108
|
// src/webgl-to-webgpu/convert-webgl-topology.ts
|
|
3665
4109
|
function convertGLDrawModeToTopology(drawMode) {
|
|
@@ -3681,8 +4125,9 @@ var __exports__ = (() => {
|
|
|
3681
4125
|
|
|
3682
4126
|
// src/gltf/create-gltf-model.ts
|
|
3683
4127
|
var import_core3 = __toESM(require_core(), 1);
|
|
3684
|
-
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
3685
4128
|
var import_engine2 = __toESM(require_engine(), 1);
|
|
4129
|
+
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
4130
|
+
var import_engine3 = __toESM(require_engine(), 1);
|
|
3686
4131
|
var SHADER = (
|
|
3687
4132
|
/* WGSL */
|
|
3688
4133
|
`
|
|
@@ -3838,6 +4283,25 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3838
4283
|
}
|
|
3839
4284
|
`
|
|
3840
4285
|
);
|
|
4286
|
+
function createGLTFMaterial(device, options) {
|
|
4287
|
+
const materialFactory = options.materialFactory || new import_engine3.MaterialFactory(device, { modules: [import_shadertools.pbrMaterial] });
|
|
4288
|
+
const pbrMaterialProps = { ...options.parsedPPBRMaterial.uniforms };
|
|
4289
|
+
delete pbrMaterialProps.camera;
|
|
4290
|
+
const materialBindings = Object.fromEntries(
|
|
4291
|
+
Object.entries({
|
|
4292
|
+
...pbrMaterialProps,
|
|
4293
|
+
...options.parsedPPBRMaterial.bindings
|
|
4294
|
+
}).filter(
|
|
4295
|
+
([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)
|
|
4296
|
+
)
|
|
4297
|
+
);
|
|
4298
|
+
const material = materialFactory.createMaterial({
|
|
4299
|
+
id: options.id,
|
|
4300
|
+
bindings: materialBindings
|
|
4301
|
+
});
|
|
4302
|
+
material.setProps({ pbrMaterial: pbrMaterialProps });
|
|
4303
|
+
return material;
|
|
4304
|
+
}
|
|
3841
4305
|
function createGLTFModel(device, options) {
|
|
3842
4306
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
3843
4307
|
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
@@ -3861,15 +4325,52 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3861
4325
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
3862
4326
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
3863
4327
|
};
|
|
3864
|
-
const
|
|
3865
|
-
|
|
4328
|
+
const material = options.material || createGLTFMaterial(device, {
|
|
4329
|
+
id: id ? `${id}-material` : void 0,
|
|
4330
|
+
parsedPPBRMaterial
|
|
4331
|
+
});
|
|
4332
|
+
modelProps.material = material;
|
|
4333
|
+
const model = new import_engine3.Model(device, modelProps);
|
|
4334
|
+
const sceneShaderInputValues = {
|
|
3866
4335
|
...parsedPPBRMaterial.uniforms,
|
|
3867
4336
|
...modelOptions.uniforms,
|
|
3868
4337
|
...parsedPPBRMaterial.bindings,
|
|
3869
4338
|
...modelOptions.bindings
|
|
3870
4339
|
};
|
|
3871
|
-
|
|
3872
|
-
|
|
4340
|
+
const sceneShaderInputProps = getSceneShaderInputProps(
|
|
4341
|
+
model.shaderInputs.getModules(),
|
|
4342
|
+
material,
|
|
4343
|
+
sceneShaderInputValues
|
|
4344
|
+
);
|
|
4345
|
+
model.shaderInputs.setProps(sceneShaderInputProps);
|
|
4346
|
+
return new import_engine3.ModelNode({ managedResources, model });
|
|
4347
|
+
}
|
|
4348
|
+
function isMaterialBindingResource(value) {
|
|
4349
|
+
return value instanceof import_core3.Buffer || value instanceof import_engine2.DynamicTexture || value instanceof import_core3.Sampler || value instanceof import_core3.Texture || value instanceof import_core3.TextureView;
|
|
4350
|
+
}
|
|
4351
|
+
function getSceneShaderInputProps(modules, material, shaderInputValues) {
|
|
4352
|
+
const propertyToModuleNameMap = /* @__PURE__ */ new Map();
|
|
4353
|
+
for (const module of modules) {
|
|
4354
|
+
for (const uniformName of Object.keys(module.uniformTypes || {})) {
|
|
4355
|
+
propertyToModuleNameMap.set(uniformName, module.name);
|
|
4356
|
+
}
|
|
4357
|
+
for (const binding of module.bindingLayout || []) {
|
|
4358
|
+
propertyToModuleNameMap.set(binding.name, module.name);
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
const sceneShaderInputProps = {};
|
|
4362
|
+
for (const [propertyName, value] of Object.entries(shaderInputValues)) {
|
|
4363
|
+
if (value === void 0) {
|
|
4364
|
+
continue;
|
|
4365
|
+
}
|
|
4366
|
+
const moduleName = propertyToModuleNameMap.get(propertyName);
|
|
4367
|
+
if (!moduleName || material.ownsModule(moduleName)) {
|
|
4368
|
+
continue;
|
|
4369
|
+
}
|
|
4370
|
+
sceneShaderInputProps[moduleName] ||= {};
|
|
4371
|
+
sceneShaderInputProps[moduleName][propertyName] = value;
|
|
4372
|
+
}
|
|
4373
|
+
return sceneShaderInputProps;
|
|
3873
4374
|
}
|
|
3874
4375
|
|
|
3875
4376
|
// src/parsers/parse-gltf.ts
|
|
@@ -3882,9 +4383,36 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3882
4383
|
};
|
|
3883
4384
|
function parseGLTF(device, gltf, options = {}) {
|
|
3884
4385
|
const combinedOptions = { ...defaultOptions, ...options };
|
|
4386
|
+
const materialFactory = new import_engine4.MaterialFactory(device, { modules: [import_shadertools2.pbrMaterial] });
|
|
4387
|
+
const materials = (gltf.materials || []).map(
|
|
4388
|
+
(gltfMaterial, materialIndex) => createGLTFMaterial(device, {
|
|
4389
|
+
id: getGLTFMaterialId(gltfMaterial, materialIndex),
|
|
4390
|
+
parsedPPBRMaterial: parsePBRMaterial(
|
|
4391
|
+
device,
|
|
4392
|
+
gltfMaterial,
|
|
4393
|
+
{},
|
|
4394
|
+
{
|
|
4395
|
+
...combinedOptions,
|
|
4396
|
+
gltf,
|
|
4397
|
+
validateAttributes: false
|
|
4398
|
+
}
|
|
4399
|
+
),
|
|
4400
|
+
materialFactory
|
|
4401
|
+
})
|
|
4402
|
+
);
|
|
4403
|
+
const gltfMaterialIdToMaterialMap = /* @__PURE__ */ new Map();
|
|
4404
|
+
(gltf.materials || []).forEach((gltfMaterial, materialIndex) => {
|
|
4405
|
+
gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);
|
|
4406
|
+
});
|
|
3885
4407
|
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
3886
4408
|
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
3887
|
-
const newMesh = createNodeForGLTFMesh(
|
|
4409
|
+
const newMesh = createNodeForGLTFMesh(
|
|
4410
|
+
device,
|
|
4411
|
+
gltfMesh,
|
|
4412
|
+
gltf,
|
|
4413
|
+
gltfMaterialIdToMaterialMap,
|
|
4414
|
+
combinedOptions
|
|
4415
|
+
);
|
|
3888
4416
|
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
3889
4417
|
});
|
|
3890
4418
|
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
@@ -3918,15 +4446,15 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3918
4446
|
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
3919
4447
|
return child;
|
|
3920
4448
|
});
|
|
3921
|
-
return new
|
|
4449
|
+
return new import_engine4.GroupNode({
|
|
3922
4450
|
id: gltfScene.name || gltfScene.id,
|
|
3923
4451
|
children
|
|
3924
4452
|
});
|
|
3925
4453
|
});
|
|
3926
|
-
return { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
4454
|
+
return { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
3927
4455
|
}
|
|
3928
4456
|
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
3929
|
-
return new
|
|
4457
|
+
return new import_engine4.GroupNode({
|
|
3930
4458
|
id: gltfNode.name || gltfNode.id,
|
|
3931
4459
|
children: [],
|
|
3932
4460
|
matrix: gltfNode.matrix,
|
|
@@ -3935,31 +4463,46 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3935
4463
|
scale: gltfNode.scale
|
|
3936
4464
|
});
|
|
3937
4465
|
}
|
|
3938
|
-
function createNodeForGLTFMesh(device, gltfMesh, options) {
|
|
4466
|
+
function createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options) {
|
|
3939
4467
|
const gltfPrimitives = gltfMesh.primitives || [];
|
|
3940
4468
|
const primitives = gltfPrimitives.map(
|
|
3941
|
-
(gltfPrimitive, i) => createNodeForGLTFPrimitive(
|
|
4469
|
+
(gltfPrimitive, i) => createNodeForGLTFPrimitive({
|
|
4470
|
+
device,
|
|
4471
|
+
gltfPrimitive,
|
|
4472
|
+
primitiveIndex: i,
|
|
4473
|
+
gltfMesh,
|
|
4474
|
+
gltf,
|
|
4475
|
+
gltfMaterialIdToMaterialMap,
|
|
4476
|
+
options
|
|
4477
|
+
})
|
|
3942
4478
|
);
|
|
3943
|
-
const mesh = new
|
|
4479
|
+
const mesh = new import_engine4.GroupNode({
|
|
3944
4480
|
id: gltfMesh.name || gltfMesh.id,
|
|
3945
4481
|
children: primitives
|
|
3946
4482
|
});
|
|
3947
4483
|
return mesh;
|
|
3948
4484
|
}
|
|
3949
|
-
function createNodeForGLTFPrimitive(
|
|
3950
|
-
|
|
4485
|
+
function createNodeForGLTFPrimitive({
|
|
4486
|
+
device,
|
|
4487
|
+
gltfPrimitive,
|
|
4488
|
+
primitiveIndex,
|
|
4489
|
+
gltfMesh,
|
|
4490
|
+
gltf,
|
|
4491
|
+
gltfMaterialIdToMaterialMap,
|
|
4492
|
+
options
|
|
4493
|
+
}) {
|
|
4494
|
+
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;
|
|
3951
4495
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
3952
4496
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
3953
4497
|
const geometry = createGeometry(id, gltfPrimitive, topology);
|
|
3954
|
-
const parsedPPBRMaterial = parsePBRMaterial(
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
options
|
|
3959
|
-
);
|
|
4498
|
+
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {
|
|
4499
|
+
...options,
|
|
4500
|
+
gltf
|
|
4501
|
+
});
|
|
3960
4502
|
const modelNode = createGLTFModel(device, {
|
|
3961
4503
|
id,
|
|
3962
4504
|
geometry: createGeometry(id, gltfPrimitive, topology),
|
|
4505
|
+
material: gltfPrimitive.material ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null : null,
|
|
3963
4506
|
parsedPPBRMaterial,
|
|
3964
4507
|
modelOptions: options.modelOptions,
|
|
3965
4508
|
vertexCount
|
|
@@ -3976,13 +4519,16 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
3976
4519
|
const { components, size, value } = attribute;
|
|
3977
4520
|
attributes[attributeName] = { size: size ?? components, value };
|
|
3978
4521
|
}
|
|
3979
|
-
return new
|
|
4522
|
+
return new import_engine4.Geometry({
|
|
3980
4523
|
id,
|
|
3981
4524
|
topology,
|
|
3982
4525
|
indices: gltfPrimitive.indices.value,
|
|
3983
4526
|
attributes
|
|
3984
4527
|
});
|
|
3985
4528
|
}
|
|
4529
|
+
function getGLTFMaterialId(gltfMaterial, materialIndex) {
|
|
4530
|
+
return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;
|
|
4531
|
+
}
|
|
3986
4532
|
|
|
3987
4533
|
// src/gltf/gltf-animator.ts
|
|
3988
4534
|
var import_core6 = __toESM(require_core(), 1);
|
|
@@ -4129,6 +4675,9 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
4129
4675
|
}
|
|
4130
4676
|
};
|
|
4131
4677
|
|
|
4678
|
+
// src/parsers/parse-gltf-animations.ts
|
|
4679
|
+
var import_core7 = __toESM(require_core(), 1);
|
|
4680
|
+
|
|
4132
4681
|
// src/webgl-to-webgpu/convert-webgl-attribute.ts
|
|
4133
4682
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
4134
4683
|
SCALAR: 1,
|
|
@@ -4161,29 +4710,48 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
4161
4710
|
const gltfAnimations = gltf.animations || [];
|
|
4162
4711
|
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
4163
4712
|
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
4164
|
-
return gltfAnimations.
|
|
4713
|
+
return gltfAnimations.flatMap((animation, index) => {
|
|
4165
4714
|
const name = animation.name || `Animation-${index}`;
|
|
4166
|
-
const
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
}
|
|
4172
|
-
);
|
|
4173
|
-
const channels = animation.channels.map(({ sampler, target }) => {
|
|
4715
|
+
const samplerCache = /* @__PURE__ */ new Map();
|
|
4716
|
+
const channels = animation.channels.flatMap(({ sampler, target }) => {
|
|
4717
|
+
const path = getSupportedAnimationPath(target.path);
|
|
4718
|
+
if (!path) {
|
|
4719
|
+
return [];
|
|
4720
|
+
}
|
|
4174
4721
|
const targetNode = gltf.nodes[target.node ?? 0];
|
|
4175
4722
|
if (!targetNode) {
|
|
4176
4723
|
throw new Error(`Cannot find animation target ${target.node}`);
|
|
4177
4724
|
}
|
|
4725
|
+
let parsedSampler = samplerCache.get(sampler);
|
|
4726
|
+
if (!parsedSampler) {
|
|
4727
|
+
const gltfSampler = animation.samplers[sampler];
|
|
4728
|
+
if (!gltfSampler) {
|
|
4729
|
+
throw new Error(`Cannot find animation sampler ${sampler}`);
|
|
4730
|
+
}
|
|
4731
|
+
const { input, interpolation = "LINEAR", output } = gltfSampler;
|
|
4732
|
+
parsedSampler = {
|
|
4733
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
4734
|
+
interpolation,
|
|
4735
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
4736
|
+
};
|
|
4737
|
+
samplerCache.set(sampler, parsedSampler);
|
|
4738
|
+
}
|
|
4178
4739
|
return {
|
|
4179
|
-
sampler:
|
|
4740
|
+
sampler: parsedSampler,
|
|
4180
4741
|
targetNodeId: targetNode.id,
|
|
4181
|
-
path
|
|
4742
|
+
path
|
|
4182
4743
|
};
|
|
4183
4744
|
});
|
|
4184
|
-
return { name, channels };
|
|
4745
|
+
return channels.length ? [{ name, channels }] : [];
|
|
4185
4746
|
});
|
|
4186
4747
|
}
|
|
4748
|
+
function getSupportedAnimationPath(path) {
|
|
4749
|
+
if (path === "pointer") {
|
|
4750
|
+
import_core7.log.warn("KHR_animation_pointer channels are not supported and will be skipped")();
|
|
4751
|
+
return null;
|
|
4752
|
+
}
|
|
4753
|
+
return path;
|
|
4754
|
+
}
|
|
4187
4755
|
function accessorToJsArray1D(accessor, accessorCache) {
|
|
4188
4756
|
if (accessorCache.has(accessor)) {
|
|
4189
4757
|
return accessorCache.get(accessor);
|
|
@@ -4199,7 +4767,7 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
4199
4767
|
return accessorCache.get(accessor);
|
|
4200
4768
|
}
|
|
4201
4769
|
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
4202
|
-
assert3(components
|
|
4770
|
+
assert3(components >= 1, "accessorToJsArray2D must have at least 1 component");
|
|
4203
4771
|
const result = [];
|
|
4204
4772
|
for (let i = 0; i < array.length; i += components) {
|
|
4205
4773
|
result.push(Array.from(array.slice(i, i + components)));
|
|
@@ -4213,26 +4781,259 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
4213
4781
|
}
|
|
4214
4782
|
}
|
|
4215
4783
|
|
|
4784
|
+
// src/gltf/gltf-extension-support.ts
|
|
4785
|
+
var UNKNOWN_EXTENSION_SUPPORT = {
|
|
4786
|
+
supportLevel: "none",
|
|
4787
|
+
comment: "Not currently listed in the luma.gl glTF extension support registry."
|
|
4788
|
+
};
|
|
4789
|
+
var GLTF_EXTENSION_SUPPORT_REGISTRY = {
|
|
4790
|
+
KHR_draco_mesh_compression: {
|
|
4791
|
+
supportLevel: "built-in",
|
|
4792
|
+
comment: "Decoded by loaders.gl before luma.gl builds the scenegraph."
|
|
4793
|
+
},
|
|
4794
|
+
EXT_meshopt_compression: {
|
|
4795
|
+
supportLevel: "built-in",
|
|
4796
|
+
comment: "Meshopt-compressed primitives are decoded during load."
|
|
4797
|
+
},
|
|
4798
|
+
KHR_mesh_quantization: {
|
|
4799
|
+
supportLevel: "built-in",
|
|
4800
|
+
comment: "Quantized accessors are unpacked before geometry creation."
|
|
4801
|
+
},
|
|
4802
|
+
KHR_lights_punctual: {
|
|
4803
|
+
supportLevel: "built-in",
|
|
4804
|
+
comment: "Parsed into luma.gl Light objects."
|
|
4805
|
+
},
|
|
4806
|
+
KHR_materials_unlit: {
|
|
4807
|
+
supportLevel: "built-in",
|
|
4808
|
+
comment: "Unlit materials bypass the default lighting path."
|
|
4809
|
+
},
|
|
4810
|
+
KHR_materials_emissive_strength: {
|
|
4811
|
+
supportLevel: "built-in",
|
|
4812
|
+
comment: "Applied by the stock PBR shader."
|
|
4813
|
+
},
|
|
4814
|
+
KHR_texture_basisu: {
|
|
4815
|
+
supportLevel: "built-in",
|
|
4816
|
+
comment: "BasisU / KTX2 textures pass through when the device supports them."
|
|
4817
|
+
},
|
|
4818
|
+
KHR_texture_transform: {
|
|
4819
|
+
supportLevel: "built-in",
|
|
4820
|
+
comment: "UV transforms are applied during load."
|
|
4821
|
+
},
|
|
4822
|
+
EXT_texture_webp: {
|
|
4823
|
+
supportLevel: "loader-only",
|
|
4824
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
4825
|
+
},
|
|
4826
|
+
EXT_texture_avif: {
|
|
4827
|
+
supportLevel: "loader-only",
|
|
4828
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
4829
|
+
},
|
|
4830
|
+
KHR_materials_specular: {
|
|
4831
|
+
supportLevel: "built-in",
|
|
4832
|
+
comment: "The stock shader now applies specular factors and textures to the dielectric F0 term."
|
|
4833
|
+
},
|
|
4834
|
+
KHR_materials_ior: {
|
|
4835
|
+
supportLevel: "built-in",
|
|
4836
|
+
comment: "The stock shader now drives dielectric reflectance from the glTF IOR value."
|
|
4837
|
+
},
|
|
4838
|
+
KHR_materials_transmission: {
|
|
4839
|
+
supportLevel: "built-in",
|
|
4840
|
+
comment: "The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer."
|
|
4841
|
+
},
|
|
4842
|
+
KHR_materials_volume: {
|
|
4843
|
+
supportLevel: "built-in",
|
|
4844
|
+
comment: "Thickness and attenuation now tint transmitted light in the stock shader."
|
|
4845
|
+
},
|
|
4846
|
+
KHR_materials_clearcoat: {
|
|
4847
|
+
supportLevel: "built-in",
|
|
4848
|
+
comment: "The stock shader now adds a secondary clearcoat specular lobe."
|
|
4849
|
+
},
|
|
4850
|
+
KHR_materials_sheen: {
|
|
4851
|
+
supportLevel: "built-in",
|
|
4852
|
+
comment: "The stock shader now adds a sheen lobe for cloth-like materials."
|
|
4853
|
+
},
|
|
4854
|
+
KHR_materials_iridescence: {
|
|
4855
|
+
supportLevel: "built-in",
|
|
4856
|
+
comment: "The stock shader now tints specular response with a view-dependent thin-film iridescence approximation."
|
|
4857
|
+
},
|
|
4858
|
+
KHR_materials_anisotropy: {
|
|
4859
|
+
supportLevel: "built-in",
|
|
4860
|
+
comment: "The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation."
|
|
4861
|
+
},
|
|
4862
|
+
KHR_materials_pbrSpecularGlossiness: {
|
|
4863
|
+
supportLevel: "loader-only",
|
|
4864
|
+
comment: "Extension data can be loaded, but it is not translated into the default metallic-roughness material path."
|
|
4865
|
+
},
|
|
4866
|
+
KHR_materials_variants: {
|
|
4867
|
+
supportLevel: "loader-only",
|
|
4868
|
+
comment: "Variant metadata can be loaded, but applications must choose and apply variants."
|
|
4869
|
+
},
|
|
4870
|
+
EXT_mesh_gpu_instancing: {
|
|
4871
|
+
supportLevel: "none",
|
|
4872
|
+
comment: "GPU instancing data is not yet converted into luma.gl instanced draw setup."
|
|
4873
|
+
},
|
|
4874
|
+
KHR_node_visibility: {
|
|
4875
|
+
supportLevel: "none",
|
|
4876
|
+
comment: "Node-visibility animations and toggles are not mapped onto runtime scenegraph state."
|
|
4877
|
+
},
|
|
4878
|
+
KHR_animation_pointer: {
|
|
4879
|
+
supportLevel: "none",
|
|
4880
|
+
comment: "Animation pointers are not mapped onto runtime scenegraph updates."
|
|
4881
|
+
},
|
|
4882
|
+
KHR_materials_diffuse_transmission: {
|
|
4883
|
+
supportLevel: "none",
|
|
4884
|
+
comment: "Diffuse-transmission shading is not implemented in the stock PBR shader."
|
|
4885
|
+
},
|
|
4886
|
+
KHR_materials_dispersion: {
|
|
4887
|
+
supportLevel: "none",
|
|
4888
|
+
comment: "Chromatic dispersion is not implemented in the stock PBR shader."
|
|
4889
|
+
},
|
|
4890
|
+
KHR_materials_volume_scatter: {
|
|
4891
|
+
supportLevel: "none",
|
|
4892
|
+
comment: "Volume scattering is not implemented in the stock PBR shader."
|
|
4893
|
+
},
|
|
4894
|
+
KHR_xmp: {
|
|
4895
|
+
supportLevel: "none",
|
|
4896
|
+
comment: "Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them."
|
|
4897
|
+
},
|
|
4898
|
+
KHR_xmp_json_ld: {
|
|
4899
|
+
supportLevel: "none",
|
|
4900
|
+
comment: "Metadata is preserved in the glTF, but luma.gl does not interpret it."
|
|
4901
|
+
},
|
|
4902
|
+
EXT_lights_image_based: {
|
|
4903
|
+
supportLevel: "none",
|
|
4904
|
+
comment: "Use loadPBREnvironment() or custom environment setup instead."
|
|
4905
|
+
},
|
|
4906
|
+
EXT_texture_video: {
|
|
4907
|
+
supportLevel: "none",
|
|
4908
|
+
comment: "Video textures are not created automatically by the stock pipeline."
|
|
4909
|
+
},
|
|
4910
|
+
MSFT_lod: {
|
|
4911
|
+
supportLevel: "none",
|
|
4912
|
+
comment: "Level-of-detail switching is not implemented in the stock scenegraph loader."
|
|
4913
|
+
}
|
|
4914
|
+
};
|
|
4915
|
+
function getGLTFExtensionSupport(gltf) {
|
|
4916
|
+
const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();
|
|
4917
|
+
const extensionSupportEntries = extensionNames.map(
|
|
4918
|
+
(extensionName) => {
|
|
4919
|
+
const extensionSupportDefinition = GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;
|
|
4920
|
+
return [
|
|
4921
|
+
extensionName,
|
|
4922
|
+
{
|
|
4923
|
+
extensionName,
|
|
4924
|
+
supported: extensionSupportDefinition.supportLevel === "built-in",
|
|
4925
|
+
supportLevel: extensionSupportDefinition.supportLevel,
|
|
4926
|
+
comment: extensionSupportDefinition.comment
|
|
4927
|
+
}
|
|
4928
|
+
];
|
|
4929
|
+
}
|
|
4930
|
+
);
|
|
4931
|
+
return new Map(extensionSupportEntries);
|
|
4932
|
+
}
|
|
4933
|
+
function collectGLTFExtensionNames(gltf) {
|
|
4934
|
+
const gltfWithRemovedExtensions = gltf;
|
|
4935
|
+
const extensionNames = /* @__PURE__ */ new Set();
|
|
4936
|
+
addExtensionNames(extensionNames, gltf.extensionsUsed);
|
|
4937
|
+
addExtensionNames(extensionNames, gltf.extensionsRequired);
|
|
4938
|
+
addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);
|
|
4939
|
+
addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));
|
|
4940
|
+
if (gltfWithRemovedExtensions.lights?.length || gltf.nodes.some((node) => "light" in node)) {
|
|
4941
|
+
extensionNames.add("KHR_lights_punctual");
|
|
4942
|
+
}
|
|
4943
|
+
if (gltf.materials.some((material) => {
|
|
4944
|
+
const gltfMaterial = material;
|
|
4945
|
+
return gltfMaterial.unlit || gltfMaterial.extensions?.KHR_materials_unlit;
|
|
4946
|
+
})) {
|
|
4947
|
+
extensionNames.add("KHR_materials_unlit");
|
|
4948
|
+
}
|
|
4949
|
+
return extensionNames;
|
|
4950
|
+
}
|
|
4951
|
+
function addExtensionNames(extensionNames, newExtensionNames = []) {
|
|
4952
|
+
for (const extensionName of newExtensionNames) {
|
|
4953
|
+
extensionNames.add(extensionName);
|
|
4954
|
+
}
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4216
4957
|
// src/gltf/create-scenegraph-from-gltf.ts
|
|
4217
4958
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
4218
|
-
const { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(
|
|
4219
|
-
device,
|
|
4220
|
-
gltf,
|
|
4221
|
-
options
|
|
4222
|
-
);
|
|
4959
|
+
const { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
4223
4960
|
const animations = parseGLTFAnimations(gltf);
|
|
4224
4961
|
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
4225
4962
|
const lights = parseGLTFLights(gltf);
|
|
4963
|
+
const extensionSupport = getGLTFExtensionSupport(gltf);
|
|
4964
|
+
const sceneBounds = scenes.map((scene) => getScenegraphBounds(scene.getBounds()));
|
|
4965
|
+
const modelBounds = getCombinedScenegraphBounds(sceneBounds);
|
|
4226
4966
|
return {
|
|
4227
4967
|
scenes,
|
|
4968
|
+
materials,
|
|
4228
4969
|
animator,
|
|
4229
4970
|
lights,
|
|
4971
|
+
extensionSupport,
|
|
4972
|
+
sceneBounds,
|
|
4973
|
+
modelBounds,
|
|
4230
4974
|
gltfMeshIdToNodeMap,
|
|
4231
4975
|
gltfNodeIdToNodeMap,
|
|
4232
4976
|
gltfNodeIndexToNodeMap,
|
|
4233
4977
|
gltf
|
|
4234
4978
|
};
|
|
4235
4979
|
}
|
|
4980
|
+
function getScenegraphBounds(bounds) {
|
|
4981
|
+
if (!bounds) {
|
|
4982
|
+
return {
|
|
4983
|
+
bounds: null,
|
|
4984
|
+
center: [0, 0, 0],
|
|
4985
|
+
size: [0, 0, 0],
|
|
4986
|
+
radius: 0.5,
|
|
4987
|
+
recommendedOrbitDistance: 1
|
|
4988
|
+
};
|
|
4989
|
+
}
|
|
4990
|
+
const normalizedBounds = [
|
|
4991
|
+
[bounds[0][0], bounds[0][1], bounds[0][2]],
|
|
4992
|
+
[bounds[1][0], bounds[1][1], bounds[1][2]]
|
|
4993
|
+
];
|
|
4994
|
+
const size = [
|
|
4995
|
+
normalizedBounds[1][0] - normalizedBounds[0][0],
|
|
4996
|
+
normalizedBounds[1][1] - normalizedBounds[0][1],
|
|
4997
|
+
normalizedBounds[1][2] - normalizedBounds[0][2]
|
|
4998
|
+
];
|
|
4999
|
+
const center = [
|
|
5000
|
+
normalizedBounds[0][0] + size[0] * 0.5,
|
|
5001
|
+
normalizedBounds[0][1] + size[1] * 0.5,
|
|
5002
|
+
normalizedBounds[0][2] + size[2] * 0.5
|
|
5003
|
+
];
|
|
5004
|
+
const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;
|
|
5005
|
+
const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 1e-3);
|
|
5006
|
+
return {
|
|
5007
|
+
bounds: normalizedBounds,
|
|
5008
|
+
center,
|
|
5009
|
+
size,
|
|
5010
|
+
radius,
|
|
5011
|
+
recommendedOrbitDistance: Math.max(
|
|
5012
|
+
Math.max(maxHalfExtent, 1e-3) / Math.tan(Math.PI / 6) * 1.15,
|
|
5013
|
+
radius * 1.1
|
|
5014
|
+
)
|
|
5015
|
+
};
|
|
5016
|
+
}
|
|
5017
|
+
function getCombinedScenegraphBounds(sceneBounds) {
|
|
5018
|
+
let combinedBounds = null;
|
|
5019
|
+
for (const sceneBoundInfo of sceneBounds) {
|
|
5020
|
+
if (!sceneBoundInfo.bounds) {
|
|
5021
|
+
continue;
|
|
5022
|
+
}
|
|
5023
|
+
if (!combinedBounds) {
|
|
5024
|
+
combinedBounds = [
|
|
5025
|
+
[...sceneBoundInfo.bounds[0]],
|
|
5026
|
+
[...sceneBoundInfo.bounds[1]]
|
|
5027
|
+
];
|
|
5028
|
+
continue;
|
|
5029
|
+
}
|
|
5030
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
5031
|
+
combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);
|
|
5032
|
+
combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
return getScenegraphBounds(combinedBounds);
|
|
5036
|
+
}
|
|
4236
5037
|
return __toCommonJS(bundle_exports);
|
|
4237
5038
|
})();
|
|
4238
5039
|
return __exports__;
|