@luma.gl/gltf 9.0.0-beta.6 → 9.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -26,6 +26,7 @@ var __exports__ = (() => {
26
26
  }
27
27
  return to;
28
28
  };
29
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
29
30
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
31
  // If the importer is in node compatibility mode or this is not an ESM
31
32
  // file that has been converted to a CommonJS file using a Babel-
@@ -50,28 +51,15 @@ var __exports__ = (() => {
50
51
  }
51
52
  });
52
53
 
53
- // external-global-plugin:@luma.gl/webgl
54
- var require_webgl = __commonJS({
55
- "external-global-plugin:@luma.gl/webgl"(exports, module) {
56
- module.exports = globalThis.luma;
57
- }
58
- });
59
-
60
- // external-global-plugin:@luma.gl/shadertools
61
- var require_shadertools = __commonJS({
62
- "external-global-plugin:@luma.gl/shadertools"(exports, module) {
63
- module.exports = globalThis.luma;
64
- }
65
- });
66
-
67
- // src/index.ts
68
- var src_exports = {};
69
- __export(src_exports, {
54
+ // bundle.ts
55
+ var bundle_exports = {};
56
+ __export(bundle_exports, {
70
57
  GLTFAnimator: () => GLTFAnimator,
71
58
  createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
72
59
  loadPBREnvironment: () => loadPBREnvironment,
73
60
  parsePBRMaterial: () => parsePBRMaterial
74
61
  });
62
+ __reExport(bundle_exports, __toESM(require_core(), 1));
75
63
 
76
64
  // src/pbr/parse-pbr-material.ts
77
65
  var import_core = __toESM(require_core(), 1);
@@ -231,14 +219,29 @@ var __exports__ = (() => {
231
219
  parsedMaterial.generatedTextures.push(texture);
232
220
  }
233
221
 
234
- // node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/assert.js
222
+ // ../../node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/assert.js
235
223
  function assert(condition, message) {
236
224
  if (!condition) {
237
225
  throw new Error(message || "loader assertion failed.");
238
226
  }
239
227
  }
240
228
 
241
- // node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/file-aliases.js
229
+ // ../../node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/globals.js
230
+ var globals = {
231
+ self: typeof self !== "undefined" && self,
232
+ window: typeof window !== "undefined" && window,
233
+ global: typeof global !== "undefined" && global,
234
+ document: typeof document !== "undefined" && document
235
+ };
236
+ var self_ = globals.self || globals.window || globals.global || {};
237
+ var window_ = globals.window || globals.self || globals.global || {};
238
+ var global_ = globals.global || globals.self || globals.window || {};
239
+ var document_ = globals.document || {};
240
+ var isBrowser = Boolean(typeof process !== "object" || String(process) !== "[object process]" || process.browser);
241
+ var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
242
+ var nodeVersion = matches && parseFloat(matches[1]) || 0;
243
+
244
+ // ../../node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/file-aliases.js
242
245
  var pathPrefix = "";
243
246
  var fileAliases = {};
244
247
  function resolvePath(filename) {
@@ -255,29 +258,7 @@ var __exports__ = (() => {
255
258
  }
256
259
 
257
260
  // ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js
258
- var VERSION = true ? "4.1.2" : "latest";
259
-
260
- // ../../node_modules/@loaders.gl/images/node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/assert.js
261
- function assert2(condition, message) {
262
- if (!condition) {
263
- throw new Error(message || "loader assertion failed.");
264
- }
265
- }
266
-
267
- // ../../node_modules/@loaders.gl/images/node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/globals.js
268
- var globals = {
269
- self: typeof self !== "undefined" && self,
270
- window: typeof window !== "undefined" && window,
271
- global: typeof global !== "undefined" && global,
272
- document: typeof document !== "undefined" && document
273
- };
274
- var self_ = globals.self || globals.window || globals.global || {};
275
- var window_ = globals.window || globals.self || globals.global || {};
276
- var global_ = globals.global || globals.self || globals.window || {};
277
- var document_ = globals.document || {};
278
- var isBrowser = Boolean(typeof process !== "object" || String(process) !== "[object process]" || process.browser);
279
- var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
280
- var nodeVersion = matches && parseFloat(matches[1]) || 0;
261
+ var VERSION = true ? "4.1.3" : "latest";
281
262
 
282
263
  // ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js
283
264
  var _globalThis$loaders;
@@ -608,7 +589,7 @@ var __exports__ = (() => {
608
589
  mimeType
609
590
  } = getBinaryImageMetadata(arrayBuffer) || {};
610
591
  const parseImageNode2 = (_globalThis$loaders2 = globalThis.loaders) === null || _globalThis$loaders2 === void 0 ? void 0 : _globalThis$loaders2.parseImageNode;
611
- assert2(parseImageNode2);
592
+ assert(parseImageNode2);
612
593
  return await parseImageNode2(arrayBuffer, mimeType);
613
594
  }
614
595
 
@@ -633,7 +614,7 @@ var __exports__ = (() => {
633
614
  image = await parseToNodeImage(arrayBuffer, options);
634
615
  break;
635
616
  default:
636
- assert2(false);
617
+ assert(false);
637
618
  }
638
619
  if (imageType === "data") {
639
620
  image = getImageData(image);
@@ -672,7 +653,7 @@ var __exports__ = (() => {
672
653
  options: DEFAULT_IMAGE_LOADER_OPTIONS
673
654
  };
674
655
 
675
- // node_modules/@loaders.gl/textures/dist/lib/texture-api/generate-url.js
656
+ // ../../node_modules/@loaders.gl/textures/dist/lib/texture-api/generate-url.js
676
657
  function generateUrl(getUrl, options, urlOptions) {
677
658
  let url = typeof getUrl === "function" ? getUrl({
678
659
  ...options,
@@ -685,7 +666,7 @@ var __exports__ = (() => {
685
666
  return resolvePath(url);
686
667
  }
687
668
 
688
- // node_modules/@loaders.gl/textures/dist/lib/texture-api/async-deep-map.js
669
+ // ../../node_modules/@loaders.gl/textures/dist/lib/texture-api/async-deep-map.js
689
670
  var isObject = (value) => value && typeof value === "object";
690
671
  async function asyncDeepMap(tree, func) {
691
672
  let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
@@ -720,7 +701,7 @@ var __exports__ = (() => {
720
701
  return await Promise.all(promises);
721
702
  }
722
703
 
723
- // node_modules/@loaders.gl/textures/dist/lib/texture-api/deep-load.js
704
+ // ../../node_modules/@loaders.gl/textures/dist/lib/texture-api/deep-load.js
724
705
  async function deepLoad(urlTree, load, options) {
725
706
  return await asyncDeepMap(urlTree, (url) => shallowLoad(url, load, options));
726
707
  }
@@ -730,7 +711,7 @@ var __exports__ = (() => {
730
711
  return await load(arrayBuffer, options);
731
712
  }
732
713
 
733
- // node_modules/@loaders.gl/textures/dist/lib/texture-api/load-image.js
714
+ // ../../node_modules/@loaders.gl/textures/dist/lib/texture-api/load-image.js
734
715
  async function loadImageTexture(getUrl) {
735
716
  let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
736
717
  const imageUrls = await getImageUrls(getUrl, options);
@@ -840,7 +821,6 @@ var __exports__ = (() => {
840
821
 
841
822
  // src/gltf/gltf-instantiator.ts
842
823
  var import_engine2 = __toESM(require_engine(), 1);
843
- var import_webgl = __toESM(require_webgl(), 1);
844
824
 
845
825
  // ../../node_modules/@math.gl/core/dist/lib/common.js
846
826
  var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
@@ -1141,7 +1121,7 @@ var __exports__ = (() => {
1141
1121
  }
1142
1122
 
1143
1123
  // ../../node_modules/@math.gl/core/dist/lib/assert.js
1144
- function assert3(condition, message) {
1124
+ function assert2(condition, message) {
1145
1125
  if (!condition) {
1146
1126
  throw new Error("math.gl assertion ".concat(message));
1147
1127
  }
@@ -1230,11 +1210,11 @@ var __exports__ = (() => {
1230
1210
  return this.distanceSquared(vector);
1231
1211
  }
1232
1212
  getComponent(i) {
1233
- assert3(i >= 0 && i < this.ELEMENTS, "index is out of range");
1213
+ assert2(i >= 0 && i < this.ELEMENTS, "index is out of range");
1234
1214
  return checkNumber(this[i]);
1235
1215
  }
1236
1216
  setComponent(i, value) {
1237
- assert3(i >= 0 && i < this.ELEMENTS, "index is out of range");
1217
+ assert2(i >= 0 && i < this.ELEMENTS, "index is out of range");
1238
1218
  this[i] = value;
1239
1219
  return this.check();
1240
1220
  }
@@ -3387,9 +3367,577 @@ var __exports__ = (() => {
3387
3367
 
3388
3368
  // src/gltf/create-gltf-model.ts
3389
3369
  var import_core4 = __toESM(require_core(), 1);
3390
- var import_shadertools = __toESM(require_shadertools(), 1);
3370
+
3371
+ // ../shadertools/src/lib/glsl-utils/highlight.ts
3372
+ var glsl = (x) => `${x}`;
3373
+
3374
+ // ../shadertools/src/modules-webgl1/lighting/lights/lights-glsl.ts
3375
+ var lightingShader = glsl`\
3376
+ #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
3377
+
3378
+ struct AmbientLight {
3379
+ vec3 color;
3380
+ };
3381
+
3382
+ struct PointLight {
3383
+ vec3 color;
3384
+ vec3 position;
3385
+
3386
+ // Constant-Linear-Exponential
3387
+ vec3 attenuation;
3388
+ };
3389
+
3390
+ struct DirectionalLight {
3391
+ vec3 color;
3392
+ vec3 direction;
3393
+ };
3394
+
3395
+ uniform AmbientLight lighting_uAmbientLight;
3396
+ uniform PointLight lighting_uPointLight[MAX_LIGHTS];
3397
+ uniform DirectionalLight lighting_uDirectionalLight[MAX_LIGHTS];
3398
+ uniform int lighting_uPointLightCount;
3399
+ uniform int lighting_uDirectionalLightCount;
3400
+
3401
+ uniform bool lighting_uEnabled;
3402
+
3403
+ float getPointLightAttenuation(PointLight pointLight, float distance) {
3404
+ return pointLight.attenuation.x
3405
+ + pointLight.attenuation.y * distance
3406
+ + pointLight.attenuation.z * distance * distance;
3407
+ }
3408
+
3409
+ #endif
3410
+ `;
3411
+
3412
+ // ../shadertools/src/modules-webgl1/lighting/lights/lights.ts
3413
+ var INITIAL_MODULE_OPTIONS = {
3414
+ lightSources: {}
3415
+ };
3416
+ function convertColor(colorDef = {}) {
3417
+ const { color = [0, 0, 0], intensity = 1 } = colorDef;
3418
+ return color.map((component) => component * intensity / 255);
3419
+ }
3420
+ function getLightSourceUniforms({
3421
+ ambientLight,
3422
+ pointLights = [],
3423
+ directionalLights = []
3424
+ }) {
3425
+ const lightSourceUniforms = {};
3426
+ if (ambientLight) {
3427
+ lightSourceUniforms["lighting_uAmbientLight.color"] = convertColor(ambientLight);
3428
+ } else {
3429
+ lightSourceUniforms["lighting_uAmbientLight.color"] = [0, 0, 0];
3430
+ }
3431
+ pointLights.forEach((pointLight, index) => {
3432
+ lightSourceUniforms[`lighting_uPointLight[${index}].color`] = convertColor(pointLight);
3433
+ lightSourceUniforms[`lighting_uPointLight[${index}].position`] = pointLight.position;
3434
+ lightSourceUniforms[`lighting_uPointLight[${index}].attenuation`] = pointLight.attenuation || [
3435
+ 1,
3436
+ 0,
3437
+ 0
3438
+ ];
3439
+ });
3440
+ lightSourceUniforms.lighting_uPointLightCount = pointLights.length;
3441
+ directionalLights.forEach((directionalLight, index) => {
3442
+ lightSourceUniforms[`lighting_uDirectionalLight[${index}].color`] = convertColor(directionalLight);
3443
+ lightSourceUniforms[`lighting_uDirectionalLight[${index}].direction`] = directionalLight.direction;
3444
+ });
3445
+ lightSourceUniforms.lighting_uDirectionalLightCount = directionalLights.length;
3446
+ return lightSourceUniforms;
3447
+ }
3448
+ function getUniforms(opts = INITIAL_MODULE_OPTIONS) {
3449
+ if ("lightSources" in opts) {
3450
+ const { ambientLight, pointLights, directionalLights } = opts.lightSources || {};
3451
+ const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
3452
+ if (!hasLights) {
3453
+ return { lighting_uEnabled: false };
3454
+ }
3455
+ return Object.assign(
3456
+ {},
3457
+ getLightSourceUniforms({ ambientLight, pointLights, directionalLights }),
3458
+ {
3459
+ lighting_uEnabled: true
3460
+ }
3461
+ );
3462
+ }
3463
+ if ("lights" in opts) {
3464
+ const lightSources = { pointLights: [], directionalLights: [] };
3465
+ for (const light of opts.lights || []) {
3466
+ switch (light.type) {
3467
+ case "ambient":
3468
+ lightSources.ambientLight = light;
3469
+ break;
3470
+ case "directional":
3471
+ lightSources.directionalLights?.push(light);
3472
+ break;
3473
+ case "point":
3474
+ lightSources.pointLights?.push(light);
3475
+ break;
3476
+ default:
3477
+ }
3478
+ }
3479
+ return getUniforms({ lightSources });
3480
+ }
3481
+ return {};
3482
+ }
3483
+ var lights = {
3484
+ name: "lights",
3485
+ vs: lightingShader,
3486
+ fs: lightingShader,
3487
+ getUniforms,
3488
+ defines: {
3489
+ MAX_LIGHTS: 3
3490
+ }
3491
+ };
3492
+
3493
+ // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-vertex-glsl.ts
3494
+ var vs = glsl`\
3495
+ uniform mat4 u_MVPMatrix;
3496
+ uniform mat4 u_ModelMatrix;
3497
+ uniform mat4 u_NormalMatrix;
3498
+
3499
+ out vec3 pbr_vPosition;
3500
+ out vec2 pbr_vUV;
3501
+
3502
+ #ifdef HAS_NORMALS
3503
+ # ifdef HAS_TANGENTS
3504
+ out mat3 pbr_vTBN;
3505
+ # else
3506
+ out vec3 pbr_vNormal;
3507
+ # endif
3508
+ #endif
3509
+
3510
+ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
3511
+ {
3512
+ vec4 pos = u_ModelMatrix * position;
3513
+ pbr_vPosition = vec3(pos.xyz) / pos.w;
3514
+
3515
+ #ifdef HAS_NORMALS
3516
+ #ifdef HAS_TANGENTS
3517
+ vec3 normalW = normalize(vec3(u_NormalMatrix * vec4(normal.xyz, 0.0)));
3518
+ vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent.xyz, 0.0)));
3519
+ vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
3520
+ pbr_vTBN = mat3(tangentW, bitangentW, normalW);
3521
+ #else // HAS_TANGENTS != 1
3522
+ pbr_vNormal = normalize(vec3(u_ModelMatrix * vec4(normal.xyz, 0.0)));
3523
+ #endif
3524
+ #endif
3525
+
3526
+ #ifdef HAS_UV
3527
+ pbr_vUV = uv;
3528
+ #else
3529
+ pbr_vUV = vec2(0.,0.);
3530
+ #endif
3531
+ }
3532
+ `;
3533
+
3534
+ // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-fragment-glsl.ts
3535
+ var fs = glsl`\
3536
+ #if defined(USE_TEX_LOD) && !defined(FEATURE_GLSL_TEXTURE_LOD)
3537
+ # error PBR fragment shader: Texture LOD is not available
3538
+ #endif
3539
+
3540
+ #if !defined(HAS_TANGENTS) && !defined(FEATURE_GLSL_DERIVATIVES)
3541
+ # error PBR fragment shader: Derivatives are not available
3542
+ #endif
3543
+
3544
+ precision highp float;
3545
+
3546
+ uniform bool pbr_uUnlit;
3547
+
3548
+ #ifdef USE_IBL
3549
+ uniform samplerCube u_DiffuseEnvSampler;
3550
+ uniform samplerCube u_SpecularEnvSampler;
3551
+ uniform sampler2D u_brdfLUT;
3552
+ uniform vec2 u_ScaleIBLAmbient;
3553
+ #endif
3554
+
3555
+ #ifdef HAS_BASECOLORMAP
3556
+ uniform sampler2D u_BaseColorSampler;
3557
+ #endif
3558
+ #ifdef HAS_NORMALMAP
3559
+ uniform sampler2D u_NormalSampler;
3560
+ uniform float u_NormalScale;
3561
+ #endif
3562
+ #ifdef HAS_EMISSIVEMAP
3563
+ uniform sampler2D u_EmissiveSampler;
3564
+ uniform vec3 u_EmissiveFactor;
3565
+ #endif
3566
+ #ifdef HAS_METALROUGHNESSMAP
3567
+ uniform sampler2D u_MetallicRoughnessSampler;
3568
+ #endif
3569
+ #ifdef HAS_OCCLUSIONMAP
3570
+ uniform sampler2D u_OcclusionSampler;
3571
+ uniform float u_OcclusionStrength;
3572
+ #endif
3573
+
3574
+ #ifdef ALPHA_CUTOFF
3575
+ uniform float u_AlphaCutoff;
3576
+ #endif
3577
+
3578
+ uniform vec2 u_MetallicRoughnessValues;
3579
+ uniform vec4 u_BaseColorFactor;
3580
+
3581
+ uniform vec3 u_Camera;
3582
+
3583
+ // debugging flags used for shader output of intermediate PBR variables
3584
+ #ifdef PBR_DEBUG
3585
+ uniform vec4 u_ScaleDiffBaseMR;
3586
+ uniform vec4 u_ScaleFGDSpec;
3587
+ #endif
3588
+
3589
+ in vec3 pbr_vPosition;
3590
+
3591
+ in vec2 pbr_vUV;
3592
+
3593
+ #ifdef HAS_NORMALS
3594
+ #ifdef HAS_TANGENTS
3595
+ in mat3 pbr_vTBN;
3596
+ #else
3597
+ in vec3 pbr_vNormal;
3598
+ #endif
3599
+ #endif
3600
+
3601
+ // Encapsulate the various inputs used by the various functions in the shading equation
3602
+ // We store values in this struct to simplify the integration of alternative implementations
3603
+ // of the shading terms, outlined in the Readme.MD Appendix.
3604
+ struct PBRInfo
3605
+ {
3606
+ float NdotL; // cos angle between normal and light direction
3607
+ float NdotV; // cos angle between normal and view direction
3608
+ float NdotH; // cos angle between normal and half vector
3609
+ float LdotH; // cos angle between light direction and half vector
3610
+ float VdotH; // cos angle between view direction and half vector
3611
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
3612
+ float metalness; // metallic value at the surface
3613
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
3614
+ vec3 reflectance90; // reflectance color at grazing angle
3615
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
3616
+ vec3 diffuseColor; // color contribution from diffuse lighting
3617
+ vec3 specularColor; // color contribution from specular lighting
3618
+ vec3 n; // normal at surface point
3619
+ vec3 v; // vector from surface point to camera
3620
+ };
3621
+
3622
+ const float M_PI = 3.141592653589793;
3623
+ const float c_MinRoughness = 0.04;
3624
+
3625
+ vec4 SRGBtoLINEAR(vec4 srgbIn)
3626
+ {
3627
+ #ifdef MANUAL_SRGB
3628
+ #ifdef SRGB_FAST_APPROXIMATION
3629
+ vec3 linOut = pow(srgbIn.xyz,vec3(2.2));
3630
+ #else //SRGB_FAST_APPROXIMATION
3631
+ vec3 bLess = step(vec3(0.04045),srgbIn.xyz);
3632
+ vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
3633
+ #endif //SRGB_FAST_APPROXIMATION
3634
+ return vec4(linOut,srgbIn.w);;
3635
+ #else //MANUAL_SRGB
3636
+ return srgbIn;
3637
+ #endif //MANUAL_SRGB
3638
+ }
3639
+
3640
+ // Find the normal for this fragment, pulling either from a predefined normal map
3641
+ // or from the interpolated mesh normal and tangent attributes.
3642
+ vec3 getNormal()
3643
+ {
3644
+ // Retrieve the tangent space matrix
3645
+ #ifndef HAS_TANGENTS
3646
+ vec3 pos_dx = dFdx(pbr_vPosition);
3647
+ vec3 pos_dy = dFdy(pbr_vPosition);
3648
+ vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));
3649
+ vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));
3650
+ vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
3651
+
3652
+ #ifdef HAS_NORMALS
3653
+ vec3 ng = normalize(pbr_vNormal);
3654
+ #else
3655
+ vec3 ng = cross(pos_dx, pos_dy);
3656
+ #endif
3657
+
3658
+ t = normalize(t - ng * dot(ng, t));
3659
+ vec3 b = normalize(cross(ng, t));
3660
+ mat3 tbn = mat3(t, b, ng);
3661
+ #else // HAS_TANGENTS
3662
+ mat3 tbn = pbr_vTBN;
3663
+ #endif
3664
+
3665
+ #ifdef HAS_NORMALMAP
3666
+ vec3 n = texture(u_NormalSampler, pbr_vUV).rgb;
3667
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_NormalScale, u_NormalScale, 1.0)));
3668
+ #else
3669
+ // The tbn matrix is linearly interpolated, so we need to re-normalize
3670
+ vec3 n = normalize(tbn[2].xyz);
3671
+ #endif
3672
+
3673
+ return n;
3674
+ }
3675
+
3676
+ // Calculation of the lighting contribution from an optional Image Based Light source.
3677
+ // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
3678
+ // See our README.md on Environment Maps [3] for additional discussion.
3679
+ #ifdef USE_IBL
3680
+ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection)
3681
+ {
3682
+ float mipCount = 9.0; // resolution of 512x512
3683
+ float lod = (pbrInputs.perceptualRoughness * mipCount);
3684
+ // retrieve a scale and bias to F0. See [1], Figure 3
3685
+ vec3 brdf = SRGBtoLINEAR(texture(u_brdfLUT,
3686
+ vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb;
3687
+ vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb;
3688
+
3689
+ #ifdef USE_TEX_LOD
3690
+ vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb;
3691
+ #else
3692
+ vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb;
3693
+ #endif
3694
+
3695
+ vec3 diffuse = diffuseLight * pbrInputs.diffuseColor;
3696
+ vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y);
3697
+
3698
+ // For presentation, this allows us to disable IBL terms
3699
+ diffuse *= u_ScaleIBLAmbient.x;
3700
+ specular *= u_ScaleIBLAmbient.y;
3701
+
3702
+ return diffuse + specular;
3703
+ }
3704
+ #endif
3705
+
3706
+ // Basic Lambertian diffuse
3707
+ // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
3708
+ // See also [1], Equation 1
3709
+ vec3 diffuse(PBRInfo pbrInputs)
3710
+ {
3711
+ return pbrInputs.diffuseColor / M_PI;
3712
+ }
3713
+
3714
+ // The following equation models the Fresnel reflectance term of the spec equation (aka F())
3715
+ // Implementation of fresnel from [4], Equation 15
3716
+ vec3 specularReflection(PBRInfo pbrInputs)
3717
+ {
3718
+ return pbrInputs.reflectance0 +
3719
+ (pbrInputs.reflectance90 - pbrInputs.reflectance0) *
3720
+ pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
3721
+ }
3722
+
3723
+ // This calculates the specular geometric attenuation (aka G()),
3724
+ // where rougher material will reflect less light back to the viewer.
3725
+ // This implementation is based on [1] Equation 4, and we adopt their modifications to
3726
+ // alphaRoughness as input as originally proposed in [2].
3727
+ float geometricOcclusion(PBRInfo pbrInputs)
3728
+ {
3729
+ float NdotL = pbrInputs.NdotL;
3730
+ float NdotV = pbrInputs.NdotV;
3731
+ float r = pbrInputs.alphaRoughness;
3732
+
3733
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
3734
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
3735
+ return attenuationL * attenuationV;
3736
+ }
3737
+
3738
+ // The following equation(s) model the distribution of microfacet normals across
3739
+ // the area being drawn (aka D())
3740
+ // Implementation from "Average Irregularity Representation of a Roughened Surface
3741
+ // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
3742
+ // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
3743
+ // from EPIC Games [1], Equation 3.
3744
+ float microfacetDistribution(PBRInfo pbrInputs)
3745
+ {
3746
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
3747
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
3748
+ return roughnessSq / (M_PI * f * f);
3749
+ }
3750
+
3751
+ void PBRInfo_setAmbientLight(inout PBRInfo pbrInputs) {
3752
+ pbrInputs.NdotL = 1.0;
3753
+ pbrInputs.NdotH = 0.0;
3754
+ pbrInputs.LdotH = 0.0;
3755
+ pbrInputs.VdotH = 1.0;
3756
+ }
3757
+
3758
+ void PBRInfo_setDirectionalLight(inout PBRInfo pbrInputs, vec3 lightDirection) {
3759
+ vec3 n = pbrInputs.n;
3760
+ vec3 v = pbrInputs.v;
3761
+ vec3 l = normalize(lightDirection); // Vector from surface point to light
3762
+ vec3 h = normalize(l+v); // Half vector between both l and v
3763
+
3764
+ pbrInputs.NdotL = clamp(dot(n, l), 0.001, 1.0);
3765
+ pbrInputs.NdotH = clamp(dot(n, h), 0.0, 1.0);
3766
+ pbrInputs.LdotH = clamp(dot(l, h), 0.0, 1.0);
3767
+ pbrInputs.VdotH = clamp(dot(v, h), 0.0, 1.0);
3768
+ }
3769
+
3770
+ void PBRInfo_setPointLight(inout PBRInfo pbrInputs, PointLight pointLight) {
3771
+ vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
3772
+ PBRInfo_setDirectionalLight(pbrInputs, light_direction);
3773
+ }
3774
+
3775
+ vec3 calculateFinalColor(PBRInfo pbrInputs, vec3 lightColor) {
3776
+ // Calculate the shading terms for the microfacet specular shading model
3777
+ vec3 F = specularReflection(pbrInputs);
3778
+ float G = geometricOcclusion(pbrInputs);
3779
+ float D = microfacetDistribution(pbrInputs);
3780
+
3781
+ // Calculation of analytical lighting contribution
3782
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
3783
+ vec3 specContrib = F * G * D / (4.0 * pbrInputs.NdotL * pbrInputs.NdotV);
3784
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
3785
+ return pbrInputs.NdotL * lightColor * (diffuseContrib + specContrib);
3786
+ }
3787
+
3788
+ vec4 pbr_filterColor(vec4 colorUnused)
3789
+ {
3790
+ // The albedo may be defined from a base texture or a flat color
3791
+ #ifdef HAS_BASECOLORMAP
3792
+ vec4 baseColor = SRGBtoLINEAR(texture(u_BaseColorSampler, pbr_vUV)) * u_BaseColorFactor;
3793
+ #else
3794
+ vec4 baseColor = u_BaseColorFactor;
3795
+ #endif
3796
+
3797
+ #ifdef ALPHA_CUTOFF
3798
+ if (baseColor.a < u_AlphaCutoff) {
3799
+ discard;
3800
+ }
3801
+ #endif
3802
+
3803
+ vec3 color = vec3(0, 0, 0);
3804
+
3805
+ if(pbr_uUnlit){
3806
+ color.rgb = baseColor.rgb;
3807
+ }
3808
+ else{
3809
+ // Metallic and Roughness material properties are packed together
3810
+ // In glTF, these factors can be specified by fixed scalar values
3811
+ // or from a metallic-roughness map
3812
+ float perceptualRoughness = u_MetallicRoughnessValues.y;
3813
+ float metallic = u_MetallicRoughnessValues.x;
3814
+ #ifdef HAS_METALROUGHNESSMAP
3815
+ // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
3816
+ // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
3817
+ vec4 mrSample = texture(u_MetallicRoughnessSampler, pbr_vUV);
3818
+ perceptualRoughness = mrSample.g * perceptualRoughness;
3819
+ metallic = mrSample.b * metallic;
3820
+ #endif
3821
+ perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
3822
+ metallic = clamp(metallic, 0.0, 1.0);
3823
+ // Roughness is authored as perceptual roughness; as is convention,
3824
+ // convert to material roughness by squaring the perceptual roughness [2].
3825
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
3826
+
3827
+ vec3 f0 = vec3(0.04);
3828
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
3829
+ diffuseColor *= 1.0 - metallic;
3830
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
3831
+
3832
+ // Compute reflectance.
3833
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
3834
+
3835
+ // For typical incident reflectance range (between 4% to 100%) set the grazing
3836
+ // reflectance to 100% for typical fresnel effect.
3837
+ // For very low reflectance range on highly diffuse objects (below 4%),
3838
+ // incrementally reduce grazing reflecance to 0%.
3839
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
3840
+ vec3 specularEnvironmentR0 = specularColor.rgb;
3841
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
3842
+
3843
+ vec3 n = getNormal(); // normal at surface point
3844
+ vec3 v = normalize(u_Camera - pbr_vPosition); // Vector from surface point to camera
3845
+
3846
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
3847
+ vec3 reflection = -normalize(reflect(v, n));
3848
+
3849
+ PBRInfo pbrInputs = PBRInfo(
3850
+ 0.0, // NdotL
3851
+ NdotV,
3852
+ 0.0, // NdotH
3853
+ 0.0, // LdotH
3854
+ 0.0, // VdotH
3855
+ perceptualRoughness,
3856
+ metallic,
3857
+ specularEnvironmentR0,
3858
+ specularEnvironmentR90,
3859
+ alphaRoughness,
3860
+ diffuseColor,
3861
+ specularColor,
3862
+ n,
3863
+ v
3864
+ );
3865
+
3866
+ #ifdef USE_LIGHTS
3867
+ // Apply ambient light
3868
+ PBRInfo_setAmbientLight(pbrInputs);
3869
+ color += calculateFinalColor(pbrInputs, lighting_uAmbientLight.color);
3870
+
3871
+ // Apply directional light
3872
+ for(int i = 0, i < lighting_uDirectionalLightCount, i++) {
3873
+ if (i < lighting_uDirectionalLightCount) {
3874
+ PBRInfo_setDirectionalLight(pbrInputs, lighting_uDirectionalLight[i].direction);
3875
+ color += calculateFinalColor(pbrInputs, lighting_uDirectionalLight[i].color);
3876
+ }
3877
+ }
3878
+
3879
+ // Apply point light
3880
+ for(int i = 0, i < lighting_uPointLightCount, i++) {
3881
+ if (i < lighting_uPointLightCount) {
3882
+ PBRInfo_setPointLight(pbrInputs, lighting_uPointLight[i]);
3883
+ float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition));
3884
+ color += calculateFinalColor(pbrInputs, lighting_uPointLight[i].color / attenuation);
3885
+ }
3886
+ }
3887
+ #endif
3888
+
3889
+ // Calculate lighting contribution from image based lighting source (IBL)
3890
+ #ifdef USE_IBL
3891
+ color += getIBLContribution(pbrInputs, n, reflection);
3892
+ #endif
3893
+
3894
+ // Apply optional PBR terms for additional (optional) shading
3895
+ #ifdef HAS_OCCLUSIONMAP
3896
+ float ao = texture(u_OcclusionSampler, pbr_vUV).r;
3897
+ color = mix(color, color * ao, u_OcclusionStrength);
3898
+ #endif
3899
+
3900
+ #ifdef HAS_EMISSIVEMAP
3901
+ vec3 emissive = SRGBtoLINEAR(texture(u_EmissiveSampler, pbr_vUV)).rgb * u_EmissiveFactor;
3902
+ color += emissive;
3903
+ #endif
3904
+
3905
+ // This section uses mix to override final color for reference app visualization
3906
+ // of various parameters in the lighting equation.
3907
+ #ifdef PBR_DEBUG
3908
+ // TODO: Figure out how to debug multiple lights
3909
+
3910
+ // color = mix(color, F, u_ScaleFGDSpec.x);
3911
+ // color = mix(color, vec3(G), u_ScaleFGDSpec.y);
3912
+ // color = mix(color, vec3(D), u_ScaleFGDSpec.z);
3913
+ // color = mix(color, specContrib, u_ScaleFGDSpec.w);
3914
+
3915
+ // color = mix(color, diffuseContrib, u_ScaleDiffBaseMR.x);
3916
+ color = mix(color, baseColor.rgb, u_ScaleDiffBaseMR.y);
3917
+ color = mix(color, vec3(metallic), u_ScaleDiffBaseMR.z);
3918
+ color = mix(color, vec3(perceptualRoughness), u_ScaleDiffBaseMR.w);
3919
+ #endif
3920
+
3921
+ }
3922
+
3923
+ return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
3924
+ }
3925
+ `;
3926
+
3927
+ // ../shadertools/src/modules-webgl1/lighting/pbr/pbr.ts
3928
+ var pbr = {
3929
+ name: "pbr",
3930
+ vs,
3931
+ fs,
3932
+ defines: {
3933
+ LIGHTING_FRAGMENT: 1
3934
+ },
3935
+ dependencies: [lights]
3936
+ };
3937
+
3938
+ // src/gltf/create-gltf-model.ts
3391
3939
  var import_engine = __toESM(require_engine(), 1);
3392
- var vs = `
3940
+ var vs2 = `
3393
3941
  #pragma vscode_glsllint_stage: vert
3394
3942
  #if (__VERSION__ < 300)
3395
3943
  #define _attr attribute
@@ -3435,7 +3983,7 @@ var __exports__ = (() => {
3435
3983
  gl_Position = u_MVPMatrix * positions;
3436
3984
  }
3437
3985
  `;
3438
- var fs = `
3986
+ var fs2 = `
3439
3987
  #pragma vscode_glsllint_stage: frag
3440
3988
  #if (__VERSION__ < 300)
3441
3989
  #define fragmentColor gl_FragColor
@@ -3464,9 +4012,9 @@ var __exports__ = (() => {
3464
4012
  geometry,
3465
4013
  topology: geometry.topology,
3466
4014
  vertexCount,
3467
- modules: [import_shadertools.pbr],
3468
- vs: addVersionToShader(device, vs),
3469
- fs: addVersionToShader(device, fs),
4015
+ modules: [pbr],
4016
+ vs: addVersionToShader(device, vs2),
4017
+ fs: addVersionToShader(device, fs2),
3470
4018
  ...modelOptions,
3471
4019
  bindings: { ...parsedMaterial.bindings, ...modelOptions.bindings },
3472
4020
  defines: { ...parsedMaterial.defines, ...modelOptions.defines },
@@ -3490,12 +4038,11 @@ ${source}`;
3490
4038
  useTangents: false
3491
4039
  };
3492
4040
  var GLTFInstantiator = class {
3493
- // TODO - replace with Device
3494
4041
  device;
3495
4042
  options;
3496
4043
  gltf;
3497
4044
  constructor(device, options = {}) {
3498
- this.device = import_webgl.WebGLDevice.attach(device);
4045
+ this.device = device;
3499
4046
  this.options = { ...DEFAULT_OPTIONS, ...options };
3500
4047
  }
3501
4048
  instantiate(gltf) {
@@ -3650,7 +4197,7 @@ ${source}`;
3650
4197
  const animator = instantiator.createAnimator();
3651
4198
  return { scenes, animator };
3652
4199
  }
3653
- return __toCommonJS(src_exports);
4200
+ return __toCommonJS(bundle_exports);
3654
4201
  })();
3655
4202
  return __exports__;
3656
4203
  });