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