@luma.gl/shadertools 9.3.0-alpha.2 → 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 (66) hide show
  1. package/dist/dist.dev.js +2114 -198
  2. package/dist/dist.min.js +315 -184
  3. package/dist/index.cjs +463 -199
  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/lib/utils/assert.d.ts.map +1 -1
  18. package/dist/lib/utils/assert.js +3 -1
  19. package/dist/lib/utils/assert.js.map +1 -1
  20. package/dist/modules/engine/skin/skin.d.ts +29 -0
  21. package/dist/modules/engine/skin/skin.d.ts.map +1 -0
  22. package/dist/modules/engine/skin/skin.js +88 -0
  23. package/dist/modules/engine/skin/skin.js.map +1 -0
  24. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  25. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  26. package/dist/modules/lighting/lights/lighting-glsl.js +20 -2
  27. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
  28. package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
  29. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
  30. package/dist/modules/lighting/lights/lighting-wgsl.js +63 -13
  31. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
  32. package/dist/modules/lighting/lights/lighting.d.ts +27 -3
  33. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  34. package/dist/modules/lighting/lights/lighting.js +32 -6
  35. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  36. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  37. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  38. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +106 -79
  39. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  40. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +20 -4
  41. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  42. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  43. package/dist/modules/lighting/pbr-material/pbr-projection.js +12 -1
  44. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  45. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -40
  46. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
  47. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +40 -76
  48. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
  49. package/dist/modules/math/random/random.d.ts +1 -1
  50. package/dist/modules/math/random/random.d.ts.map +1 -1
  51. package/dist/modules/math/random/random.js +2 -3
  52. package/dist/modules/math/random/random.js.map +1 -1
  53. package/package.json +2 -2
  54. package/src/index.ts +1 -0
  55. package/src/lib/preprocessor/preprocessor.ts +40 -7
  56. package/src/lib/shader-assembler.ts +8 -1
  57. package/src/lib/shader-module/shader-module.ts +1 -1
  58. package/src/lib/utils/assert.ts +3 -1
  59. package/src/modules/engine/skin/skin.ts +116 -0
  60. package/src/modules/lighting/lights/lighting-glsl.ts +20 -2
  61. package/src/modules/lighting/lights/lighting-wgsl.ts +63 -13
  62. package/src/modules/lighting/lights/lighting.ts +45 -9
  63. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +106 -79
  64. package/src/modules/lighting/pbr-material/pbr-projection.ts +13 -1
  65. package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +40 -77
  66. 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
@@ -94,7 +95,9 @@ var __exports__ = (() => {
94
95
  // src/lib/utils/assert.ts
95
96
  function assert(condition, message) {
96
97
  if (!condition) {
97
- throw new Error(message || "shadertools: assertion failed.");
98
+ const error = new Error(message || "shadertools: assertion failed.");
99
+ Error.captureStackTrace?.(error, assert);
100
+ throw error;
98
101
  }
99
102
  }
100
103
 
@@ -232,7 +235,7 @@ var __exports__ = (() => {
232
235
  throw new Error(type);
233
236
  }
234
237
  }
235
- function injectShader(source3, stage, inject, injectStandardStubs = false) {
238
+ function injectShader(source4, stage, inject, injectStandardStubs = false) {
236
239
  const isVertex = stage === "vertex";
237
240
  for (const key in inject) {
238
241
  const fragmentData = inject[key];
@@ -246,43 +249,43 @@ var __exports__ = (() => {
246
249
  switch (key) {
247
250
  case "vs:#decl":
248
251
  if (isVertex) {
249
- source3 = source3.replace(DECLARATION_INJECT_MARKER, fragmentString);
252
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
250
253
  }
251
254
  break;
252
255
  case "vs:#main-start":
253
256
  if (isVertex) {
254
- source3 = source3.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
257
+ source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
255
258
  }
256
259
  break;
257
260
  case "vs:#main-end":
258
261
  if (isVertex) {
259
- source3 = source3.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
262
+ source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
260
263
  }
261
264
  break;
262
265
  case "fs:#decl":
263
266
  if (!isVertex) {
264
- source3 = source3.replace(DECLARATION_INJECT_MARKER, fragmentString);
267
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
265
268
  }
266
269
  break;
267
270
  case "fs:#main-start":
268
271
  if (!isVertex) {
269
- source3 = source3.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
272
+ source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
270
273
  }
271
274
  break;
272
275
  case "fs:#main-end":
273
276
  if (!isVertex) {
274
- source3 = source3.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
277
+ source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
275
278
  }
276
279
  break;
277
280
  default:
278
- source3 = source3.replace(key, (match) => match + fragmentString);
281
+ source4 = source4.replace(key, (match) => match + fragmentString);
279
282
  }
280
283
  }
281
- source3 = source3.replace(DECLARATION_INJECT_MARKER, "");
284
+ source4 = source4.replace(DECLARATION_INJECT_MARKER, "");
282
285
  if (injectStandardStubs) {
283
- source3 = source3.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]);
286
+ source4 = source4.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]);
284
287
  }
285
- return source3;
288
+ return source4;
286
289
  }
287
290
  function combineInjects(injects) {
288
291
  const result = {};
@@ -462,18 +465,18 @@ ${inject[key]}` : inject[key];
462
465
  }
463
466
 
464
467
  // src/lib/shader-transpiler/transpile-glsl-shader.ts
465
- function transpileGLSLShader(source3, stage) {
466
- 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);
467
470
  if (sourceGLSLVersion !== 300) {
468
471
  throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");
469
472
  }
470
473
  switch (stage) {
471
474
  case "vertex":
472
- source3 = convertShader(source3, ES300_VERTEX_REPLACEMENTS);
473
- return source3;
475
+ source4 = convertShader(source4, ES300_VERTEX_REPLACEMENTS);
476
+ return source4;
474
477
  case "fragment":
475
- source3 = convertShader(source3, ES300_FRAGMENT_REPLACEMENTS);
476
- return source3;
478
+ source4 = convertShader(source4, ES300_FRAGMENT_REPLACEMENTS);
479
+ return source4;
477
480
  default:
478
481
  throw new Error(stage);
479
482
  }
@@ -497,11 +500,11 @@ ${inject[key]}` : inject[key];
497
500
  // `varying` keyword replaced with `in`
498
501
  [makeVariableTextRegExp("varying"), "in $1"]
499
502
  ];
500
- function convertShader(source3, replacements) {
503
+ function convertShader(source4, replacements) {
501
504
  for (const [pattern, replacement] of replacements) {
502
- source3 = source3.replace(pattern, replacement);
505
+ source4 = source4.replace(pattern, replacement);
503
506
  }
504
- return source3;
507
+ return source4;
505
508
  }
506
509
  function makeVariableTextRegExp(qualifier) {
507
510
  return new RegExp(`\\b${qualifier}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`, "g");
@@ -563,11 +566,11 @@ ${inject[key]}` : inject[key];
563
566
  }
564
567
 
565
568
  // src/lib/glsl-utils/get-shader-info.ts
566
- function getShaderInfo(source3, defaultName) {
569
+ function getShaderInfo(source4, defaultName) {
567
570
  return {
568
- name: getShaderName(source3, defaultName),
571
+ name: getShaderName(source4, defaultName),
569
572
  language: "glsl",
570
- version: getShaderVersion(source3)
573
+ version: getShaderVersion(source4)
571
574
  };
572
575
  }
573
576
  function getShaderName(shader, defaultName = "unnamed") {
@@ -575,9 +578,9 @@ ${inject[key]}` : inject[key];
575
578
  const match = SHADER_NAME_REGEXP.exec(shader);
576
579
  return match ? match[1] : defaultName;
577
580
  }
578
- function getShaderVersion(source3) {
581
+ function getShaderVersion(source4) {
579
582
  let version = 100;
580
- const words = source3.match(/[^\s]+/g);
583
+ const words = source4.match(/[^\s]+/g);
581
584
  if (words && words.length >= 2 && words[0] === "#version") {
582
585
  const parsedVersion = parseInt(words[1], 10);
583
586
  if (Number.isFinite(parsedVersion)) {
@@ -613,19 +616,19 @@ ${DECLARATION_INJECT_MARKER}
613
616
  };
614
617
  }
615
618
  function assembleGLSLShaderPair(options) {
616
- const { vs: vs3, fs: fs4 } = options;
619
+ const { vs: vs4, fs: fs5 } = options;
617
620
  const modules = getShaderModuleDependencies(options.modules || []);
618
621
  return {
619
622
  vs: assembleShaderGLSL(options.platformInfo, {
620
623
  ...options,
621
- source: vs3,
624
+ source: vs4,
622
625
  stage: "vertex",
623
626
  modules
624
627
  }),
625
628
  fs: assembleShaderGLSL(options.platformInfo, {
626
629
  ...options,
627
630
  // @ts-expect-error
628
- source: fs4,
631
+ source: fs5,
629
632
  stage: "fragment",
630
633
  modules
631
634
  }),
@@ -635,7 +638,7 @@ ${DECLARATION_INJECT_MARKER}
635
638
  function assembleShaderWGSL(platformInfo, options) {
636
639
  const {
637
640
  // id,
638
- source: source3,
641
+ source: source4,
639
642
  stage,
640
643
  modules,
641
644
  // defines = {},
@@ -643,8 +646,8 @@ ${DECLARATION_INJECT_MARKER}
643
646
  inject = {},
644
647
  log: log2
645
648
  } = options;
646
- assert(typeof source3 === "string", "shader source must be a string");
647
- const coreSource = source3;
649
+ assert(typeof source4 === "string", "shader source must be a string");
650
+ const coreSource = source4;
648
651
  let assembledSource = "";
649
652
  const hookFunctionMap = normalizeShaderHooks(hookFunctions);
650
653
  const hookInjections = {};
@@ -699,7 +702,7 @@ ${DECLARATION_INJECT_MARKER}
699
702
  }
700
703
  function assembleShaderGLSL(platformInfo, options) {
701
704
  const {
702
- source: source3,
705
+ source: source4,
703
706
  stage,
704
707
  language = "glsl",
705
708
  modules,
@@ -709,11 +712,11 @@ ${DECLARATION_INJECT_MARKER}
709
712
  prologue = true,
710
713
  log: log2
711
714
  } = options;
712
- assert(typeof source3 === "string", "shader source must be a string");
713
- 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;
714
717
  const targetVersion = platformInfo.shaderLanguageVersion;
715
718
  const sourceVersionDirective = sourceVersion === 100 ? "#version 100" : "#version 300 es";
716
- const sourceLines = source3.split("\n");
719
+ const sourceLines = source4.split("\n");
717
720
  const coreSource = sourceLines.slice(1).join("\n");
718
721
  const allDefines = {};
719
722
  modules.forEach((module) => {
@@ -835,38 +838,60 @@ ${getApplicationDefines(allDefines)}
835
838
  throw new Error("Shader module must have a name");
836
839
  }
837
840
  const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, "_");
838
- let source3 = `// ----- MODULE ${module.name} ---------------
841
+ let source4 = `// ----- MODULE ${module.name} ---------------
839
842
 
840
843
  `;
841
844
  if (stage !== "wgsl") {
842
- source3 += `#define MODULE_${moduleName}
845
+ source4 += `#define MODULE_${moduleName}
843
846
  `;
844
847
  }
845
- source3 += `${moduleSource}
848
+ source4 += `${moduleSource}
846
849
  `;
847
- return source3;
850
+ return source4;
848
851
  }
849
852
 
850
853
  // src/lib/preprocessor/preprocessor.ts
851
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*(?:\/\/.*)?$/;
852
857
  var ENDIF_REGEXP = /^\s*\#\s*endif\s*$/;
853
- function preprocess(source3, options) {
854
- 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");
855
862
  const output = [];
863
+ const conditionalStack = [];
856
864
  let conditional = true;
857
- let currentDefine = null;
858
865
  for (const line of lines) {
859
- const matchIf = line.match(IFDEF_REGEXP);
860
- const matchEnd = line.match(ENDIF_REGEXP);
861
- if (matchIf) {
862
- currentDefine = matchIf[1];
863
- 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;
864
885
  } else if (matchEnd) {
865
- conditional = true;
886
+ conditionalStack.pop();
887
+ conditional = conditionalStack.length ? conditionalStack[conditionalStack.length - 1].active : true;
866
888
  } else if (conditional) {
867
889
  output.push(line);
868
890
  }
869
891
  }
892
+ if (conditionalStack.length > 0) {
893
+ throw new Error("Unterminated conditional block in shader source");
894
+ }
870
895
  return output.join("\n");
871
896
  }
872
897
 
@@ -921,14 +946,21 @@ ${getApplicationDefines(allDefines)}
921
946
  assembleWGSLShader(props) {
922
947
  const modules = this._getModuleList(props.modules);
923
948
  const hookFunctions = this._hookFunctions;
924
- const { source: source3, getUniforms: getUniforms4 } = assembleWGSLShader({
949
+ const { source: source4, getUniforms: getUniforms4 } = assembleWGSLShader({
925
950
  ...props,
926
951
  // @ts-expect-error
927
952
  source: props.source,
928
953
  modules,
929
954
  hookFunctions
930
955
  });
931
- 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;
932
964
  return { source: preprocessedSource, getUniforms: getUniforms4, modules };
933
965
  }
934
966
  /**
@@ -1186,12 +1218,53 @@ void main() {
1186
1218
  };
1187
1219
  globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
1188
1220
  var config = globalThis.mathgl.config;
1221
+ function formatValue(value, { precision = config.precision } = {}) {
1222
+ value = round(value);
1223
+ return `${parseFloat(value.toPrecision(precision))}`;
1224
+ }
1189
1225
  function isArray(value) {
1190
1226
  return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
1191
1227
  }
1192
1228
  function clamp(value, min, max) {
1193
1229
  return map(value, (value2) => Math.max(min, Math.min(max, value2)));
1194
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
+ }
1195
1268
  function duplicateArray(array) {
1196
1269
  return array.clone ? array.clone() : new Array(array.length);
1197
1270
  }
@@ -1208,6 +1281,1620 @@ void main() {
1208
1281
  return func(value);
1209
1282
  }
1210
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
+
1211
2898
  // src/modules/math/fp16/fp16-utils.ts
1212
2899
  var float16Tables = null;
1213
2900
  var buffer = new ArrayBuffer(4);
@@ -1318,9 +3005,8 @@ void main() {
1318
3005
  // src/modules/math/random/random.ts
1319
3006
  var source = (
1320
3007
  /* wgsl */
1321
- `fn random(scale: vec3f, seed: float) -> f32 {
1322
- /* use the fragment position for a different seed per-pixel */
1323
- 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);
1324
3010
  }
1325
3011
  `
1326
3012
  );
@@ -2560,8 +4246,100 @@ vec4 picking_filterColor(vec4 color) {
2560
4246
  return uniforms;
2561
4247
  }
2562
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
+
2563
4341
  // src/modules/lighting/lights/lighting.ts
2564
- var import_core2 = __toESM(require_core(), 1);
4342
+ var import_core3 = __toESM(require_core(), 1);
2565
4343
 
2566
4344
  // src/modules/lighting/lights/lighting-glsl.ts
2567
4345
  var lightingUniformsGLSL = (
@@ -2607,6 +4385,16 @@ uniform lightingUniforms {
2607
4385
  vec3 lightPosition2;
2608
4386
  vec3 lightDirection2;
2609
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;
2610
4398
  } lighting;
2611
4399
 
2612
4400
  PointLight lighting_getPointLight(int index) {
@@ -2616,8 +4404,12 @@ PointLight lighting_getPointLight(int index) {
2616
4404
  case 1:
2617
4405
  return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
2618
4406
  case 2:
2619
- default:
2620
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);
2621
4413
  }
2622
4414
  }
2623
4415
 
@@ -2628,8 +4420,12 @@ DirectionalLight lighting_getDirectionalLight(int index) {
2628
4420
  case 1:
2629
4421
  return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
2630
4422
  case 2:
2631
- default:
2632
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);
2633
4429
  }
2634
4430
  }
2635
4431
 
@@ -2647,6 +4443,8 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
2647
4443
  var lightingUniformsWGSL = (
2648
4444
  /* wgsl */
2649
4445
  `// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
4446
+ const MAX_LIGHTS: i32 = 5;
4447
+
2650
4448
  struct AmbientLight {
2651
4449
  color: vec3<f32>,
2652
4450
  };
@@ -2664,32 +4462,80 @@ struct DirectionalLight {
2664
4462
 
2665
4463
  struct lightingUniforms {
2666
4464
  enabled: i32,
2667
- pointLightCount: i32,
4465
+ lightType: i32,
4466
+
2668
4467
  directionalLightCount: i32,
4468
+ pointLightCount: i32,
2669
4469
 
2670
4470
  ambientColor: vec3<f32>,
2671
4471
 
2672
- // TODO - support multiple lights by uncommenting arrays below
2673
- lightType: i32,
2674
- lightColor: vec3<f32>,
2675
- lightDirection: vec3<f32>,
2676
- lightPosition: vec3<f32>,
2677
- lightAttenuation: vec3<f32>,
2678
-
2679
- // AmbientLight ambientLight;
2680
- // PointLight pointLight[MAX_LIGHTS];
2681
- // 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>,
2682
4496
  };
2683
4497
 
2684
4498
  // Binding 0:1 is reserved for lighting (Note: could go into separate bind group as it is stable across draw calls)
2685
4499
  @binding(1) @group(0) var<uniform> lighting : lightingUniforms;
2686
4500
 
2687
4501
  fn lighting_getPointLight(index: i32) -> PointLight {
2688
- 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
+ }
2689
4519
  }
2690
4520
 
2691
4521
  fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
2692
- 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
+ }
2693
4539
  }
2694
4540
 
2695
4541
  fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
@@ -2729,7 +4575,15 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2729
4575
  lightColor2: "vec3<f32>",
2730
4576
  lightPosition2: "vec3<f32>",
2731
4577
  lightDirection2: "vec3<f32>",
2732
- 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>"
2733
4587
  },
2734
4588
  defaultUniforms: {
2735
4589
  enabled: 1,
@@ -2749,7 +4603,15 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2749
4603
  lightColor2: [1, 1, 1],
2750
4604
  lightPosition2: [1, 1, 2],
2751
4605
  lightDirection2: [1, 1, 1],
2752
- 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]
2753
4615
  },
2754
4616
  source: lightingUniformsWGSL,
2755
4617
  vs: lightingUniformsGLSL,
@@ -2787,26 +4649,36 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
2787
4649
  const lightSourceUniforms = {};
2788
4650
  lightSourceUniforms.ambientColor = convertColor(ambientLight);
2789
4651
  let currentLight = 0;
4652
+ let pointLightCount = 0;
4653
+ let directionalLightCount = 0;
2790
4654
  for (const pointLight of pointLights) {
4655
+ if (currentLight >= MAX_LIGHTS) {
4656
+ break;
4657
+ }
2791
4658
  lightSourceUniforms.lightType = 0 /* POINT */;
2792
4659
  const i = currentLight;
2793
4660
  lightSourceUniforms[`lightColor${i}`] = convertColor(pointLight);
2794
4661
  lightSourceUniforms[`lightPosition${i}`] = pointLight.position;
2795
4662
  lightSourceUniforms[`lightAttenuation${i}`] = pointLight.attenuation || [1, 0, 0];
2796
4663
  currentLight++;
4664
+ pointLightCount++;
2797
4665
  }
2798
4666
  for (const directionalLight of directionalLights) {
4667
+ if (currentLight >= MAX_LIGHTS) {
4668
+ break;
4669
+ }
2799
4670
  lightSourceUniforms.lightType = 1 /* DIRECTIONAL */;
2800
4671
  const i = currentLight;
2801
4672
  lightSourceUniforms[`lightColor${i}`] = convertColor(directionalLight);
2802
4673
  lightSourceUniforms[`lightDirection${i}`] = directionalLight.direction;
2803
4674
  currentLight++;
4675
+ directionalLightCount++;
2804
4676
  }
2805
- if (currentLight > MAX_LIGHTS) {
2806
- 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}`)();
2807
4679
  }
2808
- lightSourceUniforms.directionalLightCount = directionalLights.length;
2809
- lightSourceUniforms.pointLightCount = pointLights.length;
4680
+ lightSourceUniforms.directionalLightCount = directionalLightCount;
4681
+ lightSourceUniforms.pointLightCount = pointLightCount;
2810
4682
  return lightSourceUniforms;
2811
4683
  }
2812
4684
  function extractLightTypes(lights) {
@@ -3014,56 +4886,60 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
3014
4886
  let view_direction: vec3<f32> = normalize(cameraPosition - position_worldspace);
3015
4887
  lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor;
3016
4888
 
3017
- if (lighting.lightType == 0) {
3018
- let pointLight: PointLight = lighting_getPointLight(0);
4889
+ for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
4890
+ let pointLight: PointLight = lighting_getPointLight(i);
3019
4891
  let light_position_worldspace: vec3<f32> = pointLight.position;
3020
4892
  let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
3021
- lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color);
3022
- } else if (lighting.lightType == 1) {
3023
- var directionalLight: DirectionalLight = lighting_getDirectionalLight(0);
3024
- lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3025
- }
3026
-
3027
- return lightColor;
3028
- /*
3029
- for (int i = 0; i < MAX_LIGHTS; i++) {
3030
- if (i >= lighting.pointLightCount) {
3031
- break;
3032
- }
3033
- PointLight pointLight = lighting.pointLight[i];
3034
- vec3 light_position_worldspace = pointLight.position;
3035
- vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
3036
- 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
+ );
3037
4904
  }
3038
4905
 
3039
- for (int i = 0; i < MAX_LIGHTS; i++) {
3040
- if (i >= lighting.directionalLightCount) {
3041
- break;
3042
- }
3043
- 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);
3044
4909
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3045
- }
3046
- */
4910
+ }
4911
+
4912
+ return lightColor;
3047
4913
  }
3048
4914
 
3049
4915
  fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32>{
3050
4916
  var lightColor = vec3<f32>(0, 0, 0);
3051
4917
  let surfaceColor = vec3<f32>(0, 0, 0);
3052
4918
 
3053
- if (lighting.enabled == 0) {
4919
+ if (lighting.enabled != 0) {
3054
4920
  let view_direction = normalize(cameraPosition - position_worldspace);
3055
4921
 
3056
- switch (lighting.lightType) {
3057
- case 0, default: {
3058
- let pointLight: PointLight = lighting_getPointLight(0);
3059
- let light_position_worldspace: vec3<f32> = pointLight.position;
3060
- let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
3061
- lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color);
3062
- }
3063
- case 1: {
3064
- 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);
3065
4942
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
3066
- }
3067
4943
  }
3068
4944
  }
3069
4945
  return lightColor;
@@ -3137,7 +5013,7 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
3137
5013
  };
3138
5014
 
3139
5015
  // src/modules/lighting/pbr-material/pbr-material-glsl.ts
3140
- var vs2 = (
5016
+ var vs3 = (
3141
5017
  /* glsl */
3142
5018
  `out vec3 pbr_vPosition;
3143
5019
  out vec2 pbr_vUV;
@@ -3174,7 +5050,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
3174
5050
  }
3175
5051
  `
3176
5052
  );
3177
- var fs3 = (
5053
+ var fs4 = (
3178
5054
  /* glsl */
3179
5055
  `precision highp float;
3180
5056
 
@@ -3638,56 +5514,60 @@ vec4 pbr_filterColor(vec4 colorUnused)
3638
5514
  );
3639
5515
 
3640
5516
  // src/modules/lighting/pbr-material/pbr-material-wgsl.ts
3641
- var source2 = (
5517
+ var source3 = (
3642
5518
  /* wgsl */
3643
5519
  `struct PBRFragmentInputs {
3644
5520
  pbr_vPosition: vec3f,
3645
5521
  pbr_vUV: vec2f,
3646
- pbr_vTBN: mat3f,
5522
+ pbr_vTBN: mat3x3f,
3647
5523
  pbr_vNormal: vec3f
3648
5524
  };
3649
5525
 
3650
- var fragmentInputs: PBRFragmentInputs;
5526
+ var<private> fragmentInputs: PBRFragmentInputs;
3651
5527
 
3652
5528
  fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
3653
5529
  {
3654
5530
  var pos: vec4f = pbrProjection.modelMatrix * position;
3655
- 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);
3656
5539
 
3657
5540
  #ifdef HAS_NORMALS
5541
+ let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);
5542
+ fragmentInputs.pbr_vNormal = normalW;
3658
5543
  #ifdef HAS_TANGENTS
3659
- let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
3660
- 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);
3661
5545
  let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;
3662
- fragmentInputs.pbr_vTBN = mat3(tangentW, bitangentW, normalW);
3663
- #else // HAS_TANGENTS != 1
3664
- fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
5546
+ fragmentInputs.pbr_vTBN = mat3x3f(tangentW, bitangentW, normalW);
3665
5547
  #endif
3666
5548
  #endif
3667
5549
 
3668
5550
  #ifdef HAS_UV
3669
5551
  fragmentInputs.pbr_vUV = uv;
3670
- #else
3671
- fragmentInputs.pbr_vUV = vec2(0.,0.);
3672
5552
  #endif
3673
5553
  }
3674
5554
 
3675
5555
  struct pbrMaterialUniforms {
3676
5556
  // Material is unlit
3677
- unlit: uint32,
5557
+ unlit: u32,
3678
5558
 
3679
5559
  // Base color map
3680
- baseColorMapEnabled: uint32,
5560
+ baseColorMapEnabled: u32,
3681
5561
  baseColorFactor: vec4f,
3682
5562
 
3683
- normalMapEnabled : uint32,
5563
+ normalMapEnabled : u32,
3684
5564
  normalScale: f32, // #ifdef HAS_NORMALMAP
3685
5565
 
3686
- emissiveMapEnabled: uint32,
5566
+ emissiveMapEnabled: u32,
3687
5567
  emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP
3688
5568
 
3689
5569
  metallicRoughnessValues: vec2f,
3690
- metallicRoughnessMapEnabled: uint32,
5570
+ metallicRoughnessMapEnabled: u32,
3691
5571
 
3692
5572
  occlusionMapEnabled: i32,
3693
5573
  occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP
@@ -3702,7 +5582,7 @@ struct pbrMaterialUniforms {
3702
5582
  // debugging flags used for shader output of intermediate PBR variables
3703
5583
  // #ifdef PBR_DEBUG
3704
5584
  scaleDiffBaseMR: vec4f,
3705
- scaleFGDSpec: vec4f
5585
+ scaleFGDSpec: vec4f,
3706
5586
  // #endif
3707
5587
  }
3708
5588
 
@@ -3710,24 +5590,32 @@ struct pbrMaterialUniforms {
3710
5590
 
3711
5591
  // Samplers
3712
5592
  #ifdef HAS_BASECOLORMAP
3713
- uniform sampler2D pbr_baseColorSampler;
5593
+ @binding(3) @group(0) var pbr_baseColorSampler: texture_2d<f32>;
5594
+ @binding(4) @group(0) var pbr_baseColorSamplerSampler: sampler;
3714
5595
  #endif
3715
5596
  #ifdef HAS_NORMALMAP
3716
- uniform sampler2D pbr_normalSampler;
5597
+ @binding(5) @group(0) var pbr_normalSampler: texture_2d<f32>;
5598
+ @binding(6) @group(0) var pbr_normalSamplerSampler: sampler;
3717
5599
  #endif
3718
5600
  #ifdef HAS_EMISSIVEMAP
3719
- uniform sampler2D pbr_emissiveSampler;
5601
+ @binding(7) @group(0) var pbr_emissiveSampler: texture_2d<f32>;
5602
+ @binding(8) @group(0) var pbr_emissiveSamplerSampler: sampler;
3720
5603
  #endif
3721
5604
  #ifdef HAS_METALROUGHNESSMAP
3722
- uniform sampler2D pbr_metallicRoughnessSampler;
5605
+ @binding(9) @group(0) var pbr_metallicRoughnessSampler: texture_2d<f32>;
5606
+ @binding(10) @group(0) var pbr_metallicRoughnessSamplerSampler: sampler;
3723
5607
  #endif
3724
5608
  #ifdef HAS_OCCLUSIONMAP
3725
- uniform sampler2D pbr_occlusionSampler;
5609
+ @binding(11) @group(0) var pbr_occlusionSampler: texture_2d<f32>;
5610
+ @binding(12) @group(0) var pbr_occlusionSamplerSampler: sampler;
3726
5611
  #endif
3727
5612
  #ifdef USE_IBL
3728
- uniform samplerCube pbr_diffuseEnvSampler;
3729
- uniform samplerCube pbr_specularEnvSampler;
3730
- 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;
3731
5619
  #endif
3732
5620
 
3733
5621
  // Encapsulate the various inputs used by the various functions in the shading equation
@@ -3755,17 +5643,19 @@ const c_MinRoughness = 0.04;
3755
5643
 
3756
5644
  fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
3757
5645
  {
5646
+ var linOut: vec3f = srgbIn.xyz;
3758
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
+ );
3759
5654
  #ifdef SRGB_FAST_APPROXIMATION
3760
- var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));
3761
- #else // SRGB_FAST_APPROXIMATION
3762
- var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);
3763
- var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
3764
- #endif //SRGB_FAST_APPROXIMATION
3765
- return vec4f(linOut,srgbIn.w);;
3766
- #else //MANUAL_SRGB
3767
- return srgbIn;
3768
- #endif //MANUAL_SRGB
5655
+ linOut = pow(srgbIn.xyz, vec3f(2.2));
5656
+ #endif
5657
+ #endif
5658
+ return vec4f(linOut, srgbIn.w);
3769
5659
  }
3770
5660
 
3771
5661
  // Find the normal for this fragment, pulling either from a predefined normal map
@@ -3773,32 +5663,28 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
3773
5663
  fn getNormal() -> vec3f
3774
5664
  {
3775
5665
  // Retrieve the tangent space matrix
3776
- #ifndef HAS_TANGENTS
3777
- var pos_dx: vec3f = dFdx(fragmentInputs.pbr_vPosition);
3778
- var pos_dy: vec3f = dFdy(fragmentInputs.pbr_vPosition);
3779
- var tex_dx: vec3f = dFdx(vec3(fragmentInputs.pbr_vUV, 0.0));
3780
- var tex_dy: vec3f = dFdy(vec3(fragmentInputs.pbr_vUV, 0.0));
3781
- 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);
3782
5671
 
3783
- #ifdef HAS_NORMALS
3784
- var ng: vec3f = normalize(fragmentInputs.pbr_vNormal);
3785
- #else
3786
5672
  var ng: vec3f = cross(pos_dx, pos_dy);
5673
+ #ifdef HAS_NORMALS
5674
+ ng = normalize(fragmentInputs.pbr_vNormal);
3787
5675
  #endif
3788
-
3789
5676
  t = normalize(t - ng * dot(ng, t));
3790
5677
  var b: vec3f = normalize(cross(ng, t));
3791
- var tbn: mat3f = mat3f(t, b, ng);
3792
- #else // HAS_TANGENTS
3793
- var tbn: mat3f = fragmentInputs.pbr_vTBN;
5678
+ var tbn: mat3x3f = mat3x3f(t, b, ng);
5679
+ #ifdef HAS_TANGENTS
5680
+ tbn = fragmentInputs.pbr_vTBN;
3794
5681
  #endif
3795
5682
 
3796
- #ifdef HAS_NORMALMAP
3797
- vec3 n = texture(pbr_normalSampler, fragmentInputs.pbr_vUV).rgb;
3798
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
3799
- #else
3800
5683
  // The tbn matrix is linearly interpolated, so we need to re-normalize
3801
- 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)));
3802
5688
  #endif
3803
5689
 
3804
5690
  return n;
@@ -3808,27 +5694,37 @@ fn getNormal() -> vec3f
3808
5694
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
3809
5695
  // See our README.md on Environment Maps [3] for additional discussion.
3810
5696
  #ifdef USE_IBL
3811
- fn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f
5697
+ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
3812
5698
  {
3813
- float mipCount = 9.0; // resolution of 512x512
3814
- float lod = (pbrInfo.perceptualRoughness * mipCount);
5699
+ let mipCount: f32 = 9.0; // resolution of 512x512
5700
+ let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
3815
5701
  // retrieve a scale and bias to F0. See [1], Figure 3
3816
- vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
3817
- vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
3818
- vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
3819
-
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;
3820
5714
  #ifdef USE_TEX_LOD
3821
- vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
3822
- #else
3823
- 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;
3824
5723
  #endif
3825
5724
 
3826
- vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
3827
- vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
3828
-
3829
- // For presentation, this allows us to disable IBL terms
3830
- diffuse *= pbrMaterial.scaleIBLAmbient.x;
3831
- 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;
3832
5728
 
3833
5729
  return diffuse + specular;
3834
5730
  }
@@ -3872,7 +5768,7 @@ fn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {
3872
5768
  fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
3873
5769
  let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
3874
5770
  let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
3875
- return roughnessSq / (PI * f * f);
5771
+ return roughnessSq / (M_PI * f * f);
3876
5772
  }
3877
5773
 
3878
5774
  fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
@@ -3914,11 +5810,11 @@ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
3914
5810
 
3915
5811
  fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3916
5812
  // The albedo may be defined from a base texture or a flat color
3917
- var baseColor: vec4<f32>;
5813
+ var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;
3918
5814
  #ifdef HAS_BASECOLORMAP
3919
- baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, fragmentInputs.pbr_vUV)) * pbrMaterial.baseColorFactor;
3920
- #else
3921
- baseColor = pbrMaterial.baseColorFactor;
5815
+ baseColor = SRGBtoLINEAR(
5816
+ textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, fragmentInputs.pbr_vUV)
5817
+ ) * pbrMaterial.baseColorFactor;
3922
5818
  #endif
3923
5819
 
3924
5820
  #ifdef ALPHA_CUTOFF
@@ -3929,7 +5825,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3929
5825
 
3930
5826
  var color = vec3<f32>(0.0, 0.0, 0.0);
3931
5827
 
3932
- if (pbrMaterial.unlit) {
5828
+ if (pbrMaterial.unlit != 0u) {
3933
5829
  color = baseColor.rgb;
3934
5830
  } else {
3935
5831
  // Metallic and Roughness material properties are packed together
@@ -3940,7 +5836,11 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
3940
5836
  #ifdef HAS_METALROUGHNESSMAP
3941
5837
  // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
3942
5838
  // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
3943
- 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
+ );
3944
5844
  perceptualRoughness = mrSample.g * perceptualRoughness;
3945
5845
  metallic = mrSample.b * metallic;
3946
5846
  #endif
@@ -4017,22 +5917,25 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4017
5917
 
4018
5918
  // Calculate lighting contribution from image based lighting source (IBL)
4019
5919
  #ifdef USE_IBL
4020
- if (pbrMaterial.IBLenabled) {
5920
+ if (pbrMaterial.IBLenabled != 0) {
4021
5921
  color += getIBLContribution(pbrInfo, n, reflection);
4022
5922
  }
4023
5923
  #endif
4024
5924
 
4025
5925
  // Apply optional PBR terms for additional (optional) shading
4026
5926
  #ifdef HAS_OCCLUSIONMAP
4027
- if (pbrMaterial.occlusionMapEnabled) {
4028
- 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;
4029
5930
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
4030
5931
  }
4031
5932
  #endif
4032
5933
 
4033
5934
  #ifdef HAS_EMISSIVEMAP
4034
- if (pbrMaterial.emissiveMapEnabled) {
4035
- 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;
4036
5939
  color += emissive;
4037
5940
  }
4038
5941
  #endif
@@ -4068,10 +5971,23 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4068
5971
  mat4 normalMatrix;
4069
5972
  vec3 camera;
4070
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;
4071
5986
  `
4072
5987
  );
4073
5988
  var pbrProjection = {
4074
5989
  name: "pbrProjection",
5990
+ source: wgslUniformBlock,
4075
5991
  vs: uniformBlock,
4076
5992
  fs: uniformBlock,
4077
5993
  // TODO why is this needed?
@@ -4080,7 +5996,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4080
5996
  modelViewProjectionMatrix: "mat4x4<f32>",
4081
5997
  modelMatrix: "mat4x4<f32>",
4082
5998
  normalMatrix: "mat4x4<f32>",
4083
- camera: "vec3<i32>"
5999
+ camera: "vec3<f32>"
4084
6000
  }
4085
6001
  };
4086
6002
 
@@ -4090,9 +6006,9 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
4090
6006
  uniforms: {},
4091
6007
  name: "pbrMaterial",
4092
6008
  dependencies: [lighting, pbrProjection],
4093
- source: source2,
4094
- vs: vs2,
4095
- fs: fs3,
6009
+ source: source3,
6010
+ vs: vs3,
6011
+ fs: fs4,
4096
6012
  defines: {
4097
6013
  LIGHTING_FRAGMENT: true,
4098
6014
  HAS_NORMALMAP: false,