@luma.gl/shadertools 9.3.0-alpha.4 → 9.3.0-alpha.6

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.
Files changed (62) hide show
  1. package/dist/dist.dev.js +2111 -197
  2. package/dist/dist.min.js +315 -184
  3. package/dist/index.cjs +459 -198
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
  10. package/dist/lib/preprocessor/preprocessor.js +33 -7
  11. package/dist/lib/preprocessor/preprocessor.js.map +1 -1
  12. package/dist/lib/shader-assembler.d.ts.map +1 -1
  13. package/dist/lib/shader-assembler.js +8 -1
  14. package/dist/lib/shader-assembler.js.map +1 -1
  15. package/dist/lib/shader-module/shader-module.d.ts +1 -1
  16. package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
  17. package/dist/modules/engine/skin/skin.d.ts +29 -0
  18. package/dist/modules/engine/skin/skin.d.ts.map +1 -0
  19. package/dist/modules/engine/skin/skin.js +88 -0
  20. package/dist/modules/engine/skin/skin.js.map +1 -0
  21. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  22. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  23. package/dist/modules/lighting/lights/lighting-glsl.js +20 -2
  24. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
  25. package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
  26. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
  27. package/dist/modules/lighting/lights/lighting-wgsl.js +63 -13
  28. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
  29. package/dist/modules/lighting/lights/lighting.d.ts +27 -3
  30. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  31. package/dist/modules/lighting/lights/lighting.js +32 -6
  32. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  33. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  34. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  35. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +106 -79
  36. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  37. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +20 -4
  38. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  39. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  40. package/dist/modules/lighting/pbr-material/pbr-projection.js +12 -1
  41. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  42. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -40
  43. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
  44. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +40 -76
  45. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
  46. package/dist/modules/math/random/random.d.ts +1 -1
  47. package/dist/modules/math/random/random.d.ts.map +1 -1
  48. package/dist/modules/math/random/random.js +2 -3
  49. package/dist/modules/math/random/random.js.map +1 -1
  50. package/package.json +2 -2
  51. package/src/index.ts +1 -0
  52. package/src/lib/preprocessor/preprocessor.ts +40 -7
  53. package/src/lib/shader-assembler.ts +8 -1
  54. package/src/lib/shader-module/shader-module.ts +1 -1
  55. package/src/modules/engine/skin/skin.ts +116 -0
  56. package/src/modules/lighting/lights/lighting-glsl.ts +20 -2
  57. package/src/modules/lighting/lights/lighting-wgsl.ts +63 -13
  58. package/src/modules/lighting/lights/lighting.ts +45 -9
  59. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +106 -79
  60. package/src/modules/lighting/pbr-material/pbr-projection.ts +13 -1
  61. package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +40 -77
  62. package/src/modules/math/random/random.ts +2 -3
package/dist/dist.dev.js CHANGED
@@ -85,6 +85,7 @@ var __exports__ = (() => {
85
85
  picking: () => picking,
86
86
  preprocess: () => preprocess,
87
87
  random: () => random,
88
+ skin: () => skin,
88
89
  toHalfFloat: () => toHalfFloat,
89
90
  typeToChannelCount: () => typeToChannelCount,
90
91
  typeToChannelSuffix: () => typeToChannelSuffix
@@ -234,7 +235,7 @@ var __exports__ = (() => {
234
235
  throw new Error(type);
235
236
  }
236
237
  }
237
- function injectShader(source3, stage, inject, injectStandardStubs = false) {
238
+ function injectShader(source4, stage, inject, injectStandardStubs = false) {
238
239
  const isVertex = stage === "vertex";
239
240
  for (const key in inject) {
240
241
  const fragmentData = inject[key];
@@ -248,43 +249,43 @@ var __exports__ = (() => {
248
249
  switch (key) {
249
250
  case "vs:#decl":
250
251
  if (isVertex) {
251
- source3 = source3.replace(DECLARATION_INJECT_MARKER, fragmentString);
252
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
252
253
  }
253
254
  break;
254
255
  case "vs:#main-start":
255
256
  if (isVertex) {
256
- source3 = source3.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
257
+ source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
257
258
  }
258
259
  break;
259
260
  case "vs:#main-end":
260
261
  if (isVertex) {
261
- source3 = source3.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
262
+ source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
262
263
  }
263
264
  break;
264
265
  case "fs:#decl":
265
266
  if (!isVertex) {
266
- source3 = source3.replace(DECLARATION_INJECT_MARKER, fragmentString);
267
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
267
268
  }
268
269
  break;
269
270
  case "fs:#main-start":
270
271
  if (!isVertex) {
271
- source3 = source3.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
272
+ source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
272
273
  }
273
274
  break;
274
275
  case "fs:#main-end":
275
276
  if (!isVertex) {
276
- source3 = source3.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
277
+ source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
277
278
  }
278
279
  break;
279
280
  default:
280
- source3 = source3.replace(key, (match) => match + fragmentString);
281
+ source4 = source4.replace(key, (match) => match + fragmentString);
281
282
  }
282
283
  }
283
- source3 = source3.replace(DECLARATION_INJECT_MARKER, "");
284
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, "");
284
285
  if (injectStandardStubs) {
285
- source3 = source3.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]);
286
+ source4 = source4.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]);
286
287
  }
287
- return source3;
288
+ return source4;
288
289
  }
289
290
  function combineInjects(injects) {
290
291
  const result = {};
@@ -464,18 +465,18 @@ ${inject[key]}` : inject[key];
464
465
  }
465
466
 
466
467
  // src/lib/shader-transpiler/transpile-glsl-shader.ts
467
- function transpileGLSLShader(source3, stage) {
468
- const sourceGLSLVersion = Number(source3.match(/^#version[ \t]+(\d+)/m)?.[1] || 100);
468
+ function transpileGLSLShader(source4, stage) {
469
+ const sourceGLSLVersion = Number(source4.match(/^#version[ \t]+(\d+)/m)?.[1] || 100);
469
470
  if (sourceGLSLVersion !== 300) {
470
471
  throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");
471
472
  }
472
473
  switch (stage) {
473
474
  case "vertex":
474
- source3 = convertShader(source3, ES300_VERTEX_REPLACEMENTS);
475
- return source3;
475
+ source4 = convertShader(source4, ES300_VERTEX_REPLACEMENTS);
476
+ return source4;
476
477
  case "fragment":
477
- source3 = convertShader(source3, ES300_FRAGMENT_REPLACEMENTS);
478
- return source3;
478
+ source4 = convertShader(source4, ES300_FRAGMENT_REPLACEMENTS);
479
+ return source4;
479
480
  default:
480
481
  throw new Error(stage);
481
482
  }
@@ -499,11 +500,11 @@ ${inject[key]}` : inject[key];
499
500
  // `varying` keyword replaced with `in`
500
501
  [makeVariableTextRegExp("varying"), "in $1"]
501
502
  ];
502
- function convertShader(source3, replacements) {
503
+ function convertShader(source4, replacements) {
503
504
  for (const [pattern, replacement] of replacements) {
504
- source3 = source3.replace(pattern, replacement);
505
+ source4 = source4.replace(pattern, replacement);
505
506
  }
506
- return source3;
507
+ return source4;
507
508
  }
508
509
  function makeVariableTextRegExp(qualifier) {
509
510
  return new RegExp(`\\b${qualifier}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`, "g");
@@ -565,11 +566,11 @@ ${inject[key]}` : inject[key];
565
566
  }
566
567
 
567
568
  // src/lib/glsl-utils/get-shader-info.ts
568
- function getShaderInfo(source3, defaultName) {
569
+ function getShaderInfo(source4, defaultName) {
569
570
  return {
570
- name: getShaderName(source3, defaultName),
571
+ name: getShaderName(source4, defaultName),
571
572
  language: "glsl",
572
- version: getShaderVersion(source3)
573
+ version: getShaderVersion(source4)
573
574
  };
574
575
  }
575
576
  function getShaderName(shader, defaultName = "unnamed") {
@@ -577,9 +578,9 @@ ${inject[key]}` : inject[key];
577
578
  const match = SHADER_NAME_REGEXP.exec(shader);
578
579
  return match ? match[1] : defaultName;
579
580
  }
580
- function getShaderVersion(source3) {
581
+ function getShaderVersion(source4) {
581
582
  let version = 100;
582
- const words = source3.match(/[^\s]+/g);
583
+ const words = source4.match(/[^\s]+/g);
583
584
  if (words && words.length >= 2 && words[0] === "#version") {
584
585
  const parsedVersion = parseInt(words[1], 10);
585
586
  if (Number.isFinite(parsedVersion)) {
@@ -615,19 +616,19 @@ ${DECLARATION_INJECT_MARKER}
615
616
  };
616
617
  }
617
618
  function assembleGLSLShaderPair(options) {
618
- const { vs: vs3, fs: fs4 } = options;
619
+ const { vs: vs4, fs: fs5 } = options;
619
620
  const modules = getShaderModuleDependencies(options.modules || []);
620
621
  return {
621
622
  vs: assembleShaderGLSL(options.platformInfo, {
622
623
  ...options,
623
- source: vs3,
624
+ source: vs4,
624
625
  stage: "vertex",
625
626
  modules
626
627
  }),
627
628
  fs: assembleShaderGLSL(options.platformInfo, {
628
629
  ...options,
629
630
  // @ts-expect-error
630
- source: fs4,
631
+ source: fs5,
631
632
  stage: "fragment",
632
633
  modules
633
634
  }),
@@ -637,7 +638,7 @@ ${DECLARATION_INJECT_MARKER}
637
638
  function assembleShaderWGSL(platformInfo, options) {
638
639
  const {
639
640
  // id,
640
- source: source3,
641
+ source: source4,
641
642
  stage,
642
643
  modules,
643
644
  // defines = {},
@@ -645,8 +646,8 @@ ${DECLARATION_INJECT_MARKER}
645
646
  inject = {},
646
647
  log: log2
647
648
  } = options;
648
- assert(typeof source3 === "string", "shader source must be a string");
649
- const coreSource = source3;
649
+ assert(typeof source4 === "string", "shader source must be a string");
650
+ const coreSource = source4;
650
651
  let assembledSource = "";
651
652
  const hookFunctionMap = normalizeShaderHooks(hookFunctions);
652
653
  const hookInjections = {};
@@ -701,7 +702,7 @@ ${DECLARATION_INJECT_MARKER}
701
702
  }
702
703
  function assembleShaderGLSL(platformInfo, options) {
703
704
  const {
704
- source: source3,
705
+ source: source4,
705
706
  stage,
706
707
  language = "glsl",
707
708
  modules,
@@ -711,11 +712,11 @@ ${DECLARATION_INJECT_MARKER}
711
712
  prologue = true,
712
713
  log: log2
713
714
  } = options;
714
- assert(typeof source3 === "string", "shader source must be a string");
715
- const sourceVersion = language === "glsl" ? getShaderInfo(source3).version : -1;
715
+ assert(typeof source4 === "string", "shader source must be a string");
716
+ const sourceVersion = language === "glsl" ? getShaderInfo(source4).version : -1;
716
717
  const targetVersion = platformInfo.shaderLanguageVersion;
717
718
  const sourceVersionDirective = sourceVersion === 100 ? "#version 100" : "#version 300 es";
718
- const sourceLines = source3.split("\n");
719
+ const sourceLines = source4.split("\n");
719
720
  const coreSource = sourceLines.slice(1).join("\n");
720
721
  const allDefines = {};
721
722
  modules.forEach((module) => {
@@ -837,38 +838,60 @@ ${getApplicationDefines(allDefines)}
837
838
  throw new Error("Shader module must have a name");
838
839
  }
839
840
  const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, "_");
840
- let source3 = `// ----- MODULE ${module.name} ---------------
841
+ let source4 = `// ----- MODULE ${module.name} ---------------
841
842
 
842
843
  `;
843
844
  if (stage !== "wgsl") {
844
- source3 += `#define MODULE_${moduleName}
845
+ source4 += `#define MODULE_${moduleName}
845
846
  `;
846
847
  }
847
- source3 += `${moduleSource}
848
+ source4 += `${moduleSource}
848
849
  `;
849
- return source3;
850
+ return source4;
850
851
  }
851
852
 
852
853
  // src/lib/preprocessor/preprocessor.ts
853
854
  var IFDEF_REGEXP = /^\s*\#\s*ifdef\s*([a-zA-Z_]+)\s*$/;
855
+ var IFNDEF_REGEXP = /^\s*\#\s*ifndef\s*([a-zA-Z_]+)\s*(?:\/\/.*)?$/;
856
+ var ELSE_REGEXP = /^\s*\#\s*else\s*(?:\/\/.*)?$/;
854
857
  var ENDIF_REGEXP = /^\s*\#\s*endif\s*$/;
855
- function preprocess(source3, options) {
856
- const lines = source3.split("\n");
858
+ var IFDEF_WITH_COMMENT_REGEXP = /^\s*\#\s*ifdef\s*([a-zA-Z_]+)\s*(?:\/\/.*)?$/;
859
+ var ENDIF_WITH_COMMENT_REGEXP = /^\s*\#\s*endif\s*(?:\/\/.*)?$/;
860
+ function preprocess(source4, options) {
861
+ const lines = source4.split("\n");
857
862
  const output = [];
863
+ const conditionalStack = [];
858
864
  let conditional = true;
859
- let currentDefine = null;
860
865
  for (const line of lines) {
861
- const matchIf = line.match(IFDEF_REGEXP);
862
- const matchEnd = line.match(ENDIF_REGEXP);
863
- if (matchIf) {
864
- currentDefine = matchIf[1];
865
- conditional = Boolean(options?.defines?.[currentDefine]);
866
+ const matchIf = line.match(IFDEF_WITH_COMMENT_REGEXP) || line.match(IFDEF_REGEXP);
867
+ const matchIfNot = line.match(IFNDEF_REGEXP);
868
+ const matchElse = line.match(ELSE_REGEXP);
869
+ const matchEnd = line.match(ENDIF_WITH_COMMENT_REGEXP) || line.match(ENDIF_REGEXP);
870
+ if (matchIf || matchIfNot) {
871
+ const defineName = (matchIf || matchIfNot)?.[1];
872
+ const defineValue = Boolean(options?.defines?.[defineName]);
873
+ const branchTaken = matchIf ? defineValue : !defineValue;
874
+ const active = conditional && branchTaken;
875
+ conditionalStack.push({ parentActive: conditional, branchTaken, active });
876
+ conditional = active;
877
+ } else if (matchElse) {
878
+ const currentConditional = conditionalStack[conditionalStack.length - 1];
879
+ if (!currentConditional) {
880
+ throw new Error("Encountered #else without matching #ifdef or #ifndef");
881
+ }
882
+ currentConditional.active = currentConditional.parentActive && !currentConditional.branchTaken;
883
+ currentConditional.branchTaken = true;
884
+ conditional = currentConditional.active;
866
885
  } else if (matchEnd) {
867
- conditional = true;
886
+ conditionalStack.pop();
887
+ conditional = conditionalStack.length ? conditionalStack[conditionalStack.length - 1].active : true;
868
888
  } else if (conditional) {
869
889
  output.push(line);
870
890
  }
871
891
  }
892
+ if (conditionalStack.length > 0) {
893
+ throw new Error("Unterminated conditional block in shader source");
894
+ }
872
895
  return output.join("\n");
873
896
  }
874
897
 
@@ -923,14 +946,21 @@ ${getApplicationDefines(allDefines)}
923
946
  assembleWGSLShader(props) {
924
947
  const modules = this._getModuleList(props.modules);
925
948
  const hookFunctions = this._hookFunctions;
926
- const { source: source3, getUniforms: getUniforms4 } = assembleWGSLShader({
949
+ const { source: source4, getUniforms: getUniforms4 } = assembleWGSLShader({
927
950
  ...props,
928
951
  // @ts-expect-error
929
952
  source: props.source,
930
953
  modules,
931
954
  hookFunctions
932
955
  });
933
- const preprocessedSource = props.platformInfo.shaderLanguage === "wgsl" ? preprocess(source3) : source3;
956
+ const defines = {
957
+ ...modules.reduce((accumulator, module) => {
958
+ Object.assign(accumulator, module.defines);
959
+ return accumulator;
960
+ }, {}),
961
+ ...props.defines
962
+ };
963
+ const preprocessedSource = props.platformInfo.shaderLanguage === "wgsl" ? preprocess(source4, { defines }) : source4;
934
964
  return { source: preprocessedSource, getUniforms: getUniforms4, modules };
935
965
  }
936
966
  /**
@@ -1188,12 +1218,53 @@ void main() {
1188
1218
  };
1189
1219
  globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
1190
1220
  var config = globalThis.mathgl.config;
1221
+ function formatValue(value, { precision = config.precision } = {}) {
1222
+ value = round(value);
1223
+ return `${parseFloat(value.toPrecision(precision))}`;
1224
+ }
1191
1225
  function isArray(value) {
1192
1226
  return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
1193
1227
  }
1194
1228
  function clamp(value, min, max) {
1195
1229
  return map(value, (value2) => Math.max(min, Math.min(max, value2)));
1196
1230
  }
1231
+ function equals(a, b, epsilon) {
1232
+ const oldEpsilon = config.EPSILON;
1233
+ if (epsilon) {
1234
+ config.EPSILON = epsilon;
1235
+ }
1236
+ try {
1237
+ if (a === b) {
1238
+ return true;
1239
+ }
1240
+ if (isArray(a) && isArray(b)) {
1241
+ if (a.length !== b.length) {
1242
+ return false;
1243
+ }
1244
+ for (let i = 0; i < a.length; ++i) {
1245
+ if (!equals(a[i], b[i])) {
1246
+ return false;
1247
+ }
1248
+ }
1249
+ return true;
1250
+ }
1251
+ if (a && a.equals) {
1252
+ return a.equals(b);
1253
+ }
1254
+ if (b && b.equals) {
1255
+ return b.equals(a);
1256
+ }
1257
+ if (typeof a === "number" && typeof b === "number") {
1258
+ return Math.abs(a - b) <= config.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));
1259
+ }
1260
+ return false;
1261
+ } finally {
1262
+ config.EPSILON = oldEpsilon;
1263
+ }
1264
+ }
1265
+ function round(value) {
1266
+ return Math.round(value / config.EPSILON) * config.EPSILON;
1267
+ }
1197
1268
  function duplicateArray(array) {
1198
1269
  return array.clone ? array.clone() : new Array(array.length);
1199
1270
  }
@@ -1210,6 +1281,1620 @@ void main() {
1210
1281
  return func(value);
1211
1282
  }
1212
1283
 
1284
+ // ../../node_modules/@math.gl/core/dist/classes/base/math-array.js
1285
+ var MathArray = class extends Array {
1286
+ // Common methods
1287
+ /**
1288
+ * Clone the current object
1289
+ * @returns a new copy of this object
1290
+ */
1291
+ clone() {
1292
+ return new this.constructor().copy(this);
1293
+ }
1294
+ fromArray(array, offset = 0) {
1295
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1296
+ this[i] = array[i + offset];
1297
+ }
1298
+ return this.check();
1299
+ }
1300
+ toArray(targetArray = [], offset = 0) {
1301
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1302
+ targetArray[offset + i] = this[i];
1303
+ }
1304
+ return targetArray;
1305
+ }
1306
+ toObject(targetObject) {
1307
+ return targetObject;
1308
+ }
1309
+ from(arrayOrObject) {
1310
+ return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : (
1311
+ // @ts-ignore
1312
+ this.fromObject(arrayOrObject)
1313
+ );
1314
+ }
1315
+ to(arrayOrObject) {
1316
+ if (arrayOrObject === this) {
1317
+ return this;
1318
+ }
1319
+ return isArray(arrayOrObject) ? this.toArray(arrayOrObject) : this.toObject(arrayOrObject);
1320
+ }
1321
+ toTarget(target) {
1322
+ return target ? this.to(target) : this;
1323
+ }
1324
+ /** @deprecated */
1325
+ toFloat32Array() {
1326
+ return new Float32Array(this);
1327
+ }
1328
+ toString() {
1329
+ return this.formatString(config);
1330
+ }
1331
+ /** Formats string according to options */
1332
+ formatString(opts) {
1333
+ let string = "";
1334
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1335
+ string += (i > 0 ? ", " : "") + formatValue(this[i], opts);
1336
+ }
1337
+ return `${opts.printTypes ? this.constructor.name : ""}[${string}]`;
1338
+ }
1339
+ equals(array) {
1340
+ if (!array || this.length !== array.length) {
1341
+ return false;
1342
+ }
1343
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1344
+ if (!equals(this[i], array[i])) {
1345
+ return false;
1346
+ }
1347
+ }
1348
+ return true;
1349
+ }
1350
+ exactEquals(array) {
1351
+ if (!array || this.length !== array.length) {
1352
+ return false;
1353
+ }
1354
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1355
+ if (this[i] !== array[i]) {
1356
+ return false;
1357
+ }
1358
+ }
1359
+ return true;
1360
+ }
1361
+ // Modifiers
1362
+ /** Negates all values in this object */
1363
+ negate() {
1364
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1365
+ this[i] = -this[i];
1366
+ }
1367
+ return this.check();
1368
+ }
1369
+ lerp(a, b, t) {
1370
+ if (t === void 0) {
1371
+ return this.lerp(this, a, b);
1372
+ }
1373
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1374
+ const ai = a[i];
1375
+ const endValue = typeof b === "number" ? b : b[i];
1376
+ this[i] = ai + t * (endValue - ai);
1377
+ }
1378
+ return this.check();
1379
+ }
1380
+ /** Minimal */
1381
+ min(vector) {
1382
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1383
+ this[i] = Math.min(vector[i], this[i]);
1384
+ }
1385
+ return this.check();
1386
+ }
1387
+ /** Maximal */
1388
+ max(vector) {
1389
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1390
+ this[i] = Math.max(vector[i], this[i]);
1391
+ }
1392
+ return this.check();
1393
+ }
1394
+ clamp(minVector, maxVector) {
1395
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1396
+ this[i] = Math.min(Math.max(this[i], minVector[i]), maxVector[i]);
1397
+ }
1398
+ return this.check();
1399
+ }
1400
+ add(...vectors) {
1401
+ for (const vector of vectors) {
1402
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1403
+ this[i] += vector[i];
1404
+ }
1405
+ }
1406
+ return this.check();
1407
+ }
1408
+ subtract(...vectors) {
1409
+ for (const vector of vectors) {
1410
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1411
+ this[i] -= vector[i];
1412
+ }
1413
+ }
1414
+ return this.check();
1415
+ }
1416
+ scale(scale2) {
1417
+ if (typeof scale2 === "number") {
1418
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1419
+ this[i] *= scale2;
1420
+ }
1421
+ } else {
1422
+ for (let i = 0; i < this.ELEMENTS && i < scale2.length; ++i) {
1423
+ this[i] *= scale2[i];
1424
+ }
1425
+ }
1426
+ return this.check();
1427
+ }
1428
+ /**
1429
+ * Multiplies all elements by `scale`
1430
+ * Note: `Matrix4.multiplyByScalar` only scales its 3x3 "minor"
1431
+ */
1432
+ multiplyByScalar(scalar) {
1433
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1434
+ this[i] *= scalar;
1435
+ }
1436
+ return this.check();
1437
+ }
1438
+ // Debug checks
1439
+ /** Throws an error if array length is incorrect or contains illegal values */
1440
+ check() {
1441
+ if (config.debug && !this.validate()) {
1442
+ throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);
1443
+ }
1444
+ return this;
1445
+ }
1446
+ /** Returns false if the array length is incorrect or contains illegal values */
1447
+ validate() {
1448
+ let valid = this.length === this.ELEMENTS;
1449
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1450
+ valid = valid && Number.isFinite(this[i]);
1451
+ }
1452
+ return valid;
1453
+ }
1454
+ // three.js compatibility
1455
+ /** @deprecated */
1456
+ sub(a) {
1457
+ return this.subtract(a);
1458
+ }
1459
+ /** @deprecated */
1460
+ setScalar(a) {
1461
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1462
+ this[i] = a;
1463
+ }
1464
+ return this.check();
1465
+ }
1466
+ /** @deprecated */
1467
+ addScalar(a) {
1468
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1469
+ this[i] += a;
1470
+ }
1471
+ return this.check();
1472
+ }
1473
+ /** @deprecated */
1474
+ subScalar(a) {
1475
+ return this.addScalar(-a);
1476
+ }
1477
+ /** @deprecated */
1478
+ multiplyScalar(scalar) {
1479
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1480
+ this[i] *= scalar;
1481
+ }
1482
+ return this.check();
1483
+ }
1484
+ /** @deprecated */
1485
+ divideScalar(a) {
1486
+ return this.multiplyByScalar(1 / a);
1487
+ }
1488
+ /** @deprecated */
1489
+ clampScalar(min, max) {
1490
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1491
+ this[i] = Math.min(Math.max(this[i], min), max);
1492
+ }
1493
+ return this.check();
1494
+ }
1495
+ /** @deprecated */
1496
+ get elements() {
1497
+ return this;
1498
+ }
1499
+ };
1500
+
1501
+ // ../../node_modules/@math.gl/core/dist/lib/validators.js
1502
+ function validateVector(v, length) {
1503
+ if (v.length !== length) {
1504
+ return false;
1505
+ }
1506
+ for (let i = 0; i < v.length; ++i) {
1507
+ if (!Number.isFinite(v[i])) {
1508
+ return false;
1509
+ }
1510
+ }
1511
+ return true;
1512
+ }
1513
+ function checkNumber(value) {
1514
+ if (!Number.isFinite(value)) {
1515
+ throw new Error(`Invalid number ${JSON.stringify(value)}`);
1516
+ }
1517
+ return value;
1518
+ }
1519
+ function checkVector(v, length, callerName = "") {
1520
+ if (config.debug && !validateVector(v, length)) {
1521
+ throw new Error(`math.gl: ${callerName} some fields set to invalid numbers'`);
1522
+ }
1523
+ return v;
1524
+ }
1525
+
1526
+ // ../../node_modules/@math.gl/core/dist/gl-matrix/common.js
1527
+ var EPSILON = 1e-6;
1528
+ var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
1529
+ var degree = Math.PI / 180;
1530
+
1531
+ // ../../node_modules/@math.gl/core/dist/gl-matrix/vec2.js
1532
+ function create() {
1533
+ const out = new ARRAY_TYPE(2);
1534
+ if (ARRAY_TYPE != Float32Array) {
1535
+ out[0] = 0;
1536
+ out[1] = 0;
1537
+ }
1538
+ return out;
1539
+ }
1540
+ function transformMat4(out, a, m) {
1541
+ const x = a[0];
1542
+ const y = a[1];
1543
+ out[0] = m[0] * x + m[4] * y + m[12];
1544
+ out[1] = m[1] * x + m[5] * y + m[13];
1545
+ return out;
1546
+ }
1547
+ var forEach = function() {
1548
+ const vec = create();
1549
+ return function(a, stride, offset, count, fn, arg) {
1550
+ let i;
1551
+ let l;
1552
+ if (!stride) {
1553
+ stride = 2;
1554
+ }
1555
+ if (!offset) {
1556
+ offset = 0;
1557
+ }
1558
+ if (count) {
1559
+ l = Math.min(count * stride + offset, a.length);
1560
+ } else {
1561
+ l = a.length;
1562
+ }
1563
+ for (i = offset; i < l; i += stride) {
1564
+ vec[0] = a[i];
1565
+ vec[1] = a[i + 1];
1566
+ fn(vec, vec, arg);
1567
+ a[i] = vec[0];
1568
+ a[i + 1] = vec[1];
1569
+ }
1570
+ return a;
1571
+ };
1572
+ }();
1573
+
1574
+ // ../../node_modules/@math.gl/core/dist/lib/gl-matrix-extras.js
1575
+ function vec2_transformMat4AsVector(out, a, m) {
1576
+ const x = a[0];
1577
+ const y = a[1];
1578
+ const w = m[3] * x + m[7] * y || 1;
1579
+ out[0] = (m[0] * x + m[4] * y) / w;
1580
+ out[1] = (m[1] * x + m[5] * y) / w;
1581
+ return out;
1582
+ }
1583
+ function vec3_transformMat4AsVector(out, a, m) {
1584
+ const x = a[0];
1585
+ const y = a[1];
1586
+ const z = a[2];
1587
+ const w = m[3] * x + m[7] * y + m[11] * z || 1;
1588
+ out[0] = (m[0] * x + m[4] * y + m[8] * z) / w;
1589
+ out[1] = (m[1] * x + m[5] * y + m[9] * z) / w;
1590
+ out[2] = (m[2] * x + m[6] * y + m[10] * z) / w;
1591
+ return out;
1592
+ }
1593
+
1594
+ // ../../node_modules/@math.gl/core/dist/gl-matrix/vec3.js
1595
+ function create2() {
1596
+ const out = new ARRAY_TYPE(3);
1597
+ if (ARRAY_TYPE != Float32Array) {
1598
+ out[0] = 0;
1599
+ out[1] = 0;
1600
+ out[2] = 0;
1601
+ }
1602
+ return out;
1603
+ }
1604
+ function transformMat42(out, a, m) {
1605
+ const x = a[0];
1606
+ const y = a[1];
1607
+ const z = a[2];
1608
+ let w = m[3] * x + m[7] * y + m[11] * z + m[15];
1609
+ w = w || 1;
1610
+ out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
1611
+ out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
1612
+ out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
1613
+ return out;
1614
+ }
1615
+ var forEach2 = function() {
1616
+ const vec = create2();
1617
+ return function(a, stride, offset, count, fn, arg) {
1618
+ let i;
1619
+ let l;
1620
+ if (!stride) {
1621
+ stride = 3;
1622
+ }
1623
+ if (!offset) {
1624
+ offset = 0;
1625
+ }
1626
+ if (count) {
1627
+ l = Math.min(count * stride + offset, a.length);
1628
+ } else {
1629
+ l = a.length;
1630
+ }
1631
+ for (i = offset; i < l; i += stride) {
1632
+ vec[0] = a[i];
1633
+ vec[1] = a[i + 1];
1634
+ vec[2] = a[i + 2];
1635
+ fn(vec, vec, arg);
1636
+ a[i] = vec[0];
1637
+ a[i + 1] = vec[1];
1638
+ a[i + 2] = vec[2];
1639
+ }
1640
+ return a;
1641
+ };
1642
+ }();
1643
+
1644
+ // ../../node_modules/@math.gl/core/dist/classes/base/matrix.js
1645
+ var Matrix = class extends MathArray {
1646
+ // fromObject(object) {
1647
+ // const array = object.elements;
1648
+ // return this.fromRowMajor(array);
1649
+ // }
1650
+ // toObject(object) {
1651
+ // const array = object.elements;
1652
+ // this.toRowMajor(array);
1653
+ // return object;
1654
+ // }
1655
+ // TODO better override formatString?
1656
+ toString() {
1657
+ let string = "[";
1658
+ if (config.printRowMajor) {
1659
+ string += "row-major:";
1660
+ for (let row = 0; row < this.RANK; ++row) {
1661
+ for (let col = 0; col < this.RANK; ++col) {
1662
+ string += ` ${this[col * this.RANK + row]}`;
1663
+ }
1664
+ }
1665
+ } else {
1666
+ string += "column-major:";
1667
+ for (let i = 0; i < this.ELEMENTS; ++i) {
1668
+ string += ` ${this[i]}`;
1669
+ }
1670
+ }
1671
+ string += "]";
1672
+ return string;
1673
+ }
1674
+ getElementIndex(row, col) {
1675
+ return col * this.RANK + row;
1676
+ }
1677
+ // By default assumes row major indices
1678
+ getElement(row, col) {
1679
+ return this[col * this.RANK + row];
1680
+ }
1681
+ // By default assumes row major indices
1682
+ setElement(row, col, value) {
1683
+ this[col * this.RANK + row] = checkNumber(value);
1684
+ return this;
1685
+ }
1686
+ getColumn(columnIndex, result = new Array(this.RANK).fill(-0)) {
1687
+ const firstIndex = columnIndex * this.RANK;
1688
+ for (let i = 0; i < this.RANK; ++i) {
1689
+ result[i] = this[firstIndex + i];
1690
+ }
1691
+ return result;
1692
+ }
1693
+ setColumn(columnIndex, columnVector) {
1694
+ const firstIndex = columnIndex * this.RANK;
1695
+ for (let i = 0; i < this.RANK; ++i) {
1696
+ this[firstIndex + i] = columnVector[i];
1697
+ }
1698
+ return this;
1699
+ }
1700
+ };
1701
+
1702
+ // ../../node_modules/@math.gl/core/dist/gl-matrix/mat4.js
1703
+ function identity(out) {
1704
+ out[0] = 1;
1705
+ out[1] = 0;
1706
+ out[2] = 0;
1707
+ out[3] = 0;
1708
+ out[4] = 0;
1709
+ out[5] = 1;
1710
+ out[6] = 0;
1711
+ out[7] = 0;
1712
+ out[8] = 0;
1713
+ out[9] = 0;
1714
+ out[10] = 1;
1715
+ out[11] = 0;
1716
+ out[12] = 0;
1717
+ out[13] = 0;
1718
+ out[14] = 0;
1719
+ out[15] = 1;
1720
+ return out;
1721
+ }
1722
+ function transpose(out, a) {
1723
+ if (out === a) {
1724
+ const a01 = a[1];
1725
+ const a02 = a[2];
1726
+ const a03 = a[3];
1727
+ const a12 = a[6];
1728
+ const a13 = a[7];
1729
+ const a23 = a[11];
1730
+ out[1] = a[4];
1731
+ out[2] = a[8];
1732
+ out[3] = a[12];
1733
+ out[4] = a01;
1734
+ out[6] = a[9];
1735
+ out[7] = a[13];
1736
+ out[8] = a02;
1737
+ out[9] = a12;
1738
+ out[11] = a[14];
1739
+ out[12] = a03;
1740
+ out[13] = a13;
1741
+ out[14] = a23;
1742
+ } else {
1743
+ out[0] = a[0];
1744
+ out[1] = a[4];
1745
+ out[2] = a[8];
1746
+ out[3] = a[12];
1747
+ out[4] = a[1];
1748
+ out[5] = a[5];
1749
+ out[6] = a[9];
1750
+ out[7] = a[13];
1751
+ out[8] = a[2];
1752
+ out[9] = a[6];
1753
+ out[10] = a[10];
1754
+ out[11] = a[14];
1755
+ out[12] = a[3];
1756
+ out[13] = a[7];
1757
+ out[14] = a[11];
1758
+ out[15] = a[15];
1759
+ }
1760
+ return out;
1761
+ }
1762
+ function invert(out, a) {
1763
+ const a00 = a[0];
1764
+ const a01 = a[1];
1765
+ const a02 = a[2];
1766
+ const a03 = a[3];
1767
+ const a10 = a[4];
1768
+ const a11 = a[5];
1769
+ const a12 = a[6];
1770
+ const a13 = a[7];
1771
+ const a20 = a[8];
1772
+ const a21 = a[9];
1773
+ const a22 = a[10];
1774
+ const a23 = a[11];
1775
+ const a30 = a[12];
1776
+ const a31 = a[13];
1777
+ const a32 = a[14];
1778
+ const a33 = a[15];
1779
+ const b00 = a00 * a11 - a01 * a10;
1780
+ const b01 = a00 * a12 - a02 * a10;
1781
+ const b02 = a00 * a13 - a03 * a10;
1782
+ const b03 = a01 * a12 - a02 * a11;
1783
+ const b04 = a01 * a13 - a03 * a11;
1784
+ const b05 = a02 * a13 - a03 * a12;
1785
+ const b06 = a20 * a31 - a21 * a30;
1786
+ const b07 = a20 * a32 - a22 * a30;
1787
+ const b08 = a20 * a33 - a23 * a30;
1788
+ const b09 = a21 * a32 - a22 * a31;
1789
+ const b10 = a21 * a33 - a23 * a31;
1790
+ const b11 = a22 * a33 - a23 * a32;
1791
+ let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1792
+ if (!det) {
1793
+ return null;
1794
+ }
1795
+ det = 1 / det;
1796
+ out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
1797
+ out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
1798
+ out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
1799
+ out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
1800
+ out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
1801
+ out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
1802
+ out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
1803
+ out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
1804
+ out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
1805
+ out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
1806
+ out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
1807
+ out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
1808
+ out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
1809
+ out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
1810
+ out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
1811
+ out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
1812
+ return out;
1813
+ }
1814
+ function determinant(a) {
1815
+ const a00 = a[0];
1816
+ const a01 = a[1];
1817
+ const a02 = a[2];
1818
+ const a03 = a[3];
1819
+ const a10 = a[4];
1820
+ const a11 = a[5];
1821
+ const a12 = a[6];
1822
+ const a13 = a[7];
1823
+ const a20 = a[8];
1824
+ const a21 = a[9];
1825
+ const a22 = a[10];
1826
+ const a23 = a[11];
1827
+ const a30 = a[12];
1828
+ const a31 = a[13];
1829
+ const a32 = a[14];
1830
+ const a33 = a[15];
1831
+ const b0 = a00 * a11 - a01 * a10;
1832
+ const b1 = a00 * a12 - a02 * a10;
1833
+ const b2 = a01 * a12 - a02 * a11;
1834
+ const b3 = a20 * a31 - a21 * a30;
1835
+ const b4 = a20 * a32 - a22 * a30;
1836
+ const b5 = a21 * a32 - a22 * a31;
1837
+ const b6 = a00 * b5 - a01 * b4 + a02 * b3;
1838
+ const b7 = a10 * b5 - a11 * b4 + a12 * b3;
1839
+ const b8 = a20 * b2 - a21 * b1 + a22 * b0;
1840
+ const b9 = a30 * b2 - a31 * b1 + a32 * b0;
1841
+ return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9;
1842
+ }
1843
+ function multiply(out, a, b) {
1844
+ const a00 = a[0];
1845
+ const a01 = a[1];
1846
+ const a02 = a[2];
1847
+ const a03 = a[3];
1848
+ const a10 = a[4];
1849
+ const a11 = a[5];
1850
+ const a12 = a[6];
1851
+ const a13 = a[7];
1852
+ const a20 = a[8];
1853
+ const a21 = a[9];
1854
+ const a22 = a[10];
1855
+ const a23 = a[11];
1856
+ const a30 = a[12];
1857
+ const a31 = a[13];
1858
+ const a32 = a[14];
1859
+ const a33 = a[15];
1860
+ let b0 = b[0];
1861
+ let b1 = b[1];
1862
+ let b2 = b[2];
1863
+ let b3 = b[3];
1864
+ out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1865
+ out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1866
+ out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1867
+ out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1868
+ b0 = b[4];
1869
+ b1 = b[5];
1870
+ b2 = b[6];
1871
+ b3 = b[7];
1872
+ out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1873
+ out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1874
+ out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1875
+ out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1876
+ b0 = b[8];
1877
+ b1 = b[9];
1878
+ b2 = b[10];
1879
+ b3 = b[11];
1880
+ out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1881
+ out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1882
+ out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1883
+ out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1884
+ b0 = b[12];
1885
+ b1 = b[13];
1886
+ b2 = b[14];
1887
+ b3 = b[15];
1888
+ out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1889
+ out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1890
+ out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1891
+ out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1892
+ return out;
1893
+ }
1894
+ function translate(out, a, v) {
1895
+ const x = v[0];
1896
+ const y = v[1];
1897
+ const z = v[2];
1898
+ let a00;
1899
+ let a01;
1900
+ let a02;
1901
+ let a03;
1902
+ let a10;
1903
+ let a11;
1904
+ let a12;
1905
+ let a13;
1906
+ let a20;
1907
+ let a21;
1908
+ let a22;
1909
+ let a23;
1910
+ if (a === out) {
1911
+ out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
1912
+ out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
1913
+ out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
1914
+ out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
1915
+ } else {
1916
+ a00 = a[0];
1917
+ a01 = a[1];
1918
+ a02 = a[2];
1919
+ a03 = a[3];
1920
+ a10 = a[4];
1921
+ a11 = a[5];
1922
+ a12 = a[6];
1923
+ a13 = a[7];
1924
+ a20 = a[8];
1925
+ a21 = a[9];
1926
+ a22 = a[10];
1927
+ a23 = a[11];
1928
+ out[0] = a00;
1929
+ out[1] = a01;
1930
+ out[2] = a02;
1931
+ out[3] = a03;
1932
+ out[4] = a10;
1933
+ out[5] = a11;
1934
+ out[6] = a12;
1935
+ out[7] = a13;
1936
+ out[8] = a20;
1937
+ out[9] = a21;
1938
+ out[10] = a22;
1939
+ out[11] = a23;
1940
+ out[12] = a00 * x + a10 * y + a20 * z + a[12];
1941
+ out[13] = a01 * x + a11 * y + a21 * z + a[13];
1942
+ out[14] = a02 * x + a12 * y + a22 * z + a[14];
1943
+ out[15] = a03 * x + a13 * y + a23 * z + a[15];
1944
+ }
1945
+ return out;
1946
+ }
1947
+ function scale(out, a, v) {
1948
+ const x = v[0];
1949
+ const y = v[1];
1950
+ const z = v[2];
1951
+ out[0] = a[0] * x;
1952
+ out[1] = a[1] * x;
1953
+ out[2] = a[2] * x;
1954
+ out[3] = a[3] * x;
1955
+ out[4] = a[4] * y;
1956
+ out[5] = a[5] * y;
1957
+ out[6] = a[6] * y;
1958
+ out[7] = a[7] * y;
1959
+ out[8] = a[8] * z;
1960
+ out[9] = a[9] * z;
1961
+ out[10] = a[10] * z;
1962
+ out[11] = a[11] * z;
1963
+ out[12] = a[12];
1964
+ out[13] = a[13];
1965
+ out[14] = a[14];
1966
+ out[15] = a[15];
1967
+ return out;
1968
+ }
1969
+ function rotate(out, a, rad, axis) {
1970
+ let x = axis[0];
1971
+ let y = axis[1];
1972
+ let z = axis[2];
1973
+ let len = Math.sqrt(x * x + y * y + z * z);
1974
+ let c;
1975
+ let s;
1976
+ let t;
1977
+ let a00;
1978
+ let a01;
1979
+ let a02;
1980
+ let a03;
1981
+ let a10;
1982
+ let a11;
1983
+ let a12;
1984
+ let a13;
1985
+ let a20;
1986
+ let a21;
1987
+ let a22;
1988
+ let a23;
1989
+ let b00;
1990
+ let b01;
1991
+ let b02;
1992
+ let b10;
1993
+ let b11;
1994
+ let b12;
1995
+ let b20;
1996
+ let b21;
1997
+ let b22;
1998
+ if (len < EPSILON) {
1999
+ return null;
2000
+ }
2001
+ len = 1 / len;
2002
+ x *= len;
2003
+ y *= len;
2004
+ z *= len;
2005
+ s = Math.sin(rad);
2006
+ c = Math.cos(rad);
2007
+ t = 1 - c;
2008
+ a00 = a[0];
2009
+ a01 = a[1];
2010
+ a02 = a[2];
2011
+ a03 = a[3];
2012
+ a10 = a[4];
2013
+ a11 = a[5];
2014
+ a12 = a[6];
2015
+ a13 = a[7];
2016
+ a20 = a[8];
2017
+ a21 = a[9];
2018
+ a22 = a[10];
2019
+ a23 = a[11];
2020
+ b00 = x * x * t + c;
2021
+ b01 = y * x * t + z * s;
2022
+ b02 = z * x * t - y * s;
2023
+ b10 = x * y * t - z * s;
2024
+ b11 = y * y * t + c;
2025
+ b12 = z * y * t + x * s;
2026
+ b20 = x * z * t + y * s;
2027
+ b21 = y * z * t - x * s;
2028
+ b22 = z * z * t + c;
2029
+ out[0] = a00 * b00 + a10 * b01 + a20 * b02;
2030
+ out[1] = a01 * b00 + a11 * b01 + a21 * b02;
2031
+ out[2] = a02 * b00 + a12 * b01 + a22 * b02;
2032
+ out[3] = a03 * b00 + a13 * b01 + a23 * b02;
2033
+ out[4] = a00 * b10 + a10 * b11 + a20 * b12;
2034
+ out[5] = a01 * b10 + a11 * b11 + a21 * b12;
2035
+ out[6] = a02 * b10 + a12 * b11 + a22 * b12;
2036
+ out[7] = a03 * b10 + a13 * b11 + a23 * b12;
2037
+ out[8] = a00 * b20 + a10 * b21 + a20 * b22;
2038
+ out[9] = a01 * b20 + a11 * b21 + a21 * b22;
2039
+ out[10] = a02 * b20 + a12 * b21 + a22 * b22;
2040
+ out[11] = a03 * b20 + a13 * b21 + a23 * b22;
2041
+ if (a !== out) {
2042
+ out[12] = a[12];
2043
+ out[13] = a[13];
2044
+ out[14] = a[14];
2045
+ out[15] = a[15];
2046
+ }
2047
+ return out;
2048
+ }
2049
+ function rotateX(out, a, rad) {
2050
+ const s = Math.sin(rad);
2051
+ const c = Math.cos(rad);
2052
+ const a10 = a[4];
2053
+ const a11 = a[5];
2054
+ const a12 = a[6];
2055
+ const a13 = a[7];
2056
+ const a20 = a[8];
2057
+ const a21 = a[9];
2058
+ const a22 = a[10];
2059
+ const a23 = a[11];
2060
+ if (a !== out) {
2061
+ out[0] = a[0];
2062
+ out[1] = a[1];
2063
+ out[2] = a[2];
2064
+ out[3] = a[3];
2065
+ out[12] = a[12];
2066
+ out[13] = a[13];
2067
+ out[14] = a[14];
2068
+ out[15] = a[15];
2069
+ }
2070
+ out[4] = a10 * c + a20 * s;
2071
+ out[5] = a11 * c + a21 * s;
2072
+ out[6] = a12 * c + a22 * s;
2073
+ out[7] = a13 * c + a23 * s;
2074
+ out[8] = a20 * c - a10 * s;
2075
+ out[9] = a21 * c - a11 * s;
2076
+ out[10] = a22 * c - a12 * s;
2077
+ out[11] = a23 * c - a13 * s;
2078
+ return out;
2079
+ }
2080
+ function rotateY(out, a, rad) {
2081
+ const s = Math.sin(rad);
2082
+ const c = Math.cos(rad);
2083
+ const a00 = a[0];
2084
+ const a01 = a[1];
2085
+ const a02 = a[2];
2086
+ const a03 = a[3];
2087
+ const a20 = a[8];
2088
+ const a21 = a[9];
2089
+ const a22 = a[10];
2090
+ const a23 = a[11];
2091
+ if (a !== out) {
2092
+ out[4] = a[4];
2093
+ out[5] = a[5];
2094
+ out[6] = a[6];
2095
+ out[7] = a[7];
2096
+ out[12] = a[12];
2097
+ out[13] = a[13];
2098
+ out[14] = a[14];
2099
+ out[15] = a[15];
2100
+ }
2101
+ out[0] = a00 * c - a20 * s;
2102
+ out[1] = a01 * c - a21 * s;
2103
+ out[2] = a02 * c - a22 * s;
2104
+ out[3] = a03 * c - a23 * s;
2105
+ out[8] = a00 * s + a20 * c;
2106
+ out[9] = a01 * s + a21 * c;
2107
+ out[10] = a02 * s + a22 * c;
2108
+ out[11] = a03 * s + a23 * c;
2109
+ return out;
2110
+ }
2111
+ function rotateZ(out, a, rad) {
2112
+ const s = Math.sin(rad);
2113
+ const c = Math.cos(rad);
2114
+ const a00 = a[0];
2115
+ const a01 = a[1];
2116
+ const a02 = a[2];
2117
+ const a03 = a[3];
2118
+ const a10 = a[4];
2119
+ const a11 = a[5];
2120
+ const a12 = a[6];
2121
+ const a13 = a[7];
2122
+ if (a !== out) {
2123
+ out[8] = a[8];
2124
+ out[9] = a[9];
2125
+ out[10] = a[10];
2126
+ out[11] = a[11];
2127
+ out[12] = a[12];
2128
+ out[13] = a[13];
2129
+ out[14] = a[14];
2130
+ out[15] = a[15];
2131
+ }
2132
+ out[0] = a00 * c + a10 * s;
2133
+ out[1] = a01 * c + a11 * s;
2134
+ out[2] = a02 * c + a12 * s;
2135
+ out[3] = a03 * c + a13 * s;
2136
+ out[4] = a10 * c - a00 * s;
2137
+ out[5] = a11 * c - a01 * s;
2138
+ out[6] = a12 * c - a02 * s;
2139
+ out[7] = a13 * c - a03 * s;
2140
+ return out;
2141
+ }
2142
+ function fromQuat(out, q) {
2143
+ const x = q[0];
2144
+ const y = q[1];
2145
+ const z = q[2];
2146
+ const w = q[3];
2147
+ const x2 = x + x;
2148
+ const y2 = y + y;
2149
+ const z2 = z + z;
2150
+ const xx = x * x2;
2151
+ const yx = y * x2;
2152
+ const yy = y * y2;
2153
+ const zx = z * x2;
2154
+ const zy = z * y2;
2155
+ const zz = z * z2;
2156
+ const wx = w * x2;
2157
+ const wy = w * y2;
2158
+ const wz = w * z2;
2159
+ out[0] = 1 - yy - zz;
2160
+ out[1] = yx + wz;
2161
+ out[2] = zx - wy;
2162
+ out[3] = 0;
2163
+ out[4] = yx - wz;
2164
+ out[5] = 1 - xx - zz;
2165
+ out[6] = zy + wx;
2166
+ out[7] = 0;
2167
+ out[8] = zx + wy;
2168
+ out[9] = zy - wx;
2169
+ out[10] = 1 - xx - yy;
2170
+ out[11] = 0;
2171
+ out[12] = 0;
2172
+ out[13] = 0;
2173
+ out[14] = 0;
2174
+ out[15] = 1;
2175
+ return out;
2176
+ }
2177
+ function frustum(out, left, right, bottom, top, near, far) {
2178
+ const rl = 1 / (right - left);
2179
+ const tb = 1 / (top - bottom);
2180
+ const nf = 1 / (near - far);
2181
+ out[0] = near * 2 * rl;
2182
+ out[1] = 0;
2183
+ out[2] = 0;
2184
+ out[3] = 0;
2185
+ out[4] = 0;
2186
+ out[5] = near * 2 * tb;
2187
+ out[6] = 0;
2188
+ out[7] = 0;
2189
+ out[8] = (right + left) * rl;
2190
+ out[9] = (top + bottom) * tb;
2191
+ out[10] = (far + near) * nf;
2192
+ out[11] = -1;
2193
+ out[12] = 0;
2194
+ out[13] = 0;
2195
+ out[14] = far * near * 2 * nf;
2196
+ out[15] = 0;
2197
+ return out;
2198
+ }
2199
+ function perspectiveNO(out, fovy, aspect, near, far) {
2200
+ const f = 1 / Math.tan(fovy / 2);
2201
+ out[0] = f / aspect;
2202
+ out[1] = 0;
2203
+ out[2] = 0;
2204
+ out[3] = 0;
2205
+ out[4] = 0;
2206
+ out[5] = f;
2207
+ out[6] = 0;
2208
+ out[7] = 0;
2209
+ out[8] = 0;
2210
+ out[9] = 0;
2211
+ out[11] = -1;
2212
+ out[12] = 0;
2213
+ out[13] = 0;
2214
+ out[15] = 0;
2215
+ if (far != null && far !== Infinity) {
2216
+ const nf = 1 / (near - far);
2217
+ out[10] = (far + near) * nf;
2218
+ out[14] = 2 * far * near * nf;
2219
+ } else {
2220
+ out[10] = -1;
2221
+ out[14] = -2 * near;
2222
+ }
2223
+ return out;
2224
+ }
2225
+ var perspective = perspectiveNO;
2226
+ function orthoNO(out, left, right, bottom, top, near, far) {
2227
+ const lr = 1 / (left - right);
2228
+ const bt = 1 / (bottom - top);
2229
+ const nf = 1 / (near - far);
2230
+ out[0] = -2 * lr;
2231
+ out[1] = 0;
2232
+ out[2] = 0;
2233
+ out[3] = 0;
2234
+ out[4] = 0;
2235
+ out[5] = -2 * bt;
2236
+ out[6] = 0;
2237
+ out[7] = 0;
2238
+ out[8] = 0;
2239
+ out[9] = 0;
2240
+ out[10] = 2 * nf;
2241
+ out[11] = 0;
2242
+ out[12] = (left + right) * lr;
2243
+ out[13] = (top + bottom) * bt;
2244
+ out[14] = (far + near) * nf;
2245
+ out[15] = 1;
2246
+ return out;
2247
+ }
2248
+ var ortho = orthoNO;
2249
+ function lookAt(out, eye, center, up) {
2250
+ let len;
2251
+ let x0;
2252
+ let x1;
2253
+ let x2;
2254
+ let y0;
2255
+ let y1;
2256
+ let y2;
2257
+ let z0;
2258
+ let z1;
2259
+ let z2;
2260
+ const eyex = eye[0];
2261
+ const eyey = eye[1];
2262
+ const eyez = eye[2];
2263
+ const upx = up[0];
2264
+ const upy = up[1];
2265
+ const upz = up[2];
2266
+ const centerx = center[0];
2267
+ const centery = center[1];
2268
+ const centerz = center[2];
2269
+ if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) {
2270
+ return identity(out);
2271
+ }
2272
+ z0 = eyex - centerx;
2273
+ z1 = eyey - centery;
2274
+ z2 = eyez - centerz;
2275
+ len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
2276
+ z0 *= len;
2277
+ z1 *= len;
2278
+ z2 *= len;
2279
+ x0 = upy * z2 - upz * z1;
2280
+ x1 = upz * z0 - upx * z2;
2281
+ x2 = upx * z1 - upy * z0;
2282
+ len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
2283
+ if (!len) {
2284
+ x0 = 0;
2285
+ x1 = 0;
2286
+ x2 = 0;
2287
+ } else {
2288
+ len = 1 / len;
2289
+ x0 *= len;
2290
+ x1 *= len;
2291
+ x2 *= len;
2292
+ }
2293
+ y0 = z1 * x2 - z2 * x1;
2294
+ y1 = z2 * x0 - z0 * x2;
2295
+ y2 = z0 * x1 - z1 * x0;
2296
+ len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
2297
+ if (!len) {
2298
+ y0 = 0;
2299
+ y1 = 0;
2300
+ y2 = 0;
2301
+ } else {
2302
+ len = 1 / len;
2303
+ y0 *= len;
2304
+ y1 *= len;
2305
+ y2 *= len;
2306
+ }
2307
+ out[0] = x0;
2308
+ out[1] = y0;
2309
+ out[2] = z0;
2310
+ out[3] = 0;
2311
+ out[4] = x1;
2312
+ out[5] = y1;
2313
+ out[6] = z1;
2314
+ out[7] = 0;
2315
+ out[8] = x2;
2316
+ out[9] = y2;
2317
+ out[10] = z2;
2318
+ out[11] = 0;
2319
+ out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
2320
+ out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
2321
+ out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
2322
+ out[15] = 1;
2323
+ return out;
2324
+ }
2325
+
2326
+ // ../../node_modules/@math.gl/core/dist/gl-matrix/vec4.js
2327
+ function create3() {
2328
+ const out = new ARRAY_TYPE(4);
2329
+ if (ARRAY_TYPE != Float32Array) {
2330
+ out[0] = 0;
2331
+ out[1] = 0;
2332
+ out[2] = 0;
2333
+ out[3] = 0;
2334
+ }
2335
+ return out;
2336
+ }
2337
+ function transformMat43(out, a, m) {
2338
+ const x = a[0];
2339
+ const y = a[1];
2340
+ const z = a[2];
2341
+ const w = a[3];
2342
+ out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
2343
+ out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
2344
+ out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
2345
+ out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
2346
+ return out;
2347
+ }
2348
+ var forEach3 = function() {
2349
+ const vec = create3();
2350
+ return function(a, stride, offset, count, fn, arg) {
2351
+ let i;
2352
+ let l;
2353
+ if (!stride) {
2354
+ stride = 4;
2355
+ }
2356
+ if (!offset) {
2357
+ offset = 0;
2358
+ }
2359
+ if (count) {
2360
+ l = Math.min(count * stride + offset, a.length);
2361
+ } else {
2362
+ l = a.length;
2363
+ }
2364
+ for (i = offset; i < l; i += stride) {
2365
+ vec[0] = a[i];
2366
+ vec[1] = a[i + 1];
2367
+ vec[2] = a[i + 2];
2368
+ vec[3] = a[i + 3];
2369
+ fn(vec, vec, arg);
2370
+ a[i] = vec[0];
2371
+ a[i + 1] = vec[1];
2372
+ a[i + 2] = vec[2];
2373
+ a[i + 3] = vec[3];
2374
+ }
2375
+ return a;
2376
+ };
2377
+ }();
2378
+
2379
+ // ../../node_modules/@math.gl/core/dist/classes/matrix4.js
2380
+ var INDICES;
2381
+ (function(INDICES2) {
2382
+ INDICES2[INDICES2["COL0ROW0"] = 0] = "COL0ROW0";
2383
+ INDICES2[INDICES2["COL0ROW1"] = 1] = "COL0ROW1";
2384
+ INDICES2[INDICES2["COL0ROW2"] = 2] = "COL0ROW2";
2385
+ INDICES2[INDICES2["COL0ROW3"] = 3] = "COL0ROW3";
2386
+ INDICES2[INDICES2["COL1ROW0"] = 4] = "COL1ROW0";
2387
+ INDICES2[INDICES2["COL1ROW1"] = 5] = "COL1ROW1";
2388
+ INDICES2[INDICES2["COL1ROW2"] = 6] = "COL1ROW2";
2389
+ INDICES2[INDICES2["COL1ROW3"] = 7] = "COL1ROW3";
2390
+ INDICES2[INDICES2["COL2ROW0"] = 8] = "COL2ROW0";
2391
+ INDICES2[INDICES2["COL2ROW1"] = 9] = "COL2ROW1";
2392
+ INDICES2[INDICES2["COL2ROW2"] = 10] = "COL2ROW2";
2393
+ INDICES2[INDICES2["COL2ROW3"] = 11] = "COL2ROW3";
2394
+ INDICES2[INDICES2["COL3ROW0"] = 12] = "COL3ROW0";
2395
+ INDICES2[INDICES2["COL3ROW1"] = 13] = "COL3ROW1";
2396
+ INDICES2[INDICES2["COL3ROW2"] = 14] = "COL3ROW2";
2397
+ INDICES2[INDICES2["COL3ROW3"] = 15] = "COL3ROW3";
2398
+ })(INDICES || (INDICES = {}));
2399
+ var DEFAULT_FOVY = 45 * Math.PI / 180;
2400
+ var DEFAULT_ASPECT = 1;
2401
+ var DEFAULT_NEAR = 0.1;
2402
+ var DEFAULT_FAR = 500;
2403
+ var IDENTITY_MATRIX = Object.freeze([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
2404
+ var Matrix4 = class extends Matrix {
2405
+ static get IDENTITY() {
2406
+ return getIdentityMatrix();
2407
+ }
2408
+ static get ZERO() {
2409
+ return getZeroMatrix();
2410
+ }
2411
+ get ELEMENTS() {
2412
+ return 16;
2413
+ }
2414
+ get RANK() {
2415
+ return 4;
2416
+ }
2417
+ get INDICES() {
2418
+ return INDICES;
2419
+ }
2420
+ constructor(array) {
2421
+ super(-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0);
2422
+ if (arguments.length === 1 && Array.isArray(array)) {
2423
+ this.copy(array);
2424
+ } else {
2425
+ this.identity();
2426
+ }
2427
+ }
2428
+ copy(array) {
2429
+ this[0] = array[0];
2430
+ this[1] = array[1];
2431
+ this[2] = array[2];
2432
+ this[3] = array[3];
2433
+ this[4] = array[4];
2434
+ this[5] = array[5];
2435
+ this[6] = array[6];
2436
+ this[7] = array[7];
2437
+ this[8] = array[8];
2438
+ this[9] = array[9];
2439
+ this[10] = array[10];
2440
+ this[11] = array[11];
2441
+ this[12] = array[12];
2442
+ this[13] = array[13];
2443
+ this[14] = array[14];
2444
+ this[15] = array[15];
2445
+ return this.check();
2446
+ }
2447
+ // eslint-disable-next-line max-params
2448
+ set(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33) {
2449
+ this[0] = m00;
2450
+ this[1] = m10;
2451
+ this[2] = m20;
2452
+ this[3] = m30;
2453
+ this[4] = m01;
2454
+ this[5] = m11;
2455
+ this[6] = m21;
2456
+ this[7] = m31;
2457
+ this[8] = m02;
2458
+ this[9] = m12;
2459
+ this[10] = m22;
2460
+ this[11] = m32;
2461
+ this[12] = m03;
2462
+ this[13] = m13;
2463
+ this[14] = m23;
2464
+ this[15] = m33;
2465
+ return this.check();
2466
+ }
2467
+ // accepts row major order, stores as column major
2468
+ // eslint-disable-next-line max-params
2469
+ setRowMajor(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
2470
+ this[0] = m00;
2471
+ this[1] = m10;
2472
+ this[2] = m20;
2473
+ this[3] = m30;
2474
+ this[4] = m01;
2475
+ this[5] = m11;
2476
+ this[6] = m21;
2477
+ this[7] = m31;
2478
+ this[8] = m02;
2479
+ this[9] = m12;
2480
+ this[10] = m22;
2481
+ this[11] = m32;
2482
+ this[12] = m03;
2483
+ this[13] = m13;
2484
+ this[14] = m23;
2485
+ this[15] = m33;
2486
+ return this.check();
2487
+ }
2488
+ toRowMajor(result) {
2489
+ result[0] = this[0];
2490
+ result[1] = this[4];
2491
+ result[2] = this[8];
2492
+ result[3] = this[12];
2493
+ result[4] = this[1];
2494
+ result[5] = this[5];
2495
+ result[6] = this[9];
2496
+ result[7] = this[13];
2497
+ result[8] = this[2];
2498
+ result[9] = this[6];
2499
+ result[10] = this[10];
2500
+ result[11] = this[14];
2501
+ result[12] = this[3];
2502
+ result[13] = this[7];
2503
+ result[14] = this[11];
2504
+ result[15] = this[15];
2505
+ return result;
2506
+ }
2507
+ // Constructors
2508
+ /** Set to identity matrix */
2509
+ identity() {
2510
+ return this.copy(IDENTITY_MATRIX);
2511
+ }
2512
+ /**
2513
+ *
2514
+ * @param object
2515
+ * @returns self
2516
+ */
2517
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2518
+ fromObject(object) {
2519
+ return this.check();
2520
+ }
2521
+ /**
2522
+ * Calculates a 4x4 matrix from the given quaternion
2523
+ * @param quaternion Quaternion to create matrix from
2524
+ * @returns self
2525
+ */
2526
+ fromQuaternion(quaternion) {
2527
+ fromQuat(this, quaternion);
2528
+ return this.check();
2529
+ }
2530
+ /**
2531
+ * Generates a frustum matrix with the given bounds
2532
+ * @param view.left - Left bound of the frustum
2533
+ * @param view.right - Right bound of the frustum
2534
+ * @param view.bottom - Bottom bound of the frustum
2535
+ * @param view.top - Top bound of the frustum
2536
+ * @param view.near - Near bound of the frustum
2537
+ * @param view.far - Far bound of the frustum. Can be set to Infinity.
2538
+ * @returns self
2539
+ */
2540
+ frustum(view) {
2541
+ const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
2542
+ if (far === Infinity) {
2543
+ computeInfinitePerspectiveOffCenter(this, left, right, bottom, top, near);
2544
+ } else {
2545
+ frustum(this, left, right, bottom, top, near, far);
2546
+ }
2547
+ return this.check();
2548
+ }
2549
+ /**
2550
+ * Generates a look-at matrix with the given eye position, focal point,
2551
+ * and up axis
2552
+ * @param view.eye - (vector) Position of the viewer
2553
+ * @param view.center - (vector) Point the viewer is looking at
2554
+ * @param view.up - (vector) Up axis
2555
+ * @returns self
2556
+ */
2557
+ lookAt(view) {
2558
+ const { eye, center = [0, 0, 0], up = [0, 1, 0] } = view;
2559
+ lookAt(this, eye, center, up);
2560
+ return this.check();
2561
+ }
2562
+ /**
2563
+ * Generates a orthogonal projection matrix with the given bounds
2564
+ * from "traditional" view space parameters
2565
+ * @param view.left - Left bound of the frustum
2566
+ * @param view.right number Right bound of the frustum
2567
+ * @param view.bottom - Bottom bound of the frustum
2568
+ * @param view.top number Top bound of the frustum
2569
+ * @param view.near - Near bound of the frustum
2570
+ * @param view.far number Far bound of the frustum
2571
+ * @returns self
2572
+ */
2573
+ ortho(view) {
2574
+ const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
2575
+ ortho(this, left, right, bottom, top, near, far);
2576
+ return this.check();
2577
+ }
2578
+ /**
2579
+ * Generates an orthogonal projection matrix with the same parameters
2580
+ * as a perspective matrix (plus focalDistance)
2581
+ * @param view.fovy Vertical field of view in radians
2582
+ * @param view.aspect Aspect ratio. Typically viewport width / viewport height
2583
+ * @param view.focalDistance Distance in the view frustum used for extent calculations
2584
+ * @param view.near Near bound of the frustum
2585
+ * @param view.far Far bound of the frustum
2586
+ * @returns self
2587
+ */
2588
+ orthographic(view) {
2589
+ const { fovy = DEFAULT_FOVY, aspect = DEFAULT_ASPECT, focalDistance = 1, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
2590
+ checkRadians(fovy);
2591
+ const halfY = fovy / 2;
2592
+ const top = focalDistance * Math.tan(halfY);
2593
+ const right = top * aspect;
2594
+ return this.ortho({
2595
+ left: -right,
2596
+ right,
2597
+ bottom: -top,
2598
+ top,
2599
+ near,
2600
+ far
2601
+ });
2602
+ }
2603
+ /**
2604
+ * Generates a perspective projection matrix with the given bounds
2605
+ * @param view.fovy Vertical field of view in radians
2606
+ * @param view.aspect Aspect ratio. typically viewport width/height
2607
+ * @param view.near Near bound of the frustum
2608
+ * @param view.far Far bound of the frustum
2609
+ * @returns self
2610
+ */
2611
+ perspective(view) {
2612
+ const { fovy = 45 * Math.PI / 180, aspect = 1, near = 0.1, far = 500 } = view;
2613
+ checkRadians(fovy);
2614
+ perspective(this, fovy, aspect, near, far);
2615
+ return this.check();
2616
+ }
2617
+ // Accessors
2618
+ determinant() {
2619
+ return determinant(this);
2620
+ }
2621
+ /**
2622
+ * Extracts the non-uniform scale assuming the matrix is an affine transformation.
2623
+ * The scales are the "lengths" of the column vectors in the upper-left 3x3 matrix.
2624
+ * @param result
2625
+ * @returns self
2626
+ */
2627
+ getScale(result = [-0, -0, -0]) {
2628
+ result[0] = Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]);
2629
+ result[1] = Math.sqrt(this[4] * this[4] + this[5] * this[5] + this[6] * this[6]);
2630
+ result[2] = Math.sqrt(this[8] * this[8] + this[9] * this[9] + this[10] * this[10]);
2631
+ return result;
2632
+ }
2633
+ /**
2634
+ * Gets the translation portion, assuming the matrix is a affine transformation matrix.
2635
+ * @param result
2636
+ * @returns self
2637
+ */
2638
+ getTranslation(result = [-0, -0, -0]) {
2639
+ result[0] = this[12];
2640
+ result[1] = this[13];
2641
+ result[2] = this[14];
2642
+ return result;
2643
+ }
2644
+ /**
2645
+ * Gets upper left 3x3 pure rotation matrix (non-scaling), assume affine transformation matrix
2646
+ * @param result
2647
+ * @param scaleResult
2648
+ * @returns self
2649
+ */
2650
+ getRotation(result, scaleResult) {
2651
+ result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0];
2652
+ scaleResult = scaleResult || [-0, -0, -0];
2653
+ const scale2 = this.getScale(scaleResult);
2654
+ const inverseScale0 = 1 / scale2[0];
2655
+ const inverseScale1 = 1 / scale2[1];
2656
+ const inverseScale2 = 1 / scale2[2];
2657
+ result[0] = this[0] * inverseScale0;
2658
+ result[1] = this[1] * inverseScale1;
2659
+ result[2] = this[2] * inverseScale2;
2660
+ result[3] = 0;
2661
+ result[4] = this[4] * inverseScale0;
2662
+ result[5] = this[5] * inverseScale1;
2663
+ result[6] = this[6] * inverseScale2;
2664
+ result[7] = 0;
2665
+ result[8] = this[8] * inverseScale0;
2666
+ result[9] = this[9] * inverseScale1;
2667
+ result[10] = this[10] * inverseScale2;
2668
+ result[11] = 0;
2669
+ result[12] = 0;
2670
+ result[13] = 0;
2671
+ result[14] = 0;
2672
+ result[15] = 1;
2673
+ return result;
2674
+ }
2675
+ /**
2676
+ *
2677
+ * @param result
2678
+ * @param scaleResult
2679
+ * @returns self
2680
+ */
2681
+ getRotationMatrix3(result, scaleResult) {
2682
+ result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0];
2683
+ scaleResult = scaleResult || [-0, -0, -0];
2684
+ const scale2 = this.getScale(scaleResult);
2685
+ const inverseScale0 = 1 / scale2[0];
2686
+ const inverseScale1 = 1 / scale2[1];
2687
+ const inverseScale2 = 1 / scale2[2];
2688
+ result[0] = this[0] * inverseScale0;
2689
+ result[1] = this[1] * inverseScale1;
2690
+ result[2] = this[2] * inverseScale2;
2691
+ result[3] = this[4] * inverseScale0;
2692
+ result[4] = this[5] * inverseScale1;
2693
+ result[5] = this[6] * inverseScale2;
2694
+ result[6] = this[8] * inverseScale0;
2695
+ result[7] = this[9] * inverseScale1;
2696
+ result[8] = this[10] * inverseScale2;
2697
+ return result;
2698
+ }
2699
+ // Modifiers
2700
+ transpose() {
2701
+ transpose(this, this);
2702
+ return this.check();
2703
+ }
2704
+ invert() {
2705
+ invert(this, this);
2706
+ return this.check();
2707
+ }
2708
+ // Operations
2709
+ multiplyLeft(a) {
2710
+ multiply(this, a, this);
2711
+ return this.check();
2712
+ }
2713
+ multiplyRight(a) {
2714
+ multiply(this, this, a);
2715
+ return this.check();
2716
+ }
2717
+ // Rotates a matrix by the given angle around the X axis
2718
+ rotateX(radians2) {
2719
+ rotateX(this, this, radians2);
2720
+ return this.check();
2721
+ }
2722
+ // Rotates a matrix by the given angle around the Y axis.
2723
+ rotateY(radians2) {
2724
+ rotateY(this, this, radians2);
2725
+ return this.check();
2726
+ }
2727
+ /**
2728
+ * Rotates a matrix by the given angle around the Z axis.
2729
+ * @param radians
2730
+ * @returns self
2731
+ */
2732
+ rotateZ(radians2) {
2733
+ rotateZ(this, this, radians2);
2734
+ return this.check();
2735
+ }
2736
+ /**
2737
+ *
2738
+ * @param param0
2739
+ * @returns self
2740
+ */
2741
+ rotateXYZ(angleXYZ) {
2742
+ return this.rotateX(angleXYZ[0]).rotateY(angleXYZ[1]).rotateZ(angleXYZ[2]);
2743
+ }
2744
+ /**
2745
+ *
2746
+ * @param radians
2747
+ * @param axis
2748
+ * @returns self
2749
+ */
2750
+ rotateAxis(radians2, axis) {
2751
+ rotate(this, this, radians2, axis);
2752
+ return this.check();
2753
+ }
2754
+ /**
2755
+ *
2756
+ * @param factor
2757
+ * @returns self
2758
+ */
2759
+ scale(factor) {
2760
+ scale(this, this, Array.isArray(factor) ? factor : [factor, factor, factor]);
2761
+ return this.check();
2762
+ }
2763
+ /**
2764
+ *
2765
+ * @param vec
2766
+ * @returns self
2767
+ */
2768
+ translate(vector) {
2769
+ translate(this, this, vector);
2770
+ return this.check();
2771
+ }
2772
+ // Transforms
2773
+ /**
2774
+ * Transforms any 2, 3 or 4 element vector. 2 and 3 elements are treated as points
2775
+ * @param vector
2776
+ * @param result
2777
+ * @returns self
2778
+ */
2779
+ transform(vector, result) {
2780
+ if (vector.length === 4) {
2781
+ result = transformMat43(result || [-0, -0, -0, -0], vector, this);
2782
+ checkVector(result, 4);
2783
+ return result;
2784
+ }
2785
+ return this.transformAsPoint(vector, result);
2786
+ }
2787
+ /**
2788
+ * Transforms any 2 or 3 element array as point (w implicitly 1)
2789
+ * @param vector
2790
+ * @param result
2791
+ * @returns self
2792
+ */
2793
+ transformAsPoint(vector, result) {
2794
+ const { length } = vector;
2795
+ let out;
2796
+ switch (length) {
2797
+ case 2:
2798
+ out = transformMat4(result || [-0, -0], vector, this);
2799
+ break;
2800
+ case 3:
2801
+ out = transformMat42(result || [-0, -0, -0], vector, this);
2802
+ break;
2803
+ default:
2804
+ throw new Error("Illegal vector");
2805
+ }
2806
+ checkVector(out, vector.length);
2807
+ return out;
2808
+ }
2809
+ /**
2810
+ * Transforms any 2 or 3 element array as vector (w implicitly 0)
2811
+ * @param vector
2812
+ * @param result
2813
+ * @returns self
2814
+ */
2815
+ transformAsVector(vector, result) {
2816
+ let out;
2817
+ switch (vector.length) {
2818
+ case 2:
2819
+ out = vec2_transformMat4AsVector(result || [-0, -0], vector, this);
2820
+ break;
2821
+ case 3:
2822
+ out = vec3_transformMat4AsVector(result || [-0, -0, -0], vector, this);
2823
+ break;
2824
+ default:
2825
+ throw new Error("Illegal vector");
2826
+ }
2827
+ checkVector(out, vector.length);
2828
+ return out;
2829
+ }
2830
+ /** @deprecated */
2831
+ transformPoint(vector, result) {
2832
+ return this.transformAsPoint(vector, result);
2833
+ }
2834
+ /** @deprecated */
2835
+ transformVector(vector, result) {
2836
+ return this.transformAsPoint(vector, result);
2837
+ }
2838
+ /** @deprecated */
2839
+ transformDirection(vector, result) {
2840
+ return this.transformAsVector(vector, result);
2841
+ }
2842
+ // three.js math API compatibility
2843
+ makeRotationX(radians2) {
2844
+ return this.identity().rotateX(radians2);
2845
+ }
2846
+ makeTranslation(x, y, z) {
2847
+ return this.identity().translate([x, y, z]);
2848
+ }
2849
+ };
2850
+ var ZERO;
2851
+ var IDENTITY;
2852
+ function getZeroMatrix() {
2853
+ if (!ZERO) {
2854
+ ZERO = new Matrix4([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2855
+ Object.freeze(ZERO);
2856
+ }
2857
+ return ZERO;
2858
+ }
2859
+ function getIdentityMatrix() {
2860
+ if (!IDENTITY) {
2861
+ IDENTITY = new Matrix4();
2862
+ Object.freeze(IDENTITY);
2863
+ }
2864
+ return IDENTITY;
2865
+ }
2866
+ function checkRadians(possiblyDegrees) {
2867
+ if (possiblyDegrees > Math.PI * 2) {
2868
+ throw Error("expected radians");
2869
+ }
2870
+ }
2871
+ function computeInfinitePerspectiveOffCenter(result, left, right, bottom, top, near) {
2872
+ const column0Row0 = 2 * near / (right - left);
2873
+ const column1Row1 = 2 * near / (top - bottom);
2874
+ const column2Row0 = (right + left) / (right - left);
2875
+ const column2Row1 = (top + bottom) / (top - bottom);
2876
+ const column2Row2 = -1;
2877
+ const column2Row3 = -1;
2878
+ const column3Row2 = -2 * near;
2879
+ result[0] = column0Row0;
2880
+ result[1] = 0;
2881
+ result[2] = 0;
2882
+ result[3] = 0;
2883
+ result[4] = 0;
2884
+ result[5] = column1Row1;
2885
+ result[6] = 0;
2886
+ result[7] = 0;
2887
+ result[8] = column2Row0;
2888
+ result[9] = column2Row1;
2889
+ result[10] = column2Row2;
2890
+ result[11] = column2Row3;
2891
+ result[12] = 0;
2892
+ result[13] = 0;
2893
+ result[14] = column3Row2;
2894
+ result[15] = 0;
2895
+ return result;
2896
+ }
2897
+
1213
2898
  // src/modules/math/fp16/fp16-utils.ts
1214
2899
  var float16Tables = null;
1215
2900
  var buffer = new ArrayBuffer(4);
@@ -1320,9 +3005,8 @@ void main() {
1320
3005
  // src/modules/math/random/random.ts
1321
3006
  var source = (
1322
3007
  /* wgsl */
1323
- `fn random(scale: vec3f, seed: float) -> f32 {
1324
- /* use the fragment position for a different seed per-pixel */
1325
- return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
3008
+ `fn random(scale: vec3f, seed: f32) -> f32 {
3009
+ return fract(sin(dot(scale + vec3f(seed), vec3f(12.9898, 78.233, 151.7182))) * 43758.5453 + seed);
1326
3010
  }
1327
3011
  `
1328
3012
  );
@@ -2562,8 +4246,100 @@ vec4 picking_filterColor(vec4 color) {
2562
4246
  return uniforms;
2563
4247
  }
2564
4248
 
4249
+ // src/modules/engine/skin/skin.ts
4250
+ var SKIN_MAX_JOINTS = 20;
4251
+ var source2 = (
4252
+ /* wgsl */
4253
+ `
4254
+ struct skinUniforms {
4255
+ jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
4256
+ };
4257
+
4258
+ @binding(19) @group(0) var<uniform> skin: skinUniforms;
4259
+
4260
+ fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
4261
+ return (weights.x * skin.jointMatrix[joints.x])
4262
+ + (weights.y * skin.jointMatrix[joints.y])
4263
+ + (weights.z * skin.jointMatrix[joints.z])
4264
+ + (weights.w * skin.jointMatrix[joints.w]);
4265
+ }
4266
+ `
4267
+ );
4268
+ var vs2 = (
4269
+ /* glsl */
4270
+ `
4271
+ uniform skinUniforms {
4272
+ mat4 jointMatrix[SKIN_MAX_JOINTS];
4273
+ } skin;
4274
+
4275
+ mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
4276
+ return (weights.x * skin.jointMatrix[joints.x])
4277
+ + (weights.y * skin.jointMatrix[joints.y])
4278
+ + (weights.z * skin.jointMatrix[joints.z])
4279
+ + (weights.w * skin.jointMatrix[joints.w]);
4280
+ }
4281
+
4282
+ `
4283
+ );
4284
+ var fs3 = (
4285
+ /* glsl */
4286
+ ``
4287
+ );
4288
+ var skin = {
4289
+ props: {},
4290
+ uniforms: {},
4291
+ name: "skin",
4292
+ dependencies: [],
4293
+ source: source2,
4294
+ vs: vs2,
4295
+ fs: fs3,
4296
+ defines: {
4297
+ SKIN_MAX_JOINTS
4298
+ },
4299
+ getUniforms: (props = {}, prevUniforms) => {
4300
+ const { scenegraphsFromGLTF } = props;
4301
+ if (!scenegraphsFromGLTF?.gltf?.skins?.[0]) {
4302
+ return { jointMatrix: [] };
4303
+ }
4304
+ const { inverseBindMatrices, joints, skeleton } = scenegraphsFromGLTF.gltf.skins[0];
4305
+ const matsib = [];
4306
+ const countib = inverseBindMatrices.value.length / 16;
4307
+ for (let i = 0; i < countib; i++) {
4308
+ const slice = inverseBindMatrices.value.subarray(i * 16, i * 16 + 16);
4309
+ matsib.push(new Matrix4(Array.from(slice)));
4310
+ }
4311
+ const top = scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(skeleton);
4312
+ const matrices = {};
4313
+ top.preorderTraversal((node, { worldMatrix }) => {
4314
+ matrices[node.id] = worldMatrix;
4315
+ });
4316
+ const mats = new Float32Array(SKIN_MAX_JOINTS * 16);
4317
+ for (let i = 0; i < SKIN_MAX_JOINTS; ++i) {
4318
+ const nodeIndex = joints[i];
4319
+ if (nodeIndex === void 0)
4320
+ break;
4321
+ const worldMat = matrices[scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(nodeIndex).id];
4322
+ const invBindMat = matsib[i];
4323
+ const Z = new Matrix4().copy(worldMat).multiplyRight(invBindMat);
4324
+ const off = i * 16;
4325
+ for (let j = 0; j < 16; j++) {
4326
+ mats[off + j] = Z[j];
4327
+ }
4328
+ }
4329
+ return {
4330
+ jointMatrix: mats
4331
+ };
4332
+ },
4333
+ uniformTypes: {
4334
+ jointMatrix: "mat4x4<f32>"
4335
+ },
4336
+ uniformSizes: {
4337
+ jointMatrix: SKIN_MAX_JOINTS
4338
+ }
4339
+ };
4340
+
2565
4341
  // src/modules/lighting/lights/lighting.ts
2566
- var import_core2 = __toESM(require_core(), 1);
4342
+ var import_core3 = __toESM(require_core(), 1);
2567
4343
 
2568
4344
  // src/modules/lighting/lights/lighting-glsl.ts
2569
4345
  var lightingUniformsGLSL = (
@@ -2609,6 +4385,16 @@ uniform lightingUniforms {
2609
4385
  vec3 lightPosition2;
2610
4386
  vec3 lightDirection2;
2611
4387
  vec3 lightAttenuation2;
4388
+
4389
+ vec3 lightColor3;
4390
+ vec3 lightPosition3;
4391
+ vec3 lightDirection3;
4392
+ vec3 lightAttenuation3;
4393
+
4394
+ vec3 lightColor4;
4395
+ vec3 lightPosition4;
4396
+ vec3 lightDirection4;
4397
+ vec3 lightAttenuation4;
2612
4398
  } lighting;
2613
4399
 
2614
4400
  PointLight lighting_getPointLight(int index) {
@@ -2618,8 +4404,12 @@ PointLight lighting_getPointLight(int index) {
2618
4404
  case 1:
2619
4405
  return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
2620
4406
  case 2:
2621
- default:
2622
4407
  return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
4408
+ case 3:
4409
+ return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
4410
+ case 4:
4411
+ default:
4412
+ return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
2623
4413
  }
2624
4414
  }
2625
4415
 
@@ -2630,8 +4420,12 @@ DirectionalLight lighting_getDirectionalLight(int index) {
2630
4420
  case 1:
2631
4421
  return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
2632
4422
  case 2:
2633
- default:
2634
4423
  return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
4424
+ case 3:
4425
+ return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
4426
+ case 4:
4427
+ default:
4428
+ return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
2635
4429
  }
2636
4430
  }
2637
4431
 
@@ -2649,6 +4443,8 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
2649
4443
  var lightingUniformsWGSL = (
2650
4444
  /* wgsl */
2651
4445
  `// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
4446
+ const MAX_LIGHTS: i32 = 5;
4447
+
2652
4448
  struct AmbientLight {
2653
4449
  color: vec3<f32>,
2654
4450
  };
@@ -2666,32 +4462,80 @@ struct DirectionalLight {
2666
4462
 
2667
4463
  struct lightingUniforms {
2668
4464
  enabled: i32,
2669
- pointLightCount: i32,
4465
+ lightType: i32,
4466
+
2670
4467
  directionalLightCount: i32,
4468
+ pointLightCount: i32,
2671
4469
 
2672
4470
  ambientColor: vec3<f32>,
2673
4471
 
2674
- // TODO - support multiple lights by uncommenting arrays below
2675
- lightType: i32,
2676
- lightColor: vec3<f32>,
2677
- lightDirection: vec3<f32>,
2678
- lightPosition: vec3<f32>,
2679
- lightAttenuation: vec3<f32>,
2680
-
2681
- // AmbientLight ambientLight;
2682
- // PointLight pointLight[MAX_LIGHTS];
2683
- // DirectionalLight directionalLight[MAX_LIGHTS];
4472
+ lightColor0: vec3<f32>,
4473
+ lightPosition0: vec3<f32>,
4474
+ lightDirection0: vec3<f32>,
4475
+ lightAttenuation0: vec3<f32>,
4476
+
4477
+ lightColor1: vec3<f32>,
4478
+ lightPosition1: vec3<f32>,
4479
+ lightDirection1: vec3<f32>,
4480
+ lightAttenuation1: vec3<f32>,
4481
+
4482
+ lightColor2: vec3<f32>,
4483
+ lightPosition2: vec3<f32>,
4484
+ lightDirection2: vec3<f32>,
4485
+ lightAttenuation2: vec3<f32>,
4486
+
4487
+ lightColor3: vec3<f32>,
4488
+ lightPosition3: vec3<f32>,
4489
+ lightDirection3: vec3<f32>,
4490
+ lightAttenuation3: vec3<f32>,
4491
+
4492
+ lightColor4: vec3<f32>,
4493
+ lightPosition4: vec3<f32>,
4494
+ lightDirection4: vec3<f32>,
4495
+ lightAttenuation4: vec3<f32>,
2684
4496
  };
2685
4497
 
2686
4498
  // Binding 0:1 is reserved for lighting (Note: could go into separate bind group as it is stable across draw calls)
2687
4499
  @binding(1) @group(0) var<uniform> lighting : lightingUniforms;
2688
4500
 
2689
4501
  fn lighting_getPointLight(index: i32) -> PointLight {
2690
- return PointLight(lighting.lightColor, lighting.lightPosition, lighting.lightAttenuation);
4502
+ switch (index) {
4503
+ case 0: {
4504
+ return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);
4505
+ }
4506
+ case 1: {
4507
+ return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
4508
+ }
4509
+ case 2: {
4510
+ return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
4511
+ }
4512
+ case 3: {
4513
+ return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
4514
+ }
4515
+ case 4, default: {
4516
+ return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
4517
+ }
4518
+ }
2691
4519
  }
2692
4520
 
2693
4521
  fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
2694
- return DirectionalLight(lighting.lightColor, lighting.lightDirection);
4522
+ switch (index) {
4523
+ case 0: {
4524
+ return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);
4525
+ }
4526
+ case 1: {
4527
+ return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
4528
+ }
4529
+ case 2: {
4530
+ return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
4531
+ }
4532
+ case 3: {
4533
+ return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
4534
+ }
4535
+ case 4, default: {
4536
+ return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
4537
+ }
4538
+ }
2695
4539
  }
2696
4540
 
2697
4541
  fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
@@ -2731,7 +4575,15 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2731
4575
  lightColor2: "vec3<f32>",
2732
4576
  lightPosition2: "vec3<f32>",
2733
4577
  lightDirection2: "vec3<f32>",
2734
- lightAttenuation2: "vec3<f32>"
4578
+ lightAttenuation2: "vec3<f32>",
4579
+ lightColor3: "vec3<f32>",
4580
+ lightPosition3: "vec3<f32>",
4581
+ lightDirection3: "vec3<f32>",
4582
+ lightAttenuation3: "vec3<f32>",
4583
+ lightColor4: "vec3<f32>",
4584
+ lightPosition4: "vec3<f32>",
4585
+ lightDirection4: "vec3<f32>",
4586
+ lightAttenuation4: "vec3<f32>"
2735
4587
  },
2736
4588
  defaultUniforms: {
2737
4589
  enabled: 1,
@@ -2751,7 +4603,15 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2751
4603
  lightColor2: [1, 1, 1],
2752
4604
  lightPosition2: [1, 1, 2],
2753
4605
  lightDirection2: [1, 1, 1],
2754
- lightAttenuation2: [1, 0, 0]
4606
+ lightAttenuation2: [1, 0, 0],
4607
+ lightColor3: [1, 1, 1],
4608
+ lightPosition3: [1, 1, 2],
4609
+ lightDirection3: [1, 1, 1],
4610
+ lightAttenuation3: [1, 0, 0],
4611
+ lightColor4: [1, 1, 1],
4612
+ lightPosition4: [1, 1, 2],
4613
+ lightDirection4: [1, 1, 1],
4614
+ lightAttenuation4: [1, 0, 0]
2755
4615
  },
2756
4616
  source: lightingUniformsWGSL,
2757
4617
  vs: lightingUniformsGLSL,
@@ -2789,26 +4649,36 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2789
4649
  const lightSourceUniforms = {};
2790
4650
  lightSourceUniforms.ambientColor = convertColor(ambientLight);
2791
4651
  let currentLight = 0;
4652
+ let pointLightCount = 0;
4653
+ let directionalLightCount = 0;
2792
4654
  for (const pointLight of pointLights) {
4655
+ if (currentLight >= MAX_LIGHTS) {
4656
+ break;
4657
+ }
2793
4658
  lightSourceUniforms.lightType = 0 /* POINT */;
2794
4659
  const i = currentLight;
2795
4660
  lightSourceUniforms[`lightColor${i}`] = convertColor(pointLight);
2796
4661
  lightSourceUniforms[`lightPosition${i}`] = pointLight.position;
2797
4662
  lightSourceUniforms[`lightAttenuation${i}`] = pointLight.attenuation || [1, 0, 0];
2798
4663
  currentLight++;
4664
+ pointLightCount++;
2799
4665
  }
2800
4666
  for (const directionalLight of directionalLights) {
4667
+ if (currentLight >= MAX_LIGHTS) {
4668
+ break;
4669
+ }
2801
4670
  lightSourceUniforms.lightType = 1 /* DIRECTIONAL */;
2802
4671
  const i = currentLight;
2803
4672
  lightSourceUniforms[`lightColor${i}`] = convertColor(directionalLight);
2804
4673
  lightSourceUniforms[`lightDirection${i}`] = directionalLight.direction;
2805
4674
  currentLight++;
4675
+ directionalLightCount++;
2806
4676
  }
2807
- if (currentLight > MAX_LIGHTS) {
2808
- import_core2.log.warn("MAX_LIGHTS exceeded")();
4677
+ if (pointLights.length + directionalLights.length > MAX_LIGHTS) {
4678
+ import_core3.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
2809
4679
  }
2810
- lightSourceUniforms.directionalLightCount = directionalLights.length;
2811
- lightSourceUniforms.pointLightCount = pointLights.length;
4680
+ lightSourceUniforms.directionalLightCount = directionalLightCount;
4681
+ lightSourceUniforms.pointLightCount = pointLightCount;
2812
4682
  return lightSourceUniforms;
2813
4683
  }
2814
4684
  function extractLightTypes(lights) {
@@ -3016,56 +4886,60 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
3016
4886
  let view_direction: vec3<f32> = normalize(cameraPosition - position_worldspace);
3017
4887
  lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor;
3018
4888
 
3019
- if (lighting.lightType == 0) {
3020
- let pointLight: PointLight = lighting_getPointLight(0);
4889
+ for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
4890
+ let pointLight: PointLight = lighting_getPointLight(i);
3021
4891
  let light_position_worldspace: vec3<f32> = pointLight.position;
3022
4892
  let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
3023
- lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color);
3024
- } else if (lighting.lightType == 1) {
3025
- var directionalLight: DirectionalLight = lighting_getDirectionalLight(0);
3026
- lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3027
- }
3028
-
3029
- return lightColor;
3030
- /*
3031
- for (int i = 0; i < MAX_LIGHTS; i++) {
3032
- if (i >= lighting.pointLightCount) {
3033
- break;
3034
- }
3035
- PointLight pointLight = lighting.pointLight[i];
3036
- vec3 light_position_worldspace = pointLight.position;
3037
- vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
3038
- lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color);
4893
+ let light_attenuation = getPointLightAttenuation(
4894
+ pointLight,
4895
+ distance(light_position_worldspace, position_worldspace)
4896
+ );
4897
+ lightColor += lighting_getLightColor(
4898
+ surfaceColor,
4899
+ light_direction,
4900
+ view_direction,
4901
+ normal_worldspace,
4902
+ pointLight.color / light_attenuation
4903
+ );
3039
4904
  }
3040
4905
 
3041
- for (int i = 0; i < MAX_LIGHTS; i++) {
3042
- if (i >= lighting.directionalLightCount) {
3043
- break;
3044
- }
3045
- DirectionalLight directionalLight = lighting.directionalLight[i];
4906
+ let totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount);
4907
+ for (var i: i32 = lighting.pointLightCount; i < totalLights; i++) {
4908
+ let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
3046
4909
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3047
- }
3048
- */
4910
+ }
4911
+
4912
+ return lightColor;
3049
4913
  }
3050
4914
 
3051
4915
  fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32>{
3052
4916
  var lightColor = vec3<f32>(0, 0, 0);
3053
4917
  let surfaceColor = vec3<f32>(0, 0, 0);
3054
4918
 
3055
- if (lighting.enabled == 0) {
4919
+ if (lighting.enabled != 0) {
3056
4920
  let view_direction = normalize(cameraPosition - position_worldspace);
3057
4921
 
3058
- switch (lighting.lightType) {
3059
- case 0, default: {
3060
- let pointLight: PointLight = lighting_getPointLight(0);
3061
- let light_position_worldspace: vec3<f32> = pointLight.position;
3062
- let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
3063
- lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color);
3064
- }
3065
- case 1: {
3066
- let directionalLight: DirectionalLight = lighting_getDirectionalLight(0);
4922
+ for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
4923
+ let pointLight: PointLight = lighting_getPointLight(i);
4924
+ let light_position_worldspace: vec3<f32> = pointLight.position;
4925
+ let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
4926
+ let light_attenuation = getPointLightAttenuation(
4927
+ pointLight,
4928
+ distance(light_position_worldspace, position_worldspace)
4929
+ );
4930
+ lightColor += lighting_getLightColor(
4931
+ surfaceColor,
4932
+ light_direction,
4933
+ view_direction,
4934
+ normal_worldspace,
4935
+ pointLight.color / light_attenuation
4936
+ );
4937
+ }
4938
+
4939
+ let totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount);
4940
+ for (var i: i32 = lighting.pointLightCount; i < totalLights; i++) {
4941
+ let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
3067
4942
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3068
- }
3069
4943
  }
3070
4944
  }
3071
4945
  return lightColor;
@@ -3139,7 +5013,7 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
3139
5013
  };
3140
5014
 
3141
5015
  // src/modules/lighting/pbr-material/pbr-material-glsl.ts
3142
- var vs2 = (
5016
+ var vs3 = (
3143
5017
  /* glsl */
3144
5018
  `out vec3 pbr_vPosition;
3145
5019
  out vec2 pbr_vUV;
@@ -3176,7 +5050,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
3176
5050
  }
3177
5051
  `
3178
5052
  );
3179
- var fs3 = (
5053
+ var fs4 = (
3180
5054
  /* glsl */
3181
5055
  `precision highp float;
3182
5056
 
@@ -3640,56 +5514,60 @@ vec4 pbr_filterColor(vec4 colorUnused)
3640
5514
  );
3641
5515
 
3642
5516
  // src/modules/lighting/pbr-material/pbr-material-wgsl.ts
3643
- var source2 = (
5517
+ var source3 = (
3644
5518
  /* wgsl */
3645
5519
  `struct PBRFragmentInputs {
3646
5520
  pbr_vPosition: vec3f,
3647
5521
  pbr_vUV: vec2f,
3648
- pbr_vTBN: mat3f,
5522
+ pbr_vTBN: mat3x3f,
3649
5523
  pbr_vNormal: vec3f
3650
5524
  };
3651
5525
 
3652
- var fragmentInputs: PBRFragmentInputs;
5526
+ var<private> fragmentInputs: PBRFragmentInputs;
3653
5527
 
3654
5528
  fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
3655
5529
  {
3656
5530
  var pos: vec4f = pbrProjection.modelMatrix * position;
3657
- fragmentInputs.pbr_vPosition = vec3(pos.xyz) / pos.w;
5531
+ fragmentInputs.pbr_vPosition = pos.xyz / pos.w;
5532
+ fragmentInputs.pbr_vNormal = vec3f(0.0, 0.0, 1.0);
5533
+ fragmentInputs.pbr_vTBN = mat3x3f(
5534
+ vec3f(1.0, 0.0, 0.0),
5535
+ vec3f(0.0, 1.0, 0.0),
5536
+ vec3f(0.0, 0.0, 1.0)
5537
+ );
5538
+ fragmentInputs.pbr_vUV = vec2f(0.0, 0.0);
3658
5539
 
3659
5540
  #ifdef HAS_NORMALS
5541
+ let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);
5542
+ fragmentInputs.pbr_vNormal = normalW;
3660
5543
  #ifdef HAS_TANGENTS
3661
- let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
3662
- let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
5544
+ let tangentW: vec3f = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
3663
5545
  let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;
3664
- fragmentInputs.pbr_vTBN = mat3(tangentW, bitangentW, normalW);
3665
- #else // HAS_TANGENTS != 1
3666
- fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
5546
+ fragmentInputs.pbr_vTBN = mat3x3f(tangentW, bitangentW, normalW);
3667
5547
  #endif
3668
5548
  #endif
3669
5549
 
3670
5550
  #ifdef HAS_UV
3671
5551
  fragmentInputs.pbr_vUV = uv;
3672
- #else
3673
- fragmentInputs.pbr_vUV = vec2(0.,0.);
3674
5552
  #endif
3675
5553
  }
3676
5554
 
3677
5555
  struct pbrMaterialUniforms {
3678
5556
  // Material is unlit
3679
- unlit: uint32,
5557
+ unlit: u32,
3680
5558
 
3681
5559
  // Base color map
3682
- baseColorMapEnabled: uint32,
5560
+ baseColorMapEnabled: u32,
3683
5561
  baseColorFactor: vec4f,
3684
5562
 
3685
- normalMapEnabled : uint32,
5563
+ normalMapEnabled : u32,
3686
5564
  normalScale: f32, // #ifdef HAS_NORMALMAP
3687
5565
 
3688
- emissiveMapEnabled: uint32,
5566
+ emissiveMapEnabled: u32,
3689
5567
  emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP
3690
5568
 
3691
5569
  metallicRoughnessValues: vec2f,
3692
- metallicRoughnessMapEnabled: uint32,
5570
+ metallicRoughnessMapEnabled: u32,
3693
5571
 
3694
5572
  occlusionMapEnabled: i32,
3695
5573
  occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP
@@ -3704,7 +5582,7 @@ struct pbrMaterialUniforms {
3704
5582
  // debugging flags used for shader output of intermediate PBR variables
3705
5583
  // #ifdef PBR_DEBUG
3706
5584
  scaleDiffBaseMR: vec4f,
3707
- scaleFGDSpec: vec4f
5585
+ scaleFGDSpec: vec4f,
3708
5586
  // #endif
3709
5587
  }
3710
5588
 
@@ -3712,24 +5590,32 @@ struct pbrMaterialUniforms {
3712
5590
 
3713
5591
  // Samplers
3714
5592
  #ifdef HAS_BASECOLORMAP
3715
- uniform sampler2D pbr_baseColorSampler;
5593
+ @binding(3) @group(0) var pbr_baseColorSampler: texture_2d<f32>;
5594
+ @binding(4) @group(0) var pbr_baseColorSamplerSampler: sampler;
3716
5595
  #endif
3717
5596
  #ifdef HAS_NORMALMAP
3718
- uniform sampler2D pbr_normalSampler;
5597
+ @binding(5) @group(0) var pbr_normalSampler: texture_2d<f32>;
5598
+ @binding(6) @group(0) var pbr_normalSamplerSampler: sampler;
3719
5599
  #endif
3720
5600
  #ifdef HAS_EMISSIVEMAP
3721
- uniform sampler2D pbr_emissiveSampler;
5601
+ @binding(7) @group(0) var pbr_emissiveSampler: texture_2d<f32>;
5602
+ @binding(8) @group(0) var pbr_emissiveSamplerSampler: sampler;
3722
5603
  #endif
3723
5604
  #ifdef HAS_METALROUGHNESSMAP
3724
- uniform sampler2D pbr_metallicRoughnessSampler;
5605
+ @binding(9) @group(0) var pbr_metallicRoughnessSampler: texture_2d<f32>;
5606
+ @binding(10) @group(0) var pbr_metallicRoughnessSamplerSampler: sampler;
3725
5607
  #endif
3726
5608
  #ifdef HAS_OCCLUSIONMAP
3727
- uniform sampler2D pbr_occlusionSampler;
5609
+ @binding(11) @group(0) var pbr_occlusionSampler: texture_2d<f32>;
5610
+ @binding(12) @group(0) var pbr_occlusionSamplerSampler: sampler;
3728
5611
  #endif
3729
5612
  #ifdef USE_IBL
3730
- uniform samplerCube pbr_diffuseEnvSampler;
3731
- uniform samplerCube pbr_specularEnvSampler;
3732
- uniform sampler2D pbr_brdfLUT;
5613
+ @binding(13) @group(0) var pbr_diffuseEnvSampler: texture_cube<f32>;
5614
+ @binding(14) @group(0) var pbr_diffuseEnvSamplerSampler: sampler;
5615
+ @binding(15) @group(0) var pbr_specularEnvSampler: texture_cube<f32>;
5616
+ @binding(16) @group(0) var pbr_specularEnvSamplerSampler: sampler;
5617
+ @binding(17) @group(0) var pbr_BrdfLUT: texture_2d<f32>;
5618
+ @binding(18) @group(0) var pbr_BrdfLUTSampler: sampler;
3733
5619
  #endif
3734
5620
 
3735
5621
  // Encapsulate the various inputs used by the various functions in the shading equation
@@ -3757,17 +5643,19 @@ const c_MinRoughness = 0.04;
3757
5643
 
3758
5644
  fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
3759
5645
  {
5646
+ var linOut: vec3f = srgbIn.xyz;
3760
5647
  #ifdef MANUAL_SRGB
5648
+ let bLess: vec3f = step(vec3f(0.04045), srgbIn.xyz);
5649
+ linOut = mix(
5650
+ srgbIn.xyz / vec3f(12.92),
5651
+ pow((srgbIn.xyz + vec3f(0.055)) / vec3f(1.055), vec3f(2.4)),
5652
+ bLess
5653
+ );
3761
5654
  #ifdef SRGB_FAST_APPROXIMATION
3762
- var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));
3763
- #else // SRGB_FAST_APPROXIMATION
3764
- var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);
3765
- var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
3766
- #endif //SRGB_FAST_APPROXIMATION
3767
- return vec4f(linOut,srgbIn.w);;
3768
- #else //MANUAL_SRGB
3769
- return srgbIn;
3770
- #endif //MANUAL_SRGB
5655
+ linOut = pow(srgbIn.xyz, vec3f(2.2));
5656
+ #endif
5657
+ #endif
5658
+ return vec4f(linOut, srgbIn.w);
3771
5659
  }
3772
5660
 
3773
5661
  // Find the normal for this fragment, pulling either from a predefined normal map
@@ -3775,32 +5663,28 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
3775
5663
  fn getNormal() -> vec3f
3776
5664
  {
3777
5665
  // Retrieve the tangent space matrix
3778
- #ifndef HAS_TANGENTS
3779
- var pos_dx: vec3f = dFdx(fragmentInputs.pbr_vPosition);
3780
- var pos_dy: vec3f = dFdy(fragmentInputs.pbr_vPosition);
3781
- var tex_dx: vec3f = dFdx(vec3(fragmentInputs.pbr_vUV, 0.0));
3782
- var tex_dy: vec3f = dFdy(vec3(fragmentInputs.pbr_vUV, 0.0));
3783
- var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
5666
+ let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
5667
+ let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
5668
+ let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
5669
+ let tex_dy: vec3f = dpdy(vec3f(fragmentInputs.pbr_vUV, 0.0));
5670
+ var t: vec3f = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);
3784
5671
 
3785
- #ifdef HAS_NORMALS
3786
- var ng: vec3f = normalize(fragmentInputs.pbr_vNormal);
3787
- #else
3788
5672
  var ng: vec3f = cross(pos_dx, pos_dy);
5673
+ #ifdef HAS_NORMALS
5674
+ ng = normalize(fragmentInputs.pbr_vNormal);
3789
5675
  #endif
3790
-
3791
5676
  t = normalize(t - ng * dot(ng, t));
3792
5677
  var b: vec3f = normalize(cross(ng, t));
3793
- var tbn: mat3f = mat3f(t, b, ng);
3794
- #else // HAS_TANGENTS
3795
- var tbn: mat3f = fragmentInputs.pbr_vTBN;
5678
+ var tbn: mat3x3f = mat3x3f(t, b, ng);
5679
+ #ifdef HAS_TANGENTS
5680
+ tbn = fragmentInputs.pbr_vTBN;
3796
5681
  #endif
3797
5682
 
3798
- #ifdef HAS_NORMALMAP
3799
- vec3 n = texture(pbr_normalSampler, fragmentInputs.pbr_vUV).rgb;
3800
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
3801
- #else
3802
5683
  // The tbn matrix is linearly interpolated, so we need to re-normalize
3803
- vec3 n = normalize(tbn[2].xyz);
5684
+ var n: vec3f = normalize(tbn[2].xyz);
5685
+ #ifdef HAS_NORMALMAP
5686
+ n = textureSample(pbr_normalSampler, pbr_normalSamplerSampler, fragmentInputs.pbr_vUV).rgb;
5687
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3f(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
3804
5688
  #endif
3805
5689
 
3806
5690
  return n;
@@ -3810,27 +5694,37 @@ fn getNormal() -> vec3f
3810
5694
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
3811
5695
  // See our README.md on Environment Maps [3] for additional discussion.
3812
5696
  #ifdef USE_IBL
3813
- fn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f
5697
+ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
3814
5698
  {
3815
- float mipCount = 9.0; // resolution of 512x512
3816
- float lod = (pbrInfo.perceptualRoughness * mipCount);
5699
+ let mipCount: f32 = 9.0; // resolution of 512x512
5700
+ let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
3817
5701
  // retrieve a scale and bias to F0. See [1], Figure 3
3818
- vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
3819
- vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
3820
- vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
3821
-
5702
+ let brdf = SRGBtoLINEAR(
5703
+ textureSample(
5704
+ pbr_BrdfLUT,
5705
+ pbr_BrdfLUTSampler,
5706
+ vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
5707
+ )
5708
+ ).rgb;
5709
+ let diffuseLight =
5710
+ SRGBtoLINEAR(textureSample(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n)).rgb;
5711
+ let specularLightDefault =
5712
+ SRGBtoLINEAR(textureSample(pbr_specularEnvSampler, pbr_specularEnvSamplerSampler, reflection)).rgb;
5713
+ var specularLight = specularLightDefault;
3822
5714
  #ifdef USE_TEX_LOD
3823
- vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
3824
- #else
3825
- vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
5715
+ specularLight = SRGBtoLINEAR(
5716
+ textureSampleLevel(
5717
+ pbr_specularEnvSampler,
5718
+ pbr_specularEnvSamplerSampler,
5719
+ reflection,
5720
+ lod
5721
+ )
5722
+ ).rgb;
3826
5723
  #endif
3827
5724
 
3828
- vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
3829
- vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
3830
-
3831
- // For presentation, this allows us to disable IBL terms
3832
- diffuse *= pbrMaterial.scaleIBLAmbient.x;
3833
- specular *= pbrMaterial.scaleIBLAmbient.y;
5725
+ let diffuse = diffuseLight * pbrInfo.diffuseColor * pbrMaterial.scaleIBLAmbient.x;
5726
+ let specular =
5727
+ specularLight * (pbrInfo.specularColor * brdf.x + brdf.y) * pbrMaterial.scaleIBLAmbient.y;
3834
5728
 
3835
5729
  return diffuse + specular;
3836
5730
  }
@@ -3874,7 +5768,7 @@ fn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {
3874
5768
  fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
3875
5769
  let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
3876
5770
  let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
3877
- return roughnessSq / (PI * f * f);
5771
+ return roughnessSq / (M_PI * f * f);
3878
5772
  }
3879
5773
 
3880
5774
  fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
@@ -3916,11 +5810,11 @@ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
3916
5810
 
3917
5811
  fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3918
5812
  // The albedo may be defined from a base texture or a flat color
3919
- var baseColor: vec4<f32>;
5813
+ var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;
3920
5814
  #ifdef HAS_BASECOLORMAP
3921
- baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, fragmentInputs.pbr_vUV)) * pbrMaterial.baseColorFactor;
3922
- #else
3923
- baseColor = pbrMaterial.baseColorFactor;
5815
+ baseColor = SRGBtoLINEAR(
5816
+ textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, fragmentInputs.pbr_vUV)
5817
+ ) * pbrMaterial.baseColorFactor;
3924
5818
  #endif
3925
5819
 
3926
5820
  #ifdef ALPHA_CUTOFF
@@ -3931,7 +5825,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3931
5825
 
3932
5826
  var color = vec3<f32>(0.0, 0.0, 0.0);
3933
5827
 
3934
- if (pbrMaterial.unlit) {
5828
+ if (pbrMaterial.unlit != 0u) {
3935
5829
  color = baseColor.rgb;
3936
5830
  } else {
3937
5831
  // Metallic and Roughness material properties are packed together
@@ -3942,7 +5836,11 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3942
5836
  #ifdef HAS_METALROUGHNESSMAP
3943
5837
  // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
3944
5838
  // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
3945
- let mrSample = textureSample(pbr_metallicRoughnessSampler, pbr_metallicRoughnessSampler, fragmentInputs.pbr_vUV);
5839
+ let mrSample = textureSample(
5840
+ pbr_metallicRoughnessSampler,
5841
+ pbr_metallicRoughnessSamplerSampler,
5842
+ fragmentInputs.pbr_vUV
5843
+ );
3946
5844
  perceptualRoughness = mrSample.g * perceptualRoughness;
3947
5845
  metallic = mrSample.b * metallic;
3948
5846
  #endif
@@ -4019,22 +5917,25 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4019
5917
 
4020
5918
  // Calculate lighting contribution from image based lighting source (IBL)
4021
5919
  #ifdef USE_IBL
4022
- if (pbrMaterial.IBLenabled) {
5920
+ if (pbrMaterial.IBLenabled != 0) {
4023
5921
  color += getIBLContribution(pbrInfo, n, reflection);
4024
5922
  }
4025
5923
  #endif
4026
5924
 
4027
5925
  // Apply optional PBR terms for additional (optional) shading
4028
5926
  #ifdef HAS_OCCLUSIONMAP
4029
- if (pbrMaterial.occlusionMapEnabled) {
4030
- let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSampler, fragmentInputs.pbr_vUV).r;
5927
+ if (pbrMaterial.occlusionMapEnabled != 0) {
5928
+ let ao =
5929
+ textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
4031
5930
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
4032
5931
  }
4033
5932
  #endif
4034
5933
 
4035
5934
  #ifdef HAS_EMISSIVEMAP
4036
- if (pbrMaterial.emissiveMapEnabled) {
4037
- let emissive = SRGBtoLINEAR(textureSample(pbr_emissiveSampler, pbr_emissiveSampler, fragmentInputs.pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
5935
+ if (pbrMaterial.emissiveMapEnabled != 0u) {
5936
+ let emissive = SRGBtoLINEAR(
5937
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
5938
+ ).rgb * pbrMaterial.emissiveFactor;
4038
5939
  color += emissive;
4039
5940
  }
4040
5941
  #endif
@@ -4070,10 +5971,23 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4070
5971
  mat4 normalMatrix;
4071
5972
  vec3 camera;
4072
5973
  } pbrProjection;
5974
+ `
5975
+ );
5976
+ var wgslUniformBlock = (
5977
+ /* wgsl */
5978
+ `struct pbrProjectionUniforms {
5979
+ modelViewProjectionMatrix: mat4x4<f32>,
5980
+ modelMatrix: mat4x4<f32>,
5981
+ normalMatrix: mat4x4<f32>,
5982
+ camera: vec3<f32>
5983
+ };
5984
+
5985
+ @binding(0) @group(0) var<uniform> pbrProjection: pbrProjectionUniforms;
4073
5986
  `
4074
5987
  );
4075
5988
  var pbrProjection = {
4076
5989
  name: "pbrProjection",
5990
+ source: wgslUniformBlock,
4077
5991
  vs: uniformBlock,
4078
5992
  fs: uniformBlock,
4079
5993
  // TODO why is this needed?
@@ -4082,7 +5996,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4082
5996
  modelViewProjectionMatrix: "mat4x4<f32>",
4083
5997
  modelMatrix: "mat4x4<f32>",
4084
5998
  normalMatrix: "mat4x4<f32>",
4085
- camera: "vec3<i32>"
5999
+ camera: "vec3<f32>"
4086
6000
  }
4087
6001
  };
4088
6002
 
@@ -4092,9 +6006,9 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4092
6006
  uniforms: {},
4093
6007
  name: "pbrMaterial",
4094
6008
  dependencies: [lighting, pbrProjection],
4095
- source: source2,
4096
- vs: vs2,
4097
- fs: fs3,
6009
+ source: source3,
6010
+ vs: vs3,
6011
+ fs: fs4,
4098
6012
  defines: {
4099
6013
  LIGHTING_FRAGMENT: true,
4100
6014
  HAS_NORMALMAP: false,