@luma.gl/shadertools 9.3.0-alpha.6 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +2550 -330
- package/dist/dist.min.js +1803 -283
- package/dist/index.cjs +2495 -358
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +4 -3
- package/dist/lib/preprocessor/preprocessor.js.map +1 -1
- package/dist/lib/shader-assembler.d.ts +10 -0
- package/dist/lib/shader-assembler.d.ts.map +1 -1
- package/dist/lib/shader-assembler.js +12 -2
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js +112 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +11 -5
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js.map +1 -1
- package/dist/lib/utils/uniform-types.d.ts +11 -7
- package/dist/lib/utils/uniform-types.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.d.ts +3 -0
- package/dist/modules/engine/picking/picking.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.js +3 -0
- package/dist/modules/engine/picking/picking.js.map +1 -1
- package/dist/modules/engine/skin/skin.d.ts +7 -6
- package/dist/modules/engine/skin/skin.d.ts.map +1 -1
- package/dist/modules/engine/skin/skin.js +3 -5
- package/dist/modules/engine/skin/skin.js.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
- package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
- package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
- package/dist/modules/lighting/ibl/ibl.js +33 -0
- package/dist/modules/lighting/ibl/ibl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
- package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.js +43 -55
- package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.js +43 -65
- package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +104 -86
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +96 -83
- package/dist/modules/lighting/lights/lighting.js.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.d.ts +7 -2
- package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.js +3 -1
- package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +524 -28
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +706 -50
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -61
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +85 -9
- package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js +2 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +4 -0
- package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +15 -4
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +36 -5
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +41 -10
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
- package/dist/modules/math/fp64/fp64.d.ts +1 -0
- package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64.js +8 -2
- package/dist/modules/math/fp64/fp64.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +19 -2
- package/src/lib/preprocessor/preprocessor.ts +6 -3
- package/src/lib/shader-assembler.ts +17 -2
- package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
- package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
- package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
- package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
- package/src/lib/shader-module/shader-module-uniform-layout.ts +194 -0
- package/src/lib/shader-module/shader-module.ts +16 -6
- package/src/lib/utils/uniform-types.ts +24 -9
- package/src/modules/engine/picking/picking.ts +3 -0
- package/src/modules/engine/skin/skin.ts +3 -5
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
- package/src/modules/lighting/ibl/ibl.ts +44 -0
- package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
- package/src/modules/lighting/lights/lighting-glsl.ts +43 -55
- package/src/modules/lighting/lights/lighting-wgsl.ts +43 -65
- package/src/modules/lighting/lights/lighting.ts +186 -123
- package/src/modules/lighting/no-material/dirlight.ts +3 -1
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +524 -28
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +706 -50
- package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
- package/src/modules/lighting/pbr-material/pbr-projection.ts +2 -1
- package/src/modules/lighting/phong-material/phong-material.ts +5 -0
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +15 -4
- package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +36 -5
- package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +41 -10
- package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
- package/src/modules/math/fp64/fp64.ts +9 -3
package/dist/dist.dev.js
CHANGED
|
@@ -75,10 +75,15 @@ var __exports__ = (() => {
|
|
|
75
75
|
getShaderInfo: () => getShaderInfo,
|
|
76
76
|
getShaderModuleDependencies: () => getShaderModuleDependencies,
|
|
77
77
|
getShaderModuleSource: () => getShaderModuleSource,
|
|
78
|
+
getShaderModuleUniformBlockFields: () => getShaderModuleUniformBlockFields,
|
|
79
|
+
getShaderModuleUniformBlockName: () => getShaderModuleUniformBlockName,
|
|
80
|
+
getShaderModuleUniformLayoutValidationResult: () => getShaderModuleUniformLayoutValidationResult,
|
|
78
81
|
getShaderModuleUniforms: () => getShaderModuleUniforms,
|
|
79
82
|
gouraudMaterial: () => gouraudMaterial,
|
|
83
|
+
ibl: () => ibl,
|
|
80
84
|
initializeShaderModule: () => initializeShaderModule,
|
|
81
85
|
initializeShaderModules: () => initializeShaderModules,
|
|
86
|
+
lambertMaterial: () => lambertMaterial,
|
|
82
87
|
lighting: () => lighting,
|
|
83
88
|
pbrMaterial: () => pbrMaterial,
|
|
84
89
|
phongMaterial: () => phongMaterial,
|
|
@@ -88,7 +93,8 @@ var __exports__ = (() => {
|
|
|
88
93
|
skin: () => skin,
|
|
89
94
|
toHalfFloat: () => toHalfFloat,
|
|
90
95
|
typeToChannelCount: () => typeToChannelCount,
|
|
91
|
-
typeToChannelSuffix: () => typeToChannelSuffix
|
|
96
|
+
typeToChannelSuffix: () => typeToChannelSuffix,
|
|
97
|
+
validateShaderModuleUniformLayout: () => validateShaderModuleUniformLayout
|
|
92
98
|
});
|
|
93
99
|
__reExport(bundle_exports, __toESM(require_core(), 1));
|
|
94
100
|
|
|
@@ -409,6 +415,123 @@ ${inject[key]}` : inject[key];
|
|
|
409
415
|
return getShaderDependencies(modules);
|
|
410
416
|
}
|
|
411
417
|
|
|
418
|
+
// src/lib/shader-module/shader-module-uniform-layout.ts
|
|
419
|
+
function getShaderModuleUniformBlockName(module) {
|
|
420
|
+
return `${module.name}Uniforms`;
|
|
421
|
+
}
|
|
422
|
+
function getShaderModuleUniformBlockFields(module, stage) {
|
|
423
|
+
const shaderSource = stage === "wgsl" ? module.source : stage === "vertex" ? module.vs : module.fs;
|
|
424
|
+
if (!shaderSource) {
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
const uniformBlockName = getShaderModuleUniformBlockName(module);
|
|
428
|
+
return extractShaderUniformBlockFieldNames(
|
|
429
|
+
shaderSource,
|
|
430
|
+
stage === "wgsl" ? "wgsl" : "glsl",
|
|
431
|
+
uniformBlockName
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
function getShaderModuleUniformLayoutValidationResult(module, stage) {
|
|
435
|
+
const expectedUniformNames = Object.keys(module.uniformTypes || {});
|
|
436
|
+
if (!expectedUniformNames.length) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
const actualUniformNames = getShaderModuleUniformBlockFields(module, stage);
|
|
440
|
+
if (!actualUniformNames) {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
moduleName: module.name,
|
|
445
|
+
uniformBlockName: getShaderModuleUniformBlockName(module),
|
|
446
|
+
stage,
|
|
447
|
+
expectedUniformNames,
|
|
448
|
+
actualUniformNames,
|
|
449
|
+
matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function validateShaderModuleUniformLayout(module, stage, options = {}) {
|
|
453
|
+
const validationResult = getShaderModuleUniformLayoutValidationResult(module, stage);
|
|
454
|
+
if (!validationResult || validationResult.matches) {
|
|
455
|
+
return validationResult;
|
|
456
|
+
}
|
|
457
|
+
const message = formatShaderModuleUniformLayoutError(validationResult);
|
|
458
|
+
options.log?.error?.(message, validationResult)();
|
|
459
|
+
if (options.throwOnError !== false) {
|
|
460
|
+
assert(false, message);
|
|
461
|
+
}
|
|
462
|
+
return validationResult;
|
|
463
|
+
}
|
|
464
|
+
function extractShaderUniformBlockFieldNames(shaderSource, language, uniformBlockName) {
|
|
465
|
+
const sourceBody = language === "wgsl" ? extractWGSLStructBody(shaderSource, uniformBlockName) : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);
|
|
466
|
+
if (!sourceBody) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
const fieldNames = [];
|
|
470
|
+
for (const sourceLine of sourceBody.split("\n")) {
|
|
471
|
+
const line = sourceLine.replace(/\/\/.*$/, "").trim();
|
|
472
|
+
if (!line || line.startsWith("#")) {
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
const fieldMatch = language === "wgsl" ? line.match(/^([A-Za-z0-9_]+)\s*:/) : line.match(
|
|
476
|
+
/^(?:uniform\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/
|
|
477
|
+
);
|
|
478
|
+
if (fieldMatch) {
|
|
479
|
+
fieldNames.push(fieldMatch[1]);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return fieldNames;
|
|
483
|
+
}
|
|
484
|
+
function extractWGSLStructBody(shaderSource, uniformBlockName) {
|
|
485
|
+
const structMatch = new RegExp(`\\bstruct\\s+${uniformBlockName}\\b`, "m").exec(shaderSource);
|
|
486
|
+
if (!structMatch) {
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
489
|
+
const openBraceIndex = shaderSource.indexOf("{", structMatch.index);
|
|
490
|
+
if (openBraceIndex < 0) {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
let braceDepth = 0;
|
|
494
|
+
for (let index = openBraceIndex; index < shaderSource.length; index++) {
|
|
495
|
+
const character = shaderSource[index];
|
|
496
|
+
if (character === "{") {
|
|
497
|
+
braceDepth++;
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (character !== "}") {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
braceDepth--;
|
|
504
|
+
if (braceDepth === 0) {
|
|
505
|
+
return shaderSource.slice(openBraceIndex + 1, index);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
function extractGLSLUniformBlockBody(shaderSource, uniformBlockName) {
|
|
511
|
+
const sourceMatch = shaderSource.match(
|
|
512
|
+
new RegExp(`uniform\\s+${uniformBlockName}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`, "m")
|
|
513
|
+
);
|
|
514
|
+
return sourceMatch?.[1] || null;
|
|
515
|
+
}
|
|
516
|
+
function areStringArraysEqual(leftValues, rightValues) {
|
|
517
|
+
if (leftValues.length !== rightValues.length) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {
|
|
521
|
+
if (leftValues[valueIndex] !== rightValues[valueIndex]) {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
function formatShaderModuleUniformLayoutError(validationResult) {
|
|
528
|
+
return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${validationResult.uniformBlockName} does not match module.uniformTypes.
|
|
529
|
+
Expected: ${validationResult.expectedUniformNames.join(
|
|
530
|
+
", "
|
|
531
|
+
)}
|
|
532
|
+
Actual: ${validationResult.actualUniformNames.join(", ")}`;
|
|
533
|
+
}
|
|
534
|
+
|
|
412
535
|
// src/lib/shader-assembly/platform-defines.ts
|
|
413
536
|
function getPlatformShaderDefines(platformInfo) {
|
|
414
537
|
switch (platformInfo?.gpu.toLowerCase()) {
|
|
@@ -593,11 +716,166 @@ ${inject[key]}` : inject[key];
|
|
|
593
716
|
return version;
|
|
594
717
|
}
|
|
595
718
|
|
|
719
|
+
// src/lib/shader-assembly/wgsl-binding-debug.ts
|
|
720
|
+
var WGSL_BINDING_DEBUG_REGEXES = [
|
|
721
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g,
|
|
722
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g
|
|
723
|
+
];
|
|
724
|
+
function getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments = []) {
|
|
725
|
+
const assignmentMap = /* @__PURE__ */ new Map();
|
|
726
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
727
|
+
assignmentMap.set(
|
|
728
|
+
getBindingAssignmentKey(
|
|
729
|
+
bindingAssignment.name,
|
|
730
|
+
bindingAssignment.group,
|
|
731
|
+
bindingAssignment.location
|
|
732
|
+
),
|
|
733
|
+
bindingAssignment.moduleName
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
const rows = [];
|
|
737
|
+
for (const regex of WGSL_BINDING_DEBUG_REGEXES) {
|
|
738
|
+
regex.lastIndex = 0;
|
|
739
|
+
let match;
|
|
740
|
+
while (match = regex.exec(source4)) {
|
|
741
|
+
const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];
|
|
742
|
+
const binding = Number(match[isBindingFirst ? 1 : 2]);
|
|
743
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
744
|
+
const accessDeclaration = match[3]?.trim();
|
|
745
|
+
const name = match[4];
|
|
746
|
+
const resourceType = match[5].trim();
|
|
747
|
+
const moduleName = assignmentMap.get(getBindingAssignmentKey(name, group, binding));
|
|
748
|
+
rows.push(
|
|
749
|
+
normalizeShaderBindingDebugRow({
|
|
750
|
+
name,
|
|
751
|
+
group,
|
|
752
|
+
binding,
|
|
753
|
+
owner: moduleName ? "module" : "application",
|
|
754
|
+
moduleName,
|
|
755
|
+
accessDeclaration,
|
|
756
|
+
resourceType
|
|
757
|
+
})
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return rows.sort((left, right) => {
|
|
762
|
+
if (left.group !== right.group) {
|
|
763
|
+
return left.group - right.group;
|
|
764
|
+
}
|
|
765
|
+
if (left.binding !== right.binding) {
|
|
766
|
+
return left.binding - right.binding;
|
|
767
|
+
}
|
|
768
|
+
return left.name.localeCompare(right.name);
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
function normalizeShaderBindingDebugRow(row) {
|
|
772
|
+
const baseRow = {
|
|
773
|
+
name: row.name,
|
|
774
|
+
group: row.group,
|
|
775
|
+
binding: row.binding,
|
|
776
|
+
owner: row.owner,
|
|
777
|
+
kind: "unknown",
|
|
778
|
+
moduleName: row.moduleName,
|
|
779
|
+
resourceType: row.resourceType
|
|
780
|
+
};
|
|
781
|
+
if (row.accessDeclaration) {
|
|
782
|
+
const access = row.accessDeclaration.split(",").map((value) => value.trim());
|
|
783
|
+
if (access[0] === "uniform") {
|
|
784
|
+
return { ...baseRow, kind: "uniform", access: "uniform" };
|
|
785
|
+
}
|
|
786
|
+
if (access[0] === "storage") {
|
|
787
|
+
const storageAccess = access[1] || "read_write";
|
|
788
|
+
return {
|
|
789
|
+
...baseRow,
|
|
790
|
+
kind: storageAccess === "read" ? "read-only-storage" : "storage",
|
|
791
|
+
access: storageAccess
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
if (row.resourceType === "sampler" || row.resourceType === "sampler_comparison") {
|
|
796
|
+
return {
|
|
797
|
+
...baseRow,
|
|
798
|
+
kind: "sampler",
|
|
799
|
+
samplerKind: row.resourceType === "sampler_comparison" ? "comparison" : "filtering"
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
if (row.resourceType.startsWith("texture_storage_")) {
|
|
803
|
+
return {
|
|
804
|
+
...baseRow,
|
|
805
|
+
kind: "storage-texture",
|
|
806
|
+
access: getStorageTextureAccess(row.resourceType),
|
|
807
|
+
viewDimension: getTextureViewDimension(row.resourceType)
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
if (row.resourceType.startsWith("texture_")) {
|
|
811
|
+
return {
|
|
812
|
+
...baseRow,
|
|
813
|
+
kind: "texture",
|
|
814
|
+
viewDimension: getTextureViewDimension(row.resourceType),
|
|
815
|
+
sampleType: getTextureSampleType(row.resourceType),
|
|
816
|
+
multisampled: row.resourceType.startsWith("texture_multisampled_")
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
return baseRow;
|
|
820
|
+
}
|
|
821
|
+
function getBindingAssignmentKey(name, group, binding) {
|
|
822
|
+
return `${group}:${binding}:${name}`;
|
|
823
|
+
}
|
|
824
|
+
function getTextureViewDimension(resourceType) {
|
|
825
|
+
if (resourceType.includes("cube_array")) {
|
|
826
|
+
return "cube-array";
|
|
827
|
+
}
|
|
828
|
+
if (resourceType.includes("2d_array")) {
|
|
829
|
+
return "2d-array";
|
|
830
|
+
}
|
|
831
|
+
if (resourceType.includes("cube")) {
|
|
832
|
+
return "cube";
|
|
833
|
+
}
|
|
834
|
+
if (resourceType.includes("3d")) {
|
|
835
|
+
return "3d";
|
|
836
|
+
}
|
|
837
|
+
if (resourceType.includes("2d")) {
|
|
838
|
+
return "2d";
|
|
839
|
+
}
|
|
840
|
+
if (resourceType.includes("1d")) {
|
|
841
|
+
return "1d";
|
|
842
|
+
}
|
|
843
|
+
return void 0;
|
|
844
|
+
}
|
|
845
|
+
function getTextureSampleType(resourceType) {
|
|
846
|
+
if (resourceType.startsWith("texture_depth_")) {
|
|
847
|
+
return "depth";
|
|
848
|
+
}
|
|
849
|
+
if (resourceType.includes("<i32>")) {
|
|
850
|
+
return "sint";
|
|
851
|
+
}
|
|
852
|
+
if (resourceType.includes("<u32>")) {
|
|
853
|
+
return "uint";
|
|
854
|
+
}
|
|
855
|
+
if (resourceType.includes("<f32>")) {
|
|
856
|
+
return "float";
|
|
857
|
+
}
|
|
858
|
+
return void 0;
|
|
859
|
+
}
|
|
860
|
+
function getStorageTextureAccess(resourceType) {
|
|
861
|
+
const match = /,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(resourceType);
|
|
862
|
+
return match?.[1];
|
|
863
|
+
}
|
|
864
|
+
|
|
596
865
|
// src/lib/shader-assembly/assemble-shaders.ts
|
|
597
866
|
var INJECT_SHADER_DECLARATIONS = `
|
|
598
867
|
|
|
599
868
|
${DECLARATION_INJECT_MARKER}
|
|
600
869
|
`;
|
|
870
|
+
var MODULE_WGSL_BINDING_DECLARATION_REGEXES = [
|
|
871
|
+
/@binding\(\s*(auto|\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
872
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(auto|\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
873
|
+
];
|
|
874
|
+
var WGSL_BINDING_DECLARATION_REGEXES = [
|
|
875
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
876
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
877
|
+
];
|
|
878
|
+
var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
|
|
601
879
|
var FRAGMENT_SHADER_PROLOGUE = (
|
|
602
880
|
/* glsl */
|
|
603
881
|
`precision highp float;
|
|
@@ -605,14 +883,17 @@ ${DECLARATION_INJECT_MARKER}
|
|
|
605
883
|
);
|
|
606
884
|
function assembleWGSLShader(options) {
|
|
607
885
|
const modules = getShaderModuleDependencies(options.modules || []);
|
|
886
|
+
const { source: source4, bindingAssignments } = assembleShaderWGSL(options.platformInfo, {
|
|
887
|
+
...options,
|
|
888
|
+
source: options.source,
|
|
889
|
+
stage: "vertex",
|
|
890
|
+
modules
|
|
891
|
+
});
|
|
608
892
|
return {
|
|
609
|
-
source:
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
modules
|
|
614
|
-
}),
|
|
615
|
-
getUniforms: assembleGetUniforms(modules)
|
|
893
|
+
source: source4,
|
|
894
|
+
getUniforms: assembleGetUniforms(modules),
|
|
895
|
+
bindingAssignments,
|
|
896
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments)
|
|
616
897
|
};
|
|
617
898
|
}
|
|
618
899
|
function assembleGLSLShaderPair(options) {
|
|
@@ -673,11 +954,28 @@ ${DECLARATION_INJECT_MARKER}
|
|
|
673
954
|
}
|
|
674
955
|
}
|
|
675
956
|
const modulesToInject = modules;
|
|
957
|
+
const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(coreSource);
|
|
958
|
+
const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(
|
|
959
|
+
modulesToInject,
|
|
960
|
+
options._bindingRegistry,
|
|
961
|
+
usedBindingsByGroup
|
|
962
|
+
);
|
|
963
|
+
const bindingAssignments = [];
|
|
676
964
|
for (const module of modulesToInject) {
|
|
677
965
|
if (log2) {
|
|
678
966
|
checkShaderModuleDeprecations(module, coreSource, log2);
|
|
679
967
|
}
|
|
680
|
-
const
|
|
968
|
+
const relocation = relocateWGSLModuleBindings(
|
|
969
|
+
getShaderModuleSource(module, "wgsl", log2),
|
|
970
|
+
module,
|
|
971
|
+
{
|
|
972
|
+
usedBindingsByGroup,
|
|
973
|
+
bindingRegistry: options._bindingRegistry,
|
|
974
|
+
reservedBindingKeysByGroup
|
|
975
|
+
}
|
|
976
|
+
);
|
|
977
|
+
bindingAssignments.push(...relocation.bindingAssignments);
|
|
978
|
+
const moduleSource = relocation.source;
|
|
681
979
|
assembledSource += moduleSource;
|
|
682
980
|
const injections = module.injections?.[stage] || {};
|
|
683
981
|
for (const key in injections) {
|
|
@@ -696,9 +994,11 @@ ${DECLARATION_INJECT_MARKER}
|
|
|
696
994
|
assembledSource += INJECT_SHADER_DECLARATIONS;
|
|
697
995
|
assembledSource = injectShader(assembledSource, stage, declInjections);
|
|
698
996
|
assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);
|
|
997
|
+
assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);
|
|
699
998
|
assembledSource += coreSource;
|
|
700
999
|
assembledSource = injectShader(assembledSource, stage, mainInjections);
|
|
701
|
-
|
|
1000
|
+
assertNoUnresolvedAutoBindings(assembledSource);
|
|
1001
|
+
return { source: assembledSource, bindingAssignments };
|
|
702
1002
|
}
|
|
703
1003
|
function assembleShaderGLSL(platformInfo, options) {
|
|
704
1004
|
const {
|
|
@@ -771,7 +1071,7 @@ ${getApplicationDefines(allDefines)}
|
|
|
771
1071
|
if (log2) {
|
|
772
1072
|
checkShaderModuleDeprecations(module, coreSource, log2);
|
|
773
1073
|
}
|
|
774
|
-
const moduleSource = getShaderModuleSource(module, stage);
|
|
1074
|
+
const moduleSource = getShaderModuleSource(module, stage, log2);
|
|
775
1075
|
assembledSource += moduleSource;
|
|
776
1076
|
const injections = module.instance?.normalizedInjections[stage] || {};
|
|
777
1077
|
for (const key in injections) {
|
|
@@ -819,7 +1119,7 @@ ${getApplicationDefines(allDefines)}
|
|
|
819
1119
|
}
|
|
820
1120
|
return sourceText;
|
|
821
1121
|
}
|
|
822
|
-
function getShaderModuleSource(module, stage) {
|
|
1122
|
+
function getShaderModuleSource(module, stage, log2) {
|
|
823
1123
|
let moduleSource;
|
|
824
1124
|
switch (stage) {
|
|
825
1125
|
case "vertex":
|
|
@@ -837,6 +1137,7 @@ ${getApplicationDefines(allDefines)}
|
|
|
837
1137
|
if (!module.name) {
|
|
838
1138
|
throw new Error("Shader module must have a name");
|
|
839
1139
|
}
|
|
1140
|
+
validateShaderModuleUniformLayout(module, stage, { log: log2 });
|
|
840
1141
|
const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, "_");
|
|
841
1142
|
let source4 = `// ----- MODULE ${module.name} ---------------
|
|
842
1143
|
|
|
@@ -849,13 +1150,225 @@ ${getApplicationDefines(allDefines)}
|
|
|
849
1150
|
`;
|
|
850
1151
|
return source4;
|
|
851
1152
|
}
|
|
1153
|
+
function getUsedBindingsByGroupFromApplicationWGSL(source4) {
|
|
1154
|
+
const usedBindingsByGroup = /* @__PURE__ */ new Map();
|
|
1155
|
+
for (const regex of WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1156
|
+
regex.lastIndex = 0;
|
|
1157
|
+
let match;
|
|
1158
|
+
while (match = regex.exec(source4)) {
|
|
1159
|
+
const isBindingFirst = regex === WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1160
|
+
const location = Number(match[isBindingFirst ? 1 : 2]);
|
|
1161
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
1162
|
+
const name = match[4];
|
|
1163
|
+
validateApplicationWGSLBinding(group, location, name);
|
|
1164
|
+
registerUsedBindingLocation(
|
|
1165
|
+
usedBindingsByGroup,
|
|
1166
|
+
group,
|
|
1167
|
+
location,
|
|
1168
|
+
`application binding "${name}"`
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
return usedBindingsByGroup;
|
|
1173
|
+
}
|
|
1174
|
+
function relocateWGSLModuleBindings(moduleSource, module, context) {
|
|
1175
|
+
const bindingAssignments = [];
|
|
1176
|
+
const relocationState = {
|
|
1177
|
+
sawSupportedBindingDeclaration: false,
|
|
1178
|
+
nextHintedBindingLocation: typeof module.firstBindingSlot === "number" ? module.firstBindingSlot : null
|
|
1179
|
+
};
|
|
1180
|
+
let relocatedSource = relocateWGSLModuleBindingsWithRegex(
|
|
1181
|
+
moduleSource,
|
|
1182
|
+
MODULE_WGSL_BINDING_DECLARATION_REGEXES[0],
|
|
1183
|
+
{ isBindingFirst: true, module, context, bindingAssignments, relocationState }
|
|
1184
|
+
);
|
|
1185
|
+
relocatedSource = relocateWGSLModuleBindingsWithRegex(
|
|
1186
|
+
relocatedSource,
|
|
1187
|
+
MODULE_WGSL_BINDING_DECLARATION_REGEXES[1],
|
|
1188
|
+
{ isBindingFirst: false, module, context, bindingAssignments, relocationState }
|
|
1189
|
+
);
|
|
1190
|
+
if (moduleSource.includes("@binding(auto)") && !relocationState.sawSupportedBindingDeclaration) {
|
|
1191
|
+
throw new Error(
|
|
1192
|
+
`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.`
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
return { source: relocatedSource, bindingAssignments };
|
|
1196
|
+
}
|
|
1197
|
+
function relocateWGSLModuleBindingsWithRegex(source4, regex, params) {
|
|
1198
|
+
return source4.replace(
|
|
1199
|
+
regex,
|
|
1200
|
+
(...replaceArguments) => relocateWGSLModuleBindingMatch(replaceArguments, params)
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
function relocateWGSLModuleBindingMatch(replaceArguments, params) {
|
|
1204
|
+
const { isBindingFirst, module, context, bindingAssignments, relocationState } = params;
|
|
1205
|
+
relocationState.sawSupportedBindingDeclaration = true;
|
|
1206
|
+
const match = replaceArguments[0];
|
|
1207
|
+
const bindingToken = replaceArguments[isBindingFirst ? 1 : 2];
|
|
1208
|
+
const groupToken = replaceArguments[isBindingFirst ? 2 : 1];
|
|
1209
|
+
const name = replaceArguments[4];
|
|
1210
|
+
const group = Number(groupToken);
|
|
1211
|
+
if (bindingToken === "auto") {
|
|
1212
|
+
const registryKey = getBindingRegistryKey(group, module.name, name);
|
|
1213
|
+
const registryLocation = context.bindingRegistry?.get(registryKey);
|
|
1214
|
+
const location2 = registryLocation !== void 0 ? registryLocation : relocationState.nextHintedBindingLocation === null ? allocateAutoBindingLocation(group, context.usedBindingsByGroup) : allocateAutoBindingLocation(
|
|
1215
|
+
group,
|
|
1216
|
+
context.usedBindingsByGroup,
|
|
1217
|
+
relocationState.nextHintedBindingLocation
|
|
1218
|
+
);
|
|
1219
|
+
validateModuleWGSLBinding(module.name, group, location2, name);
|
|
1220
|
+
if (registryLocation !== void 0 && claimReservedBindingLocation(context.reservedBindingKeysByGroup, group, location2, registryKey)) {
|
|
1221
|
+
bindingAssignments.push({ moduleName: module.name, name, group, location: location2 });
|
|
1222
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1223
|
+
}
|
|
1224
|
+
registerUsedBindingLocation(
|
|
1225
|
+
context.usedBindingsByGroup,
|
|
1226
|
+
group,
|
|
1227
|
+
location2,
|
|
1228
|
+
`module "${module.name}" binding "${name}"`
|
|
1229
|
+
);
|
|
1230
|
+
context.bindingRegistry?.set(registryKey, location2);
|
|
1231
|
+
bindingAssignments.push({ moduleName: module.name, name, group, location: location2 });
|
|
1232
|
+
if (relocationState.nextHintedBindingLocation !== null && registryLocation === void 0) {
|
|
1233
|
+
relocationState.nextHintedBindingLocation = location2 + 1;
|
|
1234
|
+
}
|
|
1235
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1236
|
+
}
|
|
1237
|
+
const location = Number(bindingToken);
|
|
1238
|
+
validateModuleWGSLBinding(module.name, group, location, name);
|
|
1239
|
+
registerUsedBindingLocation(
|
|
1240
|
+
context.usedBindingsByGroup,
|
|
1241
|
+
group,
|
|
1242
|
+
location,
|
|
1243
|
+
`module "${module.name}" binding "${name}"`
|
|
1244
|
+
);
|
|
1245
|
+
bindingAssignments.push({ moduleName: module.name, name, group, location });
|
|
1246
|
+
return match;
|
|
1247
|
+
}
|
|
1248
|
+
function reserveRegisteredModuleBindings(modules, bindingRegistry, usedBindingsByGroup) {
|
|
1249
|
+
const reservedBindingKeysByGroup = /* @__PURE__ */ new Map();
|
|
1250
|
+
if (!bindingRegistry) {
|
|
1251
|
+
return reservedBindingKeysByGroup;
|
|
1252
|
+
}
|
|
1253
|
+
for (const module of modules) {
|
|
1254
|
+
for (const binding of getModuleWGSLBindingDeclarations(module)) {
|
|
1255
|
+
const registryKey = getBindingRegistryKey(binding.group, module.name, binding.name);
|
|
1256
|
+
const location = bindingRegistry.get(registryKey);
|
|
1257
|
+
if (location !== void 0) {
|
|
1258
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(binding.group) || /* @__PURE__ */ new Map();
|
|
1259
|
+
const existingReservation = reservedBindingKeys.get(location);
|
|
1260
|
+
if (existingReservation && existingReservation !== registryKey) {
|
|
1261
|
+
throw new Error(
|
|
1262
|
+
`Duplicate WGSL binding reservation for modules "${existingReservation}" and "${registryKey}": group ${binding.group}, binding ${location}.`
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
registerUsedBindingLocation(
|
|
1266
|
+
usedBindingsByGroup,
|
|
1267
|
+
binding.group,
|
|
1268
|
+
location,
|
|
1269
|
+
`registered module binding "${registryKey}"`
|
|
1270
|
+
);
|
|
1271
|
+
reservedBindingKeys.set(location, registryKey);
|
|
1272
|
+
reservedBindingKeysByGroup.set(binding.group, reservedBindingKeys);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return reservedBindingKeysByGroup;
|
|
1277
|
+
}
|
|
1278
|
+
function claimReservedBindingLocation(reservedBindingKeysByGroup, group, location, registryKey) {
|
|
1279
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(group);
|
|
1280
|
+
if (!reservedBindingKeys) {
|
|
1281
|
+
return false;
|
|
1282
|
+
}
|
|
1283
|
+
const reservedKey = reservedBindingKeys.get(location);
|
|
1284
|
+
if (!reservedKey) {
|
|
1285
|
+
return false;
|
|
1286
|
+
}
|
|
1287
|
+
if (reservedKey !== registryKey) {
|
|
1288
|
+
throw new Error(
|
|
1289
|
+
`Registered module binding "${registryKey}" collided with "${reservedKey}": group ${group}, binding ${location}.`
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
return true;
|
|
1293
|
+
}
|
|
1294
|
+
function getModuleWGSLBindingDeclarations(module) {
|
|
1295
|
+
const declarations = [];
|
|
1296
|
+
const moduleSource = module.source || "";
|
|
1297
|
+
for (const regex of MODULE_WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1298
|
+
regex.lastIndex = 0;
|
|
1299
|
+
let match;
|
|
1300
|
+
while (match = regex.exec(moduleSource)) {
|
|
1301
|
+
const isBindingFirst = regex === MODULE_WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1302
|
+
declarations.push({
|
|
1303
|
+
name: match[4],
|
|
1304
|
+
group: Number(match[isBindingFirst ? 2 : 1])
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
return declarations;
|
|
1309
|
+
}
|
|
1310
|
+
function validateApplicationWGSLBinding(group, location, name) {
|
|
1311
|
+
if (group === 0 && location >= RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1312
|
+
throw new Error(
|
|
1313
|
+
`Application binding "${name}" in group 0 uses reserved binding ${location}. Application-owned explicit group-0 bindings must stay below ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT}.`
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
function validateModuleWGSLBinding(moduleName, group, location, name) {
|
|
1318
|
+
if (group === 0 && location < RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1319
|
+
throw new Error(
|
|
1320
|
+
`Module "${moduleName}" binding "${name}" in group 0 uses reserved application binding ${location}. Module-owned explicit group-0 bindings must be ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT} or higher.`
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
function registerUsedBindingLocation(usedBindingsByGroup, group, location, label) {
|
|
1325
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1326
|
+
if (usedBindings.has(location)) {
|
|
1327
|
+
throw new Error(
|
|
1328
|
+
`Duplicate WGSL binding assignment for ${label}: group ${group}, binding ${location}.`
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
usedBindings.add(location);
|
|
1332
|
+
usedBindingsByGroup.set(group, usedBindings);
|
|
1333
|
+
}
|
|
1334
|
+
function allocateAutoBindingLocation(group, usedBindingsByGroup, preferredBindingLocation) {
|
|
1335
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1336
|
+
let nextBinding = preferredBindingLocation ?? (group === 0 ? RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT : usedBindings.size > 0 ? Math.max(...usedBindings) + 1 : 0);
|
|
1337
|
+
while (usedBindings.has(nextBinding)) {
|
|
1338
|
+
nextBinding++;
|
|
1339
|
+
}
|
|
1340
|
+
return nextBinding;
|
|
1341
|
+
}
|
|
1342
|
+
function assertNoUnresolvedAutoBindings(source4) {
|
|
1343
|
+
if (/@binding\(\s*auto\s*\)/.test(source4)) {
|
|
1344
|
+
throw new Error("Unresolved @binding(auto) remained in assembled WGSL source.");
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
function formatWGSLBindingAssignmentComments(bindingAssignments) {
|
|
1348
|
+
if (bindingAssignments.length === 0) {
|
|
1349
|
+
return "";
|
|
1350
|
+
}
|
|
1351
|
+
let source4 = "// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------\n";
|
|
1352
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
1353
|
+
source4 += `// ${bindingAssignment.moduleName}.${bindingAssignment.name} -> @group(${bindingAssignment.group}) @binding(${bindingAssignment.location})
|
|
1354
|
+
`;
|
|
1355
|
+
}
|
|
1356
|
+
source4 += "\n";
|
|
1357
|
+
return source4;
|
|
1358
|
+
}
|
|
1359
|
+
function getBindingRegistryKey(group, moduleName, bindingName) {
|
|
1360
|
+
return `${group}:${moduleName}:${bindingName}`;
|
|
1361
|
+
}
|
|
852
1362
|
|
|
853
1363
|
// src/lib/preprocessor/preprocessor.ts
|
|
854
|
-
var
|
|
855
|
-
var
|
|
1364
|
+
var DEFINE_NAME_PATTERN = "([a-zA-Z_][a-zA-Z0-9_]*)";
|
|
1365
|
+
var IFDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*$`);
|
|
1366
|
+
var IFNDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifndef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`);
|
|
856
1367
|
var ELSE_REGEXP = /^\s*\#\s*else\s*(?:\/\/.*)?$/;
|
|
857
1368
|
var ENDIF_REGEXP = /^\s*\#\s*endif\s*$/;
|
|
858
|
-
var IFDEF_WITH_COMMENT_REGEXP =
|
|
1369
|
+
var IFDEF_WITH_COMMENT_REGEXP = new RegExp(
|
|
1370
|
+
`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`
|
|
1371
|
+
);
|
|
859
1372
|
var ENDIF_WITH_COMMENT_REGEXP = /^\s*\#\s*endif\s*(?:\/\/.*)?$/;
|
|
860
1373
|
function preprocess(source4, options) {
|
|
861
1374
|
const lines = source4.split("\n");
|
|
@@ -901,6 +1414,8 @@ ${getApplicationDefines(allDefines)}
|
|
|
901
1414
|
_hookFunctions = [];
|
|
902
1415
|
/** Shader modules */
|
|
903
1416
|
_defaultModules = [];
|
|
1417
|
+
/** Stable per-run WGSL auto-binding assignments keyed by group/module/binding. */
|
|
1418
|
+
_wgslBindingRegistry = /* @__PURE__ */ new Map();
|
|
904
1419
|
/**
|
|
905
1420
|
* A default shader assembler instance - the natural place to register default modules and hooks
|
|
906
1421
|
* @returns
|
|
@@ -946,10 +1461,11 @@ ${getApplicationDefines(allDefines)}
|
|
|
946
1461
|
assembleWGSLShader(props) {
|
|
947
1462
|
const modules = this._getModuleList(props.modules);
|
|
948
1463
|
const hookFunctions = this._hookFunctions;
|
|
949
|
-
const { source: source4, getUniforms: getUniforms4 } = assembleWGSLShader({
|
|
1464
|
+
const { source: source4, getUniforms: getUniforms4, bindingAssignments } = assembleWGSLShader({
|
|
950
1465
|
...props,
|
|
951
1466
|
// @ts-expect-error
|
|
952
1467
|
source: props.source,
|
|
1468
|
+
_bindingRegistry: this._wgslBindingRegistry,
|
|
953
1469
|
modules,
|
|
954
1470
|
hookFunctions
|
|
955
1471
|
});
|
|
@@ -961,7 +1477,13 @@ ${getApplicationDefines(allDefines)}
|
|
|
961
1477
|
...props.defines
|
|
962
1478
|
};
|
|
963
1479
|
const preprocessedSource = props.platformInfo.shaderLanguage === "wgsl" ? preprocess(source4, { defines }) : source4;
|
|
964
|
-
return {
|
|
1480
|
+
return {
|
|
1481
|
+
source: preprocessedSource,
|
|
1482
|
+
getUniforms: getUniforms4,
|
|
1483
|
+
modules,
|
|
1484
|
+
bindingAssignments,
|
|
1485
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(preprocessedSource, bindingAssignments)
|
|
1486
|
+
};
|
|
965
1487
|
}
|
|
966
1488
|
/**
|
|
967
1489
|
* Assemble a pair of shaders into a single shader program
|
|
@@ -1126,6 +1648,11 @@ void main() {
|
|
|
1126
1648
|
case "uniforms":
|
|
1127
1649
|
}
|
|
1128
1650
|
for (const [uniformName, uniformFormat] of Object.entries(module.uniformTypes || {})) {
|
|
1651
|
+
if (typeof uniformFormat !== "string") {
|
|
1652
|
+
throw new Error(
|
|
1653
|
+
`Composite uniform types are not supported by GLSL shader generation: ${module.name}.${uniformName}`
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1129
1656
|
const glslUniformType = getGLSLUniformType(uniformFormat);
|
|
1130
1657
|
switch (options.uniforms) {
|
|
1131
1658
|
case "scoped-interface-blocks":
|
|
@@ -1186,6 +1713,11 @@ void main() {
|
|
|
1186
1713
|
const wgsl = [];
|
|
1187
1714
|
wgsl.push(`struct ${capitalize(module.name)} {`);
|
|
1188
1715
|
for (const [uniformName, uniformFormat] of Object.entries(module?.uniformTypes || {})) {
|
|
1716
|
+
if (typeof uniformFormat !== "string") {
|
|
1717
|
+
throw new Error(
|
|
1718
|
+
`Composite uniform types are not supported by WGSL shader generation: ${module.name}.${uniformName}`
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1189
1721
|
const wgslUniformType = uniformFormat;
|
|
1190
1722
|
wgsl.push(` ${uniformName} : ${wgslUniformType};`);
|
|
1191
1723
|
}
|
|
@@ -3190,6 +3722,7 @@ float tan_fp32(float a) {
|
|
|
3190
3722
|
`
|
|
3191
3723
|
uniform fp64arithmeticUniforms {
|
|
3192
3724
|
uniform float ONE;
|
|
3725
|
+
uniform float SPLIT;
|
|
3193
3726
|
} fp64;
|
|
3194
3727
|
|
|
3195
3728
|
/*
|
|
@@ -3199,6 +3732,12 @@ The purpose of this workaround is to prevent shader compilers from
|
|
|
3199
3732
|
optimizing away necessary arithmetic operations by swapping their sequences
|
|
3200
3733
|
or transform the equation to some 'equivalent' form.
|
|
3201
3734
|
|
|
3735
|
+
These helpers implement Dekker/Veltkamp-style error tracking. If the compiler
|
|
3736
|
+
folds constants or reassociates the arithmetic, the high/low split can stop
|
|
3737
|
+
tracking the rounding error correctly. That failure mode tends to look fine in
|
|
3738
|
+
simple coordinate setup, but then breaks down inside iterative arithmetic such
|
|
3739
|
+
as fp64 Mandelbrot loops.
|
|
3740
|
+
|
|
3202
3741
|
The method is to multiply an artifical variable, ONE, which will be known to
|
|
3203
3742
|
the compiler to be 1 only at runtime. The whole expression is then represented
|
|
3204
3743
|
as a polynomial with respective to ONE. In the coefficients of all terms, only one a
|
|
@@ -3207,17 +3746,23 @@ and one b should appear
|
|
|
3207
3746
|
err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE
|
|
3208
3747
|
*/
|
|
3209
3748
|
|
|
3210
|
-
|
|
3211
|
-
vec2 split(float a) {
|
|
3212
|
-
const float SPLIT = 4097.0;
|
|
3213
|
-
float t = a * SPLIT;
|
|
3749
|
+
float prevent_fp64_optimization(float value) {
|
|
3214
3750
|
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
3215
|
-
|
|
3216
|
-
float a_lo = a * fp64.ONE - a_hi;
|
|
3751
|
+
return value + fp64.ONE * 0.0;
|
|
3217
3752
|
#else
|
|
3218
|
-
|
|
3219
|
-
float a_lo = a - a_hi;
|
|
3753
|
+
return value;
|
|
3220
3754
|
#endif
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3757
|
+
// Divide float number to high and low floats to extend fraction bits
|
|
3758
|
+
vec2 split(float a) {
|
|
3759
|
+
// Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker
|
|
3760
|
+
// split into a constant expression and reassociate the recovery steps.
|
|
3761
|
+
float split = prevent_fp64_optimization(fp64.SPLIT);
|
|
3762
|
+
float t = prevent_fp64_optimization(a * split);
|
|
3763
|
+
float temp = t - a;
|
|
3764
|
+
float a_hi = t - temp;
|
|
3765
|
+
float a_lo = a - a_hi;
|
|
3221
3766
|
return vec2(a_hi, a_lo);
|
|
3222
3767
|
}
|
|
3223
3768
|
|
|
@@ -3281,8 +3826,26 @@ vec2 twoProd(float a, float b) {
|
|
|
3281
3826
|
float prod = a * b;
|
|
3282
3827
|
vec2 a_fp64 = split(a);
|
|
3283
3828
|
vec2 b_fp64 = split(b);
|
|
3284
|
-
|
|
3285
|
-
|
|
3829
|
+
// twoProd is especially sensitive because mul_fp64 and div_fp64 both depend
|
|
3830
|
+
// on the split terms and cross terms staying in the original evaluation
|
|
3831
|
+
// order. If the compiler folds or reassociates them, the low part tends to
|
|
3832
|
+
// collapse to zero or NaN on some drivers.
|
|
3833
|
+
float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);
|
|
3834
|
+
float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);
|
|
3835
|
+
float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);
|
|
3836
|
+
float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);
|
|
3837
|
+
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
3838
|
+
float err1 = (highProduct - prod) * fp64.ONE;
|
|
3839
|
+
float err2 = crossProduct1 * fp64.ONE * fp64.ONE;
|
|
3840
|
+
float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
3841
|
+
float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
3842
|
+
#else
|
|
3843
|
+
float err1 = highProduct - prod;
|
|
3844
|
+
float err2 = crossProduct1;
|
|
3845
|
+
float err3 = crossProduct2;
|
|
3846
|
+
float err4 = lowProduct;
|
|
3847
|
+
#endif
|
|
3848
|
+
float err = ((err1 + err2) + err3) + err4;
|
|
3286
3849
|
return vec2(prod, err);
|
|
3287
3850
|
}
|
|
3288
3851
|
|
|
@@ -3358,6 +3921,218 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
3358
3921
|
`
|
|
3359
3922
|
);
|
|
3360
3923
|
|
|
3924
|
+
// src/modules/math/fp64/fp64-arithmetic-wgsl.ts
|
|
3925
|
+
var fp64arithmeticWGSL = (
|
|
3926
|
+
/* wgsl */
|
|
3927
|
+
`struct Fp64ArithmeticUniforms {
|
|
3928
|
+
ONE: f32,
|
|
3929
|
+
SPLIT: f32,
|
|
3930
|
+
};
|
|
3931
|
+
|
|
3932
|
+
@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
|
|
3933
|
+
|
|
3934
|
+
fn fp64_nan(seed: f32) -> f32 {
|
|
3935
|
+
let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
|
|
3936
|
+
return bitcast<f32>(nanBits);
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3939
|
+
fn fp64_runtime_zero() -> f32 {
|
|
3940
|
+
return fp64arithmetic.ONE * 0.0;
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3943
|
+
fn prevent_fp64_optimization(value: f32) -> f32 {
|
|
3944
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
3945
|
+
return value + fp64_runtime_zero();
|
|
3946
|
+
#else
|
|
3947
|
+
return value;
|
|
3948
|
+
#endif
|
|
3949
|
+
}
|
|
3950
|
+
|
|
3951
|
+
fn split(a: f32) -> vec2f {
|
|
3952
|
+
let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
|
|
3953
|
+
let t = prevent_fp64_optimization(a * splitValue);
|
|
3954
|
+
let temp = prevent_fp64_optimization(t - a);
|
|
3955
|
+
let aHi = prevent_fp64_optimization(t - temp);
|
|
3956
|
+
let aLo = prevent_fp64_optimization(a - aHi);
|
|
3957
|
+
return vec2f(aHi, aLo);
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
fn split2(a: vec2f) -> vec2f {
|
|
3961
|
+
var b = split(a.x);
|
|
3962
|
+
b.y = b.y + a.y;
|
|
3963
|
+
return b;
|
|
3964
|
+
}
|
|
3965
|
+
|
|
3966
|
+
fn quickTwoSum(a: f32, b: f32) -> vec2f {
|
|
3967
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
3968
|
+
let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);
|
|
3969
|
+
let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);
|
|
3970
|
+
#else
|
|
3971
|
+
let sum = prevent_fp64_optimization(a + b);
|
|
3972
|
+
let err = prevent_fp64_optimization(b - (sum - a));
|
|
3973
|
+
#endif
|
|
3974
|
+
return vec2f(sum, err);
|
|
3975
|
+
}
|
|
3976
|
+
|
|
3977
|
+
fn twoSum(a: f32, b: f32) -> vec2f {
|
|
3978
|
+
let s = prevent_fp64_optimization(a + b);
|
|
3979
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
3980
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
3981
|
+
let err =
|
|
3982
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
3983
|
+
fp64arithmetic.ONE *
|
|
3984
|
+
fp64arithmetic.ONE *
|
|
3985
|
+
fp64arithmetic.ONE) +
|
|
3986
|
+
prevent_fp64_optimization(b - v);
|
|
3987
|
+
#else
|
|
3988
|
+
let v = prevent_fp64_optimization(s - a);
|
|
3989
|
+
let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);
|
|
3990
|
+
#endif
|
|
3991
|
+
return vec2f(s, err);
|
|
3992
|
+
}
|
|
3993
|
+
|
|
3994
|
+
fn twoSub(a: f32, b: f32) -> vec2f {
|
|
3995
|
+
let s = prevent_fp64_optimization(a - b);
|
|
3996
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
3997
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
3998
|
+
let err =
|
|
3999
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
4000
|
+
fp64arithmetic.ONE *
|
|
4001
|
+
fp64arithmetic.ONE *
|
|
4002
|
+
fp64arithmetic.ONE) -
|
|
4003
|
+
prevent_fp64_optimization(b + v);
|
|
4004
|
+
#else
|
|
4005
|
+
let v = prevent_fp64_optimization(s - a);
|
|
4006
|
+
let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);
|
|
4007
|
+
#endif
|
|
4008
|
+
return vec2f(s, err);
|
|
4009
|
+
}
|
|
4010
|
+
|
|
4011
|
+
fn twoSqr(a: f32) -> vec2f {
|
|
4012
|
+
let prod = prevent_fp64_optimization(a * a);
|
|
4013
|
+
let aFp64 = split(a);
|
|
4014
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);
|
|
4015
|
+
let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);
|
|
4016
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);
|
|
4017
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
4018
|
+
let err =
|
|
4019
|
+
(prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +
|
|
4020
|
+
crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +
|
|
4021
|
+
lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
4022
|
+
#else
|
|
4023
|
+
let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);
|
|
4024
|
+
#endif
|
|
4025
|
+
return vec2f(prod, err);
|
|
4026
|
+
}
|
|
4027
|
+
|
|
4028
|
+
fn twoProd(a: f32, b: f32) -> vec2f {
|
|
4029
|
+
let prod = prevent_fp64_optimization(a * b);
|
|
4030
|
+
let aFp64 = split(a);
|
|
4031
|
+
let bFp64 = split(b);
|
|
4032
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);
|
|
4033
|
+
let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);
|
|
4034
|
+
let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);
|
|
4035
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);
|
|
4036
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
4037
|
+
let err1 = (highProduct - prod) * fp64arithmetic.ONE;
|
|
4038
|
+
let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
4039
|
+
let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
4040
|
+
let err4 =
|
|
4041
|
+
lowProduct *
|
|
4042
|
+
fp64arithmetic.ONE *
|
|
4043
|
+
fp64arithmetic.ONE *
|
|
4044
|
+
fp64arithmetic.ONE *
|
|
4045
|
+
fp64arithmetic.ONE;
|
|
4046
|
+
#else
|
|
4047
|
+
let err1 = highProduct - prod;
|
|
4048
|
+
let err2 = crossProduct1;
|
|
4049
|
+
let err3 = crossProduct2;
|
|
4050
|
+
let err4 = lowProduct;
|
|
4051
|
+
#endif
|
|
4052
|
+
let err12InputA = prevent_fp64_optimization(err1);
|
|
4053
|
+
let err12InputB = prevent_fp64_optimization(err2);
|
|
4054
|
+
let err12 = prevent_fp64_optimization(err12InputA + err12InputB);
|
|
4055
|
+
let err123InputA = prevent_fp64_optimization(err12);
|
|
4056
|
+
let err123InputB = prevent_fp64_optimization(err3);
|
|
4057
|
+
let err123 = prevent_fp64_optimization(err123InputA + err123InputB);
|
|
4058
|
+
let err1234InputA = prevent_fp64_optimization(err123);
|
|
4059
|
+
let err1234InputB = prevent_fp64_optimization(err4);
|
|
4060
|
+
let err = prevent_fp64_optimization(err1234InputA + err1234InputB);
|
|
4061
|
+
return vec2f(prod, err);
|
|
4062
|
+
}
|
|
4063
|
+
|
|
4064
|
+
fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
4065
|
+
var s = twoSum(a.x, b.x);
|
|
4066
|
+
let t = twoSum(a.y, b.y);
|
|
4067
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
4068
|
+
s = quickTwoSum(s.x, s.y);
|
|
4069
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
4070
|
+
s = quickTwoSum(s.x, s.y);
|
|
4071
|
+
return s;
|
|
4072
|
+
}
|
|
4073
|
+
|
|
4074
|
+
fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
4075
|
+
var s = twoSub(a.x, b.x);
|
|
4076
|
+
let t = twoSub(a.y, b.y);
|
|
4077
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
4078
|
+
s = quickTwoSum(s.x, s.y);
|
|
4079
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
4080
|
+
s = quickTwoSum(s.x, s.y);
|
|
4081
|
+
return s;
|
|
4082
|
+
}
|
|
4083
|
+
|
|
4084
|
+
fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
4085
|
+
var prod = twoProd(a.x, b.x);
|
|
4086
|
+
let crossProduct1 = prevent_fp64_optimization(a.x * b.y);
|
|
4087
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct1);
|
|
4088
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
4089
|
+
prod = split2(prod);
|
|
4090
|
+
#endif
|
|
4091
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
4092
|
+
let crossProduct2 = prevent_fp64_optimization(a.y * b.x);
|
|
4093
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct2);
|
|
4094
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
4095
|
+
prod = split2(prod);
|
|
4096
|
+
#endif
|
|
4097
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
4098
|
+
return prod;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4101
|
+
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
4102
|
+
let xn = prevent_fp64_optimization(1.0 / b.x);
|
|
4103
|
+
let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
|
|
4104
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);
|
|
4105
|
+
let prod = twoProd(xn, diff);
|
|
4106
|
+
return sum_fp64(yn, prod);
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4109
|
+
fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
4110
|
+
if (a.x == 0.0 && a.y == 0.0) {
|
|
4111
|
+
return vec2f(0.0, 0.0);
|
|
4112
|
+
}
|
|
4113
|
+
if (a.x < 0.0) {
|
|
4114
|
+
let nanValue = fp64_nan(a.x);
|
|
4115
|
+
return vec2f(nanValue, nanValue);
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
let x = prevent_fp64_optimization(1.0 / sqrt(a.x));
|
|
4119
|
+
let yn = prevent_fp64_optimization(a.x * x);
|
|
4120
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
4121
|
+
let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;
|
|
4122
|
+
#else
|
|
4123
|
+
let ynSqr = twoSqr(yn);
|
|
4124
|
+
#endif
|
|
4125
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);
|
|
4126
|
+
let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);
|
|
4127
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
4128
|
+
return sum_fp64(split(yn), prod);
|
|
4129
|
+
#else
|
|
4130
|
+
return sum_fp64(vec2f(yn, 0.0), prod);
|
|
4131
|
+
#endif
|
|
4132
|
+
}
|
|
4133
|
+
`
|
|
4134
|
+
);
|
|
4135
|
+
|
|
3361
4136
|
// src/modules/math/fp64/fp64-functions-glsl.ts
|
|
3362
4137
|
var fp64functionShader = (
|
|
3363
4138
|
/* glsl */
|
|
@@ -4036,13 +4811,18 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
|
|
|
4036
4811
|
// src/modules/math/fp64/fp64.ts
|
|
4037
4812
|
var defaultUniforms = {
|
|
4038
4813
|
// Used in LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
4039
|
-
ONE: 1
|
|
4814
|
+
ONE: 1,
|
|
4815
|
+
// Runtime split factor for Dekker splitting. Keeping this as a uniform helps
|
|
4816
|
+
// prevent aggressive constant folding in shader compilers.
|
|
4817
|
+
SPLIT: 4097
|
|
4040
4818
|
};
|
|
4041
4819
|
var fp64arithmetic = {
|
|
4042
4820
|
name: "fp64arithmetic",
|
|
4821
|
+
source: fp64arithmeticWGSL,
|
|
4822
|
+
fs: fp64arithmeticShader,
|
|
4043
4823
|
vs: fp64arithmeticShader,
|
|
4044
4824
|
defaultUniforms,
|
|
4045
|
-
uniformTypes: { ONE: "f32" },
|
|
4825
|
+
uniformTypes: { ONE: "f32", SPLIT: "f32" },
|
|
4046
4826
|
// Additional Functions
|
|
4047
4827
|
fp64ify,
|
|
4048
4828
|
fp64LowPart,
|
|
@@ -4255,7 +5035,7 @@ struct skinUniforms {
|
|
|
4255
5035
|
jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
|
|
4256
5036
|
};
|
|
4257
5037
|
|
|
4258
|
-
@
|
|
5038
|
+
@group(0) @binding(auto) var<uniform> skin: skinUniforms;
|
|
4259
5039
|
|
|
4260
5040
|
fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
4261
5041
|
return (weights.x * skin.jointMatrix[joints.x])
|
|
@@ -4289,6 +5069,7 @@ mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
|
|
|
4289
5069
|
props: {},
|
|
4290
5070
|
uniforms: {},
|
|
4291
5071
|
name: "skin",
|
|
5072
|
+
bindingLayout: [{ name: "skin", group: 0 }],
|
|
4292
5073
|
dependencies: [],
|
|
4293
5074
|
source: source2,
|
|
4294
5075
|
vs: vs2,
|
|
@@ -4331,10 +5112,7 @@ mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
|
|
|
4331
5112
|
};
|
|
4332
5113
|
},
|
|
4333
5114
|
uniformTypes: {
|
|
4334
|
-
jointMatrix: "mat4x4<f32>"
|
|
4335
|
-
},
|
|
4336
|
-
uniformSizes: {
|
|
4337
|
-
jointMatrix: SKIN_MAX_JOINTS
|
|
5115
|
+
jointMatrix: ["mat4x4<f32>", SKIN_MAX_JOINTS]
|
|
4338
5116
|
}
|
|
4339
5117
|
};
|
|
4340
5118
|
|
|
@@ -4357,77 +5135,51 @@ struct PointLight {
|
|
|
4357
5135
|
vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
|
|
4358
5136
|
};
|
|
4359
5137
|
|
|
5138
|
+
struct SpotLight {
|
|
5139
|
+
vec3 color;
|
|
5140
|
+
vec3 position;
|
|
5141
|
+
vec3 direction;
|
|
5142
|
+
vec3 attenuation;
|
|
5143
|
+
vec2 coneCos;
|
|
5144
|
+
};
|
|
5145
|
+
|
|
4360
5146
|
struct DirectionalLight {
|
|
4361
5147
|
vec3 color;
|
|
4362
5148
|
vec3 direction;
|
|
4363
5149
|
};
|
|
4364
5150
|
|
|
5151
|
+
struct UniformLight {
|
|
5152
|
+
vec3 color;
|
|
5153
|
+
vec3 position;
|
|
5154
|
+
vec3 direction;
|
|
5155
|
+
vec3 attenuation;
|
|
5156
|
+
vec2 coneCos;
|
|
5157
|
+
};
|
|
5158
|
+
|
|
4365
5159
|
uniform lightingUniforms {
|
|
4366
5160
|
int enabled;
|
|
4367
|
-
int lightType;
|
|
4368
|
-
|
|
4369
5161
|
int directionalLightCount;
|
|
4370
5162
|
int pointLightCount;
|
|
4371
|
-
|
|
5163
|
+
int spotLightCount;
|
|
4372
5164
|
vec3 ambientColor;
|
|
4373
|
-
|
|
4374
|
-
vec3 lightColor0;
|
|
4375
|
-
vec3 lightPosition0;
|
|
4376
|
-
vec3 lightDirection0;
|
|
4377
|
-
vec3 lightAttenuation0;
|
|
4378
|
-
|
|
4379
|
-
vec3 lightColor1;
|
|
4380
|
-
vec3 lightPosition1;
|
|
4381
|
-
vec3 lightDirection1;
|
|
4382
|
-
vec3 lightAttenuation1;
|
|
4383
|
-
|
|
4384
|
-
vec3 lightColor2;
|
|
4385
|
-
vec3 lightPosition2;
|
|
4386
|
-
vec3 lightDirection2;
|
|
4387
|
-
vec3 lightAttenuation2;
|
|
4388
|
-
|
|
4389
|
-
vec3 lightColor3;
|
|
4390
|
-
vec3 lightPosition3;
|
|
4391
|
-
vec3 lightDirection3;
|
|
4392
|
-
vec3 lightAttenuation3;
|
|
4393
|
-
|
|
4394
|
-
vec3 lightColor4;
|
|
4395
|
-
vec3 lightPosition4;
|
|
4396
|
-
vec3 lightDirection4;
|
|
4397
|
-
vec3 lightAttenuation4;
|
|
5165
|
+
UniformLight lights[5];
|
|
4398
5166
|
} lighting;
|
|
4399
5167
|
|
|
4400
5168
|
PointLight lighting_getPointLight(int index) {
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
case 3:
|
|
4409
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
4410
|
-
case 4:
|
|
4411
|
-
default:
|
|
4412
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
4413
|
-
}
|
|
5169
|
+
UniformLight light = lighting.lights[index];
|
|
5170
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
5171
|
+
}
|
|
5172
|
+
|
|
5173
|
+
SpotLight lighting_getSpotLight(int index) {
|
|
5174
|
+
UniformLight light = lighting.lights[lighting.pointLightCount + index];
|
|
5175
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
4414
5176
|
}
|
|
4415
5177
|
|
|
4416
5178
|
DirectionalLight lighting_getDirectionalLight(int index) {
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
4422
|
-
case 2:
|
|
4423
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
4424
|
-
case 3:
|
|
4425
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
4426
|
-
case 4:
|
|
4427
|
-
default:
|
|
4428
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
4429
|
-
}
|
|
4430
|
-
}
|
|
5179
|
+
UniformLight light =
|
|
5180
|
+
lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
5181
|
+
return DirectionalLight(light.color, light.direction);
|
|
5182
|
+
}
|
|
4431
5183
|
|
|
4432
5184
|
float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
4433
5185
|
return pointLight.attenuation.x
|
|
@@ -4435,6 +5187,20 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
|
4435
5187
|
+ pointLight.attenuation.z * distance * distance;
|
|
4436
5188
|
}
|
|
4437
5189
|
|
|
5190
|
+
float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {
|
|
5191
|
+
vec3 light_direction = normalize(positionWorldspace - spotLight.position);
|
|
5192
|
+
float coneFactor = smoothstep(
|
|
5193
|
+
spotLight.coneCos.y,
|
|
5194
|
+
spotLight.coneCos.x,
|
|
5195
|
+
dot(normalize(spotLight.direction), light_direction)
|
|
5196
|
+
);
|
|
5197
|
+
float distanceAttenuation = getPointLightAttenuation(
|
|
5198
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
5199
|
+
distance(spotLight.position, positionWorldspace)
|
|
5200
|
+
);
|
|
5201
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
5202
|
+
}
|
|
5203
|
+
|
|
4438
5204
|
// #endif
|
|
4439
5205
|
`
|
|
4440
5206
|
);
|
|
@@ -4455,100 +5221,85 @@ struct PointLight {
|
|
|
4455
5221
|
attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
|
|
4456
5222
|
};
|
|
4457
5223
|
|
|
5224
|
+
struct SpotLight {
|
|
5225
|
+
color: vec3<f32>,
|
|
5226
|
+
position: vec3<f32>,
|
|
5227
|
+
direction: vec3<f32>,
|
|
5228
|
+
attenuation: vec3<f32>,
|
|
5229
|
+
coneCos: vec2<f32>,
|
|
5230
|
+
};
|
|
5231
|
+
|
|
4458
5232
|
struct DirectionalLight {
|
|
4459
5233
|
color: vec3<f32>,
|
|
4460
5234
|
direction: vec3<f32>,
|
|
4461
5235
|
};
|
|
4462
5236
|
|
|
5237
|
+
struct UniformLight {
|
|
5238
|
+
color: vec3<f32>,
|
|
5239
|
+
position: vec3<f32>,
|
|
5240
|
+
direction: vec3<f32>,
|
|
5241
|
+
attenuation: vec3<f32>,
|
|
5242
|
+
coneCos: vec2<f32>,
|
|
5243
|
+
};
|
|
5244
|
+
|
|
4463
5245
|
struct lightingUniforms {
|
|
4464
5246
|
enabled: i32,
|
|
4465
|
-
lightType: i32,
|
|
4466
|
-
|
|
4467
5247
|
directionalLightCount: i32,
|
|
4468
5248
|
pointLightCount: i32,
|
|
4469
|
-
|
|
5249
|
+
spotLightCount: i32,
|
|
4470
5250
|
ambientColor: vec3<f32>,
|
|
4471
|
-
|
|
4472
|
-
lightColor0: vec3<f32>,
|
|
4473
|
-
lightPosition0: vec3<f32>,
|
|
4474
|
-
lightDirection0: vec3<f32>,
|
|
4475
|
-
lightAttenuation0: vec3<f32>,
|
|
4476
|
-
|
|
4477
|
-
lightColor1: vec3<f32>,
|
|
4478
|
-
lightPosition1: vec3<f32>,
|
|
4479
|
-
lightDirection1: vec3<f32>,
|
|
4480
|
-
lightAttenuation1: vec3<f32>,
|
|
4481
|
-
|
|
4482
|
-
lightColor2: vec3<f32>,
|
|
4483
|
-
lightPosition2: vec3<f32>,
|
|
4484
|
-
lightDirection2: vec3<f32>,
|
|
4485
|
-
lightAttenuation2: vec3<f32>,
|
|
4486
|
-
|
|
4487
|
-
lightColor3: vec3<f32>,
|
|
4488
|
-
lightPosition3: vec3<f32>,
|
|
4489
|
-
lightDirection3: vec3<f32>,
|
|
4490
|
-
lightAttenuation3: vec3<f32>,
|
|
4491
|
-
|
|
4492
|
-
lightColor4: vec3<f32>,
|
|
4493
|
-
lightPosition4: vec3<f32>,
|
|
4494
|
-
lightDirection4: vec3<f32>,
|
|
4495
|
-
lightAttenuation4: vec3<f32>,
|
|
5251
|
+
lights: array<UniformLight, 5>,
|
|
4496
5252
|
};
|
|
4497
5253
|
|
|
4498
|
-
|
|
4499
|
-
@binding(1) @group(0) var<uniform> lighting : lightingUniforms;
|
|
5254
|
+
@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
|
|
4500
5255
|
|
|
4501
5256
|
fn lighting_getPointLight(index: i32) -> PointLight {
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
case 2: {
|
|
4510
|
-
return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
|
|
4511
|
-
}
|
|
4512
|
-
case 3: {
|
|
4513
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
4514
|
-
}
|
|
4515
|
-
case 4, default: {
|
|
4516
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
4517
|
-
}
|
|
4518
|
-
}
|
|
5257
|
+
let light = lighting.lights[index];
|
|
5258
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
5259
|
+
}
|
|
5260
|
+
|
|
5261
|
+
fn lighting_getSpotLight(index: i32) -> SpotLight {
|
|
5262
|
+
let light = lighting.lights[lighting.pointLightCount + index];
|
|
5263
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
4519
5264
|
}
|
|
4520
5265
|
|
|
4521
5266
|
fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
}
|
|
4526
|
-
case 1: {
|
|
4527
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
4528
|
-
}
|
|
4529
|
-
case 2: {
|
|
4530
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
4531
|
-
}
|
|
4532
|
-
case 3: {
|
|
4533
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
4534
|
-
}
|
|
4535
|
-
case 4, default: {
|
|
4536
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
4537
|
-
}
|
|
4538
|
-
}
|
|
4539
|
-
}
|
|
5267
|
+
let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
5268
|
+
return DirectionalLight(light.color, light.direction);
|
|
5269
|
+
}
|
|
4540
5270
|
|
|
4541
5271
|
fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
4542
5272
|
return pointLight.attenuation.x
|
|
4543
5273
|
+ pointLight.attenuation.y * distance
|
|
4544
5274
|
+ pointLight.attenuation.z * distance * distance;
|
|
4545
5275
|
}
|
|
5276
|
+
|
|
5277
|
+
fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
|
|
5278
|
+
let lightDirection = normalize(positionWorldspace - spotLight.position);
|
|
5279
|
+
let coneFactor = smoothstep(
|
|
5280
|
+
spotLight.coneCos.y,
|
|
5281
|
+
spotLight.coneCos.x,
|
|
5282
|
+
dot(normalize(spotLight.direction), lightDirection)
|
|
5283
|
+
);
|
|
5284
|
+
let distanceAttenuation = getPointLightAttenuation(
|
|
5285
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
5286
|
+
distance(spotLight.position, positionWorldspace)
|
|
5287
|
+
);
|
|
5288
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
5289
|
+
}
|
|
4546
5290
|
`
|
|
4547
5291
|
);
|
|
4548
5292
|
|
|
4549
5293
|
// src/modules/lighting/lights/lighting.ts
|
|
4550
5294
|
var MAX_LIGHTS = 5;
|
|
4551
5295
|
var COLOR_FACTOR = 255;
|
|
5296
|
+
var LIGHT_UNIFORM_TYPE = {
|
|
5297
|
+
color: "vec3<f32>",
|
|
5298
|
+
position: "vec3<f32>",
|
|
5299
|
+
direction: "vec3<f32>",
|
|
5300
|
+
attenuation: "vec3<f32>",
|
|
5301
|
+
coneCos: "vec2<f32>"
|
|
5302
|
+
};
|
|
4552
5303
|
var lighting = {
|
|
4553
5304
|
props: {},
|
|
4554
5305
|
uniforms: {},
|
|
@@ -4558,83 +5309,39 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
|
4558
5309
|
},
|
|
4559
5310
|
uniformTypes: {
|
|
4560
5311
|
enabled: "i32",
|
|
4561
|
-
lightType: "i32",
|
|
4562
5312
|
directionalLightCount: "i32",
|
|
4563
5313
|
pointLightCount: "i32",
|
|
5314
|
+
spotLightCount: "i32",
|
|
4564
5315
|
ambientColor: "vec3<f32>",
|
|
4565
|
-
|
|
4566
|
-
lightColor0: "vec3<f32>",
|
|
4567
|
-
lightPosition0: "vec3<f32>",
|
|
4568
|
-
// TODO - could combine direction and attenuation
|
|
4569
|
-
lightDirection0: "vec3<f32>",
|
|
4570
|
-
lightAttenuation0: "vec3<f32>",
|
|
4571
|
-
lightColor1: "vec3<f32>",
|
|
4572
|
-
lightPosition1: "vec3<f32>",
|
|
4573
|
-
lightDirection1: "vec3<f32>",
|
|
4574
|
-
lightAttenuation1: "vec3<f32>",
|
|
4575
|
-
lightColor2: "vec3<f32>",
|
|
4576
|
-
lightPosition2: "vec3<f32>",
|
|
4577
|
-
lightDirection2: "vec3<f32>",
|
|
4578
|
-
lightAttenuation2: "vec3<f32>",
|
|
4579
|
-
lightColor3: "vec3<f32>",
|
|
4580
|
-
lightPosition3: "vec3<f32>",
|
|
4581
|
-
lightDirection3: "vec3<f32>",
|
|
4582
|
-
lightAttenuation3: "vec3<f32>",
|
|
4583
|
-
lightColor4: "vec3<f32>",
|
|
4584
|
-
lightPosition4: "vec3<f32>",
|
|
4585
|
-
lightDirection4: "vec3<f32>",
|
|
4586
|
-
lightAttenuation4: "vec3<f32>"
|
|
4587
|
-
},
|
|
4588
|
-
defaultUniforms: {
|
|
4589
|
-
enabled: 1,
|
|
4590
|
-
lightType: 0 /* POINT */,
|
|
4591
|
-
directionalLightCount: 0,
|
|
4592
|
-
pointLightCount: 0,
|
|
4593
|
-
ambientColor: [0.1, 0.1, 0.1],
|
|
4594
|
-
lightColor0: [1, 1, 1],
|
|
4595
|
-
lightPosition0: [1, 1, 2],
|
|
4596
|
-
// TODO - could combine direction and attenuation
|
|
4597
|
-
lightDirection0: [1, 1, 1],
|
|
4598
|
-
lightAttenuation0: [1, 0, 0],
|
|
4599
|
-
lightColor1: [1, 1, 1],
|
|
4600
|
-
lightPosition1: [1, 1, 2],
|
|
4601
|
-
lightDirection1: [1, 1, 1],
|
|
4602
|
-
lightAttenuation1: [1, 0, 0],
|
|
4603
|
-
lightColor2: [1, 1, 1],
|
|
4604
|
-
lightPosition2: [1, 1, 2],
|
|
4605
|
-
lightDirection2: [1, 1, 1],
|
|
4606
|
-
lightAttenuation2: [1, 0, 0],
|
|
4607
|
-
lightColor3: [1, 1, 1],
|
|
4608
|
-
lightPosition3: [1, 1, 2],
|
|
4609
|
-
lightDirection3: [1, 1, 1],
|
|
4610
|
-
lightAttenuation3: [1, 0, 0],
|
|
4611
|
-
lightColor4: [1, 1, 1],
|
|
4612
|
-
lightPosition4: [1, 1, 2],
|
|
4613
|
-
lightDirection4: [1, 1, 1],
|
|
4614
|
-
lightAttenuation4: [1, 0, 0]
|
|
5316
|
+
lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]
|
|
4615
5317
|
},
|
|
5318
|
+
defaultUniforms: createDefaultLightingUniforms(),
|
|
5319
|
+
bindingLayout: [{ name: "lighting", group: 2 }],
|
|
5320
|
+
firstBindingSlot: 0,
|
|
4616
5321
|
source: lightingUniformsWGSL,
|
|
4617
5322
|
vs: lightingUniformsGLSL,
|
|
4618
5323
|
fs: lightingUniformsGLSL,
|
|
4619
5324
|
getUniforms: getUniforms2
|
|
4620
5325
|
};
|
|
4621
|
-
function getUniforms2(props,
|
|
5326
|
+
function getUniforms2(props, _prevUniforms = {}) {
|
|
4622
5327
|
props = props ? { ...props } : props;
|
|
4623
5328
|
if (!props) {
|
|
4624
|
-
return
|
|
5329
|
+
return createDefaultLightingUniforms();
|
|
4625
5330
|
}
|
|
4626
5331
|
if (props.lights) {
|
|
4627
5332
|
props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
|
|
4628
5333
|
}
|
|
4629
|
-
const { ambientLight, pointLights, directionalLights } = props || {};
|
|
4630
|
-
const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
5334
|
+
const { ambientLight, pointLights, spotLights, directionalLights } = props || {};
|
|
5335
|
+
const hasLights = ambientLight || pointLights && pointLights.length > 0 || spotLights && spotLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
4631
5336
|
if (!hasLights) {
|
|
4632
|
-
return {
|
|
5337
|
+
return {
|
|
5338
|
+
...createDefaultLightingUniforms(),
|
|
5339
|
+
enabled: 0
|
|
5340
|
+
};
|
|
4633
5341
|
}
|
|
4634
5342
|
const uniforms = {
|
|
4635
|
-
...
|
|
4636
|
-
...
|
|
4637
|
-
...getLightSourceUniforms({ ambientLight, pointLights, directionalLights })
|
|
5343
|
+
...createDefaultLightingUniforms(),
|
|
5344
|
+
...getLightSourceUniforms({ ambientLight, pointLights, spotLights, directionalLights })
|
|
4638
5345
|
};
|
|
4639
5346
|
if (props.enabled !== void 0) {
|
|
4640
5347
|
uniforms.enabled = props.enabled ? 1 : 0;
|
|
@@ -4644,45 +5351,67 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
|
4644
5351
|
function getLightSourceUniforms({
|
|
4645
5352
|
ambientLight,
|
|
4646
5353
|
pointLights = [],
|
|
5354
|
+
spotLights = [],
|
|
4647
5355
|
directionalLights = []
|
|
4648
5356
|
}) {
|
|
4649
|
-
const
|
|
4650
|
-
lightSourceUniforms.ambientColor = convertColor(ambientLight);
|
|
5357
|
+
const lights = createDefaultLightUniforms();
|
|
4651
5358
|
let currentLight = 0;
|
|
4652
5359
|
let pointLightCount = 0;
|
|
5360
|
+
let spotLightCount = 0;
|
|
4653
5361
|
let directionalLightCount = 0;
|
|
4654
5362
|
for (const pointLight of pointLights) {
|
|
4655
5363
|
if (currentLight >= MAX_LIGHTS) {
|
|
4656
5364
|
break;
|
|
4657
5365
|
}
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
5366
|
+
lights[currentLight] = {
|
|
5367
|
+
...lights[currentLight],
|
|
5368
|
+
color: convertColor(pointLight),
|
|
5369
|
+
position: pointLight.position,
|
|
5370
|
+
attenuation: pointLight.attenuation || [1, 0, 0]
|
|
5371
|
+
};
|
|
4663
5372
|
currentLight++;
|
|
4664
5373
|
pointLightCount++;
|
|
4665
5374
|
}
|
|
5375
|
+
for (const spotLight of spotLights) {
|
|
5376
|
+
if (currentLight >= MAX_LIGHTS) {
|
|
5377
|
+
break;
|
|
5378
|
+
}
|
|
5379
|
+
lights[currentLight] = {
|
|
5380
|
+
...lights[currentLight],
|
|
5381
|
+
color: convertColor(spotLight),
|
|
5382
|
+
position: spotLight.position,
|
|
5383
|
+
direction: spotLight.direction,
|
|
5384
|
+
attenuation: spotLight.attenuation || [1, 0, 0],
|
|
5385
|
+
coneCos: getSpotConeCos(spotLight)
|
|
5386
|
+
};
|
|
5387
|
+
currentLight++;
|
|
5388
|
+
spotLightCount++;
|
|
5389
|
+
}
|
|
4666
5390
|
for (const directionalLight of directionalLights) {
|
|
4667
5391
|
if (currentLight >= MAX_LIGHTS) {
|
|
4668
5392
|
break;
|
|
4669
5393
|
}
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
5394
|
+
lights[currentLight] = {
|
|
5395
|
+
...lights[currentLight],
|
|
5396
|
+
color: convertColor(directionalLight),
|
|
5397
|
+
direction: directionalLight.direction
|
|
5398
|
+
};
|
|
4674
5399
|
currentLight++;
|
|
4675
5400
|
directionalLightCount++;
|
|
4676
5401
|
}
|
|
4677
|
-
if (pointLights.length + directionalLights.length > MAX_LIGHTS) {
|
|
5402
|
+
if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {
|
|
4678
5403
|
import_core3.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
|
|
4679
5404
|
}
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
5405
|
+
return {
|
|
5406
|
+
ambientColor: convertColor(ambientLight),
|
|
5407
|
+
directionalLightCount,
|
|
5408
|
+
pointLightCount,
|
|
5409
|
+
spotLightCount,
|
|
5410
|
+
lights
|
|
5411
|
+
};
|
|
4683
5412
|
}
|
|
4684
5413
|
function extractLightTypes(lights) {
|
|
4685
|
-
const lightSources = { pointLights: [], directionalLights: [] };
|
|
5414
|
+
const lightSources = { pointLights: [], spotLights: [], directionalLights: [] };
|
|
4686
5415
|
for (const light of lights || []) {
|
|
4687
5416
|
switch (light.type) {
|
|
4688
5417
|
case "ambient":
|
|
@@ -4694,6 +5423,9 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
|
4694
5423
|
case "point":
|
|
4695
5424
|
lightSources.pointLights?.push(light);
|
|
4696
5425
|
break;
|
|
5426
|
+
case "spot":
|
|
5427
|
+
lightSources.spotLights?.push(light);
|
|
5428
|
+
break;
|
|
4697
5429
|
default:
|
|
4698
5430
|
}
|
|
4699
5431
|
}
|
|
@@ -4703,6 +5435,68 @@ fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
|
4703
5435
|
const { color = [0, 0, 0], intensity = 1 } = colorDef;
|
|
4704
5436
|
return color.map((component) => component * intensity / COLOR_FACTOR);
|
|
4705
5437
|
}
|
|
5438
|
+
function createDefaultLightingUniforms() {
|
|
5439
|
+
return {
|
|
5440
|
+
enabled: 1,
|
|
5441
|
+
directionalLightCount: 0,
|
|
5442
|
+
pointLightCount: 0,
|
|
5443
|
+
spotLightCount: 0,
|
|
5444
|
+
ambientColor: [0.1, 0.1, 0.1],
|
|
5445
|
+
lights: createDefaultLightUniforms()
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
function createDefaultLightUniforms() {
|
|
5449
|
+
return Array.from({ length: MAX_LIGHTS }, () => createDefaultLightUniform());
|
|
5450
|
+
}
|
|
5451
|
+
function createDefaultLightUniform() {
|
|
5452
|
+
return {
|
|
5453
|
+
color: [1, 1, 1],
|
|
5454
|
+
position: [1, 1, 2],
|
|
5455
|
+
direction: [1, 1, 1],
|
|
5456
|
+
attenuation: [1, 0, 0],
|
|
5457
|
+
coneCos: [1, 0]
|
|
5458
|
+
};
|
|
5459
|
+
}
|
|
5460
|
+
function getSpotConeCos(spotLight) {
|
|
5461
|
+
const innerConeAngle = spotLight.innerConeAngle ?? 0;
|
|
5462
|
+
const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;
|
|
5463
|
+
return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];
|
|
5464
|
+
}
|
|
5465
|
+
|
|
5466
|
+
// src/modules/lighting/ibl/ibl.ts
|
|
5467
|
+
var iblWGSL = (
|
|
5468
|
+
/* wgsl */
|
|
5469
|
+
`#ifdef USE_IBL
|
|
5470
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
|
|
5471
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
|
|
5472
|
+
@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
|
|
5473
|
+
@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
|
|
5474
|
+
@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
|
|
5475
|
+
@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
|
|
5476
|
+
#endif
|
|
5477
|
+
`
|
|
5478
|
+
);
|
|
5479
|
+
var iblGLSL = (
|
|
5480
|
+
/* glsl */
|
|
5481
|
+
`#ifdef USE_IBL
|
|
5482
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
5483
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
5484
|
+
uniform sampler2D pbr_brdfLUT;
|
|
5485
|
+
#endif
|
|
5486
|
+
`
|
|
5487
|
+
);
|
|
5488
|
+
var ibl = {
|
|
5489
|
+
name: "ibl",
|
|
5490
|
+
firstBindingSlot: 32,
|
|
5491
|
+
bindingLayout: [
|
|
5492
|
+
{ name: "pbr_diffuseEnvSampler", group: 2 },
|
|
5493
|
+
{ name: "pbr_specularEnvSampler", group: 2 },
|
|
5494
|
+
{ name: "pbr_brdfLUT", group: 2 }
|
|
5495
|
+
],
|
|
5496
|
+
source: iblWGSL,
|
|
5497
|
+
vs: iblGLSL,
|
|
5498
|
+
fs: iblGLSL
|
|
5499
|
+
};
|
|
4706
5500
|
|
|
4707
5501
|
// src/modules/lighting/no-material/dirlight.ts
|
|
4708
5502
|
var SOURCE_WGSL = (
|
|
@@ -4718,7 +5512,7 @@ struct DirlightInputs {
|
|
|
4718
5512
|
normal: DirlightNormal,
|
|
4719
5513
|
};
|
|
4720
5514
|
|
|
4721
|
-
@
|
|
5515
|
+
@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;
|
|
4722
5516
|
|
|
4723
5517
|
// For vertex
|
|
4724
5518
|
fn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {
|
|
@@ -4763,6 +5557,8 @@ vec4 dirlight_filterColor(vec4 color) {
|
|
|
4763
5557
|
props: {},
|
|
4764
5558
|
uniforms: {},
|
|
4765
5559
|
name: "dirlight",
|
|
5560
|
+
bindingLayout: [{ name: "dirlight", group: 2 }],
|
|
5561
|
+
firstBindingSlot: 16,
|
|
4766
5562
|
dependencies: [],
|
|
4767
5563
|
source: SOURCE_WGSL,
|
|
4768
5564
|
vs: VS_GLSL,
|
|
@@ -4789,10 +5585,173 @@ vec4 dirlight_filterColor(vec4 color) {
|
|
|
4789
5585
|
return uniforms;
|
|
4790
5586
|
}
|
|
4791
5587
|
|
|
5588
|
+
// src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts
|
|
5589
|
+
var LAMBERT_WGSL = (
|
|
5590
|
+
/* wgsl */
|
|
5591
|
+
`struct lambertMaterialUniforms {
|
|
5592
|
+
unlit: u32,
|
|
5593
|
+
ambient: f32,
|
|
5594
|
+
diffuse: f32,
|
|
5595
|
+
};
|
|
5596
|
+
|
|
5597
|
+
@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;
|
|
5598
|
+
|
|
5599
|
+
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
5600
|
+
let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);
|
|
5601
|
+
return lambertian * lambertMaterial.diffuse * surfaceColor * color;
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
5605
|
+
var lightColor: vec3<f32> = surfaceColor;
|
|
5606
|
+
|
|
5607
|
+
if (lambertMaterial.unlit != 0u) {
|
|
5608
|
+
return surfaceColor;
|
|
5609
|
+
}
|
|
5610
|
+
|
|
5611
|
+
if (lighting.enabled == 0) {
|
|
5612
|
+
return lightColor;
|
|
5613
|
+
}
|
|
5614
|
+
|
|
5615
|
+
lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
5616
|
+
|
|
5617
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
5618
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
5619
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
5620
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
5621
|
+
let light_attenuation = getPointLightAttenuation(
|
|
5622
|
+
pointLight,
|
|
5623
|
+
distance(light_position_worldspace, position_worldspace)
|
|
5624
|
+
);
|
|
5625
|
+
lightColor += lighting_getLightColor(
|
|
5626
|
+
surfaceColor,
|
|
5627
|
+
light_direction,
|
|
5628
|
+
normal_worldspace,
|
|
5629
|
+
pointLight.color / light_attenuation
|
|
5630
|
+
);
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5633
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
5634
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
5635
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
5636
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
5637
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
5638
|
+
lightColor += lighting_getLightColor(
|
|
5639
|
+
surfaceColor,
|
|
5640
|
+
light_direction,
|
|
5641
|
+
normal_worldspace,
|
|
5642
|
+
spotLight.color / light_attenuation
|
|
5643
|
+
);
|
|
5644
|
+
}
|
|
5645
|
+
|
|
5646
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
5647
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
5648
|
+
lightColor += lighting_getLightColor(
|
|
5649
|
+
surfaceColor,
|
|
5650
|
+
-directionalLight.direction,
|
|
5651
|
+
normal_worldspace,
|
|
5652
|
+
directionalLight.color
|
|
5653
|
+
);
|
|
5654
|
+
}
|
|
5655
|
+
|
|
5656
|
+
return lightColor;
|
|
5657
|
+
}
|
|
5658
|
+
`
|
|
5659
|
+
);
|
|
5660
|
+
|
|
5661
|
+
// src/modules/lighting/lambert-material/lambert-shaders-glsl.ts
|
|
5662
|
+
var LAMBERT_VS = (
|
|
5663
|
+
/* glsl */
|
|
5664
|
+
`uniform lambertMaterialUniforms {
|
|
5665
|
+
uniform bool unlit;
|
|
5666
|
+
uniform float ambient;
|
|
5667
|
+
uniform float diffuse;
|
|
5668
|
+
} material;
|
|
5669
|
+
`
|
|
5670
|
+
);
|
|
5671
|
+
var LAMBERT_FS = (
|
|
5672
|
+
/* glsl */
|
|
5673
|
+
`uniform lambertMaterialUniforms {
|
|
5674
|
+
uniform bool unlit;
|
|
5675
|
+
uniform float ambient;
|
|
5676
|
+
uniform float diffuse;
|
|
5677
|
+
} material;
|
|
5678
|
+
|
|
5679
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {
|
|
5680
|
+
float lambertian = max(dot(light_direction, normal_worldspace), 0.0);
|
|
5681
|
+
return lambertian * material.diffuse * surfaceColor * color;
|
|
5682
|
+
}
|
|
5683
|
+
|
|
5684
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
5685
|
+
vec3 lightColor = surfaceColor;
|
|
5686
|
+
|
|
5687
|
+
if (material.unlit) {
|
|
5688
|
+
return surfaceColor;
|
|
5689
|
+
}
|
|
5690
|
+
|
|
5691
|
+
if (lighting.enabled == 0) {
|
|
5692
|
+
return lightColor;
|
|
5693
|
+
}
|
|
5694
|
+
|
|
5695
|
+
lightColor = material.ambient * surfaceColor * lighting.ambientColor;
|
|
5696
|
+
|
|
5697
|
+
for (int i = 0; i < lighting.pointLightCount; i++) {
|
|
5698
|
+
PointLight pointLight = lighting_getPointLight(i);
|
|
5699
|
+
vec3 light_position_worldspace = pointLight.position;
|
|
5700
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
5701
|
+
float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));
|
|
5702
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
5703
|
+
}
|
|
5704
|
+
|
|
5705
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
5706
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
5707
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
5708
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
5709
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
5710
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
5711
|
+
}
|
|
5712
|
+
|
|
5713
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
5714
|
+
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
5715
|
+
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5718
|
+
return lightColor;
|
|
5719
|
+
}
|
|
5720
|
+
`
|
|
5721
|
+
);
|
|
5722
|
+
|
|
5723
|
+
// src/modules/lighting/lambert-material/lambert-material.ts
|
|
5724
|
+
var lambertMaterial = {
|
|
5725
|
+
name: "lambertMaterial",
|
|
5726
|
+
firstBindingSlot: 0,
|
|
5727
|
+
bindingLayout: [{ name: "lambertMaterial", group: 3 }],
|
|
5728
|
+
dependencies: [lighting],
|
|
5729
|
+
source: LAMBERT_WGSL,
|
|
5730
|
+
vs: LAMBERT_VS,
|
|
5731
|
+
fs: LAMBERT_FS,
|
|
5732
|
+
defines: {
|
|
5733
|
+
LIGHTING_FRAGMENT: true
|
|
5734
|
+
},
|
|
5735
|
+
uniformTypes: {
|
|
5736
|
+
unlit: "i32",
|
|
5737
|
+
ambient: "f32",
|
|
5738
|
+
diffuse: "f32"
|
|
5739
|
+
},
|
|
5740
|
+
defaultUniforms: {
|
|
5741
|
+
unlit: false,
|
|
5742
|
+
ambient: 0.35,
|
|
5743
|
+
diffuse: 0.6
|
|
5744
|
+
},
|
|
5745
|
+
getUniforms(props) {
|
|
5746
|
+
return { ...lambertMaterial.defaultUniforms, ...props };
|
|
5747
|
+
}
|
|
5748
|
+
};
|
|
5749
|
+
|
|
4792
5750
|
// src/modules/lighting/phong-material/phong-shaders-glsl.ts
|
|
4793
5751
|
var PHONG_VS = (
|
|
4794
5752
|
/* glsl */
|
|
4795
5753
|
`uniform phongMaterialUniforms {
|
|
5754
|
+
uniform bool unlit;
|
|
4796
5755
|
uniform float ambient;
|
|
4797
5756
|
uniform float diffuse;
|
|
4798
5757
|
uniform float shininess;
|
|
@@ -4802,9 +5761,8 @@ vec4 dirlight_filterColor(vec4 color) {
|
|
|
4802
5761
|
);
|
|
4803
5762
|
var PHONG_FS = (
|
|
4804
5763
|
/* glsl */
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
uniform phongMaterialUniforms {
|
|
5764
|
+
`uniform phongMaterialUniforms {
|
|
5765
|
+
uniform bool unlit;
|
|
4808
5766
|
uniform float ambient;
|
|
4809
5767
|
uniform float diffuse;
|
|
4810
5768
|
uniform float shininess;
|
|
@@ -4826,6 +5784,10 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_d
|
|
|
4826
5784
|
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
4827
5785
|
vec3 lightColor = surfaceColor;
|
|
4828
5786
|
|
|
5787
|
+
if (material.unlit) {
|
|
5788
|
+
return surfaceColor;
|
|
5789
|
+
}
|
|
5790
|
+
|
|
4829
5791
|
if (lighting.enabled == 0) {
|
|
4830
5792
|
return lightColor;
|
|
4831
5793
|
}
|
|
@@ -4841,8 +5803,15 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
4841
5803
|
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
4842
5804
|
}
|
|
4843
5805
|
|
|
4844
|
-
int
|
|
4845
|
-
|
|
5806
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
5807
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
5808
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
5809
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
5810
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
5811
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
5812
|
+
}
|
|
5813
|
+
|
|
5814
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
4846
5815
|
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
4847
5816
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
4848
5817
|
}
|
|
@@ -4856,13 +5825,14 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
4856
5825
|
var PHONG_WGSL = (
|
|
4857
5826
|
/* wgsl */
|
|
4858
5827
|
`struct phongMaterialUniforms {
|
|
5828
|
+
unlit: u32,
|
|
4859
5829
|
ambient: f32,
|
|
4860
5830
|
diffuse: f32,
|
|
4861
5831
|
shininess: f32,
|
|
4862
5832
|
specularColor: vec3<f32>,
|
|
4863
5833
|
};
|
|
4864
5834
|
|
|
4865
|
-
@
|
|
5835
|
+
@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;
|
|
4866
5836
|
|
|
4867
5837
|
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
4868
5838
|
let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);
|
|
@@ -4879,6 +5849,10 @@ fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, v
|
|
|
4879
5849
|
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
4880
5850
|
var lightColor: vec3<f32> = surfaceColor;
|
|
4881
5851
|
|
|
5852
|
+
if (phongMaterial.unlit != 0u) {
|
|
5853
|
+
return surfaceColor;
|
|
5854
|
+
}
|
|
5855
|
+
|
|
4882
5856
|
if (lighting.enabled == 0) {
|
|
4883
5857
|
return lightColor;
|
|
4884
5858
|
}
|
|
@@ -4903,8 +5877,21 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
|
|
|
4903
5877
|
);
|
|
4904
5878
|
}
|
|
4905
5879
|
|
|
4906
|
-
|
|
4907
|
-
|
|
5880
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
5881
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
5882
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
5883
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
5884
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
5885
|
+
lightColor += lighting_getLightColor(
|
|
5886
|
+
surfaceColor,
|
|
5887
|
+
light_direction,
|
|
5888
|
+
view_direction,
|
|
5889
|
+
normal_worldspace,
|
|
5890
|
+
spotLight.color / light_attenuation
|
|
5891
|
+
);
|
|
5892
|
+
}
|
|
5893
|
+
|
|
5894
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
4908
5895
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
4909
5896
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
4910
5897
|
}
|
|
@@ -4936,8 +5923,21 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
4936
5923
|
);
|
|
4937
5924
|
}
|
|
4938
5925
|
|
|
4939
|
-
|
|
4940
|
-
|
|
5926
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
5927
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
5928
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
5929
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
5930
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
5931
|
+
lightColor += lighting_getLightColor(
|
|
5932
|
+
surfaceColor,
|
|
5933
|
+
light_direction,
|
|
5934
|
+
view_direction,
|
|
5935
|
+
normal_worldspace,
|
|
5936
|
+
spotLight.color / light_attenuation
|
|
5937
|
+
);
|
|
5938
|
+
}
|
|
5939
|
+
|
|
5940
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
4941
5941
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
4942
5942
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
4943
5943
|
}
|
|
@@ -4951,6 +5951,7 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
4951
5951
|
var gouraudMaterial = {
|
|
4952
5952
|
props: {},
|
|
4953
5953
|
name: "gouraudMaterial",
|
|
5954
|
+
bindingLayout: [{ name: "gouraudMaterial", group: 3 }],
|
|
4954
5955
|
// Note these are switched between phong and gouraud
|
|
4955
5956
|
vs: PHONG_FS.replace("phongMaterial", "gouraudMaterial"),
|
|
4956
5957
|
fs: PHONG_VS.replace("phongMaterial", "gouraudMaterial"),
|
|
@@ -4960,12 +5961,14 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
4960
5961
|
},
|
|
4961
5962
|
dependencies: [lighting],
|
|
4962
5963
|
uniformTypes: {
|
|
5964
|
+
unlit: "i32",
|
|
4963
5965
|
ambient: "f32",
|
|
4964
5966
|
diffuse: "f32",
|
|
4965
5967
|
shininess: "f32",
|
|
4966
5968
|
specularColor: "vec3<f32>"
|
|
4967
5969
|
},
|
|
4968
5970
|
defaultUniforms: {
|
|
5971
|
+
unlit: false,
|
|
4969
5972
|
ambient: 0.35,
|
|
4970
5973
|
diffuse: 0.6,
|
|
4971
5974
|
shininess: 32,
|
|
@@ -4983,6 +5986,8 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
4983
5986
|
// src/modules/lighting/phong-material/phong-material.ts
|
|
4984
5987
|
var phongMaterial = {
|
|
4985
5988
|
name: "phongMaterial",
|
|
5989
|
+
firstBindingSlot: 0,
|
|
5990
|
+
bindingLayout: [{ name: "phongMaterial", group: 3 }],
|
|
4986
5991
|
dependencies: [lighting],
|
|
4987
5992
|
// Note these are switched between phong and gouraud
|
|
4988
5993
|
source: PHONG_WGSL,
|
|
@@ -4992,12 +5997,14 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
4992
5997
|
LIGHTING_FRAGMENT: true
|
|
4993
5998
|
},
|
|
4994
5999
|
uniformTypes: {
|
|
6000
|
+
unlit: "i32",
|
|
4995
6001
|
ambient: "f32",
|
|
4996
6002
|
diffuse: "f32",
|
|
4997
6003
|
shininess: "f32",
|
|
4998
6004
|
specularColor: "vec3<f32>"
|
|
4999
6005
|
},
|
|
5000
6006
|
defaultUniforms: {
|
|
6007
|
+
unlit: false,
|
|
5001
6008
|
ambient: 0.35,
|
|
5002
6009
|
diffuse: 0.6,
|
|
5003
6010
|
shininess: 32,
|
|
@@ -5094,10 +6101,12 @@ uniform pbrMaterialUniforms {
|
|
|
5094
6101
|
float clearcoatFactor;
|
|
5095
6102
|
float clearcoatRoughnessFactor;
|
|
5096
6103
|
bool clearcoatMapEnabled;
|
|
6104
|
+
bool clearcoatRoughnessMapEnabled;
|
|
5097
6105
|
|
|
5098
6106
|
vec3 sheenColorFactor;
|
|
5099
6107
|
float sheenRoughnessFactor;
|
|
5100
6108
|
bool sheenColorMapEnabled;
|
|
6109
|
+
bool sheenRoughnessMapEnabled;
|
|
5101
6110
|
|
|
5102
6111
|
float iridescenceFactor;
|
|
5103
6112
|
float iridescenceIor;
|
|
@@ -5147,26 +6156,33 @@ uniform sampler2D pbr_specularIntensitySampler;
|
|
|
5147
6156
|
#ifdef HAS_TRANSMISSIONMAP
|
|
5148
6157
|
uniform sampler2D pbr_transmissionSampler;
|
|
5149
6158
|
#endif
|
|
6159
|
+
#ifdef HAS_THICKNESSMAP
|
|
6160
|
+
uniform sampler2D pbr_thicknessSampler;
|
|
6161
|
+
#endif
|
|
5150
6162
|
#ifdef HAS_CLEARCOATMAP
|
|
5151
6163
|
uniform sampler2D pbr_clearcoatSampler;
|
|
6164
|
+
#endif
|
|
6165
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
5152
6166
|
uniform sampler2D pbr_clearcoatRoughnessSampler;
|
|
5153
6167
|
#endif
|
|
6168
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
6169
|
+
uniform sampler2D pbr_clearcoatNormalSampler;
|
|
6170
|
+
#endif
|
|
5154
6171
|
#ifdef HAS_SHEENCOLORMAP
|
|
5155
6172
|
uniform sampler2D pbr_sheenColorSampler;
|
|
6173
|
+
#endif
|
|
6174
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
5156
6175
|
uniform sampler2D pbr_sheenRoughnessSampler;
|
|
5157
6176
|
#endif
|
|
5158
6177
|
#ifdef HAS_IRIDESCENCEMAP
|
|
5159
6178
|
uniform sampler2D pbr_iridescenceSampler;
|
|
5160
6179
|
#endif
|
|
6180
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
6181
|
+
uniform sampler2D pbr_iridescenceThicknessSampler;
|
|
6182
|
+
#endif
|
|
5161
6183
|
#ifdef HAS_ANISOTROPYMAP
|
|
5162
6184
|
uniform sampler2D pbr_anisotropySampler;
|
|
5163
6185
|
#endif
|
|
5164
|
-
#ifdef USE_IBL
|
|
5165
|
-
uniform samplerCube pbr_diffuseEnvSampler;
|
|
5166
|
-
uniform samplerCube pbr_specularEnvSampler;
|
|
5167
|
-
uniform sampler2D pbr_brdfLUT;
|
|
5168
|
-
#endif
|
|
5169
|
-
|
|
5170
6186
|
// Inputs from vertex shader
|
|
5171
6187
|
|
|
5172
6188
|
in vec3 pbr_vPosition;
|
|
@@ -5203,6 +6219,8 @@ struct PBRInfo {
|
|
|
5203
6219
|
const float M_PI = 3.141592653589793;
|
|
5204
6220
|
const float c_MinRoughness = 0.04;
|
|
5205
6221
|
|
|
6222
|
+
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
|
|
6223
|
+
|
|
5206
6224
|
vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
5207
6225
|
{
|
|
5208
6226
|
#ifdef MANUAL_SRGB
|
|
@@ -5218,11 +6236,9 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
|
5218
6236
|
#endif //MANUAL_SRGB
|
|
5219
6237
|
}
|
|
5220
6238
|
|
|
5221
|
-
//
|
|
5222
|
-
|
|
5223
|
-
vec3 getNormal()
|
|
6239
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
6240
|
+
mat3 getTBN()
|
|
5224
6241
|
{
|
|
5225
|
-
// Retrieve the tangent space matrix
|
|
5226
6242
|
#ifndef HAS_TANGENTS
|
|
5227
6243
|
vec3 pos_dx = dFdx(pbr_vPosition);
|
|
5228
6244
|
vec3 pos_dy = dFdy(pbr_vPosition);
|
|
@@ -5243,9 +6259,21 @@ vec3 getNormal()
|
|
|
5243
6259
|
mat3 tbn = pbr_vTBN;
|
|
5244
6260
|
#endif
|
|
5245
6261
|
|
|
6262
|
+
return tbn;
|
|
6263
|
+
}
|
|
6264
|
+
|
|
6265
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
6266
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
6267
|
+
vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
|
|
6268
|
+
{
|
|
6269
|
+
vec3 n = texture(normalSampler, pbr_vUV).rgb;
|
|
6270
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
|
|
6271
|
+
}
|
|
6272
|
+
|
|
6273
|
+
vec3 getNormal(mat3 tbn)
|
|
6274
|
+
{
|
|
5246
6275
|
#ifdef HAS_NORMALMAP
|
|
5247
|
-
vec3 n =
|
|
5248
|
-
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
|
|
6276
|
+
vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
|
|
5249
6277
|
#else
|
|
5250
6278
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
5251
6279
|
vec3 n = normalize(tbn[2].xyz);
|
|
@@ -5254,6 +6282,15 @@ vec3 getNormal()
|
|
|
5254
6282
|
return n;
|
|
5255
6283
|
}
|
|
5256
6284
|
|
|
6285
|
+
vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
|
|
6286
|
+
{
|
|
6287
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
6288
|
+
return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
|
|
6289
|
+
#else
|
|
6290
|
+
return baseNormal;
|
|
6291
|
+
#endif
|
|
6292
|
+
}
|
|
6293
|
+
|
|
5257
6294
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
5258
6295
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
5259
6296
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -5329,7 +6366,170 @@ float microfacetDistribution(PBRInfo pbrInfo)
|
|
|
5329
6366
|
return roughnessSq / (M_PI * f * f);
|
|
5330
6367
|
}
|
|
5331
6368
|
|
|
5332
|
-
|
|
6369
|
+
float maxComponent(vec3 value)
|
|
6370
|
+
{
|
|
6371
|
+
return max(max(value.r, value.g), value.b);
|
|
6372
|
+
}
|
|
6373
|
+
|
|
6374
|
+
float getDielectricF0(float ior)
|
|
6375
|
+
{
|
|
6376
|
+
float clampedIor = max(ior, 1.0);
|
|
6377
|
+
float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
6378
|
+
return ratio * ratio;
|
|
6379
|
+
}
|
|
6380
|
+
|
|
6381
|
+
vec2 normalizeDirection(vec2 direction)
|
|
6382
|
+
{
|
|
6383
|
+
float directionLength = length(direction);
|
|
6384
|
+
return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
vec2 rotateDirection(vec2 direction, float rotation)
|
|
6388
|
+
{
|
|
6389
|
+
float s = sin(rotation);
|
|
6390
|
+
float c = cos(rotation);
|
|
6391
|
+
return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
6392
|
+
}
|
|
6393
|
+
|
|
6394
|
+
vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
|
|
6395
|
+
{
|
|
6396
|
+
if (iridescence <= 0.0) {
|
|
6397
|
+
return vec3(1.0);
|
|
6398
|
+
}
|
|
6399
|
+
|
|
6400
|
+
float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
6401
|
+
vec3 thinFilmTint =
|
|
6402
|
+
0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
|
|
6403
|
+
return mix(vec3(1.0), thinFilmTint, iridescence);
|
|
6404
|
+
}
|
|
6405
|
+
|
|
6406
|
+
vec3 getVolumeAttenuation(float thickness)
|
|
6407
|
+
{
|
|
6408
|
+
if (thickness <= 0.0) {
|
|
6409
|
+
return vec3(1.0);
|
|
6410
|
+
}
|
|
6411
|
+
|
|
6412
|
+
vec3 attenuationCoefficient =
|
|
6413
|
+
-log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
|
|
6414
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
6415
|
+
return exp(-attenuationCoefficient * thickness);
|
|
6416
|
+
}
|
|
6417
|
+
|
|
6418
|
+
PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
|
|
6419
|
+
{
|
|
6420
|
+
float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
6421
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
6422
|
+
float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
6423
|
+
|
|
6424
|
+
return PBRInfo(
|
|
6425
|
+
basePBRInfo.NdotL,
|
|
6426
|
+
NdotV,
|
|
6427
|
+
basePBRInfo.NdotH,
|
|
6428
|
+
basePBRInfo.LdotH,
|
|
6429
|
+
basePBRInfo.VdotH,
|
|
6430
|
+
perceptualRoughness,
|
|
6431
|
+
0.0,
|
|
6432
|
+
vec3(0.04),
|
|
6433
|
+
vec3(1.0),
|
|
6434
|
+
alphaRoughness,
|
|
6435
|
+
vec3(0.0),
|
|
6436
|
+
vec3(0.04),
|
|
6437
|
+
clearcoatNormal,
|
|
6438
|
+
basePBRInfo.v
|
|
6439
|
+
);
|
|
6440
|
+
}
|
|
6441
|
+
|
|
6442
|
+
vec3 calculateClearcoatContribution(
|
|
6443
|
+
PBRInfo pbrInfo,
|
|
6444
|
+
vec3 lightColor,
|
|
6445
|
+
vec3 clearcoatNormal,
|
|
6446
|
+
float clearcoatFactor,
|
|
6447
|
+
float clearcoatRoughness
|
|
6448
|
+
) {
|
|
6449
|
+
if (clearcoatFactor <= 0.0) {
|
|
6450
|
+
return vec3(0.0);
|
|
6451
|
+
}
|
|
6452
|
+
|
|
6453
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
6454
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
6455
|
+
}
|
|
6456
|
+
|
|
6457
|
+
#ifdef USE_IBL
|
|
6458
|
+
vec3 calculateClearcoatIBLContribution(
|
|
6459
|
+
PBRInfo pbrInfo,
|
|
6460
|
+
vec3 clearcoatNormal,
|
|
6461
|
+
vec3 reflection,
|
|
6462
|
+
float clearcoatFactor,
|
|
6463
|
+
float clearcoatRoughness
|
|
6464
|
+
) {
|
|
6465
|
+
if (clearcoatFactor <= 0.0) {
|
|
6466
|
+
return vec3(0.0);
|
|
6467
|
+
}
|
|
6468
|
+
|
|
6469
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
6470
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
6471
|
+
}
|
|
6472
|
+
#endif
|
|
6473
|
+
|
|
6474
|
+
vec3 calculateSheenContribution(
|
|
6475
|
+
PBRInfo pbrInfo,
|
|
6476
|
+
vec3 lightColor,
|
|
6477
|
+
vec3 sheenColor,
|
|
6478
|
+
float sheenRoughness
|
|
6479
|
+
) {
|
|
6480
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
6481
|
+
return vec3(0.0);
|
|
6482
|
+
}
|
|
6483
|
+
|
|
6484
|
+
float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
6485
|
+
float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
6486
|
+
return pbrInfo.NdotL *
|
|
6487
|
+
lightColor *
|
|
6488
|
+
sheenColor *
|
|
6489
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
6490
|
+
sheenVisibility *
|
|
6491
|
+
(1.0 - pbrInfo.metalness);
|
|
6492
|
+
}
|
|
6493
|
+
|
|
6494
|
+
float calculateAnisotropyBoost(
|
|
6495
|
+
PBRInfo pbrInfo,
|
|
6496
|
+
vec3 anisotropyTangent,
|
|
6497
|
+
float anisotropyStrength
|
|
6498
|
+
) {
|
|
6499
|
+
if (anisotropyStrength <= 0.0) {
|
|
6500
|
+
return 1.0;
|
|
6501
|
+
}
|
|
6502
|
+
|
|
6503
|
+
vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
6504
|
+
float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
6505
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
6506
|
+
}
|
|
6507
|
+
|
|
6508
|
+
vec3 calculateMaterialLightColor(
|
|
6509
|
+
PBRInfo pbrInfo,
|
|
6510
|
+
vec3 lightColor,
|
|
6511
|
+
vec3 clearcoatNormal,
|
|
6512
|
+
float clearcoatFactor,
|
|
6513
|
+
float clearcoatRoughness,
|
|
6514
|
+
vec3 sheenColor,
|
|
6515
|
+
float sheenRoughness,
|
|
6516
|
+
vec3 anisotropyTangent,
|
|
6517
|
+
float anisotropyStrength
|
|
6518
|
+
) {
|
|
6519
|
+
float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
6520
|
+
vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
6521
|
+
color += calculateClearcoatContribution(
|
|
6522
|
+
pbrInfo,
|
|
6523
|
+
lightColor,
|
|
6524
|
+
clearcoatNormal,
|
|
6525
|
+
clearcoatFactor,
|
|
6526
|
+
clearcoatRoughness
|
|
6527
|
+
);
|
|
6528
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
6529
|
+
return color;
|
|
6530
|
+
}
|
|
6531
|
+
|
|
6532
|
+
void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
|
|
5333
6533
|
pbrInfo.NdotL = 1.0;
|
|
5334
6534
|
pbrInfo.NdotH = 0.0;
|
|
5335
6535
|
pbrInfo.LdotH = 0.0;
|
|
@@ -5353,6 +6553,11 @@ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
|
|
|
5353
6553
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
5354
6554
|
}
|
|
5355
6555
|
|
|
6556
|
+
void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
|
|
6557
|
+
vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
|
|
6558
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
6559
|
+
}
|
|
6560
|
+
|
|
5356
6561
|
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
|
|
5357
6562
|
// Calculate the shading terms for the microfacet specular shading model
|
|
5358
6563
|
vec3 F = specularReflection(pbrInfo);
|
|
@@ -5383,6 +6588,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5383
6588
|
|
|
5384
6589
|
vec3 color = vec3(0, 0, 0);
|
|
5385
6590
|
|
|
6591
|
+
float transmission = 0.0;
|
|
6592
|
+
|
|
5386
6593
|
if(pbrMaterial.unlit){
|
|
5387
6594
|
color.rgb = baseColor.rgb;
|
|
5388
6595
|
}
|
|
@@ -5401,14 +6608,252 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5401
6608
|
#endif
|
|
5402
6609
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
5403
6610
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
6611
|
+
mat3 tbn = getTBN();
|
|
6612
|
+
vec3 n = getNormal(tbn); // normal at surface point
|
|
6613
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
6614
|
+
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
6615
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
6616
|
+
bool useExtendedPBR =
|
|
6617
|
+
pbrMaterial.specularColorMapEnabled ||
|
|
6618
|
+
pbrMaterial.specularIntensityMapEnabled ||
|
|
6619
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
6620
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
|
|
6621
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
6622
|
+
pbrMaterial.transmissionMapEnabled ||
|
|
6623
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
6624
|
+
pbrMaterial.clearcoatMapEnabled ||
|
|
6625
|
+
pbrMaterial.clearcoatRoughnessMapEnabled ||
|
|
6626
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
6627
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
6628
|
+
pbrMaterial.sheenColorMapEnabled ||
|
|
6629
|
+
pbrMaterial.sheenRoughnessMapEnabled ||
|
|
6630
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
6631
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
6632
|
+
pbrMaterial.iridescenceMapEnabled ||
|
|
6633
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
6634
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
6635
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
6636
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
6637
|
+
pbrMaterial.anisotropyMapEnabled ||
|
|
6638
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
6639
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
6640
|
+
length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
|
|
6641
|
+
#else
|
|
6642
|
+
bool useExtendedPBR = false;
|
|
6643
|
+
#endif
|
|
6644
|
+
|
|
6645
|
+
if (!useExtendedPBR) {
|
|
6646
|
+
// Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
|
|
6647
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
6648
|
+
|
|
6649
|
+
vec3 f0 = vec3(0.04);
|
|
6650
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
|
6651
|
+
diffuseColor *= 1.0 - metallic;
|
|
6652
|
+
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
|
6653
|
+
|
|
6654
|
+
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
6655
|
+
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
6656
|
+
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
6657
|
+
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
6658
|
+
vec3 reflection = -normalize(reflect(v, n));
|
|
6659
|
+
|
|
6660
|
+
PBRInfo pbrInfo = PBRInfo(
|
|
6661
|
+
0.0, // NdotL
|
|
6662
|
+
NdotV,
|
|
6663
|
+
0.0, // NdotH
|
|
6664
|
+
0.0, // LdotH
|
|
6665
|
+
0.0, // VdotH
|
|
6666
|
+
perceptualRoughness,
|
|
6667
|
+
metallic,
|
|
6668
|
+
specularEnvironmentR0,
|
|
6669
|
+
specularEnvironmentR90,
|
|
6670
|
+
alphaRoughness,
|
|
6671
|
+
diffuseColor,
|
|
6672
|
+
specularColor,
|
|
6673
|
+
n,
|
|
6674
|
+
v
|
|
6675
|
+
);
|
|
6676
|
+
|
|
6677
|
+
#ifdef USE_LIGHTS
|
|
6678
|
+
PBRInfo_setAmbientLight(pbrInfo);
|
|
6679
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
6680
|
+
|
|
6681
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
6682
|
+
if (i < lighting.directionalLightCount) {
|
|
6683
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
6684
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
|
|
6688
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
6689
|
+
if (i < lighting.pointLightCount) {
|
|
6690
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
6691
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
6692
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
6693
|
+
}
|
|
6694
|
+
}
|
|
6695
|
+
|
|
6696
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
6697
|
+
if (i < lighting.spotLightCount) {
|
|
6698
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
6699
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
6700
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
6701
|
+
}
|
|
6702
|
+
}
|
|
6703
|
+
#endif
|
|
6704
|
+
|
|
6705
|
+
#ifdef USE_IBL
|
|
6706
|
+
if (pbrMaterial.IBLenabled) {
|
|
6707
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
6708
|
+
}
|
|
6709
|
+
#endif
|
|
6710
|
+
|
|
6711
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
6712
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
6713
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
6714
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
6715
|
+
}
|
|
6716
|
+
#endif
|
|
6717
|
+
|
|
6718
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
6719
|
+
#ifdef HAS_EMISSIVEMAP
|
|
6720
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
6721
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
6722
|
+
}
|
|
6723
|
+
#endif
|
|
6724
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
6725
|
+
|
|
6726
|
+
#ifdef PBR_DEBUG
|
|
6727
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
6728
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
6729
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
6730
|
+
#endif
|
|
6731
|
+
|
|
6732
|
+
return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
|
|
6733
|
+
}
|
|
6734
|
+
|
|
6735
|
+
float specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
6736
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
6737
|
+
if (pbrMaterial.specularIntensityMapEnabled) {
|
|
6738
|
+
specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
|
|
6739
|
+
}
|
|
6740
|
+
#endif
|
|
6741
|
+
|
|
6742
|
+
vec3 specularFactor = pbrMaterial.specularColorFactor;
|
|
6743
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
6744
|
+
if (pbrMaterial.specularColorMapEnabled) {
|
|
6745
|
+
specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
|
|
6746
|
+
}
|
|
6747
|
+
#endif
|
|
6748
|
+
|
|
6749
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
6750
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
6751
|
+
if (pbrMaterial.transmissionMapEnabled) {
|
|
6752
|
+
transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
|
|
6753
|
+
}
|
|
6754
|
+
#endif
|
|
6755
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
6756
|
+
float thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
6757
|
+
#ifdef HAS_THICKNESSMAP
|
|
6758
|
+
thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
|
|
6759
|
+
#endif
|
|
6760
|
+
|
|
6761
|
+
float clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
6762
|
+
float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
6763
|
+
#ifdef HAS_CLEARCOATMAP
|
|
6764
|
+
if (pbrMaterial.clearcoatMapEnabled) {
|
|
6765
|
+
clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
|
|
6766
|
+
}
|
|
6767
|
+
#endif
|
|
6768
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
6769
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled) {
|
|
6770
|
+
clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
|
|
6771
|
+
}
|
|
6772
|
+
#endif
|
|
6773
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
6774
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
6775
|
+
vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
6776
|
+
|
|
6777
|
+
vec3 sheenColor = pbrMaterial.sheenColorFactor;
|
|
6778
|
+
float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
6779
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
6780
|
+
if (pbrMaterial.sheenColorMapEnabled) {
|
|
6781
|
+
sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
|
|
6782
|
+
}
|
|
6783
|
+
#endif
|
|
6784
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
6785
|
+
if (pbrMaterial.sheenRoughnessMapEnabled) {
|
|
6786
|
+
sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
|
|
6787
|
+
}
|
|
6788
|
+
#endif
|
|
6789
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
6790
|
+
|
|
6791
|
+
float iridescence = pbrMaterial.iridescenceFactor;
|
|
6792
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
6793
|
+
if (pbrMaterial.iridescenceMapEnabled) {
|
|
6794
|
+
iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
|
|
6795
|
+
}
|
|
6796
|
+
#endif
|
|
6797
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
6798
|
+
float iridescenceThickness = mix(
|
|
6799
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6800
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6801
|
+
0.5
|
|
6802
|
+
);
|
|
6803
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
6804
|
+
iridescenceThickness = mix(
|
|
6805
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6806
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6807
|
+
texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
|
|
6808
|
+
);
|
|
6809
|
+
#endif
|
|
6810
|
+
|
|
6811
|
+
float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
6812
|
+
vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
6813
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
6814
|
+
if (pbrMaterial.anisotropyMapEnabled) {
|
|
6815
|
+
vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
|
|
6816
|
+
anisotropyStrength *= anisotropySample.b;
|
|
6817
|
+
vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
6818
|
+
if (length(mappedDirection) > 0.0001) {
|
|
6819
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6822
|
+
#endif
|
|
6823
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
6824
|
+
vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
6825
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
6826
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
6827
|
+
}
|
|
6828
|
+
float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
6829
|
+
perceptualRoughness = mix(
|
|
6830
|
+
perceptualRoughness,
|
|
6831
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
6832
|
+
anisotropyStrength
|
|
6833
|
+
);
|
|
6834
|
+
|
|
5404
6835
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
5405
6836
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
5406
6837
|
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5407
6838
|
|
|
5408
|
-
|
|
5409
|
-
vec3
|
|
5410
|
-
|
|
5411
|
-
|
|
6839
|
+
float dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
6840
|
+
vec3 dielectricSpecularF0 = min(
|
|
6841
|
+
vec3(dielectricF0) * specularFactor * specularIntensity,
|
|
6842
|
+
vec3(1.0)
|
|
6843
|
+
);
|
|
6844
|
+
vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
6845
|
+
dielectricSpecularF0 = mix(
|
|
6846
|
+
dielectricSpecularF0,
|
|
6847
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
6848
|
+
iridescence
|
|
6849
|
+
);
|
|
6850
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
|
|
6851
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
6852
|
+
vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
6853
|
+
|
|
6854
|
+
float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
6855
|
+
diffuseColor *= baseLayerEnergy;
|
|
6856
|
+
specularColor *= baseLayerEnergy;
|
|
5412
6857
|
|
|
5413
6858
|
// Compute reflectance.
|
|
5414
6859
|
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -5420,11 +6865,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5420
6865
|
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
5421
6866
|
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
5422
6867
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
5423
|
-
|
|
5424
|
-
vec3 n = getNormal(); // normal at surface point
|
|
5425
|
-
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
5426
|
-
|
|
5427
|
-
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
5428
6868
|
vec3 reflection = -normalize(reflect(v, n));
|
|
5429
6869
|
|
|
5430
6870
|
PBRInfo pbrInfo = PBRInfo(
|
|
@@ -5448,13 +6888,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5448
6888
|
#ifdef USE_LIGHTS
|
|
5449
6889
|
// Apply ambient light
|
|
5450
6890
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
5451
|
-
color +=
|
|
6891
|
+
color += calculateMaterialLightColor(
|
|
6892
|
+
pbrInfo,
|
|
6893
|
+
lighting.ambientColor,
|
|
6894
|
+
clearcoatNormal,
|
|
6895
|
+
clearcoatFactor,
|
|
6896
|
+
clearcoatRoughness,
|
|
6897
|
+
sheenColor,
|
|
6898
|
+
sheenRoughness,
|
|
6899
|
+
anisotropyTangent,
|
|
6900
|
+
anisotropyStrength
|
|
6901
|
+
);
|
|
5452
6902
|
|
|
5453
6903
|
// Apply directional light
|
|
5454
6904
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
5455
6905
|
if (i < lighting.directionalLightCount) {
|
|
5456
6906
|
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
5457
|
-
color +=
|
|
6907
|
+
color += calculateMaterialLightColor(
|
|
6908
|
+
pbrInfo,
|
|
6909
|
+
lighting_getDirectionalLight(i).color,
|
|
6910
|
+
clearcoatNormal,
|
|
6911
|
+
clearcoatFactor,
|
|
6912
|
+
clearcoatRoughness,
|
|
6913
|
+
sheenColor,
|
|
6914
|
+
sheenRoughness,
|
|
6915
|
+
anisotropyTangent,
|
|
6916
|
+
anisotropyStrength
|
|
6917
|
+
);
|
|
5458
6918
|
}
|
|
5459
6919
|
}
|
|
5460
6920
|
|
|
@@ -5463,7 +6923,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5463
6923
|
if (i < lighting.pointLightCount) {
|
|
5464
6924
|
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
5465
6925
|
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
5466
|
-
color +=
|
|
6926
|
+
color += calculateMaterialLightColor(
|
|
6927
|
+
pbrInfo,
|
|
6928
|
+
lighting_getPointLight(i).color / attenuation,
|
|
6929
|
+
clearcoatNormal,
|
|
6930
|
+
clearcoatFactor,
|
|
6931
|
+
clearcoatRoughness,
|
|
6932
|
+
sheenColor,
|
|
6933
|
+
sheenRoughness,
|
|
6934
|
+
anisotropyTangent,
|
|
6935
|
+
anisotropyStrength
|
|
6936
|
+
);
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
|
|
6940
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
6941
|
+
if (i < lighting.spotLightCount) {
|
|
6942
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
6943
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
6944
|
+
color += calculateMaterialLightColor(
|
|
6945
|
+
pbrInfo,
|
|
6946
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
6947
|
+
clearcoatNormal,
|
|
6948
|
+
clearcoatFactor,
|
|
6949
|
+
clearcoatRoughness,
|
|
6950
|
+
sheenColor,
|
|
6951
|
+
sheenRoughness,
|
|
6952
|
+
anisotropyTangent,
|
|
6953
|
+
anisotropyStrength
|
|
6954
|
+
);
|
|
5467
6955
|
}
|
|
5468
6956
|
}
|
|
5469
6957
|
#endif
|
|
@@ -5471,7 +6959,16 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5471
6959
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
5472
6960
|
#ifdef USE_IBL
|
|
5473
6961
|
if (pbrMaterial.IBLenabled) {
|
|
5474
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
6962
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
6963
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
6964
|
+
color += calculateClearcoatIBLContribution(
|
|
6965
|
+
pbrInfo,
|
|
6966
|
+
clearcoatNormal,
|
|
6967
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
6968
|
+
clearcoatFactor,
|
|
6969
|
+
clearcoatRoughness
|
|
6970
|
+
);
|
|
6971
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
5475
6972
|
}
|
|
5476
6973
|
#endif
|
|
5477
6974
|
|
|
@@ -5483,12 +6980,17 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5483
6980
|
}
|
|
5484
6981
|
#endif
|
|
5485
6982
|
|
|
6983
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
5486
6984
|
#ifdef HAS_EMISSIVEMAP
|
|
5487
6985
|
if (pbrMaterial.emissiveMapEnabled) {
|
|
5488
|
-
|
|
5489
|
-
color += emissive;
|
|
6986
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
5490
6987
|
}
|
|
5491
6988
|
#endif
|
|
6989
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
6990
|
+
|
|
6991
|
+
if (transmission > 0.0) {
|
|
6992
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
6993
|
+
}
|
|
5492
6994
|
|
|
5493
6995
|
// This section uses mix to override final color for reference app visualization
|
|
5494
6996
|
// of various parameters in the lighting equation.
|
|
@@ -5508,7 +7010,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
5508
7010
|
|
|
5509
7011
|
}
|
|
5510
7012
|
|
|
5511
|
-
|
|
7013
|
+
float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
7014
|
+
return vec4(pow(color,vec3(1.0/2.2)), alpha);
|
|
5512
7015
|
}
|
|
5513
7016
|
`
|
|
5514
7017
|
);
|
|
@@ -5574,6 +7077,42 @@ struct pbrMaterialUniforms {
|
|
|
5574
7077
|
|
|
5575
7078
|
alphaCutoffEnabled: i32,
|
|
5576
7079
|
alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
|
|
7080
|
+
|
|
7081
|
+
specularColorFactor: vec3f,
|
|
7082
|
+
specularIntensityFactor: f32,
|
|
7083
|
+
specularColorMapEnabled: i32,
|
|
7084
|
+
specularIntensityMapEnabled: i32,
|
|
7085
|
+
|
|
7086
|
+
ior: f32,
|
|
7087
|
+
|
|
7088
|
+
transmissionFactor: f32,
|
|
7089
|
+
transmissionMapEnabled: i32,
|
|
7090
|
+
|
|
7091
|
+
thicknessFactor: f32,
|
|
7092
|
+
attenuationDistance: f32,
|
|
7093
|
+
attenuationColor: vec3f,
|
|
7094
|
+
|
|
7095
|
+
clearcoatFactor: f32,
|
|
7096
|
+
clearcoatRoughnessFactor: f32,
|
|
7097
|
+
clearcoatMapEnabled: i32,
|
|
7098
|
+
clearcoatRoughnessMapEnabled: i32,
|
|
7099
|
+
|
|
7100
|
+
sheenColorFactor: vec3f,
|
|
7101
|
+
sheenRoughnessFactor: f32,
|
|
7102
|
+
sheenColorMapEnabled: i32,
|
|
7103
|
+
sheenRoughnessMapEnabled: i32,
|
|
7104
|
+
|
|
7105
|
+
iridescenceFactor: f32,
|
|
7106
|
+
iridescenceIor: f32,
|
|
7107
|
+
iridescenceThicknessRange: vec2f,
|
|
7108
|
+
iridescenceMapEnabled: i32,
|
|
7109
|
+
|
|
7110
|
+
anisotropyStrength: f32,
|
|
7111
|
+
anisotropyRotation: f32,
|
|
7112
|
+
anisotropyDirection: vec2f,
|
|
7113
|
+
anisotropyMapEnabled: i32,
|
|
7114
|
+
|
|
7115
|
+
emissiveStrength: f32,
|
|
5577
7116
|
|
|
5578
7117
|
// IBL
|
|
5579
7118
|
IBLenabled: i32,
|
|
@@ -5586,38 +7125,77 @@ struct pbrMaterialUniforms {
|
|
|
5586
7125
|
// #endif
|
|
5587
7126
|
}
|
|
5588
7127
|
|
|
5589
|
-
@
|
|
7128
|
+
@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
|
|
5590
7129
|
|
|
5591
7130
|
// Samplers
|
|
5592
7131
|
#ifdef HAS_BASECOLORMAP
|
|
5593
|
-
@
|
|
5594
|
-
@
|
|
7132
|
+
@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
|
|
7133
|
+
@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
|
|
5595
7134
|
#endif
|
|
5596
7135
|
#ifdef HAS_NORMALMAP
|
|
5597
|
-
@
|
|
5598
|
-
@
|
|
7136
|
+
@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
|
|
7137
|
+
@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
|
|
5599
7138
|
#endif
|
|
5600
7139
|
#ifdef HAS_EMISSIVEMAP
|
|
5601
|
-
@
|
|
5602
|
-
@
|
|
7140
|
+
@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
|
|
7141
|
+
@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
|
|
5603
7142
|
#endif
|
|
5604
7143
|
#ifdef HAS_METALROUGHNESSMAP
|
|
5605
|
-
@
|
|
5606
|
-
@
|
|
7144
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
|
|
7145
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
|
|
5607
7146
|
#endif
|
|
5608
7147
|
#ifdef HAS_OCCLUSIONMAP
|
|
5609
|
-
@
|
|
5610
|
-
@
|
|
7148
|
+
@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
|
|
7149
|
+
@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
|
|
5611
7150
|
#endif
|
|
5612
|
-
#ifdef
|
|
5613
|
-
@
|
|
5614
|
-
@
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
@
|
|
5618
|
-
@
|
|
7151
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
7152
|
+
@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
|
|
7153
|
+
@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
|
|
7154
|
+
#endif
|
|
7155
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
7156
|
+
@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
|
|
7157
|
+
@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
|
|
7158
|
+
#endif
|
|
7159
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
7160
|
+
@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
|
|
7161
|
+
@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
|
|
7162
|
+
#endif
|
|
7163
|
+
#ifdef HAS_THICKNESSMAP
|
|
7164
|
+
@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
|
|
7165
|
+
@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
|
|
7166
|
+
#endif
|
|
7167
|
+
#ifdef HAS_CLEARCOATMAP
|
|
7168
|
+
@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
|
|
7169
|
+
@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
|
|
7170
|
+
#endif
|
|
7171
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
7172
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
|
|
7173
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
|
|
7174
|
+
#endif
|
|
7175
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
7176
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
|
|
7177
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
|
|
7178
|
+
#endif
|
|
7179
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
7180
|
+
@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
|
|
7181
|
+
@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
|
|
7182
|
+
#endif
|
|
7183
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
7184
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
|
|
7185
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
|
|
7186
|
+
#endif
|
|
7187
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
7188
|
+
@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
|
|
7189
|
+
@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
|
|
7190
|
+
#endif
|
|
7191
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
7192
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
|
|
7193
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
|
|
7194
|
+
#endif
|
|
7195
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
7196
|
+
@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
|
|
7197
|
+
@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
|
|
5619
7198
|
#endif
|
|
5620
|
-
|
|
5621
7199
|
// Encapsulate the various inputs used by the various functions in the shading equation
|
|
5622
7200
|
// We store values in this struct to simplify the integration of alternative implementations
|
|
5623
7201
|
// of the shading terms, outlined in the Readme.MD Appendix.
|
|
@@ -5658,11 +7236,9 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
|
|
|
5658
7236
|
return vec4f(linOut, srgbIn.w);
|
|
5659
7237
|
}
|
|
5660
7238
|
|
|
5661
|
-
//
|
|
5662
|
-
|
|
5663
|
-
fn getNormal() -> vec3f
|
|
7239
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
7240
|
+
fn getTBN() -> mat3x3f
|
|
5664
7241
|
{
|
|
5665
|
-
// Retrieve the tangent space matrix
|
|
5666
7242
|
let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
|
|
5667
7243
|
let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
|
|
5668
7244
|
let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
|
|
@@ -5680,16 +7256,52 @@ fn getNormal() -> vec3f
|
|
|
5680
7256
|
tbn = fragmentInputs.pbr_vTBN;
|
|
5681
7257
|
#endif
|
|
5682
7258
|
|
|
7259
|
+
return tbn;
|
|
7260
|
+
}
|
|
7261
|
+
|
|
7262
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
7263
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
7264
|
+
fn getMappedNormal(
|
|
7265
|
+
normalSampler: texture_2d<f32>,
|
|
7266
|
+
normalSamplerBinding: sampler,
|
|
7267
|
+
tbn: mat3x3f,
|
|
7268
|
+
normalScale: f32
|
|
7269
|
+
) -> vec3f
|
|
7270
|
+
{
|
|
7271
|
+
let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
|
|
7272
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
|
|
7273
|
+
}
|
|
7274
|
+
|
|
7275
|
+
fn getNormal(tbn: mat3x3f) -> vec3f
|
|
7276
|
+
{
|
|
5683
7277
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
5684
7278
|
var n: vec3f = normalize(tbn[2].xyz);
|
|
5685
7279
|
#ifdef HAS_NORMALMAP
|
|
5686
|
-
n =
|
|
5687
|
-
|
|
7280
|
+
n = getMappedNormal(
|
|
7281
|
+
pbr_normalSampler,
|
|
7282
|
+
pbr_normalSamplerSampler,
|
|
7283
|
+
tbn,
|
|
7284
|
+
pbrMaterial.normalScale
|
|
7285
|
+
);
|
|
5688
7286
|
#endif
|
|
5689
7287
|
|
|
5690
7288
|
return n;
|
|
5691
7289
|
}
|
|
5692
7290
|
|
|
7291
|
+
fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
|
|
7292
|
+
{
|
|
7293
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
7294
|
+
return getMappedNormal(
|
|
7295
|
+
pbr_clearcoatNormalSampler,
|
|
7296
|
+
pbr_clearcoatNormalSamplerSampler,
|
|
7297
|
+
tbn,
|
|
7298
|
+
1.0
|
|
7299
|
+
);
|
|
7300
|
+
#else
|
|
7301
|
+
return baseNormal;
|
|
7302
|
+
#endif
|
|
7303
|
+
}
|
|
7304
|
+
|
|
5693
7305
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
5694
7306
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
5695
7307
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -5700,17 +7312,25 @@ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
|
|
|
5700
7312
|
let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
|
|
5701
7313
|
// retrieve a scale and bias to F0. See [1], Figure 3
|
|
5702
7314
|
let brdf = SRGBtoLINEAR(
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
|
|
7315
|
+
textureSampleLevel(
|
|
7316
|
+
pbr_brdfLUT,
|
|
7317
|
+
pbr_brdfLUTSampler,
|
|
7318
|
+
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
|
|
7319
|
+
0.0
|
|
5707
7320
|
)
|
|
5708
7321
|
).rgb;
|
|
5709
7322
|
let diffuseLight =
|
|
5710
|
-
SRGBtoLINEAR(
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
var specularLight =
|
|
7323
|
+
SRGBtoLINEAR(
|
|
7324
|
+
textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
|
|
7325
|
+
).rgb;
|
|
7326
|
+
var specularLight = SRGBtoLINEAR(
|
|
7327
|
+
textureSampleLevel(
|
|
7328
|
+
pbr_specularEnvSampler,
|
|
7329
|
+
pbr_specularEnvSamplerSampler,
|
|
7330
|
+
reflection,
|
|
7331
|
+
0.0
|
|
7332
|
+
)
|
|
7333
|
+
).rgb;
|
|
5714
7334
|
#ifdef USE_TEX_LOD
|
|
5715
7335
|
specularLight = SRGBtoLINEAR(
|
|
5716
7336
|
textureSampleLevel(
|
|
@@ -5771,6 +7391,172 @@ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
|
|
|
5771
7391
|
return roughnessSq / (M_PI * f * f);
|
|
5772
7392
|
}
|
|
5773
7393
|
|
|
7394
|
+
fn maxComponent(value: vec3f) -> f32 {
|
|
7395
|
+
return max(max(value.r, value.g), value.b);
|
|
7396
|
+
}
|
|
7397
|
+
|
|
7398
|
+
fn getDielectricF0(ior: f32) -> f32 {
|
|
7399
|
+
let clampedIor = max(ior, 1.0);
|
|
7400
|
+
let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
7401
|
+
return ratio * ratio;
|
|
7402
|
+
}
|
|
7403
|
+
|
|
7404
|
+
fn normalizeDirection(direction: vec2f) -> vec2f {
|
|
7405
|
+
let directionLength = length(direction);
|
|
7406
|
+
if (directionLength > 0.0001) {
|
|
7407
|
+
return direction / directionLength;
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7410
|
+
return vec2f(1.0, 0.0);
|
|
7411
|
+
}
|
|
7412
|
+
|
|
7413
|
+
fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
|
|
7414
|
+
let s = sin(rotation);
|
|
7415
|
+
let c = cos(rotation);
|
|
7416
|
+
return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
7417
|
+
}
|
|
7418
|
+
|
|
7419
|
+
fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
|
|
7420
|
+
if (iridescence <= 0.0) {
|
|
7421
|
+
return vec3f(1.0);
|
|
7422
|
+
}
|
|
7423
|
+
|
|
7424
|
+
let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
7425
|
+
let thinFilmTint =
|
|
7426
|
+
0.5 +
|
|
7427
|
+
0.5 *
|
|
7428
|
+
cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
|
|
7429
|
+
return mix(vec3f(1.0), thinFilmTint, iridescence);
|
|
7430
|
+
}
|
|
7431
|
+
|
|
7432
|
+
fn getVolumeAttenuation(thickness: f32) -> vec3f {
|
|
7433
|
+
if (thickness <= 0.0) {
|
|
7434
|
+
return vec3f(1.0);
|
|
7435
|
+
}
|
|
7436
|
+
|
|
7437
|
+
let attenuationCoefficient =
|
|
7438
|
+
-log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
|
|
7439
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
7440
|
+
return exp(-attenuationCoefficient * thickness);
|
|
7441
|
+
}
|
|
7442
|
+
|
|
7443
|
+
fn createClearcoatPBRInfo(
|
|
7444
|
+
basePBRInfo: PBRInfo,
|
|
7445
|
+
clearcoatNormal: vec3f,
|
|
7446
|
+
clearcoatRoughness: f32
|
|
7447
|
+
) -> PBRInfo {
|
|
7448
|
+
let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
7449
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
7450
|
+
let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
7451
|
+
|
|
7452
|
+
return PBRInfo(
|
|
7453
|
+
basePBRInfo.NdotL,
|
|
7454
|
+
NdotV,
|
|
7455
|
+
basePBRInfo.NdotH,
|
|
7456
|
+
basePBRInfo.LdotH,
|
|
7457
|
+
basePBRInfo.VdotH,
|
|
7458
|
+
perceptualRoughness,
|
|
7459
|
+
0.0,
|
|
7460
|
+
vec3f(0.04),
|
|
7461
|
+
vec3f(1.0),
|
|
7462
|
+
alphaRoughness,
|
|
7463
|
+
vec3f(0.0),
|
|
7464
|
+
vec3f(0.04),
|
|
7465
|
+
clearcoatNormal,
|
|
7466
|
+
basePBRInfo.v
|
|
7467
|
+
);
|
|
7468
|
+
}
|
|
7469
|
+
|
|
7470
|
+
fn calculateClearcoatContribution(
|
|
7471
|
+
pbrInfo: PBRInfo,
|
|
7472
|
+
lightColor: vec3f,
|
|
7473
|
+
clearcoatNormal: vec3f,
|
|
7474
|
+
clearcoatFactor: f32,
|
|
7475
|
+
clearcoatRoughness: f32
|
|
7476
|
+
) -> vec3f {
|
|
7477
|
+
if (clearcoatFactor <= 0.0) {
|
|
7478
|
+
return vec3f(0.0);
|
|
7479
|
+
}
|
|
7480
|
+
|
|
7481
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
7482
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
7483
|
+
}
|
|
7484
|
+
|
|
7485
|
+
#ifdef USE_IBL
|
|
7486
|
+
fn calculateClearcoatIBLContribution(
|
|
7487
|
+
pbrInfo: PBRInfo,
|
|
7488
|
+
clearcoatNormal: vec3f,
|
|
7489
|
+
reflection: vec3f,
|
|
7490
|
+
clearcoatFactor: f32,
|
|
7491
|
+
clearcoatRoughness: f32
|
|
7492
|
+
) -> vec3f {
|
|
7493
|
+
if (clearcoatFactor <= 0.0) {
|
|
7494
|
+
return vec3f(0.0);
|
|
7495
|
+
}
|
|
7496
|
+
|
|
7497
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
7498
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
7499
|
+
}
|
|
7500
|
+
#endif
|
|
7501
|
+
|
|
7502
|
+
fn calculateSheenContribution(
|
|
7503
|
+
pbrInfo: PBRInfo,
|
|
7504
|
+
lightColor: vec3f,
|
|
7505
|
+
sheenColor: vec3f,
|
|
7506
|
+
sheenRoughness: f32
|
|
7507
|
+
) -> vec3f {
|
|
7508
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
7509
|
+
return vec3f(0.0);
|
|
7510
|
+
}
|
|
7511
|
+
|
|
7512
|
+
let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
7513
|
+
let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
7514
|
+
return pbrInfo.NdotL *
|
|
7515
|
+
lightColor *
|
|
7516
|
+
sheenColor *
|
|
7517
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
7518
|
+
sheenVisibility *
|
|
7519
|
+
(1.0 - pbrInfo.metalness);
|
|
7520
|
+
}
|
|
7521
|
+
|
|
7522
|
+
fn calculateAnisotropyBoost(
|
|
7523
|
+
pbrInfo: PBRInfo,
|
|
7524
|
+
anisotropyTangent: vec3f,
|
|
7525
|
+
anisotropyStrength: f32
|
|
7526
|
+
) -> f32 {
|
|
7527
|
+
if (anisotropyStrength <= 0.0) {
|
|
7528
|
+
return 1.0;
|
|
7529
|
+
}
|
|
7530
|
+
|
|
7531
|
+
let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
7532
|
+
let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
7533
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
7534
|
+
}
|
|
7535
|
+
|
|
7536
|
+
fn calculateMaterialLightColor(
|
|
7537
|
+
pbrInfo: PBRInfo,
|
|
7538
|
+
lightColor: vec3f,
|
|
7539
|
+
clearcoatNormal: vec3f,
|
|
7540
|
+
clearcoatFactor: f32,
|
|
7541
|
+
clearcoatRoughness: f32,
|
|
7542
|
+
sheenColor: vec3f,
|
|
7543
|
+
sheenRoughness: f32,
|
|
7544
|
+
anisotropyTangent: vec3f,
|
|
7545
|
+
anisotropyStrength: f32
|
|
7546
|
+
) -> vec3f {
|
|
7547
|
+
let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
7548
|
+
var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
7549
|
+
color += calculateClearcoatContribution(
|
|
7550
|
+
pbrInfo,
|
|
7551
|
+
lightColor,
|
|
7552
|
+
clearcoatNormal,
|
|
7553
|
+
clearcoatFactor,
|
|
7554
|
+
clearcoatRoughness
|
|
7555
|
+
);
|
|
7556
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
7557
|
+
return color;
|
|
7558
|
+
}
|
|
7559
|
+
|
|
5774
7560
|
fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
|
|
5775
7561
|
(*pbrInfo).NdotL = 1.0;
|
|
5776
7562
|
(*pbrInfo).NdotH = 0.0;
|
|
@@ -5795,6 +7581,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
|
|
|
5795
7581
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
5796
7582
|
}
|
|
5797
7583
|
|
|
7584
|
+
fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
|
|
7585
|
+
let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
|
|
7586
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
7587
|
+
}
|
|
7588
|
+
|
|
5798
7589
|
fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
|
|
5799
7590
|
// Calculate the shading terms for the microfacet specular shading model
|
|
5800
7591
|
let F = specularReflection(pbrInfo);
|
|
@@ -5824,6 +7615,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5824
7615
|
#endif
|
|
5825
7616
|
|
|
5826
7617
|
var color = vec3<f32>(0.0, 0.0, 0.0);
|
|
7618
|
+
var transmission = 0.0;
|
|
5827
7619
|
|
|
5828
7620
|
if (pbrMaterial.unlit != 0u) {
|
|
5829
7621
|
color = baseColor.rgb;
|
|
@@ -5846,14 +7638,308 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5846
7638
|
#endif
|
|
5847
7639
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
5848
7640
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
7641
|
+
let tbn = getTBN();
|
|
7642
|
+
let n = getNormal(tbn); // normal at surface point
|
|
7643
|
+
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
7644
|
+
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
7645
|
+
var useExtendedPBR = false;
|
|
7646
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
7647
|
+
useExtendedPBR =
|
|
7648
|
+
pbrMaterial.specularColorMapEnabled != 0 ||
|
|
7649
|
+
pbrMaterial.specularIntensityMapEnabled != 0 ||
|
|
7650
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
7651
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
|
|
7652
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
7653
|
+
pbrMaterial.transmissionMapEnabled != 0 ||
|
|
7654
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
7655
|
+
pbrMaterial.clearcoatMapEnabled != 0 ||
|
|
7656
|
+
pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
|
|
7657
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
7658
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
7659
|
+
pbrMaterial.sheenColorMapEnabled != 0 ||
|
|
7660
|
+
pbrMaterial.sheenRoughnessMapEnabled != 0 ||
|
|
7661
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
7662
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
7663
|
+
pbrMaterial.iridescenceMapEnabled != 0 ||
|
|
7664
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
7665
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
7666
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
7667
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
7668
|
+
pbrMaterial.anisotropyMapEnabled != 0 ||
|
|
7669
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
7670
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
7671
|
+
length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
|
|
7672
|
+
#endif
|
|
7673
|
+
|
|
7674
|
+
if (!useExtendedPBR) {
|
|
7675
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
7676
|
+
|
|
7677
|
+
let f0 = vec3<f32>(0.04);
|
|
7678
|
+
var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
|
|
7679
|
+
diffuseColor *= 1.0 - metallic;
|
|
7680
|
+
let specularColor = mix(f0, baseColor.rgb, metallic);
|
|
7681
|
+
|
|
7682
|
+
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
7683
|
+
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
7684
|
+
let specularEnvironmentR0 = specularColor;
|
|
7685
|
+
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
7686
|
+
let reflection = -normalize(reflect(v, n));
|
|
7687
|
+
|
|
7688
|
+
var pbrInfo = PBRInfo(
|
|
7689
|
+
0.0, // NdotL
|
|
7690
|
+
NdotV,
|
|
7691
|
+
0.0, // NdotH
|
|
7692
|
+
0.0, // LdotH
|
|
7693
|
+
0.0, // VdotH
|
|
7694
|
+
perceptualRoughness,
|
|
7695
|
+
metallic,
|
|
7696
|
+
specularEnvironmentR0,
|
|
7697
|
+
specularEnvironmentR90,
|
|
7698
|
+
alphaRoughness,
|
|
7699
|
+
diffuseColor,
|
|
7700
|
+
specularColor,
|
|
7701
|
+
n,
|
|
7702
|
+
v
|
|
7703
|
+
);
|
|
7704
|
+
|
|
7705
|
+
#ifdef USE_LIGHTS
|
|
7706
|
+
PBRInfo_setAmbientLight(&pbrInfo);
|
|
7707
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
7708
|
+
|
|
7709
|
+
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
7710
|
+
if (i < lighting.directionalLightCount) {
|
|
7711
|
+
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
7712
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
7713
|
+
}
|
|
7714
|
+
}
|
|
7715
|
+
|
|
7716
|
+
for (var i = 0; i < lighting.pointLightCount; i++) {
|
|
7717
|
+
if (i < lighting.pointLightCount) {
|
|
7718
|
+
PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
|
|
7719
|
+
let attenuation = getPointLightAttenuation(
|
|
7720
|
+
lighting_getPointLight(i),
|
|
7721
|
+
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
7722
|
+
);
|
|
7723
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
7724
|
+
}
|
|
7725
|
+
}
|
|
7726
|
+
|
|
7727
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
7728
|
+
if (i < lighting.spotLightCount) {
|
|
7729
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
7730
|
+
let attenuation = getSpotLightAttenuation(
|
|
7731
|
+
lighting_getSpotLight(i),
|
|
7732
|
+
fragmentInputs.pbr_vPosition
|
|
7733
|
+
);
|
|
7734
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7737
|
+
#endif
|
|
7738
|
+
|
|
7739
|
+
#ifdef USE_IBL
|
|
7740
|
+
if (pbrMaterial.IBLenabled != 0) {
|
|
7741
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
7742
|
+
}
|
|
7743
|
+
#endif
|
|
7744
|
+
|
|
7745
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
7746
|
+
if (pbrMaterial.occlusionMapEnabled != 0) {
|
|
7747
|
+
let ao =
|
|
7748
|
+
textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
|
|
7749
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
7750
|
+
}
|
|
7751
|
+
#endif
|
|
7752
|
+
|
|
7753
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
7754
|
+
#ifdef HAS_EMISSIVEMAP
|
|
7755
|
+
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
7756
|
+
emissive *= SRGBtoLINEAR(
|
|
7757
|
+
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
7758
|
+
).rgb;
|
|
7759
|
+
}
|
|
7760
|
+
#endif
|
|
7761
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
7762
|
+
|
|
7763
|
+
#ifdef PBR_DEBUG
|
|
7764
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
7765
|
+
color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
7766
|
+
color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
7767
|
+
#endif
|
|
7768
|
+
|
|
7769
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
|
|
7770
|
+
}
|
|
7771
|
+
|
|
7772
|
+
var specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
7773
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
7774
|
+
if (pbrMaterial.specularIntensityMapEnabled != 0) {
|
|
7775
|
+
specularIntensity *= textureSample(
|
|
7776
|
+
pbr_specularIntensitySampler,
|
|
7777
|
+
pbr_specularIntensitySamplerSampler,
|
|
7778
|
+
fragmentInputs.pbr_vUV
|
|
7779
|
+
).a;
|
|
7780
|
+
}
|
|
7781
|
+
#endif
|
|
7782
|
+
|
|
7783
|
+
var specularFactor = pbrMaterial.specularColorFactor;
|
|
7784
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
7785
|
+
if (pbrMaterial.specularColorMapEnabled != 0) {
|
|
7786
|
+
specularFactor *= SRGBtoLINEAR(
|
|
7787
|
+
textureSample(
|
|
7788
|
+
pbr_specularColorSampler,
|
|
7789
|
+
pbr_specularColorSamplerSampler,
|
|
7790
|
+
fragmentInputs.pbr_vUV
|
|
7791
|
+
)
|
|
7792
|
+
).rgb;
|
|
7793
|
+
}
|
|
7794
|
+
#endif
|
|
7795
|
+
|
|
7796
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
7797
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
7798
|
+
if (pbrMaterial.transmissionMapEnabled != 0) {
|
|
7799
|
+
transmission *= textureSample(
|
|
7800
|
+
pbr_transmissionSampler,
|
|
7801
|
+
pbr_transmissionSamplerSampler,
|
|
7802
|
+
fragmentInputs.pbr_vUV
|
|
7803
|
+
).r;
|
|
7804
|
+
}
|
|
7805
|
+
#endif
|
|
7806
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
7807
|
+
var thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
7808
|
+
#ifdef HAS_THICKNESSMAP
|
|
7809
|
+
thickness *= textureSample(
|
|
7810
|
+
pbr_thicknessSampler,
|
|
7811
|
+
pbr_thicknessSamplerSampler,
|
|
7812
|
+
fragmentInputs.pbr_vUV
|
|
7813
|
+
).g;
|
|
7814
|
+
#endif
|
|
7815
|
+
|
|
7816
|
+
var clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
7817
|
+
var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
7818
|
+
#ifdef HAS_CLEARCOATMAP
|
|
7819
|
+
if (pbrMaterial.clearcoatMapEnabled != 0) {
|
|
7820
|
+
clearcoatFactor *= textureSample(
|
|
7821
|
+
pbr_clearcoatSampler,
|
|
7822
|
+
pbr_clearcoatSamplerSampler,
|
|
7823
|
+
fragmentInputs.pbr_vUV
|
|
7824
|
+
).r;
|
|
7825
|
+
}
|
|
7826
|
+
#endif
|
|
7827
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
7828
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
|
|
7829
|
+
clearcoatRoughness *= textureSample(
|
|
7830
|
+
pbr_clearcoatRoughnessSampler,
|
|
7831
|
+
pbr_clearcoatRoughnessSamplerSampler,
|
|
7832
|
+
fragmentInputs.pbr_vUV
|
|
7833
|
+
).g;
|
|
7834
|
+
}
|
|
7835
|
+
#endif
|
|
7836
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
7837
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
7838
|
+
let clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
7839
|
+
|
|
7840
|
+
var sheenColor = pbrMaterial.sheenColorFactor;
|
|
7841
|
+
var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
7842
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
7843
|
+
if (pbrMaterial.sheenColorMapEnabled != 0) {
|
|
7844
|
+
sheenColor *= SRGBtoLINEAR(
|
|
7845
|
+
textureSample(
|
|
7846
|
+
pbr_sheenColorSampler,
|
|
7847
|
+
pbr_sheenColorSamplerSampler,
|
|
7848
|
+
fragmentInputs.pbr_vUV
|
|
7849
|
+
)
|
|
7850
|
+
).rgb;
|
|
7851
|
+
}
|
|
7852
|
+
#endif
|
|
7853
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
7854
|
+
if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
|
|
7855
|
+
sheenRoughness *= textureSample(
|
|
7856
|
+
pbr_sheenRoughnessSampler,
|
|
7857
|
+
pbr_sheenRoughnessSamplerSampler,
|
|
7858
|
+
fragmentInputs.pbr_vUV
|
|
7859
|
+
).a;
|
|
7860
|
+
}
|
|
7861
|
+
#endif
|
|
7862
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
7863
|
+
|
|
7864
|
+
var iridescence = pbrMaterial.iridescenceFactor;
|
|
7865
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
7866
|
+
if (pbrMaterial.iridescenceMapEnabled != 0) {
|
|
7867
|
+
iridescence *= textureSample(
|
|
7868
|
+
pbr_iridescenceSampler,
|
|
7869
|
+
pbr_iridescenceSamplerSampler,
|
|
7870
|
+
fragmentInputs.pbr_vUV
|
|
7871
|
+
).r;
|
|
7872
|
+
}
|
|
7873
|
+
#endif
|
|
7874
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
7875
|
+
var iridescenceThickness = mix(
|
|
7876
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
7877
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
7878
|
+
0.5
|
|
7879
|
+
);
|
|
7880
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
7881
|
+
iridescenceThickness = mix(
|
|
7882
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
7883
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
7884
|
+
textureSample(
|
|
7885
|
+
pbr_iridescenceThicknessSampler,
|
|
7886
|
+
pbr_iridescenceThicknessSamplerSampler,
|
|
7887
|
+
fragmentInputs.pbr_vUV
|
|
7888
|
+
).g
|
|
7889
|
+
);
|
|
7890
|
+
#endif
|
|
7891
|
+
|
|
7892
|
+
var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
7893
|
+
var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
7894
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
7895
|
+
if (pbrMaterial.anisotropyMapEnabled != 0) {
|
|
7896
|
+
let anisotropySample = textureSample(
|
|
7897
|
+
pbr_anisotropySampler,
|
|
7898
|
+
pbr_anisotropySamplerSampler,
|
|
7899
|
+
fragmentInputs.pbr_vUV
|
|
7900
|
+
).rgb;
|
|
7901
|
+
anisotropyStrength *= anisotropySample.b;
|
|
7902
|
+
let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
7903
|
+
if (length(mappedDirection) > 0.0001) {
|
|
7904
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
7905
|
+
}
|
|
7906
|
+
}
|
|
7907
|
+
#endif
|
|
7908
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
7909
|
+
var anisotropyTangent =
|
|
7910
|
+
normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
7911
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
7912
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
7913
|
+
}
|
|
7914
|
+
let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
7915
|
+
perceptualRoughness = mix(
|
|
7916
|
+
perceptualRoughness,
|
|
7917
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
7918
|
+
anisotropyStrength
|
|
7919
|
+
);
|
|
7920
|
+
|
|
5849
7921
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
5850
7922
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
5851
7923
|
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5852
7924
|
|
|
5853
|
-
let
|
|
5854
|
-
var
|
|
5855
|
-
|
|
5856
|
-
|
|
7925
|
+
let dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
7926
|
+
var dielectricSpecularF0 = min(
|
|
7927
|
+
vec3f(dielectricF0) * specularFactor * specularIntensity,
|
|
7928
|
+
vec3f(1.0)
|
|
7929
|
+
);
|
|
7930
|
+
let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
7931
|
+
dielectricSpecularF0 = mix(
|
|
7932
|
+
dielectricSpecularF0,
|
|
7933
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
7934
|
+
iridescence
|
|
7935
|
+
);
|
|
7936
|
+
var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
|
|
7937
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
7938
|
+
var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
7939
|
+
|
|
7940
|
+
let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
7941
|
+
diffuseColor *= baseLayerEnergy;
|
|
7942
|
+
specularColor *= baseLayerEnergy;
|
|
5857
7943
|
|
|
5858
7944
|
// Compute reflectance.
|
|
5859
7945
|
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -5865,11 +7951,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5865
7951
|
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
5866
7952
|
let specularEnvironmentR0 = specularColor;
|
|
5867
7953
|
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
5868
|
-
|
|
5869
|
-
let n = getNormal(); // normal at surface point
|
|
5870
|
-
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
5871
|
-
|
|
5872
|
-
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
5873
7954
|
let reflection = -normalize(reflect(v, n));
|
|
5874
7955
|
|
|
5875
7956
|
var pbrInfo = PBRInfo(
|
|
@@ -5892,13 +7973,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5892
7973
|
#ifdef USE_LIGHTS
|
|
5893
7974
|
// Apply ambient light
|
|
5894
7975
|
PBRInfo_setAmbientLight(&pbrInfo);
|
|
5895
|
-
color +=
|
|
7976
|
+
color += calculateMaterialLightColor(
|
|
7977
|
+
pbrInfo,
|
|
7978
|
+
lighting.ambientColor,
|
|
7979
|
+
clearcoatNormal,
|
|
7980
|
+
clearcoatFactor,
|
|
7981
|
+
clearcoatRoughness,
|
|
7982
|
+
sheenColor,
|
|
7983
|
+
sheenRoughness,
|
|
7984
|
+
anisotropyTangent,
|
|
7985
|
+
anisotropyStrength
|
|
7986
|
+
);
|
|
5896
7987
|
|
|
5897
7988
|
// Apply directional light
|
|
5898
7989
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
5899
7990
|
if (i < lighting.directionalLightCount) {
|
|
5900
7991
|
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
5901
|
-
color +=
|
|
7992
|
+
color += calculateMaterialLightColor(
|
|
7993
|
+
pbrInfo,
|
|
7994
|
+
lighting_getDirectionalLight(i).color,
|
|
7995
|
+
clearcoatNormal,
|
|
7996
|
+
clearcoatFactor,
|
|
7997
|
+
clearcoatRoughness,
|
|
7998
|
+
sheenColor,
|
|
7999
|
+
sheenRoughness,
|
|
8000
|
+
anisotropyTangent,
|
|
8001
|
+
anisotropyStrength
|
|
8002
|
+
);
|
|
5902
8003
|
}
|
|
5903
8004
|
}
|
|
5904
8005
|
|
|
@@ -5910,7 +8011,35 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5910
8011
|
lighting_getPointLight(i),
|
|
5911
8012
|
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
5912
8013
|
);
|
|
5913
|
-
color +=
|
|
8014
|
+
color += calculateMaterialLightColor(
|
|
8015
|
+
pbrInfo,
|
|
8016
|
+
lighting_getPointLight(i).color / attenuation,
|
|
8017
|
+
clearcoatNormal,
|
|
8018
|
+
clearcoatFactor,
|
|
8019
|
+
clearcoatRoughness,
|
|
8020
|
+
sheenColor,
|
|
8021
|
+
sheenRoughness,
|
|
8022
|
+
anisotropyTangent,
|
|
8023
|
+
anisotropyStrength
|
|
8024
|
+
);
|
|
8025
|
+
}
|
|
8026
|
+
}
|
|
8027
|
+
|
|
8028
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
8029
|
+
if (i < lighting.spotLightCount) {
|
|
8030
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
8031
|
+
let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
|
|
8032
|
+
color += calculateMaterialLightColor(
|
|
8033
|
+
pbrInfo,
|
|
8034
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
8035
|
+
clearcoatNormal,
|
|
8036
|
+
clearcoatFactor,
|
|
8037
|
+
clearcoatRoughness,
|
|
8038
|
+
sheenColor,
|
|
8039
|
+
sheenRoughness,
|
|
8040
|
+
anisotropyTangent,
|
|
8041
|
+
anisotropyStrength
|
|
8042
|
+
);
|
|
5914
8043
|
}
|
|
5915
8044
|
}
|
|
5916
8045
|
#endif
|
|
@@ -5918,7 +8047,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5918
8047
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
5919
8048
|
#ifdef USE_IBL
|
|
5920
8049
|
if (pbrMaterial.IBLenabled != 0) {
|
|
5921
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
8050
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
8051
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
8052
|
+
color += calculateClearcoatIBLContribution(
|
|
8053
|
+
pbrInfo,
|
|
8054
|
+
clearcoatNormal,
|
|
8055
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
8056
|
+
clearcoatFactor,
|
|
8057
|
+
clearcoatRoughness
|
|
8058
|
+
);
|
|
8059
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
5922
8060
|
}
|
|
5923
8061
|
#endif
|
|
5924
8062
|
|
|
@@ -5931,14 +8069,19 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5931
8069
|
}
|
|
5932
8070
|
#endif
|
|
5933
8071
|
|
|
8072
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
5934
8073
|
#ifdef HAS_EMISSIVEMAP
|
|
5935
8074
|
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
5936
|
-
|
|
8075
|
+
emissive *= SRGBtoLINEAR(
|
|
5937
8076
|
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
5938
|
-
).rgb
|
|
5939
|
-
color += emissive;
|
|
8077
|
+
).rgb;
|
|
5940
8078
|
}
|
|
5941
8079
|
#endif
|
|
8080
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
8081
|
+
|
|
8082
|
+
if (transmission > 0.0) {
|
|
8083
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
8084
|
+
}
|
|
5942
8085
|
|
|
5943
8086
|
// This section uses mix to override final color for reference app visualization
|
|
5944
8087
|
// of various parameters in the lighting equation.
|
|
@@ -5957,7 +8100,8 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5957
8100
|
#endif
|
|
5958
8101
|
}
|
|
5959
8102
|
|
|
5960
|
-
|
|
8103
|
+
let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
8104
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
|
|
5961
8105
|
}
|
|
5962
8106
|
`
|
|
5963
8107
|
);
|
|
@@ -5982,11 +8126,12 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
5982
8126
|
camera: vec3<f32>
|
|
5983
8127
|
};
|
|
5984
8128
|
|
|
5985
|
-
@
|
|
8129
|
+
@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
|
|
5986
8130
|
`
|
|
5987
8131
|
);
|
|
5988
8132
|
var pbrProjection = {
|
|
5989
8133
|
name: "pbrProjection",
|
|
8134
|
+
bindingLayout: [{ name: "pbrProjection", group: 0 }],
|
|
5990
8135
|
source: wgslUniformBlock,
|
|
5991
8136
|
vs: uniformBlock,
|
|
5992
8137
|
fs: uniformBlock,
|
|
@@ -6004,8 +8149,75 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
6004
8149
|
var pbrMaterial = {
|
|
6005
8150
|
props: {},
|
|
6006
8151
|
uniforms: {},
|
|
8152
|
+
defaultUniforms: {
|
|
8153
|
+
unlit: false,
|
|
8154
|
+
baseColorMapEnabled: false,
|
|
8155
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
8156
|
+
normalMapEnabled: false,
|
|
8157
|
+
normalScale: 1,
|
|
8158
|
+
emissiveMapEnabled: false,
|
|
8159
|
+
emissiveFactor: [0, 0, 0],
|
|
8160
|
+
metallicRoughnessValues: [1, 1],
|
|
8161
|
+
metallicRoughnessMapEnabled: false,
|
|
8162
|
+
occlusionMapEnabled: false,
|
|
8163
|
+
occlusionStrength: 1,
|
|
8164
|
+
alphaCutoffEnabled: false,
|
|
8165
|
+
alphaCutoff: 0.5,
|
|
8166
|
+
IBLenabled: false,
|
|
8167
|
+
scaleIBLAmbient: [1, 1],
|
|
8168
|
+
scaleDiffBaseMR: [0, 0, 0, 0],
|
|
8169
|
+
scaleFGDSpec: [0, 0, 0, 0],
|
|
8170
|
+
specularColorFactor: [1, 1, 1],
|
|
8171
|
+
specularIntensityFactor: 1,
|
|
8172
|
+
specularColorMapEnabled: false,
|
|
8173
|
+
specularIntensityMapEnabled: false,
|
|
8174
|
+
ior: 1.5,
|
|
8175
|
+
transmissionFactor: 0,
|
|
8176
|
+
transmissionMapEnabled: false,
|
|
8177
|
+
thicknessFactor: 0,
|
|
8178
|
+
attenuationDistance: 1e9,
|
|
8179
|
+
attenuationColor: [1, 1, 1],
|
|
8180
|
+
clearcoatFactor: 0,
|
|
8181
|
+
clearcoatRoughnessFactor: 0,
|
|
8182
|
+
clearcoatMapEnabled: false,
|
|
8183
|
+
clearcoatRoughnessMapEnabled: false,
|
|
8184
|
+
sheenColorFactor: [0, 0, 0],
|
|
8185
|
+
sheenRoughnessFactor: 0,
|
|
8186
|
+
sheenColorMapEnabled: false,
|
|
8187
|
+
sheenRoughnessMapEnabled: false,
|
|
8188
|
+
iridescenceFactor: 0,
|
|
8189
|
+
iridescenceIor: 1.3,
|
|
8190
|
+
iridescenceThicknessRange: [100, 400],
|
|
8191
|
+
iridescenceMapEnabled: false,
|
|
8192
|
+
anisotropyStrength: 0,
|
|
8193
|
+
anisotropyRotation: 0,
|
|
8194
|
+
anisotropyDirection: [1, 0],
|
|
8195
|
+
anisotropyMapEnabled: false,
|
|
8196
|
+
emissiveStrength: 1
|
|
8197
|
+
},
|
|
6007
8198
|
name: "pbrMaterial",
|
|
6008
|
-
|
|
8199
|
+
firstBindingSlot: 0,
|
|
8200
|
+
bindingLayout: [
|
|
8201
|
+
{ name: "pbrMaterial", group: 3 },
|
|
8202
|
+
{ name: "pbr_baseColorSampler", group: 3 },
|
|
8203
|
+
{ name: "pbr_normalSampler", group: 3 },
|
|
8204
|
+
{ name: "pbr_emissiveSampler", group: 3 },
|
|
8205
|
+
{ name: "pbr_metallicRoughnessSampler", group: 3 },
|
|
8206
|
+
{ name: "pbr_occlusionSampler", group: 3 },
|
|
8207
|
+
{ name: "pbr_specularColorSampler", group: 3 },
|
|
8208
|
+
{ name: "pbr_specularIntensitySampler", group: 3 },
|
|
8209
|
+
{ name: "pbr_transmissionSampler", group: 3 },
|
|
8210
|
+
{ name: "pbr_thicknessSampler", group: 3 },
|
|
8211
|
+
{ name: "pbr_clearcoatSampler", group: 3 },
|
|
8212
|
+
{ name: "pbr_clearcoatRoughnessSampler", group: 3 },
|
|
8213
|
+
{ name: "pbr_clearcoatNormalSampler", group: 3 },
|
|
8214
|
+
{ name: "pbr_sheenColorSampler", group: 3 },
|
|
8215
|
+
{ name: "pbr_sheenRoughnessSampler", group: 3 },
|
|
8216
|
+
{ name: "pbr_iridescenceSampler", group: 3 },
|
|
8217
|
+
{ name: "pbr_iridescenceThicknessSampler", group: 3 },
|
|
8218
|
+
{ name: "pbr_anisotropySampler", group: 3 }
|
|
8219
|
+
],
|
|
8220
|
+
dependencies: [lighting, ibl, pbrProjection],
|
|
6009
8221
|
source: source3,
|
|
6010
8222
|
vs: vs3,
|
|
6011
8223
|
fs: fs4,
|
|
@@ -6019,10 +8231,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
6019
8231
|
HAS_SPECULARCOLORMAP: false,
|
|
6020
8232
|
HAS_SPECULARINTENSITYMAP: false,
|
|
6021
8233
|
HAS_TRANSMISSIONMAP: false,
|
|
8234
|
+
HAS_THICKNESSMAP: false,
|
|
6022
8235
|
HAS_CLEARCOATMAP: false,
|
|
8236
|
+
HAS_CLEARCOATROUGHNESSMAP: false,
|
|
8237
|
+
HAS_CLEARCOATNORMALMAP: false,
|
|
6023
8238
|
HAS_SHEENCOLORMAP: false,
|
|
8239
|
+
HAS_SHEENROUGHNESSMAP: false,
|
|
6024
8240
|
HAS_IRIDESCENCEMAP: false,
|
|
8241
|
+
HAS_IRIDESCENCETHICKNESSMAP: false,
|
|
6025
8242
|
HAS_ANISOTROPYMAP: false,
|
|
8243
|
+
USE_MATERIAL_EXTENSIONS: false,
|
|
6026
8244
|
ALPHA_CUTOFF: false,
|
|
6027
8245
|
USE_IBL: false,
|
|
6028
8246
|
PBR_DEBUG: false
|
|
@@ -6048,14 +8266,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
6048
8266
|
alphaCutoffEnabled: "i32",
|
|
6049
8267
|
alphaCutoff: "f32",
|
|
6050
8268
|
// #ifdef ALPHA_CUTOFF
|
|
6051
|
-
// IBL
|
|
6052
|
-
IBLenabled: "i32",
|
|
6053
|
-
scaleIBLAmbient: "vec2<f32>",
|
|
6054
|
-
// #ifdef USE_IBL
|
|
6055
|
-
// debugging flags used for shader output of intermediate PBR variables
|
|
6056
|
-
// #ifdef PBR_DEBUG
|
|
6057
|
-
scaleDiffBaseMR: "vec4<f32>",
|
|
6058
|
-
scaleFGDSpec: "vec4<f32>",
|
|
6059
8269
|
specularColorFactor: "vec3<f32>",
|
|
6060
8270
|
specularIntensityFactor: "f32",
|
|
6061
8271
|
specularColorMapEnabled: "i32",
|
|
@@ -6069,9 +8279,11 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
6069
8279
|
clearcoatFactor: "f32",
|
|
6070
8280
|
clearcoatRoughnessFactor: "f32",
|
|
6071
8281
|
clearcoatMapEnabled: "i32",
|
|
8282
|
+
clearcoatRoughnessMapEnabled: "i32",
|
|
6072
8283
|
sheenColorFactor: "vec3<f32>",
|
|
6073
8284
|
sheenRoughnessFactor: "f32",
|
|
6074
8285
|
sheenColorMapEnabled: "i32",
|
|
8286
|
+
sheenRoughnessMapEnabled: "i32",
|
|
6075
8287
|
iridescenceFactor: "f32",
|
|
6076
8288
|
iridescenceIor: "f32",
|
|
6077
8289
|
iridescenceThicknessRange: "vec2<f32>",
|
|
@@ -6080,7 +8292,15 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
6080
8292
|
anisotropyRotation: "f32",
|
|
6081
8293
|
anisotropyDirection: "vec2<f32>",
|
|
6082
8294
|
anisotropyMapEnabled: "i32",
|
|
6083
|
-
emissiveStrength: "f32"
|
|
8295
|
+
emissiveStrength: "f32",
|
|
8296
|
+
// IBL
|
|
8297
|
+
IBLenabled: "i32",
|
|
8298
|
+
scaleIBLAmbient: "vec2<f32>",
|
|
8299
|
+
// #ifdef USE_IBL
|
|
8300
|
+
// debugging flags used for shader output of intermediate PBR variables
|
|
8301
|
+
// #ifdef PBR_DEBUG
|
|
8302
|
+
scaleDiffBaseMR: "vec4<f32>",
|
|
8303
|
+
scaleFGDSpec: "vec4<f32>"
|
|
6084
8304
|
}
|
|
6085
8305
|
};
|
|
6086
8306
|
return __toCommonJS(bundle_exports);
|