@luma.gl/shadertools 9.3.0-alpha.9 → 9.3.1

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 (113) hide show
  1. package/dist/dist.dev.js +1018 -188
  2. package/dist/dist.min.js +440 -145
  3. package/dist/index.cjs +913 -172
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +7 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/color/normalize-byte-colors.d.ts +23 -0
  10. package/dist/lib/color/normalize-byte-colors.d.ts.map +1 -0
  11. package/dist/lib/color/normalize-byte-colors.js +42 -0
  12. package/dist/lib/color/normalize-byte-colors.js.map +1 -0
  13. package/dist/lib/glsl-utils/shader-utils.js +4 -4
  14. package/dist/lib/glsl-utils/shader-utils.js.map +1 -1
  15. package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
  16. package/dist/lib/shader-assembly/assemble-shaders.js +102 -49
  17. package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
  18. package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -1
  19. package/dist/lib/shader-assembly/wgsl-binding-debug.js +7 -3
  20. package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -1
  21. package/dist/lib/shader-assembly/wgsl-binding-scan.d.ts +19 -0
  22. package/dist/lib/shader-assembly/wgsl-binding-scan.d.ts.map +1 -0
  23. package/dist/lib/shader-assembly/wgsl-binding-scan.js +151 -0
  24. package/dist/lib/shader-assembly/wgsl-binding-scan.js.map +1 -0
  25. package/dist/lib/shader-generator/glsl/generate-glsl.js +4 -4
  26. package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
  27. package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +69 -0
  28. package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -1
  29. package/dist/lib/shader-module/shader-module-uniform-layout.js +143 -3
  30. package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -1
  31. package/dist/modules/color/float-colors.d.ts +26 -0
  32. package/dist/modules/color/float-colors.d.ts.map +1 -0
  33. package/dist/modules/color/float-colors.js +82 -0
  34. package/dist/modules/color/float-colors.js.map +1 -0
  35. package/dist/modules/engine/picking/picking.d.ts +8 -8
  36. package/dist/modules/engine/picking/picking.d.ts.map +1 -1
  37. package/dist/modules/engine/picking/picking.js +13 -15
  38. package/dist/modules/engine/picking/picking.js.map +1 -1
  39. package/dist/modules/engine/project/project.d.ts +1 -1
  40. package/dist/modules/engine/project/project.js +1 -1
  41. package/dist/modules/engine/skin/skin.d.ts +2 -2
  42. package/dist/modules/engine/skin/skin.d.ts.map +1 -1
  43. package/dist/modules/engine/skin/skin.js +1 -1
  44. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
  45. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
  46. package/dist/modules/lighting/gouraud-material/gouraud-material.js +6 -3
  47. package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
  48. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +2 -2
  49. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -1
  50. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +2 -2
  51. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  52. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  53. package/dist/modules/lighting/lights/lighting-glsl.js +1 -1
  54. package/dist/modules/lighting/lights/lighting.d.ts +4 -2
  55. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  56. package/dist/modules/lighting/lights/lighting.js +17 -11
  57. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  58. package/dist/modules/lighting/no-material/dirlight.d.ts +3 -3
  59. package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
  60. package/dist/modules/lighting/no-material/dirlight.js +2 -2
  61. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +2 -2
  62. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
  63. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +138 -35
  64. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
  65. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  66. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  67. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +139 -35
  68. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  69. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +74 -6
  70. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  71. package/dist/modules/lighting/pbr-material/pbr-material.js +70 -2
  72. package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
  73. package/dist/modules/lighting/pbr-material/pbr-projection.js +1 -1
  74. package/dist/modules/lighting/pbr-material/pbr-scene.d.ts +40 -0
  75. package/dist/modules/lighting/pbr-material/pbr-scene.d.ts.map +1 -0
  76. package/dist/modules/lighting/pbr-material/pbr-scene.js +67 -0
  77. package/dist/modules/lighting/pbr-material/pbr-scene.js.map +1 -0
  78. package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
  79. package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
  80. package/dist/modules/lighting/phong-material/phong-material.js +6 -3
  81. package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
  82. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
  83. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
  84. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +2 -2
  85. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
  86. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
  87. package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +1 -1
  88. package/package.json +3 -3
  89. package/src/index.ts +17 -1
  90. package/src/lib/color/normalize-byte-colors.ts +57 -0
  91. package/src/lib/glsl-utils/shader-utils.ts +4 -4
  92. package/src/lib/shader-assembly/assemble-shaders.ts +197 -69
  93. package/src/lib/shader-assembly/wgsl-binding-debug.ts +14 -3
  94. package/src/lib/shader-assembly/wgsl-binding-scan.ts +228 -0
  95. package/src/lib/shader-generator/glsl/generate-glsl.ts +4 -4
  96. package/src/lib/shader-module/shader-module-uniform-layout.ts +233 -8
  97. package/src/modules/color/float-colors.ts +99 -0
  98. package/src/modules/engine/picking/picking.ts +17 -19
  99. package/src/modules/engine/project/project.ts +1 -1
  100. package/src/modules/engine/skin/skin.ts +1 -1
  101. package/src/modules/lighting/gouraud-material/gouraud-material.ts +10 -3
  102. package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +2 -2
  103. package/src/modules/lighting/lights/lighting-glsl.ts +1 -1
  104. package/src/modules/lighting/lights/lighting.ts +20 -11
  105. package/src/modules/lighting/no-material/dirlight.ts +2 -2
  106. package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +138 -35
  107. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +139 -35
  108. package/src/modules/lighting/pbr-material/pbr-material.ts +110 -3
  109. package/src/modules/lighting/pbr-material/pbr-projection.ts +1 -1
  110. package/src/modules/lighting/pbr-material/pbr-scene.ts +91 -0
  111. package/src/modules/lighting/phong-material/phong-material.ts +10 -3
  112. package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +2 -2
  113. package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +1 -1
package/dist/dist.dev.js CHANGED
@@ -62,6 +62,7 @@ var __exports__ = (() => {
62
62
  combineInjects: () => combineInjects,
63
63
  convertToVec4: () => convertToVec4,
64
64
  dirlight: () => dirlight,
65
+ floatColors: () => floatColors,
65
66
  fp32: () => fp32,
66
67
  fp64: () => fp64,
67
68
  fp64LowPart: () => fp64LowPart,
@@ -70,6 +71,7 @@ var __exports__ = (() => {
70
71
  fp64ifyMatrix4: () => fp64ifyMatrix4,
71
72
  fromHalfFloat: () => fromHalfFloat,
72
73
  generateShaderForModule: () => generateShaderForModule,
74
+ getGLSLUniformBlocks: () => getGLSLUniformBlocks,
73
75
  getPassthroughFS: () => getPassthroughFS,
74
76
  getQualifierDetails: () => getQualifierDetails,
75
77
  getShaderInfo: () => getShaderInfo,
@@ -85,16 +87,21 @@ var __exports__ = (() => {
85
87
  initializeShaderModules: () => initializeShaderModules,
86
88
  lambertMaterial: () => lambertMaterial,
87
89
  lighting: () => lighting,
90
+ normalizeByteColor3: () => normalizeByteColor3,
91
+ normalizeByteColor4: () => normalizeByteColor4,
88
92
  pbrMaterial: () => pbrMaterial,
93
+ pbrScene: () => pbrScene,
89
94
  phongMaterial: () => phongMaterial,
90
95
  picking: () => picking,
91
96
  preprocess: () => preprocess,
92
97
  random: () => random,
98
+ resolveUseByteColors: () => resolveUseByteColors,
93
99
  skin: () => skin,
94
100
  toHalfFloat: () => toHalfFloat,
95
101
  typeToChannelCount: () => typeToChannelCount,
96
102
  typeToChannelSuffix: () => typeToChannelSuffix,
97
- validateShaderModuleUniformLayout: () => validateShaderModuleUniformLayout
103
+ validateShaderModuleUniformLayout: () => validateShaderModuleUniformLayout,
104
+ warnIfGLSLUniformBlocksAreNotStd140: () => warnIfGLSLUniformBlocksAreNotStd140
98
105
  });
99
106
  __reExport(bundle_exports, __toESM(require_core(), 1));
100
107
 
@@ -417,6 +424,7 @@ ${inject[key]}` : inject[key];
417
424
 
418
425
  // src/lib/shader-module/shader-module-uniform-layout.ts
419
426
  var GLSL_UNIFORM_BLOCK_FIELD_REGEXP = /^(?:uniform\s+)?(?:(?:lowp|mediump|highp)\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/;
427
+ var GLSL_UNIFORM_BLOCK_REGEXP = /((?:layout\s*\([^)]*\)\s*)*)uniform\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{([\s\S]*?)\}\s*([A-Za-z_][A-Za-z0-9_]*)?\s*;/g;
420
428
  function getShaderModuleUniformBlockName(module) {
421
429
  return `${module.name}Uniforms`;
422
430
  }
@@ -462,6 +470,39 @@ ${inject[key]}` : inject[key];
462
470
  }
463
471
  return validationResult;
464
472
  }
473
+ function getGLSLUniformBlocks(shaderSource) {
474
+ const blocks = [];
475
+ const uncommentedSource = stripShaderComments(shaderSource);
476
+ for (const sourceMatch of uncommentedSource.matchAll(GLSL_UNIFORM_BLOCK_REGEXP)) {
477
+ const layoutQualifier = sourceMatch[1]?.trim() || null;
478
+ blocks.push({
479
+ blockName: sourceMatch[2],
480
+ body: sourceMatch[3],
481
+ instanceName: sourceMatch[4] || null,
482
+ layoutQualifier,
483
+ hasLayoutQualifier: Boolean(layoutQualifier),
484
+ isStd140: Boolean(
485
+ layoutQualifier && /\blayout\s*\([^)]*\bstd140\b[^)]*\)/.exec(layoutQualifier)
486
+ )
487
+ });
488
+ }
489
+ return blocks;
490
+ }
491
+ function warnIfGLSLUniformBlocksAreNotStd140(shaderSource, stage, log2, context) {
492
+ const nonStd140Blocks = getGLSLUniformBlocks(shaderSource).filter((block) => !block.isStd140);
493
+ const seenBlockNames = /* @__PURE__ */ new Set();
494
+ for (const block of nonStd140Blocks) {
495
+ if (seenBlockNames.has(block.blockName)) {
496
+ continue;
497
+ }
498
+ seenBlockNames.add(block.blockName);
499
+ const shaderLabel = context?.label ? `${context.label} ` : "";
500
+ const actualLayout = block.hasLayoutQualifier ? `declares ${normalizeWhitespace(block.layoutQualifier)} instead of layout(std140)` : "does not declare layout(std140)";
501
+ const message = `${shaderLabel}${stage} shader uniform block ${block.blockName} ${actualLayout}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \`layout(std140)\` to the block declaration.`;
502
+ log2?.warn?.(message, block)();
503
+ }
504
+ return nonStd140Blocks;
505
+ }
465
506
  function extractShaderUniformBlockFieldNames(shaderSource, language, uniformBlockName) {
466
507
  const sourceBody = language === "wgsl" ? extractWGSLStructBody(shaderSource, uniformBlockName) : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);
467
508
  if (!sourceBody) {
@@ -507,10 +548,10 @@ ${inject[key]}` : inject[key];
507
548
  return null;
508
549
  }
509
550
  function extractGLSLUniformBlockBody(shaderSource, uniformBlockName) {
510
- const sourceMatch = shaderSource.match(
511
- new RegExp(`uniform\\s+${uniformBlockName}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`, "m")
551
+ const block = getGLSLUniformBlocks(shaderSource).find(
552
+ (candidate) => candidate.blockName === uniformBlockName
512
553
  );
513
- return sourceMatch?.[1] || null;
554
+ return block?.body || null;
514
555
  }
515
556
  function areStringArraysEqual(leftValues, rightValues) {
516
557
  if (leftValues.length !== rightValues.length) {
@@ -524,11 +565,70 @@ ${inject[key]}` : inject[key];
524
565
  return true;
525
566
  }
526
567
  function formatShaderModuleUniformLayoutError(validationResult) {
527
- return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${validationResult.uniformBlockName} does not match module.uniformTypes.
528
- Expected: ${validationResult.expectedUniformNames.join(
529
- ", "
530
- )}
531
- Actual: ${validationResult.actualUniformNames.join(", ")}`;
568
+ const { expectedUniformNames, actualUniformNames } = validationResult;
569
+ const missingUniformNames = expectedUniformNames.filter(
570
+ (uniformName) => !actualUniformNames.includes(uniformName)
571
+ );
572
+ const unexpectedUniformNames = actualUniformNames.filter(
573
+ (uniformName) => !expectedUniformNames.includes(uniformName)
574
+ );
575
+ const mismatchDetails = [
576
+ `Expected ${expectedUniformNames.length} fields, found ${actualUniformNames.length}.`
577
+ ];
578
+ const firstMismatchDescription = getFirstUniformMismatchDescription(
579
+ expectedUniformNames,
580
+ actualUniformNames
581
+ );
582
+ if (firstMismatchDescription) {
583
+ mismatchDetails.push(firstMismatchDescription);
584
+ }
585
+ if (missingUniformNames.length) {
586
+ mismatchDetails.push(
587
+ `Missing from shader block (${missingUniformNames.length}): ${formatUniformNameList(
588
+ missingUniformNames
589
+ )}.`
590
+ );
591
+ }
592
+ if (unexpectedUniformNames.length) {
593
+ mismatchDetails.push(
594
+ `Unexpected in shader block (${unexpectedUniformNames.length}): ${formatUniformNameList(
595
+ unexpectedUniformNames
596
+ )}.`
597
+ );
598
+ }
599
+ if (expectedUniformNames.length <= 12 && actualUniformNames.length <= 12 && (missingUniformNames.length || unexpectedUniformNames.length)) {
600
+ mismatchDetails.push(`Expected: ${expectedUniformNames.join(", ")}.`);
601
+ mismatchDetails.push(`Actual: ${actualUniformNames.join(", ")}.`);
602
+ }
603
+ return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${validationResult.uniformBlockName} does not match module.uniformTypes. ${mismatchDetails.join(" ")}`;
604
+ }
605
+ function stripShaderComments(shaderSource) {
606
+ return shaderSource.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
607
+ }
608
+ function normalizeWhitespace(value) {
609
+ return value.replace(/\s+/g, " ").trim();
610
+ }
611
+ function getFirstUniformMismatchDescription(expectedUniformNames, actualUniformNames) {
612
+ const minimumLength = Math.min(expectedUniformNames.length, actualUniformNames.length);
613
+ for (let index = 0; index < minimumLength; index++) {
614
+ if (expectedUniformNames[index] !== actualUniformNames[index]) {
615
+ return `First mismatch at field ${index + 1}: expected ${expectedUniformNames[index]}, found ${actualUniformNames[index]}.`;
616
+ }
617
+ }
618
+ if (expectedUniformNames.length > actualUniformNames.length) {
619
+ return `Shader block ends after field ${actualUniformNames.length}; expected next field ${expectedUniformNames[actualUniformNames.length]}.`;
620
+ }
621
+ if (actualUniformNames.length > expectedUniformNames.length) {
622
+ return `Shader block has extra field ${actualUniformNames.length}: ${actualUniformNames[expectedUniformNames.length]}.`;
623
+ }
624
+ return null;
625
+ }
626
+ function formatUniformNameList(uniformNames, maxNames = 8) {
627
+ if (uniformNames.length <= maxNames) {
628
+ return uniformNames.join(", ");
629
+ }
630
+ const remainingCount = uniformNames.length - maxNames;
631
+ return `${uniformNames.slice(0, maxNames).join(", ")}, ... (${remainingCount} more)`;
532
632
  }
533
633
 
534
634
  // src/lib/shader-assembly/platform-defines.ts
@@ -715,12 +815,194 @@ Actual: ${validationResult.actualUniformNames.join(", ")}`;
715
815
  return version;
716
816
  }
717
817
 
818
+ // src/lib/shader-assembly/wgsl-binding-scan.ts
819
+ var WGSL_BINDABLE_VARIABLE_PATTERN = "(?:var<\\s*(uniform|storage(?:\\s*,\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\s*>|var)\\s+([A-Za-z_][A-Za-z0-9_]*)";
820
+ var WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN = "\\s*";
821
+ var MODULE_WGSL_BINDING_DECLARATION_REGEXES = [
822
+ new RegExp(
823
+ `@binding\\(\\s*(auto|\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
824
+ "g"
825
+ ),
826
+ new RegExp(
827
+ `@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\(\\s*(auto|\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
828
+ "g"
829
+ )
830
+ ];
831
+ var WGSL_BINDING_DECLARATION_REGEXES = [
832
+ new RegExp(
833
+ `@binding\\(\\s*(auto|\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
834
+ "g"
835
+ ),
836
+ new RegExp(
837
+ `@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\(\\s*(auto|\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
838
+ "g"
839
+ )
840
+ ];
841
+ var WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES = [
842
+ new RegExp(
843
+ `@binding\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
844
+ "g"
845
+ ),
846
+ new RegExp(
847
+ `@group\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}@binding\\(\\s*(\\d+)\\s*\\)${WGSL_BINDING_DECLARATION_SEPARATOR_PATTERN}${WGSL_BINDABLE_VARIABLE_PATTERN}`,
848
+ "g"
849
+ )
850
+ ];
851
+ var WGSL_AUTO_BINDING_DECLARATION_REGEXES = [
852
+ new RegExp(
853
+ `@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,
854
+ "g"
855
+ ),
856
+ new RegExp(
857
+ `@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}`,
858
+ "g"
859
+ ),
860
+ new RegExp(
861
+ `@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,
862
+ "g"
863
+ ),
864
+ new RegExp(
865
+ `@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${WGSL_BINDABLE_VARIABLE_PATTERN}`,
866
+ "g"
867
+ )
868
+ ];
869
+ function maskWGSLComments(source4) {
870
+ const maskedCharacters = source4.split("");
871
+ let index = 0;
872
+ let blockCommentDepth = 0;
873
+ let inLineComment = false;
874
+ let inString = false;
875
+ let isEscaped = false;
876
+ while (index < source4.length) {
877
+ const character = source4[index];
878
+ const nextCharacter = source4[index + 1];
879
+ if (inString) {
880
+ if (isEscaped) {
881
+ isEscaped = false;
882
+ } else if (character === "\\") {
883
+ isEscaped = true;
884
+ } else if (character === '"') {
885
+ inString = false;
886
+ }
887
+ index++;
888
+ continue;
889
+ }
890
+ if (inLineComment) {
891
+ if (character === "\n" || character === "\r") {
892
+ inLineComment = false;
893
+ } else {
894
+ maskedCharacters[index] = " ";
895
+ }
896
+ index++;
897
+ continue;
898
+ }
899
+ if (blockCommentDepth > 0) {
900
+ if (character === "/" && nextCharacter === "*") {
901
+ maskedCharacters[index] = " ";
902
+ maskedCharacters[index + 1] = " ";
903
+ blockCommentDepth++;
904
+ index += 2;
905
+ continue;
906
+ }
907
+ if (character === "*" && nextCharacter === "/") {
908
+ maskedCharacters[index] = " ";
909
+ maskedCharacters[index + 1] = " ";
910
+ blockCommentDepth--;
911
+ index += 2;
912
+ continue;
913
+ }
914
+ if (character !== "\n" && character !== "\r") {
915
+ maskedCharacters[index] = " ";
916
+ }
917
+ index++;
918
+ continue;
919
+ }
920
+ if (character === '"') {
921
+ inString = true;
922
+ index++;
923
+ continue;
924
+ }
925
+ if (character === "/" && nextCharacter === "/") {
926
+ maskedCharacters[index] = " ";
927
+ maskedCharacters[index + 1] = " ";
928
+ inLineComment = true;
929
+ index += 2;
930
+ continue;
931
+ }
932
+ if (character === "/" && nextCharacter === "*") {
933
+ maskedCharacters[index] = " ";
934
+ maskedCharacters[index + 1] = " ";
935
+ blockCommentDepth = 1;
936
+ index += 2;
937
+ continue;
938
+ }
939
+ index++;
940
+ }
941
+ return maskedCharacters.join("");
942
+ }
943
+ function getWGSLBindingDeclarationMatches(source4, regexes) {
944
+ const maskedSource = maskWGSLComments(source4);
945
+ const matches = [];
946
+ for (const regex of regexes) {
947
+ regex.lastIndex = 0;
948
+ let match;
949
+ match = regex.exec(maskedSource);
950
+ while (match) {
951
+ const isBindingFirst = regex === regexes[0];
952
+ const index = match.index;
953
+ const length = match[0].length;
954
+ matches.push({
955
+ match: source4.slice(index, index + length),
956
+ index,
957
+ length,
958
+ bindingToken: match[isBindingFirst ? 1 : 2],
959
+ groupToken: match[isBindingFirst ? 2 : 1],
960
+ accessDeclaration: match[3]?.trim(),
961
+ name: match[4]
962
+ });
963
+ match = regex.exec(maskedSource);
964
+ }
965
+ }
966
+ return matches.sort((left, right) => left.index - right.index);
967
+ }
968
+ function replaceWGSLBindingDeclarationMatches(source4, regexes, replacer) {
969
+ const matches = getWGSLBindingDeclarationMatches(source4, regexes);
970
+ if (!matches.length) {
971
+ return source4;
972
+ }
973
+ let relocatedSource = "";
974
+ let lastIndex = 0;
975
+ for (const match of matches) {
976
+ relocatedSource += source4.slice(lastIndex, match.index);
977
+ relocatedSource += replacer(match);
978
+ lastIndex = match.index + match.length;
979
+ }
980
+ relocatedSource += source4.slice(lastIndex);
981
+ return relocatedSource;
982
+ }
983
+ function hasWGSLAutoBinding(source4) {
984
+ return /@binding\(\s*auto\s*\)/.test(maskWGSLComments(source4));
985
+ }
986
+ function getFirstWGSLAutoBindingDeclarationMatch(source4, regexes) {
987
+ const autoBindingRegexes = regexes === MODULE_WGSL_BINDING_DECLARATION_REGEXES || regexes === WGSL_BINDING_DECLARATION_REGEXES ? WGSL_AUTO_BINDING_DECLARATION_REGEXES : regexes;
988
+ return getWGSLBindingDeclarationMatches(source4, autoBindingRegexes).find(
989
+ (declarationMatch) => declarationMatch.bindingToken === "auto"
990
+ );
991
+ }
992
+
718
993
  // src/lib/shader-assembly/wgsl-binding-debug.ts
719
994
  var WGSL_BINDING_DEBUG_REGEXES = [
720
- /@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g,
721
- /@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g
995
+ new RegExp(
996
+ `@binding\\(\\s*(\\d+)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\s*:\\s*([^;]+);`,
997
+ "g"
998
+ ),
999
+ new RegExp(
1000
+ `@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(\\d+)\\s*\\)\\s*${WGSL_BINDABLE_VARIABLE_PATTERN}\\s*:\\s*([^;]+);`,
1001
+ "g"
1002
+ )
722
1003
  ];
723
1004
  function getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments = []) {
1005
+ const maskedSource = maskWGSLComments(source4);
724
1006
  const assignmentMap = /* @__PURE__ */ new Map();
725
1007
  for (const bindingAssignment of bindingAssignments) {
726
1008
  assignmentMap.set(
@@ -736,7 +1018,8 @@ Actual: ${validationResult.actualUniformNames.join(", ")}`;
736
1018
  for (const regex of WGSL_BINDING_DEBUG_REGEXES) {
737
1019
  regex.lastIndex = 0;
738
1020
  let match;
739
- while (match = regex.exec(source4)) {
1021
+ match = regex.exec(maskedSource);
1022
+ while (match) {
740
1023
  const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];
741
1024
  const binding = Number(match[isBindingFirst ? 1 : 2]);
742
1025
  const group = Number(match[isBindingFirst ? 2 : 1]);
@@ -755,6 +1038,7 @@ Actual: ${validationResult.actualUniformNames.join(", ")}`;
755
1038
  resourceType
756
1039
  })
757
1040
  );
1041
+ match = regex.exec(maskedSource);
758
1042
  }
759
1043
  }
760
1044
  return rows.sort((left, right) => {
@@ -866,14 +1150,6 @@ Actual: ${validationResult.actualUniformNames.join(", ")}`;
866
1150
 
867
1151
  ${DECLARATION_INJECT_MARKER}
868
1152
  `;
869
- var MODULE_WGSL_BINDING_DECLARATION_REGEXES = [
870
- /@binding\(\s*(auto|\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
871
- /@group\(\s*(\d+)\s*\)\s*@binding\(\s*(auto|\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
872
- ];
873
- var WGSL_BINDING_DECLARATION_REGEXES = [
874
- /@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
875
- /@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
876
- ];
877
1153
  var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
878
1154
  var FRAGMENT_SHADER_PROLOGUE = (
879
1155
  /* glsl */
@@ -953,7 +1229,10 @@ ${DECLARATION_INJECT_MARKER}
953
1229
  }
954
1230
  }
955
1231
  const modulesToInject = modules;
956
- const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(coreSource);
1232
+ const applicationRelocation = relocateWGSLApplicationBindings(coreSource);
1233
+ const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(
1234
+ applicationRelocation.source
1235
+ );
957
1236
  const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(
958
1237
  modulesToInject,
959
1238
  options._bindingRegistry,
@@ -994,7 +1273,7 @@ ${DECLARATION_INJECT_MARKER}
994
1273
  assembledSource = injectShader(assembledSource, stage, declInjections);
995
1274
  assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);
996
1275
  assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);
997
- assembledSource += coreSource;
1276
+ assembledSource += applicationRelocation.source;
998
1277
  assembledSource = injectShader(assembledSource, stage, mainInjections);
999
1278
  assertNoUnresolvedAutoBindings(assembledSource);
1000
1279
  return { source: assembledSource, bindingAssignments };
@@ -1095,6 +1374,9 @@ ${getApplicationDefines(allDefines)}
1095
1374
  if (language === "glsl" && sourceVersion !== targetVersion) {
1096
1375
  assembledSource = transpileGLSLShader(assembledSource, stage);
1097
1376
  }
1377
+ if (language === "glsl") {
1378
+ warnIfGLSLUniformBlocksAreNotStd140(assembledSource, stage, log2);
1379
+ }
1098
1380
  return assembledSource.trim();
1099
1381
  }
1100
1382
  function assembleGetUniforms(modules) {
@@ -1151,61 +1433,87 @@ ${getApplicationDefines(allDefines)}
1151
1433
  }
1152
1434
  function getUsedBindingsByGroupFromApplicationWGSL(source4) {
1153
1435
  const usedBindingsByGroup = /* @__PURE__ */ new Map();
1154
- for (const regex of WGSL_BINDING_DECLARATION_REGEXES) {
1155
- regex.lastIndex = 0;
1156
- let match;
1157
- while (match = regex.exec(source4)) {
1158
- const isBindingFirst = regex === WGSL_BINDING_DECLARATION_REGEXES[0];
1159
- const location = Number(match[isBindingFirst ? 1 : 2]);
1160
- const group = Number(match[isBindingFirst ? 2 : 1]);
1161
- const name = match[4];
1162
- validateApplicationWGSLBinding(group, location, name);
1163
- registerUsedBindingLocation(
1164
- usedBindingsByGroup,
1165
- group,
1166
- location,
1167
- `application binding "${name}"`
1168
- );
1169
- }
1436
+ for (const match of getWGSLBindingDeclarationMatches(
1437
+ source4,
1438
+ WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES
1439
+ )) {
1440
+ const location = Number(match.bindingToken);
1441
+ const group = Number(match.groupToken);
1442
+ validateApplicationWGSLBinding(group, location, match.name);
1443
+ registerUsedBindingLocation(
1444
+ usedBindingsByGroup,
1445
+ group,
1446
+ location,
1447
+ `application binding "${match.name}"`
1448
+ );
1170
1449
  }
1171
1450
  return usedBindingsByGroup;
1172
1451
  }
1452
+ function relocateWGSLApplicationBindings(source4) {
1453
+ const declarationMatches = getWGSLBindingDeclarationMatches(
1454
+ source4,
1455
+ WGSL_BINDING_DECLARATION_REGEXES
1456
+ );
1457
+ const usedBindingsByGroup = /* @__PURE__ */ new Map();
1458
+ for (const declarationMatch of declarationMatches) {
1459
+ if (declarationMatch.bindingToken === "auto") {
1460
+ continue;
1461
+ }
1462
+ const location = Number(declarationMatch.bindingToken);
1463
+ const group = Number(declarationMatch.groupToken);
1464
+ validateApplicationWGSLBinding(group, location, declarationMatch.name);
1465
+ registerUsedBindingLocation(
1466
+ usedBindingsByGroup,
1467
+ group,
1468
+ location,
1469
+ `application binding "${declarationMatch.name}"`
1470
+ );
1471
+ }
1472
+ const relocationState = {
1473
+ sawSupportedBindingDeclaration: declarationMatches.length > 0
1474
+ };
1475
+ const relocatedSource = replaceWGSLBindingDeclarationMatches(
1476
+ source4,
1477
+ WGSL_BINDING_DECLARATION_REGEXES,
1478
+ (declarationMatch) => relocateWGSLApplicationBindingMatch(declarationMatch, usedBindingsByGroup, relocationState)
1479
+ );
1480
+ if (hasWGSLAutoBinding(source4) && !relocationState.sawSupportedBindingDeclaration) {
1481
+ throw new Error(
1482
+ 'Unsupported @binding(auto) declaration form in application WGSL. Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.'
1483
+ );
1484
+ }
1485
+ return { source: relocatedSource };
1486
+ }
1173
1487
  function relocateWGSLModuleBindings(moduleSource, module, context) {
1174
1488
  const bindingAssignments = [];
1489
+ const declarationMatches = getWGSLBindingDeclarationMatches(
1490
+ moduleSource,
1491
+ MODULE_WGSL_BINDING_DECLARATION_REGEXES
1492
+ );
1175
1493
  const relocationState = {
1176
- sawSupportedBindingDeclaration: false,
1494
+ sawSupportedBindingDeclaration: declarationMatches.length > 0,
1177
1495
  nextHintedBindingLocation: typeof module.firstBindingSlot === "number" ? module.firstBindingSlot : null
1178
1496
  };
1179
- let relocatedSource = relocateWGSLModuleBindingsWithRegex(
1497
+ const relocatedSource = replaceWGSLBindingDeclarationMatches(
1180
1498
  moduleSource,
1181
- MODULE_WGSL_BINDING_DECLARATION_REGEXES[0],
1182
- { isBindingFirst: true, module, context, bindingAssignments, relocationState }
1183
- );
1184
- relocatedSource = relocateWGSLModuleBindingsWithRegex(
1185
- relocatedSource,
1186
- MODULE_WGSL_BINDING_DECLARATION_REGEXES[1],
1187
- { isBindingFirst: false, module, context, bindingAssignments, relocationState }
1499
+ MODULE_WGSL_BINDING_DECLARATION_REGEXES,
1500
+ (declarationMatch) => relocateWGSLModuleBindingMatch(declarationMatch, {
1501
+ module,
1502
+ context,
1503
+ bindingAssignments,
1504
+ relocationState
1505
+ })
1188
1506
  );
1189
- if (moduleSource.includes("@binding(auto)") && !relocationState.sawSupportedBindingDeclaration) {
1507
+ if (hasWGSLAutoBinding(moduleSource) && !relocationState.sawSupportedBindingDeclaration) {
1190
1508
  throw new Error(
1191
- `Unsupported @binding(auto) declaration form in module "${module.name}". Use "@group(N) @binding(auto) var ..." or "@binding(auto) @group(N) var ..." on a single line.`
1509
+ `Unsupported @binding(auto) declaration form in module "${module.name}". Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.`
1192
1510
  );
1193
1511
  }
1194
1512
  return { source: relocatedSource, bindingAssignments };
1195
1513
  }
1196
- function relocateWGSLModuleBindingsWithRegex(source4, regex, params) {
1197
- return source4.replace(
1198
- regex,
1199
- (...replaceArguments) => relocateWGSLModuleBindingMatch(replaceArguments, params)
1200
- );
1201
- }
1202
- function relocateWGSLModuleBindingMatch(replaceArguments, params) {
1203
- const { isBindingFirst, module, context, bindingAssignments, relocationState } = params;
1204
- relocationState.sawSupportedBindingDeclaration = true;
1205
- const match = replaceArguments[0];
1206
- const bindingToken = replaceArguments[isBindingFirst ? 1 : 2];
1207
- const groupToken = replaceArguments[isBindingFirst ? 2 : 1];
1208
- const name = replaceArguments[4];
1514
+ function relocateWGSLModuleBindingMatch(declarationMatch, params) {
1515
+ const { module, context, bindingAssignments, relocationState } = params;
1516
+ const { match, bindingToken, groupToken, name } = declarationMatch;
1209
1517
  const group = Number(groupToken);
1210
1518
  if (bindingToken === "auto") {
1211
1519
  const registryKey = getBindingRegistryKey(group, module.name, name);
@@ -1244,6 +1552,23 @@ ${getApplicationDefines(allDefines)}
1244
1552
  bindingAssignments.push({ moduleName: module.name, name, group, location });
1245
1553
  return match;
1246
1554
  }
1555
+ function relocateWGSLApplicationBindingMatch(declarationMatch, usedBindingsByGroup, relocationState) {
1556
+ const { match, bindingToken, groupToken, name } = declarationMatch;
1557
+ const group = Number(groupToken);
1558
+ if (bindingToken === "auto") {
1559
+ const location = allocateApplicationAutoBindingLocation(group, usedBindingsByGroup);
1560
+ validateApplicationWGSLBinding(group, location, name);
1561
+ registerUsedBindingLocation(
1562
+ usedBindingsByGroup,
1563
+ group,
1564
+ location,
1565
+ `application binding "${name}"`
1566
+ );
1567
+ return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location})`);
1568
+ }
1569
+ relocationState.sawSupportedBindingDeclaration = true;
1570
+ return match;
1571
+ }
1247
1572
  function reserveRegisteredModuleBindings(modules, bindingRegistry, usedBindingsByGroup) {
1248
1573
  const reservedBindingKeysByGroup = /* @__PURE__ */ new Map();
1249
1574
  if (!bindingRegistry) {
@@ -1293,16 +1618,14 @@ ${getApplicationDefines(allDefines)}
1293
1618
  function getModuleWGSLBindingDeclarations(module) {
1294
1619
  const declarations = [];
1295
1620
  const moduleSource = module.source || "";
1296
- for (const regex of MODULE_WGSL_BINDING_DECLARATION_REGEXES) {
1297
- regex.lastIndex = 0;
1298
- let match;
1299
- while (match = regex.exec(moduleSource)) {
1300
- const isBindingFirst = regex === MODULE_WGSL_BINDING_DECLARATION_REGEXES[0];
1301
- declarations.push({
1302
- name: match[4],
1303
- group: Number(match[isBindingFirst ? 2 : 1])
1304
- });
1305
- }
1621
+ for (const match of getWGSLBindingDeclarationMatches(
1622
+ moduleSource,
1623
+ MODULE_WGSL_BINDING_DECLARATION_REGEXES
1624
+ )) {
1625
+ declarations.push({
1626
+ name: match.name,
1627
+ group: Number(match.groupToken)
1628
+ });
1306
1629
  }
1307
1630
  return declarations;
1308
1631
  }
@@ -1338,10 +1661,36 @@ ${getApplicationDefines(allDefines)}
1338
1661
  }
1339
1662
  return nextBinding;
1340
1663
  }
1664
+ function allocateApplicationAutoBindingLocation(group, usedBindingsByGroup) {
1665
+ const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
1666
+ let nextBinding = 0;
1667
+ while (usedBindings.has(nextBinding)) {
1668
+ nextBinding++;
1669
+ }
1670
+ return nextBinding;
1671
+ }
1341
1672
  function assertNoUnresolvedAutoBindings(source4) {
1342
- if (/@binding\(\s*auto\s*\)/.test(source4)) {
1343
- throw new Error("Unresolved @binding(auto) remained in assembled WGSL source.");
1673
+ const unresolvedBinding = getFirstWGSLAutoBindingDeclarationMatch(
1674
+ source4,
1675
+ MODULE_WGSL_BINDING_DECLARATION_REGEXES
1676
+ );
1677
+ if (!unresolvedBinding) {
1678
+ return;
1679
+ }
1680
+ const moduleName = getWGSLModuleNameAtIndex(source4, unresolvedBinding.index);
1681
+ if (moduleName) {
1682
+ throw new Error(
1683
+ `Unresolved @binding(auto) for module "${moduleName}" binding "${unresolvedBinding.name}" remained in assembled WGSL source.`
1684
+ );
1685
+ }
1686
+ if (isInApplicationWGSLSection(source4, unresolvedBinding.index)) {
1687
+ throw new Error(
1688
+ `Unresolved @binding(auto) for application binding "${unresolvedBinding.name}" remained in assembled WGSL source.`
1689
+ );
1344
1690
  }
1691
+ throw new Error(
1692
+ `Unresolved @binding(auto) remained in assembled WGSL source near "${formatWGSLSourceSnippet(unresolvedBinding.match)}".`
1693
+ );
1345
1694
  }
1346
1695
  function formatWGSLBindingAssignmentComments(bindingAssignments) {
1347
1696
  if (bindingAssignments.length === 0) {
@@ -1358,6 +1707,24 @@ ${getApplicationDefines(allDefines)}
1358
1707
  function getBindingRegistryKey(group, moduleName, bindingName) {
1359
1708
  return `${group}:${moduleName}:${bindingName}`;
1360
1709
  }
1710
+ function getWGSLModuleNameAtIndex(source4, index) {
1711
+ const moduleHeaderRegex = /^\/\/ ----- MODULE ([^\n]+) ---------------$/gm;
1712
+ let moduleName;
1713
+ let match;
1714
+ match = moduleHeaderRegex.exec(source4);
1715
+ while (match && match.index <= index) {
1716
+ moduleName = match[1];
1717
+ match = moduleHeaderRegex.exec(source4);
1718
+ }
1719
+ return moduleName;
1720
+ }
1721
+ function isInApplicationWGSLSection(source4, index) {
1722
+ const injectionMarkerIndex = source4.indexOf(INJECT_SHADER_DECLARATIONS);
1723
+ return injectionMarkerIndex >= 0 ? index > injectionMarkerIndex : true;
1724
+ }
1725
+ function formatWGSLSourceSnippet(source4) {
1726
+ return source4.replace(/\s+/g, " ").trim();
1727
+ }
1361
1728
 
1362
1729
  // src/lib/preprocessor/preprocessor.ts
1363
1730
  var DEFINE_NAME_PATTERN = "([a-zA-Z_][a-zA-Z0-9_]*)";
@@ -1642,7 +2009,7 @@ void main() {
1642
2009
  switch (options.uniforms) {
1643
2010
  case "scoped-interface-blocks":
1644
2011
  case "unscoped-interface-blocks":
1645
- glsl.push(`uniform ${capitalize(module.name)} {`);
2012
+ glsl.push(`layout(std140) uniform ${capitalize(module.name)} {`);
1646
2013
  break;
1647
2014
  case "uniforms":
1648
2015
  }
@@ -3533,6 +3900,28 @@ void main() {
3533
3900
  return matrixFP64;
3534
3901
  }
3535
3902
 
3903
+ // src/lib/color/normalize-byte-colors.ts
3904
+ function resolveUseByteColors(useByteColors, defaultUseByteColors = true) {
3905
+ return useByteColors ?? defaultUseByteColors;
3906
+ }
3907
+ function normalizeByteColor3(color = [0, 0, 0], useByteColors = true) {
3908
+ if (!useByteColors) {
3909
+ return [...color];
3910
+ }
3911
+ return color.map((component) => component / 255);
3912
+ }
3913
+ function normalizeByteColor4(color, useByteColors = true) {
3914
+ const normalizedColor = normalizeByteColor3(color.slice(0, 3), useByteColors);
3915
+ const hasAlpha = Number.isFinite(color[3]);
3916
+ const alpha = hasAlpha ? color[3] : 1;
3917
+ return [
3918
+ normalizedColor[0],
3919
+ normalizedColor[1],
3920
+ normalizedColor[2],
3921
+ useByteColors && hasAlpha ? alpha / 255 : alpha
3922
+ ];
3923
+ }
3924
+
3536
3925
  // src/modules/math/random/random.ts
3537
3926
  var source = (
3538
3927
  /* wgsl */
@@ -3719,7 +4108,7 @@ float tan_fp32(float a) {
3719
4108
  var fp64arithmeticShader = (
3720
4109
  /* glsl */
3721
4110
  `
3722
- uniform fp64arithmeticUniforms {
4111
+ layout(std140) uniform fp64arithmeticUniforms {
3723
4112
  uniform float ONE;
3724
4113
  uniform float SPLIT;
3725
4114
  } fp64;
@@ -4837,15 +5226,99 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
4837
5226
  fp64ifyMatrix4
4838
5227
  };
4839
5228
 
5229
+ // src/modules/color/float-colors.ts
5230
+ var GLSL_UNIFORMS = (
5231
+ /* glsl */
5232
+ `layout(std140) uniform floatColorsUniforms {
5233
+ float useByteColors;
5234
+ } floatColors;
5235
+
5236
+ vec3 floatColors_normalize(vec3 inputColor) {
5237
+ return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;
5238
+ }
5239
+
5240
+ vec4 floatColors_normalize(vec4 inputColor) {
5241
+ return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;
5242
+ }
5243
+
5244
+ vec4 floatColors_premultiplyAlpha(vec4 inputColor) {
5245
+ return vec4(inputColor.rgb * inputColor.a, inputColor.a);
5246
+ }
5247
+
5248
+ vec4 floatColors_unpremultiplyAlpha(vec4 inputColor) {
5249
+ return inputColor.a > 0.0 ? vec4(inputColor.rgb / inputColor.a, inputColor.a) : vec4(0.0);
5250
+ }
5251
+
5252
+ vec4 floatColors_premultiply_alpha(vec4 inputColor) {
5253
+ return floatColors_premultiplyAlpha(inputColor);
5254
+ }
5255
+
5256
+ vec4 floatColors_unpremultiply_alpha(vec4 inputColor) {
5257
+ return floatColors_unpremultiplyAlpha(inputColor);
5258
+ }
5259
+ `
5260
+ );
5261
+ var WGSL_UNIFORMS = (
5262
+ /* wgsl */
5263
+ `struct floatColorsUniforms {
5264
+ useByteColors: f32
5265
+ };
5266
+
5267
+ @group(0) @binding(auto) var<uniform> floatColors : floatColorsUniforms;
5268
+
5269
+ fn floatColors_normalize(inputColor: vec3<f32>) -> vec3<f32> {
5270
+ return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);
5271
+ }
5272
+
5273
+ fn floatColors_normalize4(inputColor: vec4<f32>) -> vec4<f32> {
5274
+ return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5);
5275
+ }
5276
+
5277
+ fn floatColors_premultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {
5278
+ return vec4<f32>(inputColor.rgb * inputColor.a, inputColor.a);
5279
+ }
5280
+
5281
+ fn floatColors_unpremultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {
5282
+ return select(
5283
+ vec4<f32>(0.0),
5284
+ vec4<f32>(inputColor.rgb / inputColor.a, inputColor.a),
5285
+ inputColor.a > 0.0
5286
+ );
5287
+ }
5288
+
5289
+ fn floatColors_premultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {
5290
+ return floatColors_premultiplyAlpha(inputColor);
5291
+ }
5292
+
5293
+ fn floatColors_unpremultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {
5294
+ return floatColors_unpremultiplyAlpha(inputColor);
5295
+ }
5296
+ `
5297
+ );
5298
+ var floatColors = {
5299
+ name: "floatColors",
5300
+ props: {},
5301
+ uniforms: {},
5302
+ vs: GLSL_UNIFORMS,
5303
+ fs: GLSL_UNIFORMS,
5304
+ source: WGSL_UNIFORMS,
5305
+ uniformTypes: {
5306
+ useByteColors: "f32"
5307
+ },
5308
+ defaultUniforms: {
5309
+ useByteColors: true
5310
+ }
5311
+ };
5312
+
4840
5313
  // src/modules/engine/picking/picking.ts
4841
5314
  var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
4842
5315
  var vs = (
4843
5316
  /* glsl */
4844
- `uniform pickingUniforms {
5317
+ `layout(std140) uniform pickingUniforms {
4845
5318
  float isActive;
4846
5319
  float isAttribute;
4847
5320
  float isHighlightActive;
4848
- float useFloatColors;
5321
+ float useByteColors;
4849
5322
  vec3 highlightedObjectColor;
4850
5323
  vec4 highlightColor;
4851
5324
  } picking;
@@ -4854,12 +5327,12 @@ out vec4 picking_vRGBcolor_Avalid;
4854
5327
 
4855
5328
  // Normalize unsigned byte color to 0-1 range
4856
5329
  vec3 picking_normalizeColor(vec3 color) {
4857
- return picking.useFloatColors > 0.5 ? color : color / 255.0;
5330
+ return picking.useByteColors > 0.5 ? color / 255.0 : color;
4858
5331
  }
4859
5332
 
4860
5333
  // Normalize unsigned byte color to 0-1 range
4861
5334
  vec4 picking_normalizeColor(vec4 color) {
4862
- return picking.useFloatColors > 0.5 ? color : color / 255.0;
5335
+ return picking.useByteColors > 0.5 ? color / 255.0 : color;
4863
5336
  }
4864
5337
 
4865
5338
  bool picking_isColorZero(vec3 color) {
@@ -4916,11 +5389,11 @@ void picking_setPickingAttribute(vec3 value) {
4916
5389
  );
4917
5390
  var fs2 = (
4918
5391
  /* glsl */
4919
- `uniform pickingUniforms {
5392
+ `layout(std140) uniform pickingUniforms {
4920
5393
  float isActive;
4921
5394
  float isAttribute;
4922
5395
  float isHighlightActive;
4923
- float useFloatColors;
5396
+ float useByteColors;
4924
5397
  vec3 highlightedObjectColor;
4925
5398
  vec4 highlightColor;
4926
5399
  } picking;
@@ -4982,7 +5455,7 @@ vec4 picking_filterColor(vec4 color) {
4982
5455
  isActive: "f32",
4983
5456
  isAttribute: "f32",
4984
5457
  isHighlightActive: "f32",
4985
- useFloatColors: "f32",
5458
+ useByteColors: "f32",
4986
5459
  highlightedObjectColor: "vec3<f32>",
4987
5460
  highlightColor: "vec4<f32>"
4988
5461
  },
@@ -4990,7 +5463,7 @@ vec4 picking_filterColor(vec4 color) {
4990
5463
  isActive: false,
4991
5464
  isAttribute: false,
4992
5465
  isHighlightActive: false,
4993
- useFloatColors: true,
5466
+ useByteColors: true,
4994
5467
  highlightedObjectColor: [0, 0, 0],
4995
5468
  highlightColor: DEFAULT_HIGHLIGHT_COLOR
4996
5469
  },
@@ -5000,6 +5473,7 @@ vec4 picking_filterColor(vec4 color) {
5000
5473
  };
5001
5474
  function getUniforms(opts = {}, prevUniforms) {
5002
5475
  const uniforms = {};
5476
+ const useByteColors = resolveUseByteColors(opts.useByteColors, true);
5003
5477
  if (opts.highlightedObjectColor === void 0) {
5004
5478
  } else if (opts.highlightedObjectColor === null) {
5005
5479
  uniforms.isHighlightActive = false;
@@ -5009,18 +5483,14 @@ vec4 picking_filterColor(vec4 color) {
5009
5483
  uniforms.highlightedObjectColor = highlightedObjectColor;
5010
5484
  }
5011
5485
  if (opts.highlightColor) {
5012
- const color = Array.from(opts.highlightColor, (x) => x / 255);
5013
- if (!Number.isFinite(color[3])) {
5014
- color[3] = 1;
5015
- }
5016
- uniforms.highlightColor = color;
5486
+ uniforms.highlightColor = normalizeByteColor4(opts.highlightColor, useByteColors);
5017
5487
  }
5018
5488
  if (opts.isActive !== void 0) {
5019
5489
  uniforms.isActive = Boolean(opts.isActive);
5020
5490
  uniforms.isAttribute = Boolean(opts.isAttribute);
5021
5491
  }
5022
- if (opts.useFloatColors !== void 0) {
5023
- uniforms.useFloatColors = Boolean(opts.useFloatColors);
5492
+ if (opts.useByteColors !== void 0) {
5493
+ uniforms.useByteColors = Boolean(opts.useByteColors);
5024
5494
  }
5025
5495
  return uniforms;
5026
5496
  }
@@ -5047,7 +5517,7 @@ fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
5047
5517
  var vs2 = (
5048
5518
  /* glsl */
5049
5519
  `
5050
- uniform skinUniforms {
5520
+ layout(std140) uniform skinUniforms {
5051
5521
  mat4 jointMatrix[SKIN_MAX_JOINTS];
5052
5522
  } skin;
5053
5523
 
@@ -5155,7 +5625,7 @@ struct UniformLight {
5155
5625
  vec2 coneCos;
5156
5626
  };
5157
5627
 
5158
- uniform lightingUniforms {
5628
+ layout(std140) uniform lightingUniforms {
5159
5629
  int enabled;
5160
5630
  int directionalLightCount;
5161
5631
  int pointLightCount;
@@ -5291,7 +5761,6 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5291
5761
 
5292
5762
  // src/modules/lighting/lights/lighting.ts
5293
5763
  var MAX_LIGHTS = 5;
5294
- var COLOR_FACTOR = 255;
5295
5764
  var LIGHT_UNIFORM_TYPE = {
5296
5765
  color: "vec3<f32>",
5297
5766
  position: "vec3<f32>",
@@ -5330,7 +5799,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5330
5799
  if (props.lights) {
5331
5800
  props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
5332
5801
  }
5333
- const { ambientLight, pointLights, spotLights, directionalLights } = props || {};
5802
+ const { useByteColors, ambientLight, pointLights, spotLights, directionalLights } = props || {};
5334
5803
  const hasLights = ambientLight || pointLights && pointLights.length > 0 || spotLights && spotLights.length > 0 || directionalLights && directionalLights.length > 0;
5335
5804
  if (!hasLights) {
5336
5805
  return {
@@ -5340,7 +5809,13 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5340
5809
  }
5341
5810
  const uniforms = {
5342
5811
  ...createDefaultLightingUniforms(),
5343
- ...getLightSourceUniforms({ ambientLight, pointLights, spotLights, directionalLights })
5812
+ ...getLightSourceUniforms({
5813
+ useByteColors,
5814
+ ambientLight,
5815
+ pointLights,
5816
+ spotLights,
5817
+ directionalLights
5818
+ })
5344
5819
  };
5345
5820
  if (props.enabled !== void 0) {
5346
5821
  uniforms.enabled = props.enabled ? 1 : 0;
@@ -5348,6 +5823,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5348
5823
  return uniforms;
5349
5824
  }
5350
5825
  function getLightSourceUniforms({
5826
+ useByteColors,
5351
5827
  ambientLight,
5352
5828
  pointLights = [],
5353
5829
  spotLights = [],
@@ -5364,7 +5840,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5364
5840
  }
5365
5841
  lights[currentLight] = {
5366
5842
  ...lights[currentLight],
5367
- color: convertColor(pointLight),
5843
+ color: convertColor(pointLight, useByteColors),
5368
5844
  position: pointLight.position,
5369
5845
  attenuation: pointLight.attenuation || [1, 0, 0]
5370
5846
  };
@@ -5377,7 +5853,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5377
5853
  }
5378
5854
  lights[currentLight] = {
5379
5855
  ...lights[currentLight],
5380
- color: convertColor(spotLight),
5856
+ color: convertColor(spotLight, useByteColors),
5381
5857
  position: spotLight.position,
5382
5858
  direction: spotLight.direction,
5383
5859
  attenuation: spotLight.attenuation || [1, 0, 0],
@@ -5392,7 +5868,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5392
5868
  }
5393
5869
  lights[currentLight] = {
5394
5870
  ...lights[currentLight],
5395
- color: convertColor(directionalLight),
5871
+ color: convertColor(directionalLight, useByteColors),
5396
5872
  direction: directionalLight.direction
5397
5873
  };
5398
5874
  currentLight++;
@@ -5402,7 +5878,7 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5402
5878
  import_core3.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
5403
5879
  }
5404
5880
  return {
5405
- ambientColor: convertColor(ambientLight),
5881
+ ambientColor: convertColor(ambientLight, useByteColors),
5406
5882
  directionalLightCount,
5407
5883
  pointLightCount,
5408
5884
  spotLightCount,
@@ -5430,9 +5906,10 @@ fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>)
5430
5906
  }
5431
5907
  return lightSources;
5432
5908
  }
5433
- function convertColor(colorDef = {}) {
5909
+ function convertColor(colorDef = {}, useByteColors) {
5434
5910
  const { color = [0, 0, 0], intensity = 1 } = colorDef;
5435
- return color.map((component) => component * intensity / COLOR_FACTOR);
5911
+ const normalizedColor = normalizeByteColor3(color, resolveUseByteColors(useByteColors, true));
5912
+ return normalizedColor.map((component) => component * intensity);
5436
5913
  }
5437
5914
  function createDefaultLightingUniforms() {
5438
5915
  return {
@@ -5500,8 +5977,7 @@ uniform sampler2D pbr_brdfLUT;
5500
5977
  // src/modules/lighting/no-material/dirlight.ts
5501
5978
  var SOURCE_WGSL = (
5502
5979
  /* WGSL */
5503
- `
5504
- struct dirlightUniforms {
5980
+ `struct dirlightUniforms {
5505
5981
  lightDirection: vec3<f32>,
5506
5982
  };
5507
5983
 
@@ -5539,7 +6015,7 @@ void dirlight_setNormal(vec3 normal) {
5539
6015
  );
5540
6016
  var FS_GLSL = (
5541
6017
  /* glsl */
5542
- `uniform dirlightUniforms {
6018
+ `layout(std140) uniform dirlightUniforms {
5543
6019
  vec3 lightDirection;
5544
6020
  } dirlight;
5545
6021
 
@@ -5660,7 +6136,7 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
5660
6136
  // src/modules/lighting/lambert-material/lambert-shaders-glsl.ts
5661
6137
  var LAMBERT_VS = (
5662
6138
  /* glsl */
5663
- `uniform lambertMaterialUniforms {
6139
+ `layout(std140) uniform lambertMaterialUniforms {
5664
6140
  uniform bool unlit;
5665
6141
  uniform float ambient;
5666
6142
  uniform float diffuse;
@@ -5669,7 +6145,7 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
5669
6145
  );
5670
6146
  var LAMBERT_FS = (
5671
6147
  /* glsl */
5672
- `uniform lambertMaterialUniforms {
6148
+ `layout(std140) uniform lambertMaterialUniforms {
5673
6149
  uniform bool unlit;
5674
6150
  uniform float ambient;
5675
6151
  uniform float diffuse;
@@ -5749,7 +6225,7 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
5749
6225
  // src/modules/lighting/phong-material/phong-shaders-glsl.ts
5750
6226
  var PHONG_VS = (
5751
6227
  /* glsl */
5752
- `uniform phongMaterialUniforms {
6228
+ `layout(std140) uniform phongMaterialUniforms {
5753
6229
  uniform bool unlit;
5754
6230
  uniform float ambient;
5755
6231
  uniform float diffuse;
@@ -5760,7 +6236,7 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
5760
6236
  );
5761
6237
  var PHONG_FS = (
5762
6238
  /* glsl */
5763
- `uniform phongMaterialUniforms {
6239
+ `layout(std140) uniform phongMaterialUniforms {
5764
6240
  uniform bool unlit;
5765
6241
  uniform float ambient;
5766
6242
  uniform float diffuse;
@@ -5964,19 +6440,24 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
5964
6440
  ambient: "f32",
5965
6441
  diffuse: "f32",
5966
6442
  shininess: "f32",
5967
- specularColor: "vec3<f32>"
6443
+ specularColor: "vec3<f32>",
6444
+ useByteColors: "i32"
5968
6445
  },
5969
6446
  defaultUniforms: {
5970
6447
  unlit: false,
5971
6448
  ambient: 0.35,
5972
6449
  diffuse: 0.6,
5973
6450
  shininess: 32,
5974
- specularColor: [0.15, 0.15, 0.15]
6451
+ specularColor: [0.15, 0.15, 0.15],
6452
+ useByteColors: true
5975
6453
  },
5976
6454
  getUniforms(props) {
5977
6455
  const uniforms = { ...props };
5978
6456
  if (uniforms.specularColor) {
5979
- uniforms.specularColor = uniforms.specularColor.map((x) => x / 255);
6457
+ uniforms.specularColor = normalizeByteColor3(
6458
+ uniforms.specularColor,
6459
+ resolveUseByteColors(uniforms.useByteColors, true)
6460
+ );
5980
6461
  }
5981
6462
  return { ...gouraudMaterial.defaultUniforms, ...uniforms };
5982
6463
  }
@@ -6000,19 +6481,24 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
6000
6481
  ambient: "f32",
6001
6482
  diffuse: "f32",
6002
6483
  shininess: "f32",
6003
- specularColor: "vec3<f32>"
6484
+ specularColor: "vec3<f32>",
6485
+ useByteColors: "i32"
6004
6486
  },
6005
6487
  defaultUniforms: {
6006
6488
  unlit: false,
6007
6489
  ambient: 0.35,
6008
6490
  diffuse: 0.6,
6009
6491
  shininess: 32,
6010
- specularColor: [0.15, 0.15, 0.15]
6492
+ specularColor: [0.15, 0.15, 0.15],
6493
+ useByteColors: true
6011
6494
  },
6012
6495
  getUniforms(props) {
6013
6496
  const uniforms = { ...props };
6014
6497
  if (uniforms.specularColor) {
6015
- uniforms.specularColor = uniforms.specularColor.map((x) => x / 255);
6498
+ uniforms.specularColor = normalizeByteColor3(
6499
+ uniforms.specularColor,
6500
+ resolveUseByteColors(uniforms.useByteColors, true)
6501
+ );
6016
6502
  }
6017
6503
  return { ...phongMaterial.defaultUniforms, ...uniforms };
6018
6504
  }
@@ -6022,7 +6508,8 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
6022
6508
  var vs3 = (
6023
6509
  /* glsl */
6024
6510
  `out vec3 pbr_vPosition;
6025
- out vec2 pbr_vUV;
6511
+ out vec2 pbr_vUV0;
6512
+ out vec2 pbr_vUV1;
6026
6513
 
6027
6514
  #ifdef HAS_NORMALS
6028
6515
  # ifdef HAS_TANGENTS
@@ -6032,7 +6519,13 @@ out vec3 pbr_vNormal;
6032
6519
  # endif
6033
6520
  #endif
6034
6521
 
6035
- void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
6522
+ void pbr_setPositionNormalTangentUV(
6523
+ vec4 position,
6524
+ vec4 normal,
6525
+ vec4 tangent,
6526
+ vec2 uv0,
6527
+ vec2 uv1
6528
+ )
6036
6529
  {
6037
6530
  vec4 pos = pbrProjection.modelMatrix * position;
6038
6531
  pbr_vPosition = vec3(pos.xyz) / pos.w;
@@ -6049,10 +6542,12 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
6049
6542
  #endif
6050
6543
 
6051
6544
  #ifdef HAS_UV
6052
- pbr_vUV = uv;
6545
+ pbr_vUV0 = uv0;
6053
6546
  #else
6054
- pbr_vUV = vec2(0.,0.);
6547
+ pbr_vUV0 = vec2(0.,0.);
6055
6548
  #endif
6549
+
6550
+ pbr_vUV1 = uv1;
6056
6551
  }
6057
6552
  `
6058
6553
  );
@@ -6060,7 +6555,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
6060
6555
  /* glsl */
6061
6556
  `precision highp float;
6062
6557
 
6063
- uniform pbrMaterialUniforms {
6558
+ layout(std140) uniform pbrMaterialUniforms {
6064
6559
  // Material is unlit
6065
6560
  bool unlit;
6066
6561
 
@@ -6128,6 +6623,41 @@ uniform pbrMaterialUniforms {
6128
6623
  vec4 scaleDiffBaseMR;
6129
6624
  vec4 scaleFGDSpec;
6130
6625
  // #endif
6626
+
6627
+ int baseColorUVSet;
6628
+ mat3 baseColorUVTransform;
6629
+ int metallicRoughnessUVSet;
6630
+ mat3 metallicRoughnessUVTransform;
6631
+ int normalUVSet;
6632
+ mat3 normalUVTransform;
6633
+ int occlusionUVSet;
6634
+ mat3 occlusionUVTransform;
6635
+ int emissiveUVSet;
6636
+ mat3 emissiveUVTransform;
6637
+ int specularColorUVSet;
6638
+ mat3 specularColorUVTransform;
6639
+ int specularIntensityUVSet;
6640
+ mat3 specularIntensityUVTransform;
6641
+ int transmissionUVSet;
6642
+ mat3 transmissionUVTransform;
6643
+ int thicknessUVSet;
6644
+ mat3 thicknessUVTransform;
6645
+ int clearcoatUVSet;
6646
+ mat3 clearcoatUVTransform;
6647
+ int clearcoatRoughnessUVSet;
6648
+ mat3 clearcoatRoughnessUVTransform;
6649
+ int clearcoatNormalUVSet;
6650
+ mat3 clearcoatNormalUVTransform;
6651
+ int sheenColorUVSet;
6652
+ mat3 sheenColorUVTransform;
6653
+ int sheenRoughnessUVSet;
6654
+ mat3 sheenRoughnessUVTransform;
6655
+ int iridescenceUVSet;
6656
+ mat3 iridescenceUVTransform;
6657
+ int iridescenceThicknessUVSet;
6658
+ mat3 iridescenceThicknessUVTransform;
6659
+ int anisotropyUVSet;
6660
+ mat3 anisotropyUVTransform;
6131
6661
  } pbrMaterial;
6132
6662
 
6133
6663
  // Samplers
@@ -6185,7 +6715,8 @@ uniform sampler2D pbr_anisotropySampler;
6185
6715
  // Inputs from vertex shader
6186
6716
 
6187
6717
  in vec3 pbr_vPosition;
6188
- in vec2 pbr_vUV;
6718
+ in vec2 pbr_vUV0;
6719
+ in vec2 pbr_vUV1;
6189
6720
 
6190
6721
  #ifdef HAS_NORMALS
6191
6722
  #ifdef HAS_TANGENTS
@@ -6235,14 +6766,20 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
6235
6766
  #endif //MANUAL_SRGB
6236
6767
  }
6237
6768
 
6769
+ vec2 getMaterialUV(int uvSet, mat3 uvTransform)
6770
+ {
6771
+ vec2 baseUV = uvSet == 1 ? pbr_vUV1 : pbr_vUV0;
6772
+ return (uvTransform * vec3(baseUV, 1.0)).xy;
6773
+ }
6774
+
6238
6775
  // Build the tangent basis from interpolated attributes or screen-space derivatives.
6239
- mat3 getTBN()
6776
+ mat3 getTBN(vec2 uv)
6240
6777
  {
6241
6778
  #ifndef HAS_TANGENTS
6242
6779
  vec3 pos_dx = dFdx(pbr_vPosition);
6243
6780
  vec3 pos_dy = dFdy(pbr_vPosition);
6244
- vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));
6245
- vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));
6781
+ vec3 tex_dx = dFdx(vec3(uv, 0.0));
6782
+ vec3 tex_dy = dFdy(vec3(uv, 0.0));
6246
6783
  vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
6247
6784
 
6248
6785
  #ifdef HAS_NORMALS
@@ -6263,16 +6800,16 @@ mat3 getTBN()
6263
6800
 
6264
6801
  // Find the normal for this fragment, pulling either from a predefined normal map
6265
6802
  // or from the interpolated mesh normal and tangent attributes.
6266
- vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
6803
+ vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale, vec2 uv)
6267
6804
  {
6268
- vec3 n = texture(normalSampler, pbr_vUV).rgb;
6805
+ vec3 n = texture(normalSampler, uv).rgb;
6269
6806
  return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
6270
6807
  }
6271
6808
 
6272
- vec3 getNormal(mat3 tbn)
6809
+ vec3 getNormal(mat3 tbn, vec2 uv)
6273
6810
  {
6274
6811
  #ifdef HAS_NORMALMAP
6275
- vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
6812
+ vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale, uv);
6276
6813
  #else
6277
6814
  // The tbn matrix is linearly interpolated, so we need to re-normalize
6278
6815
  vec3 n = normalize(tbn[2].xyz);
@@ -6281,10 +6818,10 @@ vec3 getNormal(mat3 tbn)
6281
6818
  return n;
6282
6819
  }
6283
6820
 
6284
- vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
6821
+ vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal, vec2 uv)
6285
6822
  {
6286
6823
  #ifdef HAS_CLEARCOATNORMALMAP
6287
- return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
6824
+ return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0, uv);
6288
6825
  #else
6289
6826
  return baseNormal;
6290
6827
  #endif
@@ -6572,9 +7109,61 @@ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
6572
7109
 
6573
7110
  vec4 pbr_filterColor(vec4 colorUnused)
6574
7111
  {
7112
+ vec2 baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);
7113
+ vec2 metallicRoughnessUV = getMaterialUV(
7114
+ pbrMaterial.metallicRoughnessUVSet,
7115
+ pbrMaterial.metallicRoughnessUVTransform
7116
+ );
7117
+ vec2 normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);
7118
+ vec2 occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);
7119
+ vec2 emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);
7120
+ vec2 specularColorUV = getMaterialUV(
7121
+ pbrMaterial.specularColorUVSet,
7122
+ pbrMaterial.specularColorUVTransform
7123
+ );
7124
+ vec2 specularIntensityUV = getMaterialUV(
7125
+ pbrMaterial.specularIntensityUVSet,
7126
+ pbrMaterial.specularIntensityUVTransform
7127
+ );
7128
+ vec2 transmissionUV = getMaterialUV(
7129
+ pbrMaterial.transmissionUVSet,
7130
+ pbrMaterial.transmissionUVTransform
7131
+ );
7132
+ vec2 thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);
7133
+ vec2 clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);
7134
+ vec2 clearcoatRoughnessUV = getMaterialUV(
7135
+ pbrMaterial.clearcoatRoughnessUVSet,
7136
+ pbrMaterial.clearcoatRoughnessUVTransform
7137
+ );
7138
+ vec2 clearcoatNormalUV = getMaterialUV(
7139
+ pbrMaterial.clearcoatNormalUVSet,
7140
+ pbrMaterial.clearcoatNormalUVTransform
7141
+ );
7142
+ vec2 sheenColorUV = getMaterialUV(
7143
+ pbrMaterial.sheenColorUVSet,
7144
+ pbrMaterial.sheenColorUVTransform
7145
+ );
7146
+ vec2 sheenRoughnessUV = getMaterialUV(
7147
+ pbrMaterial.sheenRoughnessUVSet,
7148
+ pbrMaterial.sheenRoughnessUVTransform
7149
+ );
7150
+ vec2 iridescenceUV = getMaterialUV(
7151
+ pbrMaterial.iridescenceUVSet,
7152
+ pbrMaterial.iridescenceUVTransform
7153
+ );
7154
+ vec2 iridescenceThicknessUV = getMaterialUV(
7155
+ pbrMaterial.iridescenceThicknessUVSet,
7156
+ pbrMaterial.iridescenceThicknessUVTransform
7157
+ );
7158
+ vec2 anisotropyUV = getMaterialUV(
7159
+ pbrMaterial.anisotropyUVSet,
7160
+ pbrMaterial.anisotropyUVTransform
7161
+ );
7162
+
6575
7163
  // The albedo may be defined from a base texture or a flat color
6576
7164
  #ifdef HAS_BASECOLORMAP
6577
- vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
7165
+ vec4 baseColor =
7166
+ SRGBtoLINEAR(texture(pbr_baseColorSampler, baseColorUV)) * pbrMaterial.baseColorFactor;
6578
7167
  #else
6579
7168
  vec4 baseColor = pbrMaterial.baseColorFactor;
6580
7169
  #endif
@@ -6601,14 +7190,14 @@ vec4 pbr_filterColor(vec4 colorUnused)
6601
7190
  #ifdef HAS_METALROUGHNESSMAP
6602
7191
  // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
6603
7192
  // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
6604
- vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
7193
+ vec4 mrSample = texture(pbr_metallicRoughnessSampler, metallicRoughnessUV);
6605
7194
  perceptualRoughness = mrSample.g * perceptualRoughness;
6606
7195
  metallic = mrSample.b * metallic;
6607
7196
  #endif
6608
7197
  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
6609
7198
  metallic = clamp(metallic, 0.0, 1.0);
6610
- mat3 tbn = getTBN();
6611
- vec3 n = getNormal(tbn); // normal at surface point
7199
+ mat3 tbn = getTBN(normalUV);
7200
+ vec3 n = getNormal(tbn, normalUV); // normal at surface point
6612
7201
  vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
6613
7202
  float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
6614
7203
  #ifdef USE_MATERIAL_EXTENSIONS
@@ -6709,7 +7298,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6709
7298
 
6710
7299
  #ifdef HAS_OCCLUSIONMAP
6711
7300
  if (pbrMaterial.occlusionMapEnabled) {
6712
- float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
7301
+ float ao = texture(pbr_occlusionSampler, occlusionUV).r;
6713
7302
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
6714
7303
  }
6715
7304
  #endif
@@ -6717,7 +7306,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6717
7306
  vec3 emissive = pbrMaterial.emissiveFactor;
6718
7307
  #ifdef HAS_EMISSIVEMAP
6719
7308
  if (pbrMaterial.emissiveMapEnabled) {
6720
- emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
7309
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;
6721
7310
  }
6722
7311
  #endif
6723
7312
  color += emissive * pbrMaterial.emissiveStrength;
@@ -6734,55 +7323,55 @@ vec4 pbr_filterColor(vec4 colorUnused)
6734
7323
  float specularIntensity = pbrMaterial.specularIntensityFactor;
6735
7324
  #ifdef HAS_SPECULARINTENSITYMAP
6736
7325
  if (pbrMaterial.specularIntensityMapEnabled) {
6737
- specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
7326
+ specularIntensity *= texture(pbr_specularIntensitySampler, specularIntensityUV).a;
6738
7327
  }
6739
7328
  #endif
6740
7329
 
6741
7330
  vec3 specularFactor = pbrMaterial.specularColorFactor;
6742
7331
  #ifdef HAS_SPECULARCOLORMAP
6743
7332
  if (pbrMaterial.specularColorMapEnabled) {
6744
- specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
7333
+ specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, specularColorUV)).rgb;
6745
7334
  }
6746
7335
  #endif
6747
7336
 
6748
7337
  transmission = pbrMaterial.transmissionFactor;
6749
7338
  #ifdef HAS_TRANSMISSIONMAP
6750
7339
  if (pbrMaterial.transmissionMapEnabled) {
6751
- transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
7340
+ transmission *= texture(pbr_transmissionSampler, transmissionUV).r;
6752
7341
  }
6753
7342
  #endif
6754
7343
  transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
6755
7344
  float thickness = max(pbrMaterial.thicknessFactor, 0.0);
6756
7345
  #ifdef HAS_THICKNESSMAP
6757
- thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
7346
+ thickness *= texture(pbr_thicknessSampler, thicknessUV).g;
6758
7347
  #endif
6759
7348
 
6760
7349
  float clearcoatFactor = pbrMaterial.clearcoatFactor;
6761
7350
  float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
6762
7351
  #ifdef HAS_CLEARCOATMAP
6763
7352
  if (pbrMaterial.clearcoatMapEnabled) {
6764
- clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
7353
+ clearcoatFactor *= texture(pbr_clearcoatSampler, clearcoatUV).r;
6765
7354
  }
6766
7355
  #endif
6767
7356
  #ifdef HAS_CLEARCOATROUGHNESSMAP
6768
7357
  if (pbrMaterial.clearcoatRoughnessMapEnabled) {
6769
- clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
7358
+ clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, clearcoatRoughnessUV).g;
6770
7359
  }
6771
7360
  #endif
6772
7361
  clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
6773
7362
  clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
6774
- vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
7363
+ vec3 clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);
6775
7364
 
6776
7365
  vec3 sheenColor = pbrMaterial.sheenColorFactor;
6777
7366
  float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
6778
7367
  #ifdef HAS_SHEENCOLORMAP
6779
7368
  if (pbrMaterial.sheenColorMapEnabled) {
6780
- sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
7369
+ sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, sheenColorUV)).rgb;
6781
7370
  }
6782
7371
  #endif
6783
7372
  #ifdef HAS_SHEENROUGHNESSMAP
6784
7373
  if (pbrMaterial.sheenRoughnessMapEnabled) {
6785
- sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
7374
+ sheenRoughness *= texture(pbr_sheenRoughnessSampler, sheenRoughnessUV).a;
6786
7375
  }
6787
7376
  #endif
6788
7377
  sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
@@ -6790,7 +7379,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6790
7379
  float iridescence = pbrMaterial.iridescenceFactor;
6791
7380
  #ifdef HAS_IRIDESCENCEMAP
6792
7381
  if (pbrMaterial.iridescenceMapEnabled) {
6793
- iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
7382
+ iridescence *= texture(pbr_iridescenceSampler, iridescenceUV).r;
6794
7383
  }
6795
7384
  #endif
6796
7385
  iridescence = clamp(iridescence, 0.0, 1.0);
@@ -6803,7 +7392,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6803
7392
  iridescenceThickness = mix(
6804
7393
  pbrMaterial.iridescenceThicknessRange.x,
6805
7394
  pbrMaterial.iridescenceThicknessRange.y,
6806
- texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
7395
+ texture(pbr_iridescenceThicknessSampler, iridescenceThicknessUV).g
6807
7396
  );
6808
7397
  #endif
6809
7398
 
@@ -6811,7 +7400,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6811
7400
  vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
6812
7401
  #ifdef HAS_ANISOTROPYMAP
6813
7402
  if (pbrMaterial.anisotropyMapEnabled) {
6814
- vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
7403
+ vec3 anisotropySample = texture(pbr_anisotropySampler, anisotropyUV).rgb;
6815
7404
  anisotropyStrength *= anisotropySample.b;
6816
7405
  vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
6817
7406
  if (length(mappedDirection) > 0.0001) {
@@ -6974,7 +7563,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6974
7563
  // Apply optional PBR terms for additional (optional) shading
6975
7564
  #ifdef HAS_OCCLUSIONMAP
6976
7565
  if (pbrMaterial.occlusionMapEnabled) {
6977
- float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
7566
+ float ao = texture(pbr_occlusionSampler, occlusionUV).r;
6978
7567
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
6979
7568
  }
6980
7569
  #endif
@@ -6982,7 +7571,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
6982
7571
  vec3 emissive = pbrMaterial.emissiveFactor;
6983
7572
  #ifdef HAS_EMISSIVEMAP
6984
7573
  if (pbrMaterial.emissiveMapEnabled) {
6985
- emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
7574
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, emissiveUV)).rgb;
6986
7575
  }
6987
7576
  #endif
6988
7577
  color += emissive * pbrMaterial.emissiveStrength;
@@ -7020,14 +7609,21 @@ vec4 pbr_filterColor(vec4 colorUnused)
7020
7609
  /* wgsl */
7021
7610
  `struct PBRFragmentInputs {
7022
7611
  pbr_vPosition: vec3f,
7023
- pbr_vUV: vec2f,
7612
+ pbr_vUV0: vec2f,
7613
+ pbr_vUV1: vec2f,
7024
7614
  pbr_vTBN: mat3x3f,
7025
7615
  pbr_vNormal: vec3f
7026
7616
  };
7027
7617
 
7028
7618
  var<private> fragmentInputs: PBRFragmentInputs;
7029
7619
 
7030
- fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
7620
+ fn pbr_setPositionNormalTangentUV(
7621
+ position: vec4f,
7622
+ normal: vec4f,
7623
+ tangent: vec4f,
7624
+ uv0: vec2f,
7625
+ uv1: vec2f
7626
+ )
7031
7627
  {
7032
7628
  var pos: vec4f = pbrProjection.modelMatrix * position;
7033
7629
  fragmentInputs.pbr_vPosition = pos.xyz / pos.w;
@@ -7037,7 +7633,8 @@ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f
7037
7633
  vec3f(0.0, 1.0, 0.0),
7038
7634
  vec3f(0.0, 0.0, 1.0)
7039
7635
  );
7040
- fragmentInputs.pbr_vUV = vec2f(0.0, 0.0);
7636
+ fragmentInputs.pbr_vUV0 = vec2f(0.0, 0.0);
7637
+ fragmentInputs.pbr_vUV1 = uv1;
7041
7638
 
7042
7639
  #ifdef HAS_NORMALS
7043
7640
  let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);
@@ -7050,7 +7647,7 @@ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f
7050
7647
  #endif
7051
7648
 
7052
7649
  #ifdef HAS_UV
7053
- fragmentInputs.pbr_vUV = uv;
7650
+ fragmentInputs.pbr_vUV0 = uv0;
7054
7651
  #endif
7055
7652
  }
7056
7653
 
@@ -7122,6 +7719,41 @@ struct pbrMaterialUniforms {
7122
7719
  scaleDiffBaseMR: vec4f,
7123
7720
  scaleFGDSpec: vec4f,
7124
7721
  // #endif
7722
+
7723
+ baseColorUVSet: i32,
7724
+ baseColorUVTransform: mat3x3f,
7725
+ metallicRoughnessUVSet: i32,
7726
+ metallicRoughnessUVTransform: mat3x3f,
7727
+ normalUVSet: i32,
7728
+ normalUVTransform: mat3x3f,
7729
+ occlusionUVSet: i32,
7730
+ occlusionUVTransform: mat3x3f,
7731
+ emissiveUVSet: i32,
7732
+ emissiveUVTransform: mat3x3f,
7733
+ specularColorUVSet: i32,
7734
+ specularColorUVTransform: mat3x3f,
7735
+ specularIntensityUVSet: i32,
7736
+ specularIntensityUVTransform: mat3x3f,
7737
+ transmissionUVSet: i32,
7738
+ transmissionUVTransform: mat3x3f,
7739
+ thicknessUVSet: i32,
7740
+ thicknessUVTransform: mat3x3f,
7741
+ clearcoatUVSet: i32,
7742
+ clearcoatUVTransform: mat3x3f,
7743
+ clearcoatRoughnessUVSet: i32,
7744
+ clearcoatRoughnessUVTransform: mat3x3f,
7745
+ clearcoatNormalUVSet: i32,
7746
+ clearcoatNormalUVTransform: mat3x3f,
7747
+ sheenColorUVSet: i32,
7748
+ sheenColorUVTransform: mat3x3f,
7749
+ sheenRoughnessUVSet: i32,
7750
+ sheenRoughnessUVTransform: mat3x3f,
7751
+ iridescenceUVSet: i32,
7752
+ iridescenceUVTransform: mat3x3f,
7753
+ iridescenceThicknessUVSet: i32,
7754
+ iridescenceThicknessUVTransform: mat3x3f,
7755
+ anisotropyUVSet: i32,
7756
+ anisotropyUVTransform: mat3x3f,
7125
7757
  }
7126
7758
 
7127
7759
  @group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
@@ -7235,13 +7867,22 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
7235
7867
  return vec4f(linOut, srgbIn.w);
7236
7868
  }
7237
7869
 
7870
+ fn getMaterialUV(uvSet: i32, uvTransform: mat3x3f) -> vec2f
7871
+ {
7872
+ var baseUV = fragmentInputs.pbr_vUV0;
7873
+ if (uvSet == 1) {
7874
+ baseUV = fragmentInputs.pbr_vUV1;
7875
+ }
7876
+ return (uvTransform * vec3f(baseUV, 1.0)).xy;
7877
+ }
7878
+
7238
7879
  // Build the tangent basis from interpolated attributes or screen-space derivatives.
7239
- fn getTBN() -> mat3x3f
7880
+ fn getTBN(uv: vec2f) -> mat3x3f
7240
7881
  {
7241
7882
  let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
7242
7883
  let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
7243
- let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
7244
- let tex_dy: vec3f = dpdy(vec3f(fragmentInputs.pbr_vUV, 0.0));
7884
+ let tex_dx: vec3f = dpdx(vec3f(uv, 0.0));
7885
+ let tex_dy: vec3f = dpdy(vec3f(uv, 0.0));
7245
7886
  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);
7246
7887
 
7247
7888
  var ng: vec3f = cross(pos_dx, pos_dy);
@@ -7264,14 +7905,15 @@ fn getMappedNormal(
7264
7905
  normalSampler: texture_2d<f32>,
7265
7906
  normalSamplerBinding: sampler,
7266
7907
  tbn: mat3x3f,
7267
- normalScale: f32
7908
+ normalScale: f32,
7909
+ uv: vec2f
7268
7910
  ) -> vec3f
7269
7911
  {
7270
- let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
7912
+ let n = textureSample(normalSampler, normalSamplerBinding, uv).rgb;
7271
7913
  return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
7272
7914
  }
7273
7915
 
7274
- fn getNormal(tbn: mat3x3f) -> vec3f
7916
+ fn getNormal(tbn: mat3x3f, uv: vec2f) -> vec3f
7275
7917
  {
7276
7918
  // The tbn matrix is linearly interpolated, so we need to re-normalize
7277
7919
  var n: vec3f = normalize(tbn[2].xyz);
@@ -7280,21 +7922,23 @@ fn getNormal(tbn: mat3x3f) -> vec3f
7280
7922
  pbr_normalSampler,
7281
7923
  pbr_normalSamplerSampler,
7282
7924
  tbn,
7283
- pbrMaterial.normalScale
7925
+ pbrMaterial.normalScale,
7926
+ uv
7284
7927
  );
7285
7928
  #endif
7286
7929
 
7287
7930
  return n;
7288
7931
  }
7289
7932
 
7290
- fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
7933
+ fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f, uv: vec2f) -> vec3f
7291
7934
  {
7292
7935
  #ifdef HAS_CLEARCOATNORMALMAP
7293
7936
  return getMappedNormal(
7294
7937
  pbr_clearcoatNormalSampler,
7295
7938
  pbr_clearcoatNormalSamplerSampler,
7296
7939
  tbn,
7297
- 1.0
7940
+ 1.0,
7941
+ uv
7298
7942
  );
7299
7943
  #else
7300
7944
  return baseNormal;
@@ -7599,11 +8243,62 @@ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
7599
8243
  }
7600
8244
 
7601
8245
  fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8246
+ let baseColorUV = getMaterialUV(pbrMaterial.baseColorUVSet, pbrMaterial.baseColorUVTransform);
8247
+ let metallicRoughnessUV = getMaterialUV(
8248
+ pbrMaterial.metallicRoughnessUVSet,
8249
+ pbrMaterial.metallicRoughnessUVTransform
8250
+ );
8251
+ let normalUV = getMaterialUV(pbrMaterial.normalUVSet, pbrMaterial.normalUVTransform);
8252
+ let occlusionUV = getMaterialUV(pbrMaterial.occlusionUVSet, pbrMaterial.occlusionUVTransform);
8253
+ let emissiveUV = getMaterialUV(pbrMaterial.emissiveUVSet, pbrMaterial.emissiveUVTransform);
8254
+ let specularColorUV = getMaterialUV(
8255
+ pbrMaterial.specularColorUVSet,
8256
+ pbrMaterial.specularColorUVTransform
8257
+ );
8258
+ let specularIntensityUV = getMaterialUV(
8259
+ pbrMaterial.specularIntensityUVSet,
8260
+ pbrMaterial.specularIntensityUVTransform
8261
+ );
8262
+ let transmissionUV = getMaterialUV(
8263
+ pbrMaterial.transmissionUVSet,
8264
+ pbrMaterial.transmissionUVTransform
8265
+ );
8266
+ let thicknessUV = getMaterialUV(pbrMaterial.thicknessUVSet, pbrMaterial.thicknessUVTransform);
8267
+ let clearcoatUV = getMaterialUV(pbrMaterial.clearcoatUVSet, pbrMaterial.clearcoatUVTransform);
8268
+ let clearcoatRoughnessUV = getMaterialUV(
8269
+ pbrMaterial.clearcoatRoughnessUVSet,
8270
+ pbrMaterial.clearcoatRoughnessUVTransform
8271
+ );
8272
+ let clearcoatNormalUV = getMaterialUV(
8273
+ pbrMaterial.clearcoatNormalUVSet,
8274
+ pbrMaterial.clearcoatNormalUVTransform
8275
+ );
8276
+ let sheenColorUV = getMaterialUV(
8277
+ pbrMaterial.sheenColorUVSet,
8278
+ pbrMaterial.sheenColorUVTransform
8279
+ );
8280
+ let sheenRoughnessUV = getMaterialUV(
8281
+ pbrMaterial.sheenRoughnessUVSet,
8282
+ pbrMaterial.sheenRoughnessUVTransform
8283
+ );
8284
+ let iridescenceUV = getMaterialUV(
8285
+ pbrMaterial.iridescenceUVSet,
8286
+ pbrMaterial.iridescenceUVTransform
8287
+ );
8288
+ let iridescenceThicknessUV = getMaterialUV(
8289
+ pbrMaterial.iridescenceThicknessUVSet,
8290
+ pbrMaterial.iridescenceThicknessUVTransform
8291
+ );
8292
+ let anisotropyUV = getMaterialUV(
8293
+ pbrMaterial.anisotropyUVSet,
8294
+ pbrMaterial.anisotropyUVTransform
8295
+ );
8296
+
7602
8297
  // The albedo may be defined from a base texture or a flat color
7603
8298
  var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;
7604
8299
  #ifdef HAS_BASECOLORMAP
7605
8300
  baseColor = SRGBtoLINEAR(
7606
- textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, fragmentInputs.pbr_vUV)
8301
+ textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, baseColorUV)
7607
8302
  ) * pbrMaterial.baseColorFactor;
7608
8303
  #endif
7609
8304
 
@@ -7630,15 +8325,15 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7630
8325
  let mrSample = textureSample(
7631
8326
  pbr_metallicRoughnessSampler,
7632
8327
  pbr_metallicRoughnessSamplerSampler,
7633
- fragmentInputs.pbr_vUV
8328
+ metallicRoughnessUV
7634
8329
  );
7635
8330
  perceptualRoughness = mrSample.g * perceptualRoughness;
7636
8331
  metallic = mrSample.b * metallic;
7637
8332
  #endif
7638
8333
  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
7639
8334
  metallic = clamp(metallic, 0.0, 1.0);
7640
- let tbn = getTBN();
7641
- let n = getNormal(tbn); // normal at surface point
8335
+ let tbn = getTBN(normalUV);
8336
+ let n = getNormal(tbn, normalUV); // normal at surface point
7642
8337
  let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
7643
8338
  let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
7644
8339
  var useExtendedPBR = false;
@@ -7743,8 +8438,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7743
8438
 
7744
8439
  #ifdef HAS_OCCLUSIONMAP
7745
8440
  if (pbrMaterial.occlusionMapEnabled != 0) {
7746
- let ao =
7747
- textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
8441
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;
7748
8442
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
7749
8443
  }
7750
8444
  #endif
@@ -7753,7 +8447,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7753
8447
  #ifdef HAS_EMISSIVEMAP
7754
8448
  if (pbrMaterial.emissiveMapEnabled != 0u) {
7755
8449
  emissive *= SRGBtoLINEAR(
7756
- textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
8450
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)
7757
8451
  ).rgb;
7758
8452
  }
7759
8453
  #endif
@@ -7774,7 +8468,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7774
8468
  specularIntensity *= textureSample(
7775
8469
  pbr_specularIntensitySampler,
7776
8470
  pbr_specularIntensitySamplerSampler,
7777
- fragmentInputs.pbr_vUV
8471
+ specularIntensityUV
7778
8472
  ).a;
7779
8473
  }
7780
8474
  #endif
@@ -7786,7 +8480,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7786
8480
  textureSample(
7787
8481
  pbr_specularColorSampler,
7788
8482
  pbr_specularColorSamplerSampler,
7789
- fragmentInputs.pbr_vUV
8483
+ specularColorUV
7790
8484
  )
7791
8485
  ).rgb;
7792
8486
  }
@@ -7798,7 +8492,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7798
8492
  transmission *= textureSample(
7799
8493
  pbr_transmissionSampler,
7800
8494
  pbr_transmissionSamplerSampler,
7801
- fragmentInputs.pbr_vUV
8495
+ transmissionUV
7802
8496
  ).r;
7803
8497
  }
7804
8498
  #endif
@@ -7808,7 +8502,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7808
8502
  thickness *= textureSample(
7809
8503
  pbr_thicknessSampler,
7810
8504
  pbr_thicknessSamplerSampler,
7811
- fragmentInputs.pbr_vUV
8505
+ thicknessUV
7812
8506
  ).g;
7813
8507
  #endif
7814
8508
 
@@ -7819,7 +8513,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7819
8513
  clearcoatFactor *= textureSample(
7820
8514
  pbr_clearcoatSampler,
7821
8515
  pbr_clearcoatSamplerSampler,
7822
- fragmentInputs.pbr_vUV
8516
+ clearcoatUV
7823
8517
  ).r;
7824
8518
  }
7825
8519
  #endif
@@ -7828,13 +8522,13 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7828
8522
  clearcoatRoughness *= textureSample(
7829
8523
  pbr_clearcoatRoughnessSampler,
7830
8524
  pbr_clearcoatRoughnessSamplerSampler,
7831
- fragmentInputs.pbr_vUV
8525
+ clearcoatRoughnessUV
7832
8526
  ).g;
7833
8527
  }
7834
8528
  #endif
7835
8529
  clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
7836
8530
  clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
7837
- let clearcoatNormal = getClearcoatNormal(tbn, n);
8531
+ let clearcoatNormal = getClearcoatNormal(getTBN(clearcoatNormalUV), n, clearcoatNormalUV);
7838
8532
 
7839
8533
  var sheenColor = pbrMaterial.sheenColorFactor;
7840
8534
  var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
@@ -7844,7 +8538,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7844
8538
  textureSample(
7845
8539
  pbr_sheenColorSampler,
7846
8540
  pbr_sheenColorSamplerSampler,
7847
- fragmentInputs.pbr_vUV
8541
+ sheenColorUV
7848
8542
  )
7849
8543
  ).rgb;
7850
8544
  }
@@ -7854,7 +8548,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7854
8548
  sheenRoughness *= textureSample(
7855
8549
  pbr_sheenRoughnessSampler,
7856
8550
  pbr_sheenRoughnessSamplerSampler,
7857
- fragmentInputs.pbr_vUV
8551
+ sheenRoughnessUV
7858
8552
  ).a;
7859
8553
  }
7860
8554
  #endif
@@ -7866,7 +8560,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7866
8560
  iridescence *= textureSample(
7867
8561
  pbr_iridescenceSampler,
7868
8562
  pbr_iridescenceSamplerSampler,
7869
- fragmentInputs.pbr_vUV
8563
+ iridescenceUV
7870
8564
  ).r;
7871
8565
  }
7872
8566
  #endif
@@ -7883,7 +8577,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7883
8577
  textureSample(
7884
8578
  pbr_iridescenceThicknessSampler,
7885
8579
  pbr_iridescenceThicknessSamplerSampler,
7886
- fragmentInputs.pbr_vUV
8580
+ iridescenceThicknessUV
7887
8581
  ).g
7888
8582
  );
7889
8583
  #endif
@@ -7895,7 +8589,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
7895
8589
  let anisotropySample = textureSample(
7896
8590
  pbr_anisotropySampler,
7897
8591
  pbr_anisotropySamplerSampler,
7898
- fragmentInputs.pbr_vUV
8592
+ anisotropyUV
7899
8593
  ).rgb;
7900
8594
  anisotropyStrength *= anisotropySample.b;
7901
8595
  let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
@@ -8062,8 +8756,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8062
8756
  // Apply optional PBR terms for additional (optional) shading
8063
8757
  #ifdef HAS_OCCLUSIONMAP
8064
8758
  if (pbrMaterial.occlusionMapEnabled != 0) {
8065
- let ao =
8066
- textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
8759
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, occlusionUV).r;
8067
8760
  color = mix(color, color * ao, pbrMaterial.occlusionStrength);
8068
8761
  }
8069
8762
  #endif
@@ -8072,7 +8765,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8072
8765
  #ifdef HAS_EMISSIVEMAP
8073
8766
  if (pbrMaterial.emissiveMapEnabled != 0u) {
8074
8767
  emissive *= SRGBtoLINEAR(
8075
- textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
8768
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, emissiveUV)
8076
8769
  ).rgb;
8077
8770
  }
8078
8771
  #endif
@@ -8108,7 +8801,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8108
8801
  // src/modules/lighting/pbr-material/pbr-projection.ts
8109
8802
  var uniformBlock = (
8110
8803
  /* glsl */
8111
- `uniform pbrProjectionUniforms {
8804
+ `layout(std140) uniform pbrProjectionUniforms {
8112
8805
  mat4 modelViewProjectionMatrix;
8113
8806
  mat4 modelMatrix;
8114
8807
  mat4 normalMatrix;
@@ -8192,7 +8885,41 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8192
8885
  anisotropyRotation: 0,
8193
8886
  anisotropyDirection: [1, 0],
8194
8887
  anisotropyMapEnabled: false,
8195
- emissiveStrength: 1
8888
+ emissiveStrength: 1,
8889
+ baseColorUVSet: 0,
8890
+ baseColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8891
+ metallicRoughnessUVSet: 0,
8892
+ metallicRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8893
+ normalUVSet: 0,
8894
+ normalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8895
+ occlusionUVSet: 0,
8896
+ occlusionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8897
+ emissiveUVSet: 0,
8898
+ emissiveUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8899
+ specularColorUVSet: 0,
8900
+ specularColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8901
+ specularIntensityUVSet: 0,
8902
+ specularIntensityUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8903
+ transmissionUVSet: 0,
8904
+ transmissionUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8905
+ thicknessUVSet: 0,
8906
+ thicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8907
+ clearcoatUVSet: 0,
8908
+ clearcoatUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8909
+ clearcoatRoughnessUVSet: 0,
8910
+ clearcoatRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8911
+ clearcoatNormalUVSet: 0,
8912
+ clearcoatNormalUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8913
+ sheenColorUVSet: 0,
8914
+ sheenColorUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8915
+ sheenRoughnessUVSet: 0,
8916
+ sheenRoughnessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8917
+ iridescenceUVSet: 0,
8918
+ iridescenceUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8919
+ iridescenceThicknessUVSet: 0,
8920
+ iridescenceThicknessUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1],
8921
+ anisotropyUVSet: 0,
8922
+ anisotropyUVTransform: [1, 0, 0, 0, 1, 0, 0, 0, 1]
8196
8923
  },
8197
8924
  name: "pbrMaterial",
8198
8925
  firstBindingSlot: 0,
@@ -8299,7 +9026,110 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
8299
9026
  // debugging flags used for shader output of intermediate PBR variables
8300
9027
  // #ifdef PBR_DEBUG
8301
9028
  scaleDiffBaseMR: "vec4<f32>",
8302
- scaleFGDSpec: "vec4<f32>"
9029
+ scaleFGDSpec: "vec4<f32>",
9030
+ baseColorUVSet: "i32",
9031
+ baseColorUVTransform: "mat3x3<f32>",
9032
+ metallicRoughnessUVSet: "i32",
9033
+ metallicRoughnessUVTransform: "mat3x3<f32>",
9034
+ normalUVSet: "i32",
9035
+ normalUVTransform: "mat3x3<f32>",
9036
+ occlusionUVSet: "i32",
9037
+ occlusionUVTransform: "mat3x3<f32>",
9038
+ emissiveUVSet: "i32",
9039
+ emissiveUVTransform: "mat3x3<f32>",
9040
+ specularColorUVSet: "i32",
9041
+ specularColorUVTransform: "mat3x3<f32>",
9042
+ specularIntensityUVSet: "i32",
9043
+ specularIntensityUVTransform: "mat3x3<f32>",
9044
+ transmissionUVSet: "i32",
9045
+ transmissionUVTransform: "mat3x3<f32>",
9046
+ thicknessUVSet: "i32",
9047
+ thicknessUVTransform: "mat3x3<f32>",
9048
+ clearcoatUVSet: "i32",
9049
+ clearcoatUVTransform: "mat3x3<f32>",
9050
+ clearcoatRoughnessUVSet: "i32",
9051
+ clearcoatRoughnessUVTransform: "mat3x3<f32>",
9052
+ clearcoatNormalUVSet: "i32",
9053
+ clearcoatNormalUVTransform: "mat3x3<f32>",
9054
+ sheenColorUVSet: "i32",
9055
+ sheenColorUVTransform: "mat3x3<f32>",
9056
+ sheenRoughnessUVSet: "i32",
9057
+ sheenRoughnessUVTransform: "mat3x3<f32>",
9058
+ iridescenceUVSet: "i32",
9059
+ iridescenceUVTransform: "mat3x3<f32>",
9060
+ iridescenceThicknessUVSet: "i32",
9061
+ iridescenceThicknessUVTransform: "mat3x3<f32>",
9062
+ anisotropyUVSet: "i32",
9063
+ anisotropyUVTransform: "mat3x3<f32>"
9064
+ }
9065
+ };
9066
+
9067
+ // src/modules/lighting/pbr-material/pbr-scene.ts
9068
+ var IDENTITY_MATRIX2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
9069
+ var uniformBlock2 = (
9070
+ /* glsl */
9071
+ `layout(std140) uniform pbrSceneUniforms {
9072
+ float exposure;
9073
+ int toneMapMode;
9074
+ float environmentIntensity;
9075
+ float environmentRotation;
9076
+ vec2 framebufferSize;
9077
+ mat4 viewMatrix;
9078
+ mat4 projectionMatrix;
9079
+ } pbrScene;
9080
+
9081
+ #ifdef USE_TRANSMISSION_FRAMEBUFFER
9082
+ uniform sampler2D pbr_transmissionFramebufferSampler;
9083
+ #endif
9084
+ `
9085
+ );
9086
+ var wgslUniformBlock2 = (
9087
+ /* wgsl */
9088
+ `struct pbrSceneUniforms {
9089
+ exposure: f32,
9090
+ toneMapMode: i32,
9091
+ environmentIntensity: f32,
9092
+ environmentRotation: f32,
9093
+ framebufferSize: vec2<f32>,
9094
+ viewMatrix: mat4x4<f32>,
9095
+ projectionMatrix: mat4x4<f32>
9096
+ };
9097
+
9098
+ @group(1) @binding(auto) var<uniform> pbrScene: pbrSceneUniforms;
9099
+
9100
+ #ifdef USE_TRANSMISSION_FRAMEBUFFER
9101
+ @group(1) @binding(auto) var pbr_transmissionFramebufferSampler: texture_2d<f32>;
9102
+ @group(1) @binding(auto) var pbr_transmissionFramebufferSamplerSampler: sampler;
9103
+ #endif
9104
+ `
9105
+ );
9106
+ var pbrScene = {
9107
+ name: "pbrScene",
9108
+ bindingLayout: [
9109
+ { name: "pbrScene", group: 1 },
9110
+ { name: "pbr_transmissionFramebufferSampler", group: 1 }
9111
+ ],
9112
+ source: wgslUniformBlock2,
9113
+ vs: uniformBlock2,
9114
+ fs: uniformBlock2,
9115
+ getUniforms: (props) => props,
9116
+ uniformTypes: {
9117
+ exposure: "f32",
9118
+ toneMapMode: "i32",
9119
+ environmentIntensity: "f32",
9120
+ environmentRotation: "f32",
9121
+ framebufferSize: "vec2<f32>",
9122
+ viewMatrix: "mat4x4<f32>",
9123
+ projectionMatrix: "mat4x4<f32>"
9124
+ },
9125
+ defaultUniforms: {
9126
+ exposure: 1,
9127
+ toneMapMode: 2,
9128
+ environmentIntensity: 1,
9129
+ environmentRotation: Math.PI * 0.5,
9130
+ framebufferSize: [1, 1],
9131
+ viewMatrix: IDENTITY_MATRIX2,
9132
+ projectionMatrix: IDENTITY_MATRIX2
8303
9133
  }
8304
9134
  };
8305
9135
  return __toCommonJS(bundle_exports);