@luma.gl/shadertools 9.3.0-alpha.6 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +2550 -330
- package/dist/dist.min.js +1803 -283
- package/dist/index.cjs +2495 -358
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +4 -3
- package/dist/lib/preprocessor/preprocessor.js.map +1 -1
- package/dist/lib/shader-assembler.d.ts +10 -0
- package/dist/lib/shader-assembler.d.ts.map +1 -1
- package/dist/lib/shader-assembler.js +12 -2
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js +112 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +11 -5
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js.map +1 -1
- package/dist/lib/utils/uniform-types.d.ts +11 -7
- package/dist/lib/utils/uniform-types.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.d.ts +3 -0
- package/dist/modules/engine/picking/picking.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.js +3 -0
- package/dist/modules/engine/picking/picking.js.map +1 -1
- package/dist/modules/engine/skin/skin.d.ts +7 -6
- package/dist/modules/engine/skin/skin.d.ts.map +1 -1
- package/dist/modules/engine/skin/skin.js +3 -5
- package/dist/modules/engine/skin/skin.js.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
- package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
- package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
- package/dist/modules/lighting/ibl/ibl.js +33 -0
- package/dist/modules/lighting/ibl/ibl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
- package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.js +43 -55
- package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.js +43 -65
- package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +104 -86
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +96 -83
- package/dist/modules/lighting/lights/lighting.js.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.d.ts +7 -2
- package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.js +3 -1
- package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +524 -28
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +706 -50
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -61
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +85 -9
- package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js +2 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +4 -0
- package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +15 -4
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +36 -5
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +41 -10
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
- package/dist/modules/math/fp64/fp64.d.ts +1 -0
- package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64.js +8 -2
- package/dist/modules/math/fp64/fp64.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +19 -2
- package/src/lib/preprocessor/preprocessor.ts +6 -3
- package/src/lib/shader-assembler.ts +17 -2
- package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
- package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
- package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
- package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
- package/src/lib/shader-module/shader-module-uniform-layout.ts +194 -0
- package/src/lib/shader-module/shader-module.ts +16 -6
- package/src/lib/utils/uniform-types.ts +24 -9
- package/src/modules/engine/picking/picking.ts +3 -0
- package/src/modules/engine/skin/skin.ts +3 -5
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
- package/src/modules/lighting/ibl/ibl.ts +44 -0
- package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
- package/src/modules/lighting/lights/lighting-glsl.ts +43 -55
- package/src/modules/lighting/lights/lighting-wgsl.ts +43 -65
- package/src/modules/lighting/lights/lighting.ts +186 -123
- package/src/modules/lighting/no-material/dirlight.ts +3 -1
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +524 -28
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +706 -50
- package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
- package/src/modules/lighting/pbr-material/pbr-projection.ts +2 -1
- package/src/modules/lighting/phong-material/phong-material.ts +5 -0
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +15 -4
- package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +36 -5
- package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +41 -10
- package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
- package/src/modules/math/fp64/fp64.ts +9 -3
package/dist/index.cjs
CHANGED
|
@@ -47,10 +47,15 @@ __export(dist_exports, {
|
|
|
47
47
|
getShaderInfo: () => getShaderInfo,
|
|
48
48
|
getShaderModuleDependencies: () => getShaderModuleDependencies,
|
|
49
49
|
getShaderModuleSource: () => getShaderModuleSource,
|
|
50
|
+
getShaderModuleUniformBlockFields: () => getShaderModuleUniformBlockFields,
|
|
51
|
+
getShaderModuleUniformBlockName: () => getShaderModuleUniformBlockName,
|
|
52
|
+
getShaderModuleUniformLayoutValidationResult: () => getShaderModuleUniformLayoutValidationResult,
|
|
50
53
|
getShaderModuleUniforms: () => getShaderModuleUniforms,
|
|
51
54
|
gouraudMaterial: () => gouraudMaterial,
|
|
55
|
+
ibl: () => ibl,
|
|
52
56
|
initializeShaderModule: () => initializeShaderModule,
|
|
53
57
|
initializeShaderModules: () => initializeShaderModules,
|
|
58
|
+
lambertMaterial: () => lambertMaterial,
|
|
54
59
|
lighting: () => lighting,
|
|
55
60
|
pbrMaterial: () => pbrMaterial,
|
|
56
61
|
phongMaterial: () => phongMaterial,
|
|
@@ -60,7 +65,8 @@ __export(dist_exports, {
|
|
|
60
65
|
skin: () => skin,
|
|
61
66
|
toHalfFloat: () => toHalfFloat,
|
|
62
67
|
typeToChannelCount: () => typeToChannelCount,
|
|
63
|
-
typeToChannelSuffix: () => typeToChannelSuffix
|
|
68
|
+
typeToChannelSuffix: () => typeToChannelSuffix,
|
|
69
|
+
validateShaderModuleUniformLayout: () => validateShaderModuleUniformLayout
|
|
64
70
|
});
|
|
65
71
|
module.exports = __toCommonJS(dist_exports);
|
|
66
72
|
|
|
@@ -379,6 +385,114 @@ function resolveModules(modules) {
|
|
|
379
385
|
return getShaderDependencies(modules);
|
|
380
386
|
}
|
|
381
387
|
|
|
388
|
+
// dist/lib/shader-module/shader-module-uniform-layout.js
|
|
389
|
+
function getShaderModuleUniformBlockName(module2) {
|
|
390
|
+
return `${module2.name}Uniforms`;
|
|
391
|
+
}
|
|
392
|
+
function getShaderModuleUniformBlockFields(module2, stage) {
|
|
393
|
+
const shaderSource = stage === "wgsl" ? module2.source : stage === "vertex" ? module2.vs : module2.fs;
|
|
394
|
+
if (!shaderSource) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
const uniformBlockName = getShaderModuleUniformBlockName(module2);
|
|
398
|
+
return extractShaderUniformBlockFieldNames(shaderSource, stage === "wgsl" ? "wgsl" : "glsl", uniformBlockName);
|
|
399
|
+
}
|
|
400
|
+
function getShaderModuleUniformLayoutValidationResult(module2, stage) {
|
|
401
|
+
const expectedUniformNames = Object.keys(module2.uniformTypes || {});
|
|
402
|
+
if (!expectedUniformNames.length) {
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
const actualUniformNames = getShaderModuleUniformBlockFields(module2, stage);
|
|
406
|
+
if (!actualUniformNames) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
moduleName: module2.name,
|
|
411
|
+
uniformBlockName: getShaderModuleUniformBlockName(module2),
|
|
412
|
+
stage,
|
|
413
|
+
expectedUniformNames,
|
|
414
|
+
actualUniformNames,
|
|
415
|
+
matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function validateShaderModuleUniformLayout(module2, stage, options = {}) {
|
|
419
|
+
var _a, _b;
|
|
420
|
+
const validationResult = getShaderModuleUniformLayoutValidationResult(module2, stage);
|
|
421
|
+
if (!validationResult || validationResult.matches) {
|
|
422
|
+
return validationResult;
|
|
423
|
+
}
|
|
424
|
+
const message = formatShaderModuleUniformLayoutError(validationResult);
|
|
425
|
+
(_b = (_a = options.log) == null ? void 0 : _a.error) == null ? void 0 : _b.call(_a, message, validationResult)();
|
|
426
|
+
if (options.throwOnError !== false) {
|
|
427
|
+
assert(false, message);
|
|
428
|
+
}
|
|
429
|
+
return validationResult;
|
|
430
|
+
}
|
|
431
|
+
function extractShaderUniformBlockFieldNames(shaderSource, language, uniformBlockName) {
|
|
432
|
+
const sourceBody = language === "wgsl" ? extractWGSLStructBody(shaderSource, uniformBlockName) : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);
|
|
433
|
+
if (!sourceBody) {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
const fieldNames = [];
|
|
437
|
+
for (const sourceLine of sourceBody.split("\n")) {
|
|
438
|
+
const line = sourceLine.replace(/\/\/.*$/, "").trim();
|
|
439
|
+
if (!line || line.startsWith("#")) {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const fieldMatch = language === "wgsl" ? line.match(/^([A-Za-z0-9_]+)\s*:/) : line.match(/^(?:uniform\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/);
|
|
443
|
+
if (fieldMatch) {
|
|
444
|
+
fieldNames.push(fieldMatch[1]);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return fieldNames;
|
|
448
|
+
}
|
|
449
|
+
function extractWGSLStructBody(shaderSource, uniformBlockName) {
|
|
450
|
+
const structMatch = new RegExp(`\\bstruct\\s+${uniformBlockName}\\b`, "m").exec(shaderSource);
|
|
451
|
+
if (!structMatch) {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
const openBraceIndex = shaderSource.indexOf("{", structMatch.index);
|
|
455
|
+
if (openBraceIndex < 0) {
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
let braceDepth = 0;
|
|
459
|
+
for (let index = openBraceIndex; index < shaderSource.length; index++) {
|
|
460
|
+
const character = shaderSource[index];
|
|
461
|
+
if (character === "{") {
|
|
462
|
+
braceDepth++;
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
if (character !== "}") {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
braceDepth--;
|
|
469
|
+
if (braceDepth === 0) {
|
|
470
|
+
return shaderSource.slice(openBraceIndex + 1, index);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
function extractGLSLUniformBlockBody(shaderSource, uniformBlockName) {
|
|
476
|
+
const sourceMatch = shaderSource.match(new RegExp(`uniform\\s+${uniformBlockName}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`, "m"));
|
|
477
|
+
return (sourceMatch == null ? void 0 : sourceMatch[1]) || null;
|
|
478
|
+
}
|
|
479
|
+
function areStringArraysEqual(leftValues, rightValues) {
|
|
480
|
+
if (leftValues.length !== rightValues.length) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {
|
|
484
|
+
if (leftValues[valueIndex] !== rightValues[valueIndex]) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
function formatShaderModuleUniformLayoutError(validationResult) {
|
|
491
|
+
return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${validationResult.uniformBlockName} does not match module.uniformTypes.
|
|
492
|
+
Expected: ${validationResult.expectedUniformNames.join(", ")}
|
|
493
|
+
Actual: ${validationResult.actualUniformNames.join(", ")}`;
|
|
494
|
+
}
|
|
495
|
+
|
|
382
496
|
// dist/lib/shader-assembly/platform-defines.js
|
|
383
497
|
function getPlatformShaderDefines(platformInfo) {
|
|
384
498
|
switch (platformInfo == null ? void 0 : platformInfo.gpu.toLowerCase()) {
|
|
@@ -564,11 +678,158 @@ function getShaderVersion(source4) {
|
|
|
564
678
|
return version;
|
|
565
679
|
}
|
|
566
680
|
|
|
681
|
+
// dist/lib/shader-assembly/wgsl-binding-debug.js
|
|
682
|
+
var WGSL_BINDING_DEBUG_REGEXES = [
|
|
683
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g,
|
|
684
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g
|
|
685
|
+
];
|
|
686
|
+
function getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments = []) {
|
|
687
|
+
var _a;
|
|
688
|
+
const assignmentMap = /* @__PURE__ */ new Map();
|
|
689
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
690
|
+
assignmentMap.set(getBindingAssignmentKey(bindingAssignment.name, bindingAssignment.group, bindingAssignment.location), bindingAssignment.moduleName);
|
|
691
|
+
}
|
|
692
|
+
const rows = [];
|
|
693
|
+
for (const regex of WGSL_BINDING_DEBUG_REGEXES) {
|
|
694
|
+
regex.lastIndex = 0;
|
|
695
|
+
let match;
|
|
696
|
+
while (match = regex.exec(source4)) {
|
|
697
|
+
const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];
|
|
698
|
+
const binding = Number(match[isBindingFirst ? 1 : 2]);
|
|
699
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
700
|
+
const accessDeclaration = (_a = match[3]) == null ? void 0 : _a.trim();
|
|
701
|
+
const name = match[4];
|
|
702
|
+
const resourceType = match[5].trim();
|
|
703
|
+
const moduleName = assignmentMap.get(getBindingAssignmentKey(name, group, binding));
|
|
704
|
+
rows.push(normalizeShaderBindingDebugRow({
|
|
705
|
+
name,
|
|
706
|
+
group,
|
|
707
|
+
binding,
|
|
708
|
+
owner: moduleName ? "module" : "application",
|
|
709
|
+
moduleName,
|
|
710
|
+
accessDeclaration,
|
|
711
|
+
resourceType
|
|
712
|
+
}));
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return rows.sort((left, right) => {
|
|
716
|
+
if (left.group !== right.group) {
|
|
717
|
+
return left.group - right.group;
|
|
718
|
+
}
|
|
719
|
+
if (left.binding !== right.binding) {
|
|
720
|
+
return left.binding - right.binding;
|
|
721
|
+
}
|
|
722
|
+
return left.name.localeCompare(right.name);
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
function normalizeShaderBindingDebugRow(row) {
|
|
726
|
+
const baseRow = {
|
|
727
|
+
name: row.name,
|
|
728
|
+
group: row.group,
|
|
729
|
+
binding: row.binding,
|
|
730
|
+
owner: row.owner,
|
|
731
|
+
kind: "unknown",
|
|
732
|
+
moduleName: row.moduleName,
|
|
733
|
+
resourceType: row.resourceType
|
|
734
|
+
};
|
|
735
|
+
if (row.accessDeclaration) {
|
|
736
|
+
const access = row.accessDeclaration.split(",").map((value) => value.trim());
|
|
737
|
+
if (access[0] === "uniform") {
|
|
738
|
+
return { ...baseRow, kind: "uniform", access: "uniform" };
|
|
739
|
+
}
|
|
740
|
+
if (access[0] === "storage") {
|
|
741
|
+
const storageAccess = access[1] || "read_write";
|
|
742
|
+
return {
|
|
743
|
+
...baseRow,
|
|
744
|
+
kind: storageAccess === "read" ? "read-only-storage" : "storage",
|
|
745
|
+
access: storageAccess
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
if (row.resourceType === "sampler" || row.resourceType === "sampler_comparison") {
|
|
750
|
+
return {
|
|
751
|
+
...baseRow,
|
|
752
|
+
kind: "sampler",
|
|
753
|
+
samplerKind: row.resourceType === "sampler_comparison" ? "comparison" : "filtering"
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
if (row.resourceType.startsWith("texture_storage_")) {
|
|
757
|
+
return {
|
|
758
|
+
...baseRow,
|
|
759
|
+
kind: "storage-texture",
|
|
760
|
+
access: getStorageTextureAccess(row.resourceType),
|
|
761
|
+
viewDimension: getTextureViewDimension(row.resourceType)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
if (row.resourceType.startsWith("texture_")) {
|
|
765
|
+
return {
|
|
766
|
+
...baseRow,
|
|
767
|
+
kind: "texture",
|
|
768
|
+
viewDimension: getTextureViewDimension(row.resourceType),
|
|
769
|
+
sampleType: getTextureSampleType(row.resourceType),
|
|
770
|
+
multisampled: row.resourceType.startsWith("texture_multisampled_")
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
return baseRow;
|
|
774
|
+
}
|
|
775
|
+
function getBindingAssignmentKey(name, group, binding) {
|
|
776
|
+
return `${group}:${binding}:${name}`;
|
|
777
|
+
}
|
|
778
|
+
function getTextureViewDimension(resourceType) {
|
|
779
|
+
if (resourceType.includes("cube_array")) {
|
|
780
|
+
return "cube-array";
|
|
781
|
+
}
|
|
782
|
+
if (resourceType.includes("2d_array")) {
|
|
783
|
+
return "2d-array";
|
|
784
|
+
}
|
|
785
|
+
if (resourceType.includes("cube")) {
|
|
786
|
+
return "cube";
|
|
787
|
+
}
|
|
788
|
+
if (resourceType.includes("3d")) {
|
|
789
|
+
return "3d";
|
|
790
|
+
}
|
|
791
|
+
if (resourceType.includes("2d")) {
|
|
792
|
+
return "2d";
|
|
793
|
+
}
|
|
794
|
+
if (resourceType.includes("1d")) {
|
|
795
|
+
return "1d";
|
|
796
|
+
}
|
|
797
|
+
return void 0;
|
|
798
|
+
}
|
|
799
|
+
function getTextureSampleType(resourceType) {
|
|
800
|
+
if (resourceType.startsWith("texture_depth_")) {
|
|
801
|
+
return "depth";
|
|
802
|
+
}
|
|
803
|
+
if (resourceType.includes("<i32>")) {
|
|
804
|
+
return "sint";
|
|
805
|
+
}
|
|
806
|
+
if (resourceType.includes("<u32>")) {
|
|
807
|
+
return "uint";
|
|
808
|
+
}
|
|
809
|
+
if (resourceType.includes("<f32>")) {
|
|
810
|
+
return "float";
|
|
811
|
+
}
|
|
812
|
+
return void 0;
|
|
813
|
+
}
|
|
814
|
+
function getStorageTextureAccess(resourceType) {
|
|
815
|
+
const match = /,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(resourceType);
|
|
816
|
+
return match == null ? void 0 : match[1];
|
|
817
|
+
}
|
|
818
|
+
|
|
567
819
|
// dist/lib/shader-assembly/assemble-shaders.js
|
|
568
820
|
var INJECT_SHADER_DECLARATIONS = `
|
|
569
821
|
|
|
570
822
|
${DECLARATION_INJECT_MARKER}
|
|
571
823
|
`;
|
|
824
|
+
var MODULE_WGSL_BINDING_DECLARATION_REGEXES = [
|
|
825
|
+
/@binding\(\s*(auto|\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
826
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(auto|\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
827
|
+
];
|
|
828
|
+
var WGSL_BINDING_DECLARATION_REGEXES = [
|
|
829
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
830
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
831
|
+
];
|
|
832
|
+
var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
|
|
572
833
|
var FRAGMENT_SHADER_PROLOGUE = (
|
|
573
834
|
/* glsl */
|
|
574
835
|
`precision highp float;
|
|
@@ -576,14 +837,17 @@ var FRAGMENT_SHADER_PROLOGUE = (
|
|
|
576
837
|
);
|
|
577
838
|
function assembleWGSLShader(options) {
|
|
578
839
|
const modules = getShaderModuleDependencies(options.modules || []);
|
|
840
|
+
const { source: source4, bindingAssignments } = assembleShaderWGSL(options.platformInfo, {
|
|
841
|
+
...options,
|
|
842
|
+
source: options.source,
|
|
843
|
+
stage: "vertex",
|
|
844
|
+
modules
|
|
845
|
+
});
|
|
579
846
|
return {
|
|
580
|
-
source:
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
modules
|
|
585
|
-
}),
|
|
586
|
-
getUniforms: assembleGetUniforms(modules)
|
|
847
|
+
source: source4,
|
|
848
|
+
getUniforms: assembleGetUniforms(modules),
|
|
849
|
+
bindingAssignments,
|
|
850
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments)
|
|
587
851
|
};
|
|
588
852
|
}
|
|
589
853
|
function assembleGLSLShaderPair(options) {
|
|
@@ -645,11 +909,20 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
645
909
|
}
|
|
646
910
|
}
|
|
647
911
|
const modulesToInject = modules;
|
|
912
|
+
const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(coreSource);
|
|
913
|
+
const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(modulesToInject, options._bindingRegistry, usedBindingsByGroup);
|
|
914
|
+
const bindingAssignments = [];
|
|
648
915
|
for (const module2 of modulesToInject) {
|
|
649
916
|
if (log2) {
|
|
650
917
|
checkShaderModuleDeprecations(module2, coreSource, log2);
|
|
651
918
|
}
|
|
652
|
-
const
|
|
919
|
+
const relocation = relocateWGSLModuleBindings(getShaderModuleSource(module2, "wgsl", log2), module2, {
|
|
920
|
+
usedBindingsByGroup,
|
|
921
|
+
bindingRegistry: options._bindingRegistry,
|
|
922
|
+
reservedBindingKeysByGroup
|
|
923
|
+
});
|
|
924
|
+
bindingAssignments.push(...relocation.bindingAssignments);
|
|
925
|
+
const moduleSource = relocation.source;
|
|
653
926
|
assembledSource += moduleSource;
|
|
654
927
|
const injections = ((_a = module2.injections) == null ? void 0 : _a[stage]) || {};
|
|
655
928
|
for (const key in injections) {
|
|
@@ -668,9 +941,11 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
668
941
|
assembledSource += INJECT_SHADER_DECLARATIONS;
|
|
669
942
|
assembledSource = injectShader(assembledSource, stage, declInjections);
|
|
670
943
|
assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);
|
|
944
|
+
assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);
|
|
671
945
|
assembledSource += coreSource;
|
|
672
946
|
assembledSource = injectShader(assembledSource, stage, mainInjections);
|
|
673
|
-
|
|
947
|
+
assertNoUnresolvedAutoBindings(assembledSource);
|
|
948
|
+
return { source: assembledSource, bindingAssignments };
|
|
674
949
|
}
|
|
675
950
|
function assembleShaderGLSL(platformInfo, options) {
|
|
676
951
|
var _a;
|
|
@@ -734,7 +1009,7 @@ ${getApplicationDefines(allDefines)}
|
|
|
734
1009
|
if (log2) {
|
|
735
1010
|
checkShaderModuleDeprecations(module2, coreSource, log2);
|
|
736
1011
|
}
|
|
737
|
-
const moduleSource = getShaderModuleSource(module2, stage);
|
|
1012
|
+
const moduleSource = getShaderModuleSource(module2, stage, log2);
|
|
738
1013
|
assembledSource += moduleSource;
|
|
739
1014
|
const injections = ((_a = module2.instance) == null ? void 0 : _a.normalizedInjections[stage]) || {};
|
|
740
1015
|
for (const key in injections) {
|
|
@@ -783,7 +1058,7 @@ function getApplicationDefines(defines = {}) {
|
|
|
783
1058
|
}
|
|
784
1059
|
return sourceText;
|
|
785
1060
|
}
|
|
786
|
-
function getShaderModuleSource(module2, stage) {
|
|
1061
|
+
function getShaderModuleSource(module2, stage, log2) {
|
|
787
1062
|
let moduleSource;
|
|
788
1063
|
switch (stage) {
|
|
789
1064
|
case "vertex":
|
|
@@ -801,6 +1076,7 @@ function getShaderModuleSource(module2, stage) {
|
|
|
801
1076
|
if (!module2.name) {
|
|
802
1077
|
throw new Error("Shader module must have a name");
|
|
803
1078
|
}
|
|
1079
|
+
validateShaderModuleUniformLayout(module2, stage, { log: log2 });
|
|
804
1080
|
const moduleName = module2.name.toUpperCase().replace(/[^0-9a-z]/gi, "_");
|
|
805
1081
|
let source4 = `// ----- MODULE ${module2.name} ---------------
|
|
806
1082
|
|
|
@@ -813,13 +1089,177 @@ function getShaderModuleSource(module2, stage) {
|
|
|
813
1089
|
`;
|
|
814
1090
|
return source4;
|
|
815
1091
|
}
|
|
1092
|
+
function getUsedBindingsByGroupFromApplicationWGSL(source4) {
|
|
1093
|
+
const usedBindingsByGroup = /* @__PURE__ */ new Map();
|
|
1094
|
+
for (const regex of WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1095
|
+
regex.lastIndex = 0;
|
|
1096
|
+
let match;
|
|
1097
|
+
while (match = regex.exec(source4)) {
|
|
1098
|
+
const isBindingFirst = regex === WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1099
|
+
const location = Number(match[isBindingFirst ? 1 : 2]);
|
|
1100
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
1101
|
+
const name = match[4];
|
|
1102
|
+
validateApplicationWGSLBinding(group, location, name);
|
|
1103
|
+
registerUsedBindingLocation(usedBindingsByGroup, group, location, `application binding "${name}"`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return usedBindingsByGroup;
|
|
1107
|
+
}
|
|
1108
|
+
function relocateWGSLModuleBindings(moduleSource, module2, context) {
|
|
1109
|
+
const bindingAssignments = [];
|
|
1110
|
+
const relocationState = {
|
|
1111
|
+
sawSupportedBindingDeclaration: false,
|
|
1112
|
+
nextHintedBindingLocation: typeof module2.firstBindingSlot === "number" ? module2.firstBindingSlot : null
|
|
1113
|
+
};
|
|
1114
|
+
let relocatedSource = relocateWGSLModuleBindingsWithRegex(moduleSource, MODULE_WGSL_BINDING_DECLARATION_REGEXES[0], { isBindingFirst: true, module: module2, context, bindingAssignments, relocationState });
|
|
1115
|
+
relocatedSource = relocateWGSLModuleBindingsWithRegex(relocatedSource, MODULE_WGSL_BINDING_DECLARATION_REGEXES[1], { isBindingFirst: false, module: module2, context, bindingAssignments, relocationState });
|
|
1116
|
+
if (moduleSource.includes("@binding(auto)") && !relocationState.sawSupportedBindingDeclaration) {
|
|
1117
|
+
throw new Error(`Unsupported @binding(auto) declaration form in module "${module2.name}". Use "@group(N) @binding(auto) var ..." or "@binding(auto) @group(N) var ..." on a single line.`);
|
|
1118
|
+
}
|
|
1119
|
+
return { source: relocatedSource, bindingAssignments };
|
|
1120
|
+
}
|
|
1121
|
+
function relocateWGSLModuleBindingsWithRegex(source4, regex, params) {
|
|
1122
|
+
return source4.replace(regex, (...replaceArguments) => relocateWGSLModuleBindingMatch(replaceArguments, params));
|
|
1123
|
+
}
|
|
1124
|
+
function relocateWGSLModuleBindingMatch(replaceArguments, params) {
|
|
1125
|
+
var _a, _b;
|
|
1126
|
+
const { isBindingFirst, module: module2, context, bindingAssignments, relocationState } = params;
|
|
1127
|
+
relocationState.sawSupportedBindingDeclaration = true;
|
|
1128
|
+
const match = replaceArguments[0];
|
|
1129
|
+
const bindingToken = replaceArguments[isBindingFirst ? 1 : 2];
|
|
1130
|
+
const groupToken = replaceArguments[isBindingFirst ? 2 : 1];
|
|
1131
|
+
const name = replaceArguments[4];
|
|
1132
|
+
const group = Number(groupToken);
|
|
1133
|
+
if (bindingToken === "auto") {
|
|
1134
|
+
const registryKey = getBindingRegistryKey(group, module2.name, name);
|
|
1135
|
+
const registryLocation = (_a = context.bindingRegistry) == null ? void 0 : _a.get(registryKey);
|
|
1136
|
+
const location2 = registryLocation !== void 0 ? registryLocation : relocationState.nextHintedBindingLocation === null ? allocateAutoBindingLocation(group, context.usedBindingsByGroup) : allocateAutoBindingLocation(group, context.usedBindingsByGroup, relocationState.nextHintedBindingLocation);
|
|
1137
|
+
validateModuleWGSLBinding(module2.name, group, location2, name);
|
|
1138
|
+
if (registryLocation !== void 0 && claimReservedBindingLocation(context.reservedBindingKeysByGroup, group, location2, registryKey)) {
|
|
1139
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location: location2 });
|
|
1140
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1141
|
+
}
|
|
1142
|
+
registerUsedBindingLocation(context.usedBindingsByGroup, group, location2, `module "${module2.name}" binding "${name}"`);
|
|
1143
|
+
(_b = context.bindingRegistry) == null ? void 0 : _b.set(registryKey, location2);
|
|
1144
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location: location2 });
|
|
1145
|
+
if (relocationState.nextHintedBindingLocation !== null && registryLocation === void 0) {
|
|
1146
|
+
relocationState.nextHintedBindingLocation = location2 + 1;
|
|
1147
|
+
}
|
|
1148
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1149
|
+
}
|
|
1150
|
+
const location = Number(bindingToken);
|
|
1151
|
+
validateModuleWGSLBinding(module2.name, group, location, name);
|
|
1152
|
+
registerUsedBindingLocation(context.usedBindingsByGroup, group, location, `module "${module2.name}" binding "${name}"`);
|
|
1153
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location });
|
|
1154
|
+
return match;
|
|
1155
|
+
}
|
|
1156
|
+
function reserveRegisteredModuleBindings(modules, bindingRegistry, usedBindingsByGroup) {
|
|
1157
|
+
const reservedBindingKeysByGroup = /* @__PURE__ */ new Map();
|
|
1158
|
+
if (!bindingRegistry) {
|
|
1159
|
+
return reservedBindingKeysByGroup;
|
|
1160
|
+
}
|
|
1161
|
+
for (const module2 of modules) {
|
|
1162
|
+
for (const binding of getModuleWGSLBindingDeclarations(module2)) {
|
|
1163
|
+
const registryKey = getBindingRegistryKey(binding.group, module2.name, binding.name);
|
|
1164
|
+
const location = bindingRegistry.get(registryKey);
|
|
1165
|
+
if (location !== void 0) {
|
|
1166
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(binding.group) || /* @__PURE__ */ new Map();
|
|
1167
|
+
const existingReservation = reservedBindingKeys.get(location);
|
|
1168
|
+
if (existingReservation && existingReservation !== registryKey) {
|
|
1169
|
+
throw new Error(`Duplicate WGSL binding reservation for modules "${existingReservation}" and "${registryKey}": group ${binding.group}, binding ${location}.`);
|
|
1170
|
+
}
|
|
1171
|
+
registerUsedBindingLocation(usedBindingsByGroup, binding.group, location, `registered module binding "${registryKey}"`);
|
|
1172
|
+
reservedBindingKeys.set(location, registryKey);
|
|
1173
|
+
reservedBindingKeysByGroup.set(binding.group, reservedBindingKeys);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return reservedBindingKeysByGroup;
|
|
1178
|
+
}
|
|
1179
|
+
function claimReservedBindingLocation(reservedBindingKeysByGroup, group, location, registryKey) {
|
|
1180
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(group);
|
|
1181
|
+
if (!reservedBindingKeys) {
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
const reservedKey = reservedBindingKeys.get(location);
|
|
1185
|
+
if (!reservedKey) {
|
|
1186
|
+
return false;
|
|
1187
|
+
}
|
|
1188
|
+
if (reservedKey !== registryKey) {
|
|
1189
|
+
throw new Error(`Registered module binding "${registryKey}" collided with "${reservedKey}": group ${group}, binding ${location}.`);
|
|
1190
|
+
}
|
|
1191
|
+
return true;
|
|
1192
|
+
}
|
|
1193
|
+
function getModuleWGSLBindingDeclarations(module2) {
|
|
1194
|
+
const declarations = [];
|
|
1195
|
+
const moduleSource = module2.source || "";
|
|
1196
|
+
for (const regex of MODULE_WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1197
|
+
regex.lastIndex = 0;
|
|
1198
|
+
let match;
|
|
1199
|
+
while (match = regex.exec(moduleSource)) {
|
|
1200
|
+
const isBindingFirst = regex === MODULE_WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1201
|
+
declarations.push({
|
|
1202
|
+
name: match[4],
|
|
1203
|
+
group: Number(match[isBindingFirst ? 2 : 1])
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
return declarations;
|
|
1208
|
+
}
|
|
1209
|
+
function validateApplicationWGSLBinding(group, location, name) {
|
|
1210
|
+
if (group === 0 && location >= RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1211
|
+
throw new Error(`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}.`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function validateModuleWGSLBinding(moduleName, group, location, name) {
|
|
1215
|
+
if (group === 0 && location < RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1216
|
+
throw new Error(`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.`);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function registerUsedBindingLocation(usedBindingsByGroup, group, location, label) {
|
|
1220
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1221
|
+
if (usedBindings.has(location)) {
|
|
1222
|
+
throw new Error(`Duplicate WGSL binding assignment for ${label}: group ${group}, binding ${location}.`);
|
|
1223
|
+
}
|
|
1224
|
+
usedBindings.add(location);
|
|
1225
|
+
usedBindingsByGroup.set(group, usedBindings);
|
|
1226
|
+
}
|
|
1227
|
+
function allocateAutoBindingLocation(group, usedBindingsByGroup, preferredBindingLocation) {
|
|
1228
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1229
|
+
let nextBinding = preferredBindingLocation ?? (group === 0 ? RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT : usedBindings.size > 0 ? Math.max(...usedBindings) + 1 : 0);
|
|
1230
|
+
while (usedBindings.has(nextBinding)) {
|
|
1231
|
+
nextBinding++;
|
|
1232
|
+
}
|
|
1233
|
+
return nextBinding;
|
|
1234
|
+
}
|
|
1235
|
+
function assertNoUnresolvedAutoBindings(source4) {
|
|
1236
|
+
if (/@binding\(\s*auto\s*\)/.test(source4)) {
|
|
1237
|
+
throw new Error("Unresolved @binding(auto) remained in assembled WGSL source.");
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
function formatWGSLBindingAssignmentComments(bindingAssignments) {
|
|
1241
|
+
if (bindingAssignments.length === 0) {
|
|
1242
|
+
return "";
|
|
1243
|
+
}
|
|
1244
|
+
let source4 = "// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------\n";
|
|
1245
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
1246
|
+
source4 += `// ${bindingAssignment.moduleName}.${bindingAssignment.name} -> @group(${bindingAssignment.group}) @binding(${bindingAssignment.location})
|
|
1247
|
+
`;
|
|
1248
|
+
}
|
|
1249
|
+
source4 += "\n";
|
|
1250
|
+
return source4;
|
|
1251
|
+
}
|
|
1252
|
+
function getBindingRegistryKey(group, moduleName, bindingName) {
|
|
1253
|
+
return `${group}:${moduleName}:${bindingName}`;
|
|
1254
|
+
}
|
|
816
1255
|
|
|
817
1256
|
// dist/lib/preprocessor/preprocessor.js
|
|
818
|
-
var
|
|
819
|
-
var
|
|
1257
|
+
var DEFINE_NAME_PATTERN = "([a-zA-Z_][a-zA-Z0-9_]*)";
|
|
1258
|
+
var IFDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*$`);
|
|
1259
|
+
var IFNDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifndef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`);
|
|
820
1260
|
var ELSE_REGEXP = /^\s*\#\s*else\s*(?:\/\/.*)?$/;
|
|
821
1261
|
var ENDIF_REGEXP = /^\s*\#\s*endif\s*$/;
|
|
822
|
-
var IFDEF_WITH_COMMENT_REGEXP =
|
|
1262
|
+
var IFDEF_WITH_COMMENT_REGEXP = new RegExp(`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`);
|
|
823
1263
|
var ENDIF_WITH_COMMENT_REGEXP = /^\s*\#\s*endif\s*(?:\/\/.*)?$/;
|
|
824
1264
|
function preprocess(source4, options) {
|
|
825
1265
|
var _a, _b;
|
|
@@ -866,6 +1306,8 @@ var _ShaderAssembler = class {
|
|
|
866
1306
|
_hookFunctions = [];
|
|
867
1307
|
/** Shader modules */
|
|
868
1308
|
_defaultModules = [];
|
|
1309
|
+
/** Stable per-run WGSL auto-binding assignments keyed by group/module/binding. */
|
|
1310
|
+
_wgslBindingRegistry = /* @__PURE__ */ new Map();
|
|
869
1311
|
/**
|
|
870
1312
|
* A default shader assembler instance - the natural place to register default modules and hooks
|
|
871
1313
|
* @returns
|
|
@@ -909,10 +1351,11 @@ var _ShaderAssembler = class {
|
|
|
909
1351
|
assembleWGSLShader(props) {
|
|
910
1352
|
const modules = this._getModuleList(props.modules);
|
|
911
1353
|
const hookFunctions = this._hookFunctions;
|
|
912
|
-
const { source: source4, getUniforms: getUniforms4 } = assembleWGSLShader({
|
|
1354
|
+
const { source: source4, getUniforms: getUniforms4, bindingAssignments } = assembleWGSLShader({
|
|
913
1355
|
...props,
|
|
914
1356
|
// @ts-expect-error
|
|
915
1357
|
source: props.source,
|
|
1358
|
+
_bindingRegistry: this._wgslBindingRegistry,
|
|
916
1359
|
modules,
|
|
917
1360
|
hookFunctions
|
|
918
1361
|
});
|
|
@@ -924,7 +1367,13 @@ var _ShaderAssembler = class {
|
|
|
924
1367
|
...props.defines
|
|
925
1368
|
};
|
|
926
1369
|
const preprocessedSource = props.platformInfo.shaderLanguage === "wgsl" ? preprocess(source4, { defines }) : source4;
|
|
927
|
-
return {
|
|
1370
|
+
return {
|
|
1371
|
+
source: preprocessedSource,
|
|
1372
|
+
getUniforms: getUniforms4,
|
|
1373
|
+
modules,
|
|
1374
|
+
bindingAssignments,
|
|
1375
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(preprocessedSource, bindingAssignments)
|
|
1376
|
+
};
|
|
928
1377
|
}
|
|
929
1378
|
/**
|
|
930
1379
|
* Assemble a pair of shaders into a single shader program
|
|
@@ -1089,6 +1538,9 @@ function generateGLSLUniformDeclarations(module2, options) {
|
|
|
1089
1538
|
case "uniforms":
|
|
1090
1539
|
}
|
|
1091
1540
|
for (const [uniformName, uniformFormat] of Object.entries(module2.uniformTypes || {})) {
|
|
1541
|
+
if (typeof uniformFormat !== "string") {
|
|
1542
|
+
throw new Error(`Composite uniform types are not supported by GLSL shader generation: ${module2.name}.${uniformName}`);
|
|
1543
|
+
}
|
|
1092
1544
|
const glslUniformType = getGLSLUniformType(uniformFormat);
|
|
1093
1545
|
switch (options.uniforms) {
|
|
1094
1546
|
case "scoped-interface-blocks":
|
|
@@ -1149,6 +1601,9 @@ function generateWGSLUniformDeclarations(module2, options) {
|
|
|
1149
1601
|
const wgsl = [];
|
|
1150
1602
|
wgsl.push(`struct ${capitalize(module2.name)} {`);
|
|
1151
1603
|
for (const [uniformName, uniformFormat] of Object.entries((module2 == null ? void 0 : module2.uniformTypes) || {})) {
|
|
1604
|
+
if (typeof uniformFormat !== "string") {
|
|
1605
|
+
throw new Error(`Composite uniform types are not supported by WGSL shader generation: ${module2.name}.${uniformName}`);
|
|
1606
|
+
}
|
|
1152
1607
|
const wgslUniformType = uniformFormat;
|
|
1153
1608
|
wgsl.push(` ${uniformName} : ${wgslUniformType};`);
|
|
1154
1609
|
}
|
|
@@ -1463,6 +1918,7 @@ var fp64arithmeticShader = (
|
|
|
1463
1918
|
`
|
|
1464
1919
|
uniform fp64arithmeticUniforms {
|
|
1465
1920
|
uniform float ONE;
|
|
1921
|
+
uniform float SPLIT;
|
|
1466
1922
|
} fp64;
|
|
1467
1923
|
|
|
1468
1924
|
/*
|
|
@@ -1472,6 +1928,12 @@ The purpose of this workaround is to prevent shader compilers from
|
|
|
1472
1928
|
optimizing away necessary arithmetic operations by swapping their sequences
|
|
1473
1929
|
or transform the equation to some 'equivalent' form.
|
|
1474
1930
|
|
|
1931
|
+
These helpers implement Dekker/Veltkamp-style error tracking. If the compiler
|
|
1932
|
+
folds constants or reassociates the arithmetic, the high/low split can stop
|
|
1933
|
+
tracking the rounding error correctly. That failure mode tends to look fine in
|
|
1934
|
+
simple coordinate setup, but then breaks down inside iterative arithmetic such
|
|
1935
|
+
as fp64 Mandelbrot loops.
|
|
1936
|
+
|
|
1475
1937
|
The method is to multiply an artifical variable, ONE, which will be known to
|
|
1476
1938
|
the compiler to be 1 only at runtime. The whole expression is then represented
|
|
1477
1939
|
as a polynomial with respective to ONE. In the coefficients of all terms, only one a
|
|
@@ -1480,17 +1942,23 @@ and one b should appear
|
|
|
1480
1942
|
err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE
|
|
1481
1943
|
*/
|
|
1482
1944
|
|
|
1483
|
-
|
|
1484
|
-
vec2 split(float a) {
|
|
1485
|
-
const float SPLIT = 4097.0;
|
|
1486
|
-
float t = a * SPLIT;
|
|
1945
|
+
float prevent_fp64_optimization(float value) {
|
|
1487
1946
|
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
1488
|
-
|
|
1489
|
-
float a_lo = a * fp64.ONE - a_hi;
|
|
1947
|
+
return value + fp64.ONE * 0.0;
|
|
1490
1948
|
#else
|
|
1491
|
-
|
|
1492
|
-
float a_lo = a - a_hi;
|
|
1949
|
+
return value;
|
|
1493
1950
|
#endif
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// Divide float number to high and low floats to extend fraction bits
|
|
1954
|
+
vec2 split(float a) {
|
|
1955
|
+
// Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker
|
|
1956
|
+
// split into a constant expression and reassociate the recovery steps.
|
|
1957
|
+
float split = prevent_fp64_optimization(fp64.SPLIT);
|
|
1958
|
+
float t = prevent_fp64_optimization(a * split);
|
|
1959
|
+
float temp = t - a;
|
|
1960
|
+
float a_hi = t - temp;
|
|
1961
|
+
float a_lo = a - a_hi;
|
|
1494
1962
|
return vec2(a_hi, a_lo);
|
|
1495
1963
|
}
|
|
1496
1964
|
|
|
@@ -1554,8 +2022,26 @@ vec2 twoProd(float a, float b) {
|
|
|
1554
2022
|
float prod = a * b;
|
|
1555
2023
|
vec2 a_fp64 = split(a);
|
|
1556
2024
|
vec2 b_fp64 = split(b);
|
|
1557
|
-
|
|
1558
|
-
|
|
2025
|
+
// twoProd is especially sensitive because mul_fp64 and div_fp64 both depend
|
|
2026
|
+
// on the split terms and cross terms staying in the original evaluation
|
|
2027
|
+
// order. If the compiler folds or reassociates them, the low part tends to
|
|
2028
|
+
// collapse to zero or NaN on some drivers.
|
|
2029
|
+
float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);
|
|
2030
|
+
float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);
|
|
2031
|
+
float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);
|
|
2032
|
+
float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);
|
|
2033
|
+
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
2034
|
+
float err1 = (highProduct - prod) * fp64.ONE;
|
|
2035
|
+
float err2 = crossProduct1 * fp64.ONE * fp64.ONE;
|
|
2036
|
+
float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
2037
|
+
float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
2038
|
+
#else
|
|
2039
|
+
float err1 = highProduct - prod;
|
|
2040
|
+
float err2 = crossProduct1;
|
|
2041
|
+
float err3 = crossProduct2;
|
|
2042
|
+
float err4 = lowProduct;
|
|
2043
|
+
#endif
|
|
2044
|
+
float err = ((err1 + err2) + err3) + err4;
|
|
1559
2045
|
return vec2(prod, err);
|
|
1560
2046
|
}
|
|
1561
2047
|
|
|
@@ -1631,6 +2117,218 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
1631
2117
|
`
|
|
1632
2118
|
);
|
|
1633
2119
|
|
|
2120
|
+
// dist/modules/math/fp64/fp64-arithmetic-wgsl.js
|
|
2121
|
+
var fp64arithmeticWGSL = (
|
|
2122
|
+
/* wgsl */
|
|
2123
|
+
`struct Fp64ArithmeticUniforms {
|
|
2124
|
+
ONE: f32,
|
|
2125
|
+
SPLIT: f32,
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
|
|
2129
|
+
|
|
2130
|
+
fn fp64_nan(seed: f32) -> f32 {
|
|
2131
|
+
let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
|
|
2132
|
+
return bitcast<f32>(nanBits);
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
fn fp64_runtime_zero() -> f32 {
|
|
2136
|
+
return fp64arithmetic.ONE * 0.0;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
fn prevent_fp64_optimization(value: f32) -> f32 {
|
|
2140
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2141
|
+
return value + fp64_runtime_zero();
|
|
2142
|
+
#else
|
|
2143
|
+
return value;
|
|
2144
|
+
#endif
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
fn split(a: f32) -> vec2f {
|
|
2148
|
+
let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
|
|
2149
|
+
let t = prevent_fp64_optimization(a * splitValue);
|
|
2150
|
+
let temp = prevent_fp64_optimization(t - a);
|
|
2151
|
+
let aHi = prevent_fp64_optimization(t - temp);
|
|
2152
|
+
let aLo = prevent_fp64_optimization(a - aHi);
|
|
2153
|
+
return vec2f(aHi, aLo);
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
fn split2(a: vec2f) -> vec2f {
|
|
2157
|
+
var b = split(a.x);
|
|
2158
|
+
b.y = b.y + a.y;
|
|
2159
|
+
return b;
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
fn quickTwoSum(a: f32, b: f32) -> vec2f {
|
|
2163
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2164
|
+
let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);
|
|
2165
|
+
let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);
|
|
2166
|
+
#else
|
|
2167
|
+
let sum = prevent_fp64_optimization(a + b);
|
|
2168
|
+
let err = prevent_fp64_optimization(b - (sum - a));
|
|
2169
|
+
#endif
|
|
2170
|
+
return vec2f(sum, err);
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
fn twoSum(a: f32, b: f32) -> vec2f {
|
|
2174
|
+
let s = prevent_fp64_optimization(a + b);
|
|
2175
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2176
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
2177
|
+
let err =
|
|
2178
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
2179
|
+
fp64arithmetic.ONE *
|
|
2180
|
+
fp64arithmetic.ONE *
|
|
2181
|
+
fp64arithmetic.ONE) +
|
|
2182
|
+
prevent_fp64_optimization(b - v);
|
|
2183
|
+
#else
|
|
2184
|
+
let v = prevent_fp64_optimization(s - a);
|
|
2185
|
+
let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);
|
|
2186
|
+
#endif
|
|
2187
|
+
return vec2f(s, err);
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
fn twoSub(a: f32, b: f32) -> vec2f {
|
|
2191
|
+
let s = prevent_fp64_optimization(a - b);
|
|
2192
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2193
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
2194
|
+
let err =
|
|
2195
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
2196
|
+
fp64arithmetic.ONE *
|
|
2197
|
+
fp64arithmetic.ONE *
|
|
2198
|
+
fp64arithmetic.ONE) -
|
|
2199
|
+
prevent_fp64_optimization(b + v);
|
|
2200
|
+
#else
|
|
2201
|
+
let v = prevent_fp64_optimization(s - a);
|
|
2202
|
+
let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);
|
|
2203
|
+
#endif
|
|
2204
|
+
return vec2f(s, err);
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
fn twoSqr(a: f32) -> vec2f {
|
|
2208
|
+
let prod = prevent_fp64_optimization(a * a);
|
|
2209
|
+
let aFp64 = split(a);
|
|
2210
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);
|
|
2211
|
+
let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);
|
|
2212
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);
|
|
2213
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2214
|
+
let err =
|
|
2215
|
+
(prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +
|
|
2216
|
+
crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +
|
|
2217
|
+
lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2218
|
+
#else
|
|
2219
|
+
let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);
|
|
2220
|
+
#endif
|
|
2221
|
+
return vec2f(prod, err);
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
fn twoProd(a: f32, b: f32) -> vec2f {
|
|
2225
|
+
let prod = prevent_fp64_optimization(a * b);
|
|
2226
|
+
let aFp64 = split(a);
|
|
2227
|
+
let bFp64 = split(b);
|
|
2228
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);
|
|
2229
|
+
let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);
|
|
2230
|
+
let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);
|
|
2231
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);
|
|
2232
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2233
|
+
let err1 = (highProduct - prod) * fp64arithmetic.ONE;
|
|
2234
|
+
let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2235
|
+
let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2236
|
+
let err4 =
|
|
2237
|
+
lowProduct *
|
|
2238
|
+
fp64arithmetic.ONE *
|
|
2239
|
+
fp64arithmetic.ONE *
|
|
2240
|
+
fp64arithmetic.ONE *
|
|
2241
|
+
fp64arithmetic.ONE;
|
|
2242
|
+
#else
|
|
2243
|
+
let err1 = highProduct - prod;
|
|
2244
|
+
let err2 = crossProduct1;
|
|
2245
|
+
let err3 = crossProduct2;
|
|
2246
|
+
let err4 = lowProduct;
|
|
2247
|
+
#endif
|
|
2248
|
+
let err12InputA = prevent_fp64_optimization(err1);
|
|
2249
|
+
let err12InputB = prevent_fp64_optimization(err2);
|
|
2250
|
+
let err12 = prevent_fp64_optimization(err12InputA + err12InputB);
|
|
2251
|
+
let err123InputA = prevent_fp64_optimization(err12);
|
|
2252
|
+
let err123InputB = prevent_fp64_optimization(err3);
|
|
2253
|
+
let err123 = prevent_fp64_optimization(err123InputA + err123InputB);
|
|
2254
|
+
let err1234InputA = prevent_fp64_optimization(err123);
|
|
2255
|
+
let err1234InputB = prevent_fp64_optimization(err4);
|
|
2256
|
+
let err = prevent_fp64_optimization(err1234InputA + err1234InputB);
|
|
2257
|
+
return vec2f(prod, err);
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2261
|
+
var s = twoSum(a.x, b.x);
|
|
2262
|
+
let t = twoSum(a.y, b.y);
|
|
2263
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
2264
|
+
s = quickTwoSum(s.x, s.y);
|
|
2265
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
2266
|
+
s = quickTwoSum(s.x, s.y);
|
|
2267
|
+
return s;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2271
|
+
var s = twoSub(a.x, b.x);
|
|
2272
|
+
let t = twoSub(a.y, b.y);
|
|
2273
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
2274
|
+
s = quickTwoSum(s.x, s.y);
|
|
2275
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
2276
|
+
s = quickTwoSum(s.x, s.y);
|
|
2277
|
+
return s;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2281
|
+
var prod = twoProd(a.x, b.x);
|
|
2282
|
+
let crossProduct1 = prevent_fp64_optimization(a.x * b.y);
|
|
2283
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct1);
|
|
2284
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2285
|
+
prod = split2(prod);
|
|
2286
|
+
#endif
|
|
2287
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
2288
|
+
let crossProduct2 = prevent_fp64_optimization(a.y * b.x);
|
|
2289
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct2);
|
|
2290
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2291
|
+
prod = split2(prod);
|
|
2292
|
+
#endif
|
|
2293
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
2294
|
+
return prod;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2298
|
+
let xn = prevent_fp64_optimization(1.0 / b.x);
|
|
2299
|
+
let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
|
|
2300
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);
|
|
2301
|
+
let prod = twoProd(xn, diff);
|
|
2302
|
+
return sum_fp64(yn, prod);
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
2306
|
+
if (a.x == 0.0 && a.y == 0.0) {
|
|
2307
|
+
return vec2f(0.0, 0.0);
|
|
2308
|
+
}
|
|
2309
|
+
if (a.x < 0.0) {
|
|
2310
|
+
let nanValue = fp64_nan(a.x);
|
|
2311
|
+
return vec2f(nanValue, nanValue);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
let x = prevent_fp64_optimization(1.0 / sqrt(a.x));
|
|
2315
|
+
let yn = prevent_fp64_optimization(a.x * x);
|
|
2316
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2317
|
+
let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;
|
|
2318
|
+
#else
|
|
2319
|
+
let ynSqr = twoSqr(yn);
|
|
2320
|
+
#endif
|
|
2321
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);
|
|
2322
|
+
let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);
|
|
2323
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2324
|
+
return sum_fp64(split(yn), prod);
|
|
2325
|
+
#else
|
|
2326
|
+
return sum_fp64(vec2f(yn, 0.0), prod);
|
|
2327
|
+
#endif
|
|
2328
|
+
}
|
|
2329
|
+
`
|
|
2330
|
+
);
|
|
2331
|
+
|
|
1634
2332
|
// dist/modules/math/fp64/fp64-functions-glsl.js
|
|
1635
2333
|
var fp64functionShader = (
|
|
1636
2334
|
/* glsl */
|
|
@@ -2309,13 +3007,18 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
|
|
|
2309
3007
|
// dist/modules/math/fp64/fp64.js
|
|
2310
3008
|
var defaultUniforms = {
|
|
2311
3009
|
// Used in LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2312
|
-
ONE: 1
|
|
3010
|
+
ONE: 1,
|
|
3011
|
+
// Runtime split factor for Dekker splitting. Keeping this as a uniform helps
|
|
3012
|
+
// prevent aggressive constant folding in shader compilers.
|
|
3013
|
+
SPLIT: 4097
|
|
2313
3014
|
};
|
|
2314
3015
|
var fp64arithmetic = {
|
|
2315
3016
|
name: "fp64arithmetic",
|
|
3017
|
+
source: fp64arithmeticWGSL,
|
|
3018
|
+
fs: fp64arithmeticShader,
|
|
2316
3019
|
vs: fp64arithmeticShader,
|
|
2317
3020
|
defaultUniforms,
|
|
2318
|
-
uniformTypes: { ONE: "f32" },
|
|
3021
|
+
uniformTypes: { ONE: "f32", SPLIT: "f32" },
|
|
2319
3022
|
// Additional Functions
|
|
2320
3023
|
fp64ify,
|
|
2321
3024
|
fp64LowPart,
|
|
@@ -2529,7 +3232,7 @@ struct skinUniforms {
|
|
|
2529
3232
|
jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
|
|
2530
3233
|
};
|
|
2531
3234
|
|
|
2532
|
-
@
|
|
3235
|
+
@group(0) @binding(auto) var<uniform> skin: skinUniforms;
|
|
2533
3236
|
|
|
2534
3237
|
fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
2535
3238
|
return (weights.x * skin.jointMatrix[joints.x])
|
|
@@ -2563,6 +3266,7 @@ var skin = {
|
|
|
2563
3266
|
props: {},
|
|
2564
3267
|
uniforms: {},
|
|
2565
3268
|
name: "skin",
|
|
3269
|
+
bindingLayout: [{ name: "skin", group: 0 }],
|
|
2566
3270
|
dependencies: [],
|
|
2567
3271
|
source: source2,
|
|
2568
3272
|
vs: vs2,
|
|
@@ -2606,10 +3310,7 @@ var skin = {
|
|
|
2606
3310
|
};
|
|
2607
3311
|
},
|
|
2608
3312
|
uniformTypes: {
|
|
2609
|
-
jointMatrix: "mat4x4<f32>"
|
|
2610
|
-
},
|
|
2611
|
-
uniformSizes: {
|
|
2612
|
-
jointMatrix: SKIN_MAX_JOINTS
|
|
3313
|
+
jointMatrix: ["mat4x4<f32>", SKIN_MAX_JOINTS]
|
|
2613
3314
|
}
|
|
2614
3315
|
};
|
|
2615
3316
|
|
|
@@ -2632,77 +3333,51 @@ struct PointLight {
|
|
|
2632
3333
|
vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
|
|
2633
3334
|
};
|
|
2634
3335
|
|
|
3336
|
+
struct SpotLight {
|
|
3337
|
+
vec3 color;
|
|
3338
|
+
vec3 position;
|
|
3339
|
+
vec3 direction;
|
|
3340
|
+
vec3 attenuation;
|
|
3341
|
+
vec2 coneCos;
|
|
3342
|
+
};
|
|
3343
|
+
|
|
2635
3344
|
struct DirectionalLight {
|
|
2636
3345
|
vec3 color;
|
|
2637
3346
|
vec3 direction;
|
|
2638
3347
|
};
|
|
2639
3348
|
|
|
3349
|
+
struct UniformLight {
|
|
3350
|
+
vec3 color;
|
|
3351
|
+
vec3 position;
|
|
3352
|
+
vec3 direction;
|
|
3353
|
+
vec3 attenuation;
|
|
3354
|
+
vec2 coneCos;
|
|
3355
|
+
};
|
|
3356
|
+
|
|
2640
3357
|
uniform lightingUniforms {
|
|
2641
3358
|
int enabled;
|
|
2642
|
-
int lightType;
|
|
2643
|
-
|
|
2644
3359
|
int directionalLightCount;
|
|
2645
3360
|
int pointLightCount;
|
|
2646
|
-
|
|
3361
|
+
int spotLightCount;
|
|
2647
3362
|
vec3 ambientColor;
|
|
2648
|
-
|
|
2649
|
-
vec3 lightColor0;
|
|
2650
|
-
vec3 lightPosition0;
|
|
2651
|
-
vec3 lightDirection0;
|
|
2652
|
-
vec3 lightAttenuation0;
|
|
2653
|
-
|
|
2654
|
-
vec3 lightColor1;
|
|
2655
|
-
vec3 lightPosition1;
|
|
2656
|
-
vec3 lightDirection1;
|
|
2657
|
-
vec3 lightAttenuation1;
|
|
2658
|
-
|
|
2659
|
-
vec3 lightColor2;
|
|
2660
|
-
vec3 lightPosition2;
|
|
2661
|
-
vec3 lightDirection2;
|
|
2662
|
-
vec3 lightAttenuation2;
|
|
2663
|
-
|
|
2664
|
-
vec3 lightColor3;
|
|
2665
|
-
vec3 lightPosition3;
|
|
2666
|
-
vec3 lightDirection3;
|
|
2667
|
-
vec3 lightAttenuation3;
|
|
2668
|
-
|
|
2669
|
-
vec3 lightColor4;
|
|
2670
|
-
vec3 lightPosition4;
|
|
2671
|
-
vec3 lightDirection4;
|
|
2672
|
-
vec3 lightAttenuation4;
|
|
3363
|
+
UniformLight lights[5];
|
|
2673
3364
|
} lighting;
|
|
2674
3365
|
|
|
2675
3366
|
PointLight lighting_getPointLight(int index) {
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
case 3:
|
|
2684
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
2685
|
-
case 4:
|
|
2686
|
-
default:
|
|
2687
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
2688
|
-
}
|
|
3367
|
+
UniformLight light = lighting.lights[index];
|
|
3368
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
SpotLight lighting_getSpotLight(int index) {
|
|
3372
|
+
UniformLight light = lighting.lights[lighting.pointLightCount + index];
|
|
3373
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
2689
3374
|
}
|
|
2690
3375
|
|
|
2691
3376
|
DirectionalLight lighting_getDirectionalLight(int index) {
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
2697
|
-
case 2:
|
|
2698
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
2699
|
-
case 3:
|
|
2700
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
2701
|
-
case 4:
|
|
2702
|
-
default:
|
|
2703
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
2704
|
-
}
|
|
2705
|
-
}
|
|
3377
|
+
UniformLight light =
|
|
3378
|
+
lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
3379
|
+
return DirectionalLight(light.color, light.direction);
|
|
3380
|
+
}
|
|
2706
3381
|
|
|
2707
3382
|
float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
2708
3383
|
return pointLight.attenuation.x
|
|
@@ -2710,6 +3385,20 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
|
2710
3385
|
+ pointLight.attenuation.z * distance * distance;
|
|
2711
3386
|
}
|
|
2712
3387
|
|
|
3388
|
+
float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {
|
|
3389
|
+
vec3 light_direction = normalize(positionWorldspace - spotLight.position);
|
|
3390
|
+
float coneFactor = smoothstep(
|
|
3391
|
+
spotLight.coneCos.y,
|
|
3392
|
+
spotLight.coneCos.x,
|
|
3393
|
+
dot(normalize(spotLight.direction), light_direction)
|
|
3394
|
+
);
|
|
3395
|
+
float distanceAttenuation = getPointLightAttenuation(
|
|
3396
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
3397
|
+
distance(spotLight.position, positionWorldspace)
|
|
3398
|
+
);
|
|
3399
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
3400
|
+
}
|
|
3401
|
+
|
|
2713
3402
|
// #endif
|
|
2714
3403
|
`
|
|
2715
3404
|
);
|
|
@@ -2730,105 +3419,85 @@ struct PointLight {
|
|
|
2730
3419
|
attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
|
|
2731
3420
|
};
|
|
2732
3421
|
|
|
3422
|
+
struct SpotLight {
|
|
3423
|
+
color: vec3<f32>,
|
|
3424
|
+
position: vec3<f32>,
|
|
3425
|
+
direction: vec3<f32>,
|
|
3426
|
+
attenuation: vec3<f32>,
|
|
3427
|
+
coneCos: vec2<f32>,
|
|
3428
|
+
};
|
|
3429
|
+
|
|
2733
3430
|
struct DirectionalLight {
|
|
2734
3431
|
color: vec3<f32>,
|
|
2735
3432
|
direction: vec3<f32>,
|
|
2736
3433
|
};
|
|
2737
3434
|
|
|
3435
|
+
struct UniformLight {
|
|
3436
|
+
color: vec3<f32>,
|
|
3437
|
+
position: vec3<f32>,
|
|
3438
|
+
direction: vec3<f32>,
|
|
3439
|
+
attenuation: vec3<f32>,
|
|
3440
|
+
coneCos: vec2<f32>,
|
|
3441
|
+
};
|
|
3442
|
+
|
|
2738
3443
|
struct lightingUniforms {
|
|
2739
3444
|
enabled: i32,
|
|
2740
|
-
lightType: i32,
|
|
2741
|
-
|
|
2742
3445
|
directionalLightCount: i32,
|
|
2743
3446
|
pointLightCount: i32,
|
|
2744
|
-
|
|
3447
|
+
spotLightCount: i32,
|
|
2745
3448
|
ambientColor: vec3<f32>,
|
|
2746
|
-
|
|
2747
|
-
lightColor0: vec3<f32>,
|
|
2748
|
-
lightPosition0: vec3<f32>,
|
|
2749
|
-
lightDirection0: vec3<f32>,
|
|
2750
|
-
lightAttenuation0: vec3<f32>,
|
|
2751
|
-
|
|
2752
|
-
lightColor1: vec3<f32>,
|
|
2753
|
-
lightPosition1: vec3<f32>,
|
|
2754
|
-
lightDirection1: vec3<f32>,
|
|
2755
|
-
lightAttenuation1: vec3<f32>,
|
|
2756
|
-
|
|
2757
|
-
lightColor2: vec3<f32>,
|
|
2758
|
-
lightPosition2: vec3<f32>,
|
|
2759
|
-
lightDirection2: vec3<f32>,
|
|
2760
|
-
lightAttenuation2: vec3<f32>,
|
|
2761
|
-
|
|
2762
|
-
lightColor3: vec3<f32>,
|
|
2763
|
-
lightPosition3: vec3<f32>,
|
|
2764
|
-
lightDirection3: vec3<f32>,
|
|
2765
|
-
lightAttenuation3: vec3<f32>,
|
|
2766
|
-
|
|
2767
|
-
lightColor4: vec3<f32>,
|
|
2768
|
-
lightPosition4: vec3<f32>,
|
|
2769
|
-
lightDirection4: vec3<f32>,
|
|
2770
|
-
lightAttenuation4: vec3<f32>,
|
|
3449
|
+
lights: array<UniformLight, 5>,
|
|
2771
3450
|
};
|
|
2772
3451
|
|
|
2773
|
-
|
|
2774
|
-
@binding(1) @group(0) var<uniform> lighting : lightingUniforms;
|
|
3452
|
+
@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
|
|
2775
3453
|
|
|
2776
3454
|
fn lighting_getPointLight(index: i32) -> PointLight {
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
case 2: {
|
|
2785
|
-
return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
|
|
2786
|
-
}
|
|
2787
|
-
case 3: {
|
|
2788
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
2789
|
-
}
|
|
2790
|
-
case 4, default: {
|
|
2791
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
3455
|
+
let light = lighting.lights[index];
|
|
3456
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
fn lighting_getSpotLight(index: i32) -> SpotLight {
|
|
3460
|
+
let light = lighting.lights[lighting.pointLightCount + index];
|
|
3461
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
2794
3462
|
}
|
|
2795
3463
|
|
|
2796
3464
|
fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
}
|
|
2801
|
-
case 1: {
|
|
2802
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
2803
|
-
}
|
|
2804
|
-
case 2: {
|
|
2805
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
2806
|
-
}
|
|
2807
|
-
case 3: {
|
|
2808
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
2809
|
-
}
|
|
2810
|
-
case 4, default: {
|
|
2811
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
2812
|
-
}
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
3465
|
+
let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
3466
|
+
return DirectionalLight(light.color, light.direction);
|
|
3467
|
+
}
|
|
2815
3468
|
|
|
2816
3469
|
fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
2817
3470
|
return pointLight.attenuation.x
|
|
2818
3471
|
+ pointLight.attenuation.y * distance
|
|
2819
3472
|
+ pointLight.attenuation.z * distance * distance;
|
|
2820
3473
|
}
|
|
3474
|
+
|
|
3475
|
+
fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
|
|
3476
|
+
let lightDirection = normalize(positionWorldspace - spotLight.position);
|
|
3477
|
+
let coneFactor = smoothstep(
|
|
3478
|
+
spotLight.coneCos.y,
|
|
3479
|
+
spotLight.coneCos.x,
|
|
3480
|
+
dot(normalize(spotLight.direction), lightDirection)
|
|
3481
|
+
);
|
|
3482
|
+
let distanceAttenuation = getPointLightAttenuation(
|
|
3483
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
3484
|
+
distance(spotLight.position, positionWorldspace)
|
|
3485
|
+
);
|
|
3486
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
3487
|
+
}
|
|
2821
3488
|
`
|
|
2822
3489
|
);
|
|
2823
3490
|
|
|
2824
3491
|
// dist/modules/lighting/lights/lighting.js
|
|
2825
3492
|
var MAX_LIGHTS = 5;
|
|
2826
3493
|
var COLOR_FACTOR = 255;
|
|
2827
|
-
var
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
3494
|
+
var LIGHT_UNIFORM_TYPE = {
|
|
3495
|
+
color: "vec3<f32>",
|
|
3496
|
+
position: "vec3<f32>",
|
|
3497
|
+
direction: "vec3<f32>",
|
|
3498
|
+
attenuation: "vec3<f32>",
|
|
3499
|
+
coneCos: "vec2<f32>"
|
|
3500
|
+
};
|
|
2832
3501
|
var lighting = {
|
|
2833
3502
|
props: {},
|
|
2834
3503
|
uniforms: {},
|
|
@@ -2838,128 +3507,105 @@ var lighting = {
|
|
|
2838
3507
|
},
|
|
2839
3508
|
uniformTypes: {
|
|
2840
3509
|
enabled: "i32",
|
|
2841
|
-
lightType: "i32",
|
|
2842
3510
|
directionalLightCount: "i32",
|
|
2843
3511
|
pointLightCount: "i32",
|
|
3512
|
+
spotLightCount: "i32",
|
|
2844
3513
|
ambientColor: "vec3<f32>",
|
|
2845
|
-
|
|
2846
|
-
lightColor0: "vec3<f32>",
|
|
2847
|
-
lightPosition0: "vec3<f32>",
|
|
2848
|
-
// TODO - could combine direction and attenuation
|
|
2849
|
-
lightDirection0: "vec3<f32>",
|
|
2850
|
-
lightAttenuation0: "vec3<f32>",
|
|
2851
|
-
lightColor1: "vec3<f32>",
|
|
2852
|
-
lightPosition1: "vec3<f32>",
|
|
2853
|
-
lightDirection1: "vec3<f32>",
|
|
2854
|
-
lightAttenuation1: "vec3<f32>",
|
|
2855
|
-
lightColor2: "vec3<f32>",
|
|
2856
|
-
lightPosition2: "vec3<f32>",
|
|
2857
|
-
lightDirection2: "vec3<f32>",
|
|
2858
|
-
lightAttenuation2: "vec3<f32>",
|
|
2859
|
-
lightColor3: "vec3<f32>",
|
|
2860
|
-
lightPosition3: "vec3<f32>",
|
|
2861
|
-
lightDirection3: "vec3<f32>",
|
|
2862
|
-
lightAttenuation3: "vec3<f32>",
|
|
2863
|
-
lightColor4: "vec3<f32>",
|
|
2864
|
-
lightPosition4: "vec3<f32>",
|
|
2865
|
-
lightDirection4: "vec3<f32>",
|
|
2866
|
-
lightAttenuation4: "vec3<f32>"
|
|
2867
|
-
},
|
|
2868
|
-
defaultUniforms: {
|
|
2869
|
-
enabled: 1,
|
|
2870
|
-
lightType: LIGHT_TYPE.POINT,
|
|
2871
|
-
directionalLightCount: 0,
|
|
2872
|
-
pointLightCount: 0,
|
|
2873
|
-
ambientColor: [0.1, 0.1, 0.1],
|
|
2874
|
-
lightColor0: [1, 1, 1],
|
|
2875
|
-
lightPosition0: [1, 1, 2],
|
|
2876
|
-
// TODO - could combine direction and attenuation
|
|
2877
|
-
lightDirection0: [1, 1, 1],
|
|
2878
|
-
lightAttenuation0: [1, 0, 0],
|
|
2879
|
-
lightColor1: [1, 1, 1],
|
|
2880
|
-
lightPosition1: [1, 1, 2],
|
|
2881
|
-
lightDirection1: [1, 1, 1],
|
|
2882
|
-
lightAttenuation1: [1, 0, 0],
|
|
2883
|
-
lightColor2: [1, 1, 1],
|
|
2884
|
-
lightPosition2: [1, 1, 2],
|
|
2885
|
-
lightDirection2: [1, 1, 1],
|
|
2886
|
-
lightAttenuation2: [1, 0, 0],
|
|
2887
|
-
lightColor3: [1, 1, 1],
|
|
2888
|
-
lightPosition3: [1, 1, 2],
|
|
2889
|
-
lightDirection3: [1, 1, 1],
|
|
2890
|
-
lightAttenuation3: [1, 0, 0],
|
|
2891
|
-
lightColor4: [1, 1, 1],
|
|
2892
|
-
lightPosition4: [1, 1, 2],
|
|
2893
|
-
lightDirection4: [1, 1, 1],
|
|
2894
|
-
lightAttenuation4: [1, 0, 0]
|
|
3514
|
+
lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]
|
|
2895
3515
|
},
|
|
3516
|
+
defaultUniforms: createDefaultLightingUniforms(),
|
|
3517
|
+
bindingLayout: [{ name: "lighting", group: 2 }],
|
|
3518
|
+
firstBindingSlot: 0,
|
|
2896
3519
|
source: lightingUniformsWGSL,
|
|
2897
3520
|
vs: lightingUniformsGLSL,
|
|
2898
3521
|
fs: lightingUniformsGLSL,
|
|
2899
3522
|
getUniforms: getUniforms2
|
|
2900
3523
|
};
|
|
2901
|
-
function getUniforms2(props,
|
|
3524
|
+
function getUniforms2(props, _prevUniforms = {}) {
|
|
2902
3525
|
props = props ? { ...props } : props;
|
|
2903
3526
|
if (!props) {
|
|
2904
|
-
return
|
|
3527
|
+
return createDefaultLightingUniforms();
|
|
2905
3528
|
}
|
|
2906
3529
|
if (props.lights) {
|
|
2907
3530
|
props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
|
|
2908
3531
|
}
|
|
2909
|
-
const { ambientLight, pointLights, directionalLights } = props || {};
|
|
2910
|
-
const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
3532
|
+
const { ambientLight, pointLights, spotLights, directionalLights } = props || {};
|
|
3533
|
+
const hasLights = ambientLight || pointLights && pointLights.length > 0 || spotLights && spotLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
2911
3534
|
if (!hasLights) {
|
|
2912
|
-
return {
|
|
3535
|
+
return {
|
|
3536
|
+
...createDefaultLightingUniforms(),
|
|
3537
|
+
enabled: 0
|
|
3538
|
+
};
|
|
2913
3539
|
}
|
|
2914
3540
|
const uniforms = {
|
|
2915
|
-
...
|
|
2916
|
-
...
|
|
2917
|
-
...getLightSourceUniforms({ ambientLight, pointLights, directionalLights })
|
|
3541
|
+
...createDefaultLightingUniforms(),
|
|
3542
|
+
...getLightSourceUniforms({ ambientLight, pointLights, spotLights, directionalLights })
|
|
2918
3543
|
};
|
|
2919
3544
|
if (props.enabled !== void 0) {
|
|
2920
3545
|
uniforms.enabled = props.enabled ? 1 : 0;
|
|
2921
3546
|
}
|
|
2922
3547
|
return uniforms;
|
|
2923
3548
|
}
|
|
2924
|
-
function getLightSourceUniforms({ ambientLight, pointLights = [], directionalLights = [] }) {
|
|
2925
|
-
const
|
|
2926
|
-
lightSourceUniforms.ambientColor = convertColor(ambientLight);
|
|
3549
|
+
function getLightSourceUniforms({ ambientLight, pointLights = [], spotLights = [], directionalLights = [] }) {
|
|
3550
|
+
const lights = createDefaultLightUniforms();
|
|
2927
3551
|
let currentLight = 0;
|
|
2928
3552
|
let pointLightCount = 0;
|
|
3553
|
+
let spotLightCount = 0;
|
|
2929
3554
|
let directionalLightCount = 0;
|
|
2930
3555
|
for (const pointLight of pointLights) {
|
|
2931
3556
|
if (currentLight >= MAX_LIGHTS) {
|
|
2932
3557
|
break;
|
|
2933
3558
|
}
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
3559
|
+
lights[currentLight] = {
|
|
3560
|
+
...lights[currentLight],
|
|
3561
|
+
color: convertColor(pointLight),
|
|
3562
|
+
position: pointLight.position,
|
|
3563
|
+
attenuation: pointLight.attenuation || [1, 0, 0]
|
|
3564
|
+
};
|
|
2939
3565
|
currentLight++;
|
|
2940
3566
|
pointLightCount++;
|
|
2941
3567
|
}
|
|
3568
|
+
for (const spotLight of spotLights) {
|
|
3569
|
+
if (currentLight >= MAX_LIGHTS) {
|
|
3570
|
+
break;
|
|
3571
|
+
}
|
|
3572
|
+
lights[currentLight] = {
|
|
3573
|
+
...lights[currentLight],
|
|
3574
|
+
color: convertColor(spotLight),
|
|
3575
|
+
position: spotLight.position,
|
|
3576
|
+
direction: spotLight.direction,
|
|
3577
|
+
attenuation: spotLight.attenuation || [1, 0, 0],
|
|
3578
|
+
coneCos: getSpotConeCos(spotLight)
|
|
3579
|
+
};
|
|
3580
|
+
currentLight++;
|
|
3581
|
+
spotLightCount++;
|
|
3582
|
+
}
|
|
2942
3583
|
for (const directionalLight of directionalLights) {
|
|
2943
3584
|
if (currentLight >= MAX_LIGHTS) {
|
|
2944
3585
|
break;
|
|
2945
3586
|
}
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
3587
|
+
lights[currentLight] = {
|
|
3588
|
+
...lights[currentLight],
|
|
3589
|
+
color: convertColor(directionalLight),
|
|
3590
|
+
direction: directionalLight.direction
|
|
3591
|
+
};
|
|
2950
3592
|
currentLight++;
|
|
2951
3593
|
directionalLightCount++;
|
|
2952
3594
|
}
|
|
2953
|
-
if (pointLights.length + directionalLights.length > MAX_LIGHTS) {
|
|
3595
|
+
if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {
|
|
2954
3596
|
import_core3.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
|
|
2955
3597
|
}
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
3598
|
+
return {
|
|
3599
|
+
ambientColor: convertColor(ambientLight),
|
|
3600
|
+
directionalLightCount,
|
|
3601
|
+
pointLightCount,
|
|
3602
|
+
spotLightCount,
|
|
3603
|
+
lights
|
|
3604
|
+
};
|
|
2959
3605
|
}
|
|
2960
3606
|
function extractLightTypes(lights) {
|
|
2961
|
-
var _a, _b;
|
|
2962
|
-
const lightSources = { pointLights: [], directionalLights: [] };
|
|
3607
|
+
var _a, _b, _c;
|
|
3608
|
+
const lightSources = { pointLights: [], spotLights: [], directionalLights: [] };
|
|
2963
3609
|
for (const light of lights || []) {
|
|
2964
3610
|
switch (light.type) {
|
|
2965
3611
|
case "ambient":
|
|
@@ -2971,6 +3617,9 @@ function extractLightTypes(lights) {
|
|
|
2971
3617
|
case "point":
|
|
2972
3618
|
(_b = lightSources.pointLights) == null ? void 0 : _b.push(light);
|
|
2973
3619
|
break;
|
|
3620
|
+
case "spot":
|
|
3621
|
+
(_c = lightSources.spotLights) == null ? void 0 : _c.push(light);
|
|
3622
|
+
break;
|
|
2974
3623
|
default:
|
|
2975
3624
|
}
|
|
2976
3625
|
}
|
|
@@ -2980,6 +3629,68 @@ function convertColor(colorDef = {}) {
|
|
|
2980
3629
|
const { color = [0, 0, 0], intensity = 1 } = colorDef;
|
|
2981
3630
|
return color.map((component) => component * intensity / COLOR_FACTOR);
|
|
2982
3631
|
}
|
|
3632
|
+
function createDefaultLightingUniforms() {
|
|
3633
|
+
return {
|
|
3634
|
+
enabled: 1,
|
|
3635
|
+
directionalLightCount: 0,
|
|
3636
|
+
pointLightCount: 0,
|
|
3637
|
+
spotLightCount: 0,
|
|
3638
|
+
ambientColor: [0.1, 0.1, 0.1],
|
|
3639
|
+
lights: createDefaultLightUniforms()
|
|
3640
|
+
};
|
|
3641
|
+
}
|
|
3642
|
+
function createDefaultLightUniforms() {
|
|
3643
|
+
return Array.from({ length: MAX_LIGHTS }, () => createDefaultLightUniform());
|
|
3644
|
+
}
|
|
3645
|
+
function createDefaultLightUniform() {
|
|
3646
|
+
return {
|
|
3647
|
+
color: [1, 1, 1],
|
|
3648
|
+
position: [1, 1, 2],
|
|
3649
|
+
direction: [1, 1, 1],
|
|
3650
|
+
attenuation: [1, 0, 0],
|
|
3651
|
+
coneCos: [1, 0]
|
|
3652
|
+
};
|
|
3653
|
+
}
|
|
3654
|
+
function getSpotConeCos(spotLight) {
|
|
3655
|
+
const innerConeAngle = spotLight.innerConeAngle ?? 0;
|
|
3656
|
+
const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;
|
|
3657
|
+
return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
// dist/modules/lighting/ibl/ibl.js
|
|
3661
|
+
var iblWGSL = (
|
|
3662
|
+
/* wgsl */
|
|
3663
|
+
`#ifdef USE_IBL
|
|
3664
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
|
|
3665
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
|
|
3666
|
+
@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
|
|
3667
|
+
@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
|
|
3668
|
+
@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
|
|
3669
|
+
@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
|
|
3670
|
+
#endif
|
|
3671
|
+
`
|
|
3672
|
+
);
|
|
3673
|
+
var iblGLSL = (
|
|
3674
|
+
/* glsl */
|
|
3675
|
+
`#ifdef USE_IBL
|
|
3676
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
3677
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
3678
|
+
uniform sampler2D pbr_brdfLUT;
|
|
3679
|
+
#endif
|
|
3680
|
+
`
|
|
3681
|
+
);
|
|
3682
|
+
var ibl = {
|
|
3683
|
+
name: "ibl",
|
|
3684
|
+
firstBindingSlot: 32,
|
|
3685
|
+
bindingLayout: [
|
|
3686
|
+
{ name: "pbr_diffuseEnvSampler", group: 2 },
|
|
3687
|
+
{ name: "pbr_specularEnvSampler", group: 2 },
|
|
3688
|
+
{ name: "pbr_brdfLUT", group: 2 }
|
|
3689
|
+
],
|
|
3690
|
+
source: iblWGSL,
|
|
3691
|
+
vs: iblGLSL,
|
|
3692
|
+
fs: iblGLSL
|
|
3693
|
+
};
|
|
2983
3694
|
|
|
2984
3695
|
// dist/modules/lighting/no-material/dirlight.js
|
|
2985
3696
|
var SOURCE_WGSL = (
|
|
@@ -2995,7 +3706,7 @@ struct DirlightInputs {
|
|
|
2995
3706
|
normal: DirlightNormal,
|
|
2996
3707
|
};
|
|
2997
3708
|
|
|
2998
|
-
@
|
|
3709
|
+
@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;
|
|
2999
3710
|
|
|
3000
3711
|
// For vertex
|
|
3001
3712
|
fn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {
|
|
@@ -3040,6 +3751,8 @@ var dirlight = {
|
|
|
3040
3751
|
props: {},
|
|
3041
3752
|
uniforms: {},
|
|
3042
3753
|
name: "dirlight",
|
|
3754
|
+
bindingLayout: [{ name: "dirlight", group: 2 }],
|
|
3755
|
+
firstBindingSlot: 16,
|
|
3043
3756
|
dependencies: [],
|
|
3044
3757
|
source: SOURCE_WGSL,
|
|
3045
3758
|
vs: VS_GLSL,
|
|
@@ -3066,10 +3779,173 @@ function getUniforms3(opts = dirlight.defaultUniforms) {
|
|
|
3066
3779
|
return uniforms;
|
|
3067
3780
|
}
|
|
3068
3781
|
|
|
3782
|
+
// dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js
|
|
3783
|
+
var LAMBERT_WGSL = (
|
|
3784
|
+
/* wgsl */
|
|
3785
|
+
`struct lambertMaterialUniforms {
|
|
3786
|
+
unlit: u32,
|
|
3787
|
+
ambient: f32,
|
|
3788
|
+
diffuse: f32,
|
|
3789
|
+
};
|
|
3790
|
+
|
|
3791
|
+
@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;
|
|
3792
|
+
|
|
3793
|
+
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
3794
|
+
let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);
|
|
3795
|
+
return lambertian * lambertMaterial.diffuse * surfaceColor * color;
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
3799
|
+
var lightColor: vec3<f32> = surfaceColor;
|
|
3800
|
+
|
|
3801
|
+
if (lambertMaterial.unlit != 0u) {
|
|
3802
|
+
return surfaceColor;
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
if (lighting.enabled == 0) {
|
|
3806
|
+
return lightColor;
|
|
3807
|
+
}
|
|
3808
|
+
|
|
3809
|
+
lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
3810
|
+
|
|
3811
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
3812
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
3813
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
3814
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
3815
|
+
let light_attenuation = getPointLightAttenuation(
|
|
3816
|
+
pointLight,
|
|
3817
|
+
distance(light_position_worldspace, position_worldspace)
|
|
3818
|
+
);
|
|
3819
|
+
lightColor += lighting_getLightColor(
|
|
3820
|
+
surfaceColor,
|
|
3821
|
+
light_direction,
|
|
3822
|
+
normal_worldspace,
|
|
3823
|
+
pointLight.color / light_attenuation
|
|
3824
|
+
);
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
3828
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
3829
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
3830
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
3831
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
3832
|
+
lightColor += lighting_getLightColor(
|
|
3833
|
+
surfaceColor,
|
|
3834
|
+
light_direction,
|
|
3835
|
+
normal_worldspace,
|
|
3836
|
+
spotLight.color / light_attenuation
|
|
3837
|
+
);
|
|
3838
|
+
}
|
|
3839
|
+
|
|
3840
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
3841
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
3842
|
+
lightColor += lighting_getLightColor(
|
|
3843
|
+
surfaceColor,
|
|
3844
|
+
-directionalLight.direction,
|
|
3845
|
+
normal_worldspace,
|
|
3846
|
+
directionalLight.color
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3850
|
+
return lightColor;
|
|
3851
|
+
}
|
|
3852
|
+
`
|
|
3853
|
+
);
|
|
3854
|
+
|
|
3855
|
+
// dist/modules/lighting/lambert-material/lambert-shaders-glsl.js
|
|
3856
|
+
var LAMBERT_VS = (
|
|
3857
|
+
/* glsl */
|
|
3858
|
+
`uniform lambertMaterialUniforms {
|
|
3859
|
+
uniform bool unlit;
|
|
3860
|
+
uniform float ambient;
|
|
3861
|
+
uniform float diffuse;
|
|
3862
|
+
} material;
|
|
3863
|
+
`
|
|
3864
|
+
);
|
|
3865
|
+
var LAMBERT_FS = (
|
|
3866
|
+
/* glsl */
|
|
3867
|
+
`uniform lambertMaterialUniforms {
|
|
3868
|
+
uniform bool unlit;
|
|
3869
|
+
uniform float ambient;
|
|
3870
|
+
uniform float diffuse;
|
|
3871
|
+
} material;
|
|
3872
|
+
|
|
3873
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {
|
|
3874
|
+
float lambertian = max(dot(light_direction, normal_worldspace), 0.0);
|
|
3875
|
+
return lambertian * material.diffuse * surfaceColor * color;
|
|
3876
|
+
}
|
|
3877
|
+
|
|
3878
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
3879
|
+
vec3 lightColor = surfaceColor;
|
|
3880
|
+
|
|
3881
|
+
if (material.unlit) {
|
|
3882
|
+
return surfaceColor;
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3885
|
+
if (lighting.enabled == 0) {
|
|
3886
|
+
return lightColor;
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
lightColor = material.ambient * surfaceColor * lighting.ambientColor;
|
|
3890
|
+
|
|
3891
|
+
for (int i = 0; i < lighting.pointLightCount; i++) {
|
|
3892
|
+
PointLight pointLight = lighting_getPointLight(i);
|
|
3893
|
+
vec3 light_position_worldspace = pointLight.position;
|
|
3894
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
3895
|
+
float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));
|
|
3896
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
3900
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
3901
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
3902
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
3903
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
3904
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3907
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
3908
|
+
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
3909
|
+
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
return lightColor;
|
|
3913
|
+
}
|
|
3914
|
+
`
|
|
3915
|
+
);
|
|
3916
|
+
|
|
3917
|
+
// dist/modules/lighting/lambert-material/lambert-material.js
|
|
3918
|
+
var lambertMaterial = {
|
|
3919
|
+
name: "lambertMaterial",
|
|
3920
|
+
firstBindingSlot: 0,
|
|
3921
|
+
bindingLayout: [{ name: "lambertMaterial", group: 3 }],
|
|
3922
|
+
dependencies: [lighting],
|
|
3923
|
+
source: LAMBERT_WGSL,
|
|
3924
|
+
vs: LAMBERT_VS,
|
|
3925
|
+
fs: LAMBERT_FS,
|
|
3926
|
+
defines: {
|
|
3927
|
+
LIGHTING_FRAGMENT: true
|
|
3928
|
+
},
|
|
3929
|
+
uniformTypes: {
|
|
3930
|
+
unlit: "i32",
|
|
3931
|
+
ambient: "f32",
|
|
3932
|
+
diffuse: "f32"
|
|
3933
|
+
},
|
|
3934
|
+
defaultUniforms: {
|
|
3935
|
+
unlit: false,
|
|
3936
|
+
ambient: 0.35,
|
|
3937
|
+
diffuse: 0.6
|
|
3938
|
+
},
|
|
3939
|
+
getUniforms(props) {
|
|
3940
|
+
return { ...lambertMaterial.defaultUniforms, ...props };
|
|
3941
|
+
}
|
|
3942
|
+
};
|
|
3943
|
+
|
|
3069
3944
|
// dist/modules/lighting/phong-material/phong-shaders-glsl.js
|
|
3070
3945
|
var PHONG_VS = (
|
|
3071
3946
|
/* glsl */
|
|
3072
3947
|
`uniform phongMaterialUniforms {
|
|
3948
|
+
uniform bool unlit;
|
|
3073
3949
|
uniform float ambient;
|
|
3074
3950
|
uniform float diffuse;
|
|
3075
3951
|
uniform float shininess;
|
|
@@ -3079,9 +3955,8 @@ var PHONG_VS = (
|
|
|
3079
3955
|
);
|
|
3080
3956
|
var PHONG_FS = (
|
|
3081
3957
|
/* glsl */
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
uniform phongMaterialUniforms {
|
|
3958
|
+
`uniform phongMaterialUniforms {
|
|
3959
|
+
uniform bool unlit;
|
|
3085
3960
|
uniform float ambient;
|
|
3086
3961
|
uniform float diffuse;
|
|
3087
3962
|
uniform float shininess;
|
|
@@ -3103,6 +3978,10 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_d
|
|
|
3103
3978
|
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
3104
3979
|
vec3 lightColor = surfaceColor;
|
|
3105
3980
|
|
|
3981
|
+
if (material.unlit) {
|
|
3982
|
+
return surfaceColor;
|
|
3983
|
+
}
|
|
3984
|
+
|
|
3106
3985
|
if (lighting.enabled == 0) {
|
|
3107
3986
|
return lightColor;
|
|
3108
3987
|
}
|
|
@@ -3118,8 +3997,15 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
3118
3997
|
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
3119
3998
|
}
|
|
3120
3999
|
|
|
3121
|
-
int
|
|
3122
|
-
|
|
4000
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
4001
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
4002
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
4003
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
4004
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4005
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
3123
4009
|
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
3124
4010
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
3125
4011
|
}
|
|
@@ -3133,13 +4019,14 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
3133
4019
|
var PHONG_WGSL = (
|
|
3134
4020
|
/* wgsl */
|
|
3135
4021
|
`struct phongMaterialUniforms {
|
|
4022
|
+
unlit: u32,
|
|
3136
4023
|
ambient: f32,
|
|
3137
4024
|
diffuse: f32,
|
|
3138
4025
|
shininess: f32,
|
|
3139
4026
|
specularColor: vec3<f32>,
|
|
3140
4027
|
};
|
|
3141
4028
|
|
|
3142
|
-
@
|
|
4029
|
+
@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;
|
|
3143
4030
|
|
|
3144
4031
|
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
3145
4032
|
let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);
|
|
@@ -3156,6 +4043,10 @@ fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, v
|
|
|
3156
4043
|
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
3157
4044
|
var lightColor: vec3<f32> = surfaceColor;
|
|
3158
4045
|
|
|
4046
|
+
if (phongMaterial.unlit != 0u) {
|
|
4047
|
+
return surfaceColor;
|
|
4048
|
+
}
|
|
4049
|
+
|
|
3159
4050
|
if (lighting.enabled == 0) {
|
|
3160
4051
|
return lightColor;
|
|
3161
4052
|
}
|
|
@@ -3180,8 +4071,21 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
|
|
|
3180
4071
|
);
|
|
3181
4072
|
}
|
|
3182
4073
|
|
|
3183
|
-
|
|
3184
|
-
|
|
4074
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
4075
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
4076
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
4077
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
4078
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4079
|
+
lightColor += lighting_getLightColor(
|
|
4080
|
+
surfaceColor,
|
|
4081
|
+
light_direction,
|
|
4082
|
+
view_direction,
|
|
4083
|
+
normal_worldspace,
|
|
4084
|
+
spotLight.color / light_attenuation
|
|
4085
|
+
);
|
|
4086
|
+
}
|
|
4087
|
+
|
|
4088
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
3185
4089
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
3186
4090
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
3187
4091
|
}
|
|
@@ -3213,8 +4117,21 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
3213
4117
|
);
|
|
3214
4118
|
}
|
|
3215
4119
|
|
|
3216
|
-
|
|
3217
|
-
|
|
4120
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
4121
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
4122
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
4123
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
4124
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4125
|
+
lightColor += lighting_getLightColor(
|
|
4126
|
+
surfaceColor,
|
|
4127
|
+
light_direction,
|
|
4128
|
+
view_direction,
|
|
4129
|
+
normal_worldspace,
|
|
4130
|
+
spotLight.color / light_attenuation
|
|
4131
|
+
);
|
|
4132
|
+
}
|
|
4133
|
+
|
|
4134
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
3218
4135
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
3219
4136
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
3220
4137
|
}
|
|
@@ -3228,6 +4145,7 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
3228
4145
|
var gouraudMaterial = {
|
|
3229
4146
|
props: {},
|
|
3230
4147
|
name: "gouraudMaterial",
|
|
4148
|
+
bindingLayout: [{ name: "gouraudMaterial", group: 3 }],
|
|
3231
4149
|
// Note these are switched between phong and gouraud
|
|
3232
4150
|
vs: PHONG_FS.replace("phongMaterial", "gouraudMaterial"),
|
|
3233
4151
|
fs: PHONG_VS.replace("phongMaterial", "gouraudMaterial"),
|
|
@@ -3237,12 +4155,14 @@ var gouraudMaterial = {
|
|
|
3237
4155
|
},
|
|
3238
4156
|
dependencies: [lighting],
|
|
3239
4157
|
uniformTypes: {
|
|
4158
|
+
unlit: "i32",
|
|
3240
4159
|
ambient: "f32",
|
|
3241
4160
|
diffuse: "f32",
|
|
3242
4161
|
shininess: "f32",
|
|
3243
4162
|
specularColor: "vec3<f32>"
|
|
3244
4163
|
},
|
|
3245
4164
|
defaultUniforms: {
|
|
4165
|
+
unlit: false,
|
|
3246
4166
|
ambient: 0.35,
|
|
3247
4167
|
diffuse: 0.6,
|
|
3248
4168
|
shininess: 32,
|
|
@@ -3260,6 +4180,8 @@ var gouraudMaterial = {
|
|
|
3260
4180
|
// dist/modules/lighting/phong-material/phong-material.js
|
|
3261
4181
|
var phongMaterial = {
|
|
3262
4182
|
name: "phongMaterial",
|
|
4183
|
+
firstBindingSlot: 0,
|
|
4184
|
+
bindingLayout: [{ name: "phongMaterial", group: 3 }],
|
|
3263
4185
|
dependencies: [lighting],
|
|
3264
4186
|
// Note these are switched between phong and gouraud
|
|
3265
4187
|
source: PHONG_WGSL,
|
|
@@ -3269,12 +4191,14 @@ var phongMaterial = {
|
|
|
3269
4191
|
LIGHTING_FRAGMENT: true
|
|
3270
4192
|
},
|
|
3271
4193
|
uniformTypes: {
|
|
4194
|
+
unlit: "i32",
|
|
3272
4195
|
ambient: "f32",
|
|
3273
4196
|
diffuse: "f32",
|
|
3274
4197
|
shininess: "f32",
|
|
3275
4198
|
specularColor: "vec3<f32>"
|
|
3276
4199
|
},
|
|
3277
4200
|
defaultUniforms: {
|
|
4201
|
+
unlit: false,
|
|
3278
4202
|
ambient: 0.35,
|
|
3279
4203
|
diffuse: 0.6,
|
|
3280
4204
|
shininess: 32,
|
|
@@ -3371,10 +4295,12 @@ uniform pbrMaterialUniforms {
|
|
|
3371
4295
|
float clearcoatFactor;
|
|
3372
4296
|
float clearcoatRoughnessFactor;
|
|
3373
4297
|
bool clearcoatMapEnabled;
|
|
4298
|
+
bool clearcoatRoughnessMapEnabled;
|
|
3374
4299
|
|
|
3375
4300
|
vec3 sheenColorFactor;
|
|
3376
4301
|
float sheenRoughnessFactor;
|
|
3377
4302
|
bool sheenColorMapEnabled;
|
|
4303
|
+
bool sheenRoughnessMapEnabled;
|
|
3378
4304
|
|
|
3379
4305
|
float iridescenceFactor;
|
|
3380
4306
|
float iridescenceIor;
|
|
@@ -3424,26 +4350,33 @@ uniform sampler2D pbr_specularIntensitySampler;
|
|
|
3424
4350
|
#ifdef HAS_TRANSMISSIONMAP
|
|
3425
4351
|
uniform sampler2D pbr_transmissionSampler;
|
|
3426
4352
|
#endif
|
|
4353
|
+
#ifdef HAS_THICKNESSMAP
|
|
4354
|
+
uniform sampler2D pbr_thicknessSampler;
|
|
4355
|
+
#endif
|
|
3427
4356
|
#ifdef HAS_CLEARCOATMAP
|
|
3428
4357
|
uniform sampler2D pbr_clearcoatSampler;
|
|
4358
|
+
#endif
|
|
4359
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
3429
4360
|
uniform sampler2D pbr_clearcoatRoughnessSampler;
|
|
3430
4361
|
#endif
|
|
4362
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
4363
|
+
uniform sampler2D pbr_clearcoatNormalSampler;
|
|
4364
|
+
#endif
|
|
3431
4365
|
#ifdef HAS_SHEENCOLORMAP
|
|
3432
4366
|
uniform sampler2D pbr_sheenColorSampler;
|
|
4367
|
+
#endif
|
|
4368
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
3433
4369
|
uniform sampler2D pbr_sheenRoughnessSampler;
|
|
3434
4370
|
#endif
|
|
3435
4371
|
#ifdef HAS_IRIDESCENCEMAP
|
|
3436
4372
|
uniform sampler2D pbr_iridescenceSampler;
|
|
3437
4373
|
#endif
|
|
4374
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
4375
|
+
uniform sampler2D pbr_iridescenceThicknessSampler;
|
|
4376
|
+
#endif
|
|
3438
4377
|
#ifdef HAS_ANISOTROPYMAP
|
|
3439
4378
|
uniform sampler2D pbr_anisotropySampler;
|
|
3440
4379
|
#endif
|
|
3441
|
-
#ifdef USE_IBL
|
|
3442
|
-
uniform samplerCube pbr_diffuseEnvSampler;
|
|
3443
|
-
uniform samplerCube pbr_specularEnvSampler;
|
|
3444
|
-
uniform sampler2D pbr_brdfLUT;
|
|
3445
|
-
#endif
|
|
3446
|
-
|
|
3447
4380
|
// Inputs from vertex shader
|
|
3448
4381
|
|
|
3449
4382
|
in vec3 pbr_vPosition;
|
|
@@ -3480,6 +4413,8 @@ struct PBRInfo {
|
|
|
3480
4413
|
const float M_PI = 3.141592653589793;
|
|
3481
4414
|
const float c_MinRoughness = 0.04;
|
|
3482
4415
|
|
|
4416
|
+
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
|
|
4417
|
+
|
|
3483
4418
|
vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
3484
4419
|
{
|
|
3485
4420
|
#ifdef MANUAL_SRGB
|
|
@@ -3495,11 +4430,9 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
|
3495
4430
|
#endif //MANUAL_SRGB
|
|
3496
4431
|
}
|
|
3497
4432
|
|
|
3498
|
-
//
|
|
3499
|
-
|
|
3500
|
-
vec3 getNormal()
|
|
4433
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
4434
|
+
mat3 getTBN()
|
|
3501
4435
|
{
|
|
3502
|
-
// Retrieve the tangent space matrix
|
|
3503
4436
|
#ifndef HAS_TANGENTS
|
|
3504
4437
|
vec3 pos_dx = dFdx(pbr_vPosition);
|
|
3505
4438
|
vec3 pos_dy = dFdy(pbr_vPosition);
|
|
@@ -3520,9 +4453,21 @@ vec3 getNormal()
|
|
|
3520
4453
|
mat3 tbn = pbr_vTBN;
|
|
3521
4454
|
#endif
|
|
3522
4455
|
|
|
4456
|
+
return tbn;
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4459
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
4460
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
4461
|
+
vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
|
|
4462
|
+
{
|
|
4463
|
+
vec3 n = texture(normalSampler, pbr_vUV).rgb;
|
|
4464
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
vec3 getNormal(mat3 tbn)
|
|
4468
|
+
{
|
|
3523
4469
|
#ifdef HAS_NORMALMAP
|
|
3524
|
-
vec3 n =
|
|
3525
|
-
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
|
|
4470
|
+
vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
|
|
3526
4471
|
#else
|
|
3527
4472
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
3528
4473
|
vec3 n = normalize(tbn[2].xyz);
|
|
@@ -3531,6 +4476,15 @@ vec3 getNormal()
|
|
|
3531
4476
|
return n;
|
|
3532
4477
|
}
|
|
3533
4478
|
|
|
4479
|
+
vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
|
|
4480
|
+
{
|
|
4481
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
4482
|
+
return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
|
|
4483
|
+
#else
|
|
4484
|
+
return baseNormal;
|
|
4485
|
+
#endif
|
|
4486
|
+
}
|
|
4487
|
+
|
|
3534
4488
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
3535
4489
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
3536
4490
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -3606,35 +4560,203 @@ float microfacetDistribution(PBRInfo pbrInfo)
|
|
|
3606
4560
|
return roughnessSq / (M_PI * f * f);
|
|
3607
4561
|
}
|
|
3608
4562
|
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
pbrInfo.LdotH = 0.0;
|
|
3613
|
-
pbrInfo.VdotH = 1.0;
|
|
4563
|
+
float maxComponent(vec3 value)
|
|
4564
|
+
{
|
|
4565
|
+
return max(max(value.r, value.g), value.b);
|
|
3614
4566
|
}
|
|
3615
4567
|
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
4568
|
+
float getDielectricF0(float ior)
|
|
4569
|
+
{
|
|
4570
|
+
float clampedIor = max(ior, 1.0);
|
|
4571
|
+
float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
4572
|
+
return ratio * ratio;
|
|
4573
|
+
}
|
|
3621
4574
|
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
4575
|
+
vec2 normalizeDirection(vec2 direction)
|
|
4576
|
+
{
|
|
4577
|
+
float directionLength = length(direction);
|
|
4578
|
+
return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
|
|
3626
4579
|
}
|
|
3627
4580
|
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
4581
|
+
vec2 rotateDirection(vec2 direction, float rotation)
|
|
4582
|
+
{
|
|
4583
|
+
float s = sin(rotation);
|
|
4584
|
+
float c = cos(rotation);
|
|
4585
|
+
return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
3631
4586
|
}
|
|
3632
4587
|
|
|
3633
|
-
vec3
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
4588
|
+
vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
|
|
4589
|
+
{
|
|
4590
|
+
if (iridescence <= 0.0) {
|
|
4591
|
+
return vec3(1.0);
|
|
4592
|
+
}
|
|
4593
|
+
|
|
4594
|
+
float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
4595
|
+
vec3 thinFilmTint =
|
|
4596
|
+
0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
|
|
4597
|
+
return mix(vec3(1.0), thinFilmTint, iridescence);
|
|
4598
|
+
}
|
|
4599
|
+
|
|
4600
|
+
vec3 getVolumeAttenuation(float thickness)
|
|
4601
|
+
{
|
|
4602
|
+
if (thickness <= 0.0) {
|
|
4603
|
+
return vec3(1.0);
|
|
4604
|
+
}
|
|
4605
|
+
|
|
4606
|
+
vec3 attenuationCoefficient =
|
|
4607
|
+
-log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
|
|
4608
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
4609
|
+
return exp(-attenuationCoefficient * thickness);
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4612
|
+
PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
|
|
4613
|
+
{
|
|
4614
|
+
float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
4615
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
4616
|
+
float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
4617
|
+
|
|
4618
|
+
return PBRInfo(
|
|
4619
|
+
basePBRInfo.NdotL,
|
|
4620
|
+
NdotV,
|
|
4621
|
+
basePBRInfo.NdotH,
|
|
4622
|
+
basePBRInfo.LdotH,
|
|
4623
|
+
basePBRInfo.VdotH,
|
|
4624
|
+
perceptualRoughness,
|
|
4625
|
+
0.0,
|
|
4626
|
+
vec3(0.04),
|
|
4627
|
+
vec3(1.0),
|
|
4628
|
+
alphaRoughness,
|
|
4629
|
+
vec3(0.0),
|
|
4630
|
+
vec3(0.04),
|
|
4631
|
+
clearcoatNormal,
|
|
4632
|
+
basePBRInfo.v
|
|
4633
|
+
);
|
|
4634
|
+
}
|
|
4635
|
+
|
|
4636
|
+
vec3 calculateClearcoatContribution(
|
|
4637
|
+
PBRInfo pbrInfo,
|
|
4638
|
+
vec3 lightColor,
|
|
4639
|
+
vec3 clearcoatNormal,
|
|
4640
|
+
float clearcoatFactor,
|
|
4641
|
+
float clearcoatRoughness
|
|
4642
|
+
) {
|
|
4643
|
+
if (clearcoatFactor <= 0.0) {
|
|
4644
|
+
return vec3(0.0);
|
|
4645
|
+
}
|
|
4646
|
+
|
|
4647
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
4648
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
#ifdef USE_IBL
|
|
4652
|
+
vec3 calculateClearcoatIBLContribution(
|
|
4653
|
+
PBRInfo pbrInfo,
|
|
4654
|
+
vec3 clearcoatNormal,
|
|
4655
|
+
vec3 reflection,
|
|
4656
|
+
float clearcoatFactor,
|
|
4657
|
+
float clearcoatRoughness
|
|
4658
|
+
) {
|
|
4659
|
+
if (clearcoatFactor <= 0.0) {
|
|
4660
|
+
return vec3(0.0);
|
|
4661
|
+
}
|
|
4662
|
+
|
|
4663
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
4664
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
4665
|
+
}
|
|
4666
|
+
#endif
|
|
4667
|
+
|
|
4668
|
+
vec3 calculateSheenContribution(
|
|
4669
|
+
PBRInfo pbrInfo,
|
|
4670
|
+
vec3 lightColor,
|
|
4671
|
+
vec3 sheenColor,
|
|
4672
|
+
float sheenRoughness
|
|
4673
|
+
) {
|
|
4674
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
4675
|
+
return vec3(0.0);
|
|
4676
|
+
}
|
|
4677
|
+
|
|
4678
|
+
float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
4679
|
+
float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
4680
|
+
return pbrInfo.NdotL *
|
|
4681
|
+
lightColor *
|
|
4682
|
+
sheenColor *
|
|
4683
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
4684
|
+
sheenVisibility *
|
|
4685
|
+
(1.0 - pbrInfo.metalness);
|
|
4686
|
+
}
|
|
4687
|
+
|
|
4688
|
+
float calculateAnisotropyBoost(
|
|
4689
|
+
PBRInfo pbrInfo,
|
|
4690
|
+
vec3 anisotropyTangent,
|
|
4691
|
+
float anisotropyStrength
|
|
4692
|
+
) {
|
|
4693
|
+
if (anisotropyStrength <= 0.0) {
|
|
4694
|
+
return 1.0;
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
4698
|
+
float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
4699
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4702
|
+
vec3 calculateMaterialLightColor(
|
|
4703
|
+
PBRInfo pbrInfo,
|
|
4704
|
+
vec3 lightColor,
|
|
4705
|
+
vec3 clearcoatNormal,
|
|
4706
|
+
float clearcoatFactor,
|
|
4707
|
+
float clearcoatRoughness,
|
|
4708
|
+
vec3 sheenColor,
|
|
4709
|
+
float sheenRoughness,
|
|
4710
|
+
vec3 anisotropyTangent,
|
|
4711
|
+
float anisotropyStrength
|
|
4712
|
+
) {
|
|
4713
|
+
float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
4714
|
+
vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
4715
|
+
color += calculateClearcoatContribution(
|
|
4716
|
+
pbrInfo,
|
|
4717
|
+
lightColor,
|
|
4718
|
+
clearcoatNormal,
|
|
4719
|
+
clearcoatFactor,
|
|
4720
|
+
clearcoatRoughness
|
|
4721
|
+
);
|
|
4722
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
4723
|
+
return color;
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4726
|
+
void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
|
|
4727
|
+
pbrInfo.NdotL = 1.0;
|
|
4728
|
+
pbrInfo.NdotH = 0.0;
|
|
4729
|
+
pbrInfo.LdotH = 0.0;
|
|
4730
|
+
pbrInfo.VdotH = 1.0;
|
|
4731
|
+
}
|
|
4732
|
+
|
|
4733
|
+
void PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {
|
|
4734
|
+
vec3 n = pbrInfo.n;
|
|
4735
|
+
vec3 v = pbrInfo.v;
|
|
4736
|
+
vec3 l = normalize(lightDirection); // Vector from surface point to light
|
|
4737
|
+
vec3 h = normalize(l+v); // Half vector between both l and v
|
|
4738
|
+
|
|
4739
|
+
pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);
|
|
4740
|
+
pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);
|
|
4741
|
+
pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);
|
|
4742
|
+
pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);
|
|
4743
|
+
}
|
|
4744
|
+
|
|
4745
|
+
void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
|
|
4746
|
+
vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
|
|
4747
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
4748
|
+
}
|
|
4749
|
+
|
|
4750
|
+
void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
|
|
4751
|
+
vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
|
|
4752
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
4753
|
+
}
|
|
4754
|
+
|
|
4755
|
+
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
|
|
4756
|
+
// Calculate the shading terms for the microfacet specular shading model
|
|
4757
|
+
vec3 F = specularReflection(pbrInfo);
|
|
4758
|
+
float G = geometricOcclusion(pbrInfo);
|
|
4759
|
+
float D = microfacetDistribution(pbrInfo);
|
|
3638
4760
|
|
|
3639
4761
|
// Calculation of analytical lighting contribution
|
|
3640
4762
|
vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);
|
|
@@ -3660,6 +4782,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3660
4782
|
|
|
3661
4783
|
vec3 color = vec3(0, 0, 0);
|
|
3662
4784
|
|
|
4785
|
+
float transmission = 0.0;
|
|
4786
|
+
|
|
3663
4787
|
if(pbrMaterial.unlit){
|
|
3664
4788
|
color.rgb = baseColor.rgb;
|
|
3665
4789
|
}
|
|
@@ -3678,14 +4802,252 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3678
4802
|
#endif
|
|
3679
4803
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
3680
4804
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
4805
|
+
mat3 tbn = getTBN();
|
|
4806
|
+
vec3 n = getNormal(tbn); // normal at surface point
|
|
4807
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
4808
|
+
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
4809
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
4810
|
+
bool useExtendedPBR =
|
|
4811
|
+
pbrMaterial.specularColorMapEnabled ||
|
|
4812
|
+
pbrMaterial.specularIntensityMapEnabled ||
|
|
4813
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
4814
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
|
|
4815
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
4816
|
+
pbrMaterial.transmissionMapEnabled ||
|
|
4817
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
4818
|
+
pbrMaterial.clearcoatMapEnabled ||
|
|
4819
|
+
pbrMaterial.clearcoatRoughnessMapEnabled ||
|
|
4820
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
4821
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
4822
|
+
pbrMaterial.sheenColorMapEnabled ||
|
|
4823
|
+
pbrMaterial.sheenRoughnessMapEnabled ||
|
|
4824
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
4825
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
4826
|
+
pbrMaterial.iridescenceMapEnabled ||
|
|
4827
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
4828
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
4829
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
4830
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
4831
|
+
pbrMaterial.anisotropyMapEnabled ||
|
|
4832
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
4833
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
4834
|
+
length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
|
|
4835
|
+
#else
|
|
4836
|
+
bool useExtendedPBR = false;
|
|
4837
|
+
#endif
|
|
4838
|
+
|
|
4839
|
+
if (!useExtendedPBR) {
|
|
4840
|
+
// Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
|
|
4841
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
4842
|
+
|
|
4843
|
+
vec3 f0 = vec3(0.04);
|
|
4844
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
|
4845
|
+
diffuseColor *= 1.0 - metallic;
|
|
4846
|
+
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
|
4847
|
+
|
|
4848
|
+
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
4849
|
+
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
4850
|
+
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
4851
|
+
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
4852
|
+
vec3 reflection = -normalize(reflect(v, n));
|
|
4853
|
+
|
|
4854
|
+
PBRInfo pbrInfo = PBRInfo(
|
|
4855
|
+
0.0, // NdotL
|
|
4856
|
+
NdotV,
|
|
4857
|
+
0.0, // NdotH
|
|
4858
|
+
0.0, // LdotH
|
|
4859
|
+
0.0, // VdotH
|
|
4860
|
+
perceptualRoughness,
|
|
4861
|
+
metallic,
|
|
4862
|
+
specularEnvironmentR0,
|
|
4863
|
+
specularEnvironmentR90,
|
|
4864
|
+
alphaRoughness,
|
|
4865
|
+
diffuseColor,
|
|
4866
|
+
specularColor,
|
|
4867
|
+
n,
|
|
4868
|
+
v
|
|
4869
|
+
);
|
|
4870
|
+
|
|
4871
|
+
#ifdef USE_LIGHTS
|
|
4872
|
+
PBRInfo_setAmbientLight(pbrInfo);
|
|
4873
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
4874
|
+
|
|
4875
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
4876
|
+
if (i < lighting.directionalLightCount) {
|
|
4877
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
4878
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
4883
|
+
if (i < lighting.pointLightCount) {
|
|
4884
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
4885
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
4886
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4890
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
4891
|
+
if (i < lighting.spotLightCount) {
|
|
4892
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
4893
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
4894
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
#endif
|
|
4898
|
+
|
|
4899
|
+
#ifdef USE_IBL
|
|
4900
|
+
if (pbrMaterial.IBLenabled) {
|
|
4901
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
4902
|
+
}
|
|
4903
|
+
#endif
|
|
4904
|
+
|
|
4905
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
4906
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
4907
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
4908
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
4909
|
+
}
|
|
4910
|
+
#endif
|
|
4911
|
+
|
|
4912
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
4913
|
+
#ifdef HAS_EMISSIVEMAP
|
|
4914
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
4915
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
4916
|
+
}
|
|
4917
|
+
#endif
|
|
4918
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
4919
|
+
|
|
4920
|
+
#ifdef PBR_DEBUG
|
|
4921
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
4922
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
4923
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
4924
|
+
#endif
|
|
4925
|
+
|
|
4926
|
+
return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
|
|
4927
|
+
}
|
|
4928
|
+
|
|
4929
|
+
float specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
4930
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
4931
|
+
if (pbrMaterial.specularIntensityMapEnabled) {
|
|
4932
|
+
specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
|
|
4933
|
+
}
|
|
4934
|
+
#endif
|
|
4935
|
+
|
|
4936
|
+
vec3 specularFactor = pbrMaterial.specularColorFactor;
|
|
4937
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
4938
|
+
if (pbrMaterial.specularColorMapEnabled) {
|
|
4939
|
+
specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
|
|
4940
|
+
}
|
|
4941
|
+
#endif
|
|
4942
|
+
|
|
4943
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
4944
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
4945
|
+
if (pbrMaterial.transmissionMapEnabled) {
|
|
4946
|
+
transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
|
|
4947
|
+
}
|
|
4948
|
+
#endif
|
|
4949
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
4950
|
+
float thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
4951
|
+
#ifdef HAS_THICKNESSMAP
|
|
4952
|
+
thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
|
|
4953
|
+
#endif
|
|
4954
|
+
|
|
4955
|
+
float clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
4956
|
+
float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
4957
|
+
#ifdef HAS_CLEARCOATMAP
|
|
4958
|
+
if (pbrMaterial.clearcoatMapEnabled) {
|
|
4959
|
+
clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
|
|
4960
|
+
}
|
|
4961
|
+
#endif
|
|
4962
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
4963
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled) {
|
|
4964
|
+
clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
|
|
4965
|
+
}
|
|
4966
|
+
#endif
|
|
4967
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
4968
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
4969
|
+
vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
4970
|
+
|
|
4971
|
+
vec3 sheenColor = pbrMaterial.sheenColorFactor;
|
|
4972
|
+
float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
4973
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
4974
|
+
if (pbrMaterial.sheenColorMapEnabled) {
|
|
4975
|
+
sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
|
|
4976
|
+
}
|
|
4977
|
+
#endif
|
|
4978
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
4979
|
+
if (pbrMaterial.sheenRoughnessMapEnabled) {
|
|
4980
|
+
sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
|
|
4981
|
+
}
|
|
4982
|
+
#endif
|
|
4983
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
4984
|
+
|
|
4985
|
+
float iridescence = pbrMaterial.iridescenceFactor;
|
|
4986
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
4987
|
+
if (pbrMaterial.iridescenceMapEnabled) {
|
|
4988
|
+
iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
|
|
4989
|
+
}
|
|
4990
|
+
#endif
|
|
4991
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
4992
|
+
float iridescenceThickness = mix(
|
|
4993
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
4994
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
4995
|
+
0.5
|
|
4996
|
+
);
|
|
4997
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
4998
|
+
iridescenceThickness = mix(
|
|
4999
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
5000
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
5001
|
+
texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
|
|
5002
|
+
);
|
|
5003
|
+
#endif
|
|
5004
|
+
|
|
5005
|
+
float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
5006
|
+
vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
5007
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
5008
|
+
if (pbrMaterial.anisotropyMapEnabled) {
|
|
5009
|
+
vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
|
|
5010
|
+
anisotropyStrength *= anisotropySample.b;
|
|
5011
|
+
vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
5012
|
+
if (length(mappedDirection) > 0.0001) {
|
|
5013
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
5014
|
+
}
|
|
5015
|
+
}
|
|
5016
|
+
#endif
|
|
5017
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
5018
|
+
vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
5019
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
5020
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
5021
|
+
}
|
|
5022
|
+
float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
5023
|
+
perceptualRoughness = mix(
|
|
5024
|
+
perceptualRoughness,
|
|
5025
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
5026
|
+
anisotropyStrength
|
|
5027
|
+
);
|
|
5028
|
+
|
|
3681
5029
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
3682
5030
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
3683
5031
|
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
3684
5032
|
|
|
3685
|
-
|
|
3686
|
-
vec3
|
|
3687
|
-
|
|
3688
|
-
|
|
5033
|
+
float dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
5034
|
+
vec3 dielectricSpecularF0 = min(
|
|
5035
|
+
vec3(dielectricF0) * specularFactor * specularIntensity,
|
|
5036
|
+
vec3(1.0)
|
|
5037
|
+
);
|
|
5038
|
+
vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
5039
|
+
dielectricSpecularF0 = mix(
|
|
5040
|
+
dielectricSpecularF0,
|
|
5041
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
5042
|
+
iridescence
|
|
5043
|
+
);
|
|
5044
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
|
|
5045
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
5046
|
+
vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
5047
|
+
|
|
5048
|
+
float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
5049
|
+
diffuseColor *= baseLayerEnergy;
|
|
5050
|
+
specularColor *= baseLayerEnergy;
|
|
3689
5051
|
|
|
3690
5052
|
// Compute reflectance.
|
|
3691
5053
|
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -3697,11 +5059,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3697
5059
|
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
3698
5060
|
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
3699
5061
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
3700
|
-
|
|
3701
|
-
vec3 n = getNormal(); // normal at surface point
|
|
3702
|
-
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
3703
|
-
|
|
3704
|
-
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
3705
5062
|
vec3 reflection = -normalize(reflect(v, n));
|
|
3706
5063
|
|
|
3707
5064
|
PBRInfo pbrInfo = PBRInfo(
|
|
@@ -3725,13 +5082,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3725
5082
|
#ifdef USE_LIGHTS
|
|
3726
5083
|
// Apply ambient light
|
|
3727
5084
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
3728
|
-
color +=
|
|
5085
|
+
color += calculateMaterialLightColor(
|
|
5086
|
+
pbrInfo,
|
|
5087
|
+
lighting.ambientColor,
|
|
5088
|
+
clearcoatNormal,
|
|
5089
|
+
clearcoatFactor,
|
|
5090
|
+
clearcoatRoughness,
|
|
5091
|
+
sheenColor,
|
|
5092
|
+
sheenRoughness,
|
|
5093
|
+
anisotropyTangent,
|
|
5094
|
+
anisotropyStrength
|
|
5095
|
+
);
|
|
3729
5096
|
|
|
3730
5097
|
// Apply directional light
|
|
3731
5098
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
3732
5099
|
if (i < lighting.directionalLightCount) {
|
|
3733
5100
|
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
3734
|
-
color +=
|
|
5101
|
+
color += calculateMaterialLightColor(
|
|
5102
|
+
pbrInfo,
|
|
5103
|
+
lighting_getDirectionalLight(i).color,
|
|
5104
|
+
clearcoatNormal,
|
|
5105
|
+
clearcoatFactor,
|
|
5106
|
+
clearcoatRoughness,
|
|
5107
|
+
sheenColor,
|
|
5108
|
+
sheenRoughness,
|
|
5109
|
+
anisotropyTangent,
|
|
5110
|
+
anisotropyStrength
|
|
5111
|
+
);
|
|
3735
5112
|
}
|
|
3736
5113
|
}
|
|
3737
5114
|
|
|
@@ -3740,7 +5117,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3740
5117
|
if (i < lighting.pointLightCount) {
|
|
3741
5118
|
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
3742
5119
|
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
3743
|
-
color +=
|
|
5120
|
+
color += calculateMaterialLightColor(
|
|
5121
|
+
pbrInfo,
|
|
5122
|
+
lighting_getPointLight(i).color / attenuation,
|
|
5123
|
+
clearcoatNormal,
|
|
5124
|
+
clearcoatFactor,
|
|
5125
|
+
clearcoatRoughness,
|
|
5126
|
+
sheenColor,
|
|
5127
|
+
sheenRoughness,
|
|
5128
|
+
anisotropyTangent,
|
|
5129
|
+
anisotropyStrength
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
|
|
5134
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
5135
|
+
if (i < lighting.spotLightCount) {
|
|
5136
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
5137
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
5138
|
+
color += calculateMaterialLightColor(
|
|
5139
|
+
pbrInfo,
|
|
5140
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
5141
|
+
clearcoatNormal,
|
|
5142
|
+
clearcoatFactor,
|
|
5143
|
+
clearcoatRoughness,
|
|
5144
|
+
sheenColor,
|
|
5145
|
+
sheenRoughness,
|
|
5146
|
+
anisotropyTangent,
|
|
5147
|
+
anisotropyStrength
|
|
5148
|
+
);
|
|
3744
5149
|
}
|
|
3745
5150
|
}
|
|
3746
5151
|
#endif
|
|
@@ -3748,7 +5153,16 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3748
5153
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
3749
5154
|
#ifdef USE_IBL
|
|
3750
5155
|
if (pbrMaterial.IBLenabled) {
|
|
3751
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
5156
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
5157
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
5158
|
+
color += calculateClearcoatIBLContribution(
|
|
5159
|
+
pbrInfo,
|
|
5160
|
+
clearcoatNormal,
|
|
5161
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
5162
|
+
clearcoatFactor,
|
|
5163
|
+
clearcoatRoughness
|
|
5164
|
+
);
|
|
5165
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
3752
5166
|
}
|
|
3753
5167
|
#endif
|
|
3754
5168
|
|
|
@@ -3760,12 +5174,17 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3760
5174
|
}
|
|
3761
5175
|
#endif
|
|
3762
5176
|
|
|
5177
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
3763
5178
|
#ifdef HAS_EMISSIVEMAP
|
|
3764
5179
|
if (pbrMaterial.emissiveMapEnabled) {
|
|
3765
|
-
|
|
3766
|
-
color += emissive;
|
|
5180
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
3767
5181
|
}
|
|
3768
5182
|
#endif
|
|
5183
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
5184
|
+
|
|
5185
|
+
if (transmission > 0.0) {
|
|
5186
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
5187
|
+
}
|
|
3769
5188
|
|
|
3770
5189
|
// This section uses mix to override final color for reference app visualization
|
|
3771
5190
|
// of various parameters in the lighting equation.
|
|
@@ -3785,7 +5204,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3785
5204
|
|
|
3786
5205
|
}
|
|
3787
5206
|
|
|
3788
|
-
|
|
5207
|
+
float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
5208
|
+
return vec4(pow(color,vec3(1.0/2.2)), alpha);
|
|
3789
5209
|
}
|
|
3790
5210
|
`
|
|
3791
5211
|
);
|
|
@@ -3851,6 +5271,42 @@ struct pbrMaterialUniforms {
|
|
|
3851
5271
|
|
|
3852
5272
|
alphaCutoffEnabled: i32,
|
|
3853
5273
|
alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
|
|
5274
|
+
|
|
5275
|
+
specularColorFactor: vec3f,
|
|
5276
|
+
specularIntensityFactor: f32,
|
|
5277
|
+
specularColorMapEnabled: i32,
|
|
5278
|
+
specularIntensityMapEnabled: i32,
|
|
5279
|
+
|
|
5280
|
+
ior: f32,
|
|
5281
|
+
|
|
5282
|
+
transmissionFactor: f32,
|
|
5283
|
+
transmissionMapEnabled: i32,
|
|
5284
|
+
|
|
5285
|
+
thicknessFactor: f32,
|
|
5286
|
+
attenuationDistance: f32,
|
|
5287
|
+
attenuationColor: vec3f,
|
|
5288
|
+
|
|
5289
|
+
clearcoatFactor: f32,
|
|
5290
|
+
clearcoatRoughnessFactor: f32,
|
|
5291
|
+
clearcoatMapEnabled: i32,
|
|
5292
|
+
clearcoatRoughnessMapEnabled: i32,
|
|
5293
|
+
|
|
5294
|
+
sheenColorFactor: vec3f,
|
|
5295
|
+
sheenRoughnessFactor: f32,
|
|
5296
|
+
sheenColorMapEnabled: i32,
|
|
5297
|
+
sheenRoughnessMapEnabled: i32,
|
|
5298
|
+
|
|
5299
|
+
iridescenceFactor: f32,
|
|
5300
|
+
iridescenceIor: f32,
|
|
5301
|
+
iridescenceThicknessRange: vec2f,
|
|
5302
|
+
iridescenceMapEnabled: i32,
|
|
5303
|
+
|
|
5304
|
+
anisotropyStrength: f32,
|
|
5305
|
+
anisotropyRotation: f32,
|
|
5306
|
+
anisotropyDirection: vec2f,
|
|
5307
|
+
anisotropyMapEnabled: i32,
|
|
5308
|
+
|
|
5309
|
+
emissiveStrength: f32,
|
|
3854
5310
|
|
|
3855
5311
|
// IBL
|
|
3856
5312
|
IBLenabled: i32,
|
|
@@ -3863,38 +5319,77 @@ struct pbrMaterialUniforms {
|
|
|
3863
5319
|
// #endif
|
|
3864
5320
|
}
|
|
3865
5321
|
|
|
3866
|
-
@
|
|
5322
|
+
@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
|
|
3867
5323
|
|
|
3868
5324
|
// Samplers
|
|
3869
5325
|
#ifdef HAS_BASECOLORMAP
|
|
3870
|
-
@
|
|
3871
|
-
@
|
|
5326
|
+
@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
|
|
5327
|
+
@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
|
|
3872
5328
|
#endif
|
|
3873
5329
|
#ifdef HAS_NORMALMAP
|
|
3874
|
-
@
|
|
3875
|
-
@
|
|
5330
|
+
@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
|
|
5331
|
+
@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
|
|
3876
5332
|
#endif
|
|
3877
5333
|
#ifdef HAS_EMISSIVEMAP
|
|
3878
|
-
@
|
|
3879
|
-
@
|
|
5334
|
+
@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
|
|
5335
|
+
@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
|
|
3880
5336
|
#endif
|
|
3881
5337
|
#ifdef HAS_METALROUGHNESSMAP
|
|
3882
|
-
@
|
|
3883
|
-
@
|
|
5338
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
|
|
5339
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
|
|
3884
5340
|
#endif
|
|
3885
5341
|
#ifdef HAS_OCCLUSIONMAP
|
|
3886
|
-
@
|
|
3887
|
-
@
|
|
5342
|
+
@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
|
|
5343
|
+
@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
|
|
3888
5344
|
#endif
|
|
3889
|
-
#ifdef
|
|
3890
|
-
@
|
|
3891
|
-
@
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
@
|
|
3895
|
-
@
|
|
5345
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
5346
|
+
@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
|
|
5347
|
+
@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
|
|
5348
|
+
#endif
|
|
5349
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
5350
|
+
@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
|
|
5351
|
+
@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
|
|
5352
|
+
#endif
|
|
5353
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
5354
|
+
@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
|
|
5355
|
+
@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
|
|
5356
|
+
#endif
|
|
5357
|
+
#ifdef HAS_THICKNESSMAP
|
|
5358
|
+
@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
|
|
5359
|
+
@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
|
|
5360
|
+
#endif
|
|
5361
|
+
#ifdef HAS_CLEARCOATMAP
|
|
5362
|
+
@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
|
|
5363
|
+
@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
|
|
5364
|
+
#endif
|
|
5365
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
5366
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
|
|
5367
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
|
|
5368
|
+
#endif
|
|
5369
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
5370
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
|
|
5371
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
|
|
5372
|
+
#endif
|
|
5373
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
5374
|
+
@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
|
|
5375
|
+
@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
|
|
5376
|
+
#endif
|
|
5377
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
5378
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
|
|
5379
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
|
|
5380
|
+
#endif
|
|
5381
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
5382
|
+
@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
|
|
5383
|
+
@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
|
|
5384
|
+
#endif
|
|
5385
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
5386
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
|
|
5387
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
|
|
5388
|
+
#endif
|
|
5389
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
5390
|
+
@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
|
|
5391
|
+
@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
|
|
3896
5392
|
#endif
|
|
3897
|
-
|
|
3898
5393
|
// Encapsulate the various inputs used by the various functions in the shading equation
|
|
3899
5394
|
// We store values in this struct to simplify the integration of alternative implementations
|
|
3900
5395
|
// of the shading terms, outlined in the Readme.MD Appendix.
|
|
@@ -3935,11 +5430,9 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
|
|
|
3935
5430
|
return vec4f(linOut, srgbIn.w);
|
|
3936
5431
|
}
|
|
3937
5432
|
|
|
3938
|
-
//
|
|
3939
|
-
|
|
3940
|
-
fn getNormal() -> vec3f
|
|
5433
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
5434
|
+
fn getTBN() -> mat3x3f
|
|
3941
5435
|
{
|
|
3942
|
-
// Retrieve the tangent space matrix
|
|
3943
5436
|
let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
|
|
3944
5437
|
let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
|
|
3945
5438
|
let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
|
|
@@ -3957,16 +5450,52 @@ fn getNormal() -> vec3f
|
|
|
3957
5450
|
tbn = fragmentInputs.pbr_vTBN;
|
|
3958
5451
|
#endif
|
|
3959
5452
|
|
|
5453
|
+
return tbn;
|
|
5454
|
+
}
|
|
5455
|
+
|
|
5456
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
5457
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
5458
|
+
fn getMappedNormal(
|
|
5459
|
+
normalSampler: texture_2d<f32>,
|
|
5460
|
+
normalSamplerBinding: sampler,
|
|
5461
|
+
tbn: mat3x3f,
|
|
5462
|
+
normalScale: f32
|
|
5463
|
+
) -> vec3f
|
|
5464
|
+
{
|
|
5465
|
+
let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
|
|
5466
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
fn getNormal(tbn: mat3x3f) -> vec3f
|
|
5470
|
+
{
|
|
3960
5471
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
3961
5472
|
var n: vec3f = normalize(tbn[2].xyz);
|
|
3962
5473
|
#ifdef HAS_NORMALMAP
|
|
3963
|
-
n =
|
|
3964
|
-
|
|
5474
|
+
n = getMappedNormal(
|
|
5475
|
+
pbr_normalSampler,
|
|
5476
|
+
pbr_normalSamplerSampler,
|
|
5477
|
+
tbn,
|
|
5478
|
+
pbrMaterial.normalScale
|
|
5479
|
+
);
|
|
3965
5480
|
#endif
|
|
3966
5481
|
|
|
3967
5482
|
return n;
|
|
3968
5483
|
}
|
|
3969
5484
|
|
|
5485
|
+
fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
|
|
5486
|
+
{
|
|
5487
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
5488
|
+
return getMappedNormal(
|
|
5489
|
+
pbr_clearcoatNormalSampler,
|
|
5490
|
+
pbr_clearcoatNormalSamplerSampler,
|
|
5491
|
+
tbn,
|
|
5492
|
+
1.0
|
|
5493
|
+
);
|
|
5494
|
+
#else
|
|
5495
|
+
return baseNormal;
|
|
5496
|
+
#endif
|
|
5497
|
+
}
|
|
5498
|
+
|
|
3970
5499
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
3971
5500
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
3972
5501
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -3977,17 +5506,25 @@ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
|
|
|
3977
5506
|
let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
|
|
3978
5507
|
// retrieve a scale and bias to F0. See [1], Figure 3
|
|
3979
5508
|
let brdf = SRGBtoLINEAR(
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
|
|
5509
|
+
textureSampleLevel(
|
|
5510
|
+
pbr_brdfLUT,
|
|
5511
|
+
pbr_brdfLUTSampler,
|
|
5512
|
+
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
|
|
5513
|
+
0.0
|
|
3984
5514
|
)
|
|
3985
5515
|
).rgb;
|
|
3986
5516
|
let diffuseLight =
|
|
3987
|
-
SRGBtoLINEAR(
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
var specularLight =
|
|
5517
|
+
SRGBtoLINEAR(
|
|
5518
|
+
textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
|
|
5519
|
+
).rgb;
|
|
5520
|
+
var specularLight = SRGBtoLINEAR(
|
|
5521
|
+
textureSampleLevel(
|
|
5522
|
+
pbr_specularEnvSampler,
|
|
5523
|
+
pbr_specularEnvSamplerSampler,
|
|
5524
|
+
reflection,
|
|
5525
|
+
0.0
|
|
5526
|
+
)
|
|
5527
|
+
).rgb;
|
|
3991
5528
|
#ifdef USE_TEX_LOD
|
|
3992
5529
|
specularLight = SRGBtoLINEAR(
|
|
3993
5530
|
textureSampleLevel(
|
|
@@ -4048,6 +5585,172 @@ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
|
|
|
4048
5585
|
return roughnessSq / (M_PI * f * f);
|
|
4049
5586
|
}
|
|
4050
5587
|
|
|
5588
|
+
fn maxComponent(value: vec3f) -> f32 {
|
|
5589
|
+
return max(max(value.r, value.g), value.b);
|
|
5590
|
+
}
|
|
5591
|
+
|
|
5592
|
+
fn getDielectricF0(ior: f32) -> f32 {
|
|
5593
|
+
let clampedIor = max(ior, 1.0);
|
|
5594
|
+
let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
5595
|
+
return ratio * ratio;
|
|
5596
|
+
}
|
|
5597
|
+
|
|
5598
|
+
fn normalizeDirection(direction: vec2f) -> vec2f {
|
|
5599
|
+
let directionLength = length(direction);
|
|
5600
|
+
if (directionLength > 0.0001) {
|
|
5601
|
+
return direction / directionLength;
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
return vec2f(1.0, 0.0);
|
|
5605
|
+
}
|
|
5606
|
+
|
|
5607
|
+
fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
|
|
5608
|
+
let s = sin(rotation);
|
|
5609
|
+
let c = cos(rotation);
|
|
5610
|
+
return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
5611
|
+
}
|
|
5612
|
+
|
|
5613
|
+
fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
|
|
5614
|
+
if (iridescence <= 0.0) {
|
|
5615
|
+
return vec3f(1.0);
|
|
5616
|
+
}
|
|
5617
|
+
|
|
5618
|
+
let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
5619
|
+
let thinFilmTint =
|
|
5620
|
+
0.5 +
|
|
5621
|
+
0.5 *
|
|
5622
|
+
cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
|
|
5623
|
+
return mix(vec3f(1.0), thinFilmTint, iridescence);
|
|
5624
|
+
}
|
|
5625
|
+
|
|
5626
|
+
fn getVolumeAttenuation(thickness: f32) -> vec3f {
|
|
5627
|
+
if (thickness <= 0.0) {
|
|
5628
|
+
return vec3f(1.0);
|
|
5629
|
+
}
|
|
5630
|
+
|
|
5631
|
+
let attenuationCoefficient =
|
|
5632
|
+
-log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
|
|
5633
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
5634
|
+
return exp(-attenuationCoefficient * thickness);
|
|
5635
|
+
}
|
|
5636
|
+
|
|
5637
|
+
fn createClearcoatPBRInfo(
|
|
5638
|
+
basePBRInfo: PBRInfo,
|
|
5639
|
+
clearcoatNormal: vec3f,
|
|
5640
|
+
clearcoatRoughness: f32
|
|
5641
|
+
) -> PBRInfo {
|
|
5642
|
+
let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
5643
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5644
|
+
let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
5645
|
+
|
|
5646
|
+
return PBRInfo(
|
|
5647
|
+
basePBRInfo.NdotL,
|
|
5648
|
+
NdotV,
|
|
5649
|
+
basePBRInfo.NdotH,
|
|
5650
|
+
basePBRInfo.LdotH,
|
|
5651
|
+
basePBRInfo.VdotH,
|
|
5652
|
+
perceptualRoughness,
|
|
5653
|
+
0.0,
|
|
5654
|
+
vec3f(0.04),
|
|
5655
|
+
vec3f(1.0),
|
|
5656
|
+
alphaRoughness,
|
|
5657
|
+
vec3f(0.0),
|
|
5658
|
+
vec3f(0.04),
|
|
5659
|
+
clearcoatNormal,
|
|
5660
|
+
basePBRInfo.v
|
|
5661
|
+
);
|
|
5662
|
+
}
|
|
5663
|
+
|
|
5664
|
+
fn calculateClearcoatContribution(
|
|
5665
|
+
pbrInfo: PBRInfo,
|
|
5666
|
+
lightColor: vec3f,
|
|
5667
|
+
clearcoatNormal: vec3f,
|
|
5668
|
+
clearcoatFactor: f32,
|
|
5669
|
+
clearcoatRoughness: f32
|
|
5670
|
+
) -> vec3f {
|
|
5671
|
+
if (clearcoatFactor <= 0.0) {
|
|
5672
|
+
return vec3f(0.0);
|
|
5673
|
+
}
|
|
5674
|
+
|
|
5675
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
5676
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
5677
|
+
}
|
|
5678
|
+
|
|
5679
|
+
#ifdef USE_IBL
|
|
5680
|
+
fn calculateClearcoatIBLContribution(
|
|
5681
|
+
pbrInfo: PBRInfo,
|
|
5682
|
+
clearcoatNormal: vec3f,
|
|
5683
|
+
reflection: vec3f,
|
|
5684
|
+
clearcoatFactor: f32,
|
|
5685
|
+
clearcoatRoughness: f32
|
|
5686
|
+
) -> vec3f {
|
|
5687
|
+
if (clearcoatFactor <= 0.0) {
|
|
5688
|
+
return vec3f(0.0);
|
|
5689
|
+
}
|
|
5690
|
+
|
|
5691
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
5692
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
5693
|
+
}
|
|
5694
|
+
#endif
|
|
5695
|
+
|
|
5696
|
+
fn calculateSheenContribution(
|
|
5697
|
+
pbrInfo: PBRInfo,
|
|
5698
|
+
lightColor: vec3f,
|
|
5699
|
+
sheenColor: vec3f,
|
|
5700
|
+
sheenRoughness: f32
|
|
5701
|
+
) -> vec3f {
|
|
5702
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
5703
|
+
return vec3f(0.0);
|
|
5704
|
+
}
|
|
5705
|
+
|
|
5706
|
+
let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
5707
|
+
let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
5708
|
+
return pbrInfo.NdotL *
|
|
5709
|
+
lightColor *
|
|
5710
|
+
sheenColor *
|
|
5711
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
5712
|
+
sheenVisibility *
|
|
5713
|
+
(1.0 - pbrInfo.metalness);
|
|
5714
|
+
}
|
|
5715
|
+
|
|
5716
|
+
fn calculateAnisotropyBoost(
|
|
5717
|
+
pbrInfo: PBRInfo,
|
|
5718
|
+
anisotropyTangent: vec3f,
|
|
5719
|
+
anisotropyStrength: f32
|
|
5720
|
+
) -> f32 {
|
|
5721
|
+
if (anisotropyStrength <= 0.0) {
|
|
5722
|
+
return 1.0;
|
|
5723
|
+
}
|
|
5724
|
+
|
|
5725
|
+
let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
5726
|
+
let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
5727
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
5728
|
+
}
|
|
5729
|
+
|
|
5730
|
+
fn calculateMaterialLightColor(
|
|
5731
|
+
pbrInfo: PBRInfo,
|
|
5732
|
+
lightColor: vec3f,
|
|
5733
|
+
clearcoatNormal: vec3f,
|
|
5734
|
+
clearcoatFactor: f32,
|
|
5735
|
+
clearcoatRoughness: f32,
|
|
5736
|
+
sheenColor: vec3f,
|
|
5737
|
+
sheenRoughness: f32,
|
|
5738
|
+
anisotropyTangent: vec3f,
|
|
5739
|
+
anisotropyStrength: f32
|
|
5740
|
+
) -> vec3f {
|
|
5741
|
+
let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
5742
|
+
var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
5743
|
+
color += calculateClearcoatContribution(
|
|
5744
|
+
pbrInfo,
|
|
5745
|
+
lightColor,
|
|
5746
|
+
clearcoatNormal,
|
|
5747
|
+
clearcoatFactor,
|
|
5748
|
+
clearcoatRoughness
|
|
5749
|
+
);
|
|
5750
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
5751
|
+
return color;
|
|
5752
|
+
}
|
|
5753
|
+
|
|
4051
5754
|
fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
|
|
4052
5755
|
(*pbrInfo).NdotL = 1.0;
|
|
4053
5756
|
(*pbrInfo).NdotH = 0.0;
|
|
@@ -4072,6 +5775,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
|
|
|
4072
5775
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
4073
5776
|
}
|
|
4074
5777
|
|
|
5778
|
+
fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
|
|
5779
|
+
let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
|
|
5780
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
5781
|
+
}
|
|
5782
|
+
|
|
4075
5783
|
fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
|
|
4076
5784
|
// Calculate the shading terms for the microfacet specular shading model
|
|
4077
5785
|
let F = specularReflection(pbrInfo);
|
|
@@ -4101,6 +5809,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4101
5809
|
#endif
|
|
4102
5810
|
|
|
4103
5811
|
var color = vec3<f32>(0.0, 0.0, 0.0);
|
|
5812
|
+
var transmission = 0.0;
|
|
4104
5813
|
|
|
4105
5814
|
if (pbrMaterial.unlit != 0u) {
|
|
4106
5815
|
color = baseColor.rgb;
|
|
@@ -4123,14 +5832,308 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4123
5832
|
#endif
|
|
4124
5833
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
4125
5834
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
5835
|
+
let tbn = getTBN();
|
|
5836
|
+
let n = getNormal(tbn); // normal at surface point
|
|
5837
|
+
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
5838
|
+
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
5839
|
+
var useExtendedPBR = false;
|
|
5840
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
5841
|
+
useExtendedPBR =
|
|
5842
|
+
pbrMaterial.specularColorMapEnabled != 0 ||
|
|
5843
|
+
pbrMaterial.specularIntensityMapEnabled != 0 ||
|
|
5844
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
5845
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
|
|
5846
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
5847
|
+
pbrMaterial.transmissionMapEnabled != 0 ||
|
|
5848
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
5849
|
+
pbrMaterial.clearcoatMapEnabled != 0 ||
|
|
5850
|
+
pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
|
|
5851
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
5852
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
5853
|
+
pbrMaterial.sheenColorMapEnabled != 0 ||
|
|
5854
|
+
pbrMaterial.sheenRoughnessMapEnabled != 0 ||
|
|
5855
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
5856
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
5857
|
+
pbrMaterial.iridescenceMapEnabled != 0 ||
|
|
5858
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
5859
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
5860
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
5861
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
5862
|
+
pbrMaterial.anisotropyMapEnabled != 0 ||
|
|
5863
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
5864
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
5865
|
+
length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
|
|
5866
|
+
#endif
|
|
5867
|
+
|
|
5868
|
+
if (!useExtendedPBR) {
|
|
5869
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5870
|
+
|
|
5871
|
+
let f0 = vec3<f32>(0.04);
|
|
5872
|
+
var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
|
|
5873
|
+
diffuseColor *= 1.0 - metallic;
|
|
5874
|
+
let specularColor = mix(f0, baseColor.rgb, metallic);
|
|
5875
|
+
|
|
5876
|
+
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
5877
|
+
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
5878
|
+
let specularEnvironmentR0 = specularColor;
|
|
5879
|
+
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
5880
|
+
let reflection = -normalize(reflect(v, n));
|
|
5881
|
+
|
|
5882
|
+
var pbrInfo = PBRInfo(
|
|
5883
|
+
0.0, // NdotL
|
|
5884
|
+
NdotV,
|
|
5885
|
+
0.0, // NdotH
|
|
5886
|
+
0.0, // LdotH
|
|
5887
|
+
0.0, // VdotH
|
|
5888
|
+
perceptualRoughness,
|
|
5889
|
+
metallic,
|
|
5890
|
+
specularEnvironmentR0,
|
|
5891
|
+
specularEnvironmentR90,
|
|
5892
|
+
alphaRoughness,
|
|
5893
|
+
diffuseColor,
|
|
5894
|
+
specularColor,
|
|
5895
|
+
n,
|
|
5896
|
+
v
|
|
5897
|
+
);
|
|
5898
|
+
|
|
5899
|
+
#ifdef USE_LIGHTS
|
|
5900
|
+
PBRInfo_setAmbientLight(&pbrInfo);
|
|
5901
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
5902
|
+
|
|
5903
|
+
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
5904
|
+
if (i < lighting.directionalLightCount) {
|
|
5905
|
+
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
5906
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
|
|
5910
|
+
for (var i = 0; i < lighting.pointLightCount; i++) {
|
|
5911
|
+
if (i < lighting.pointLightCount) {
|
|
5912
|
+
PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
|
|
5913
|
+
let attenuation = getPointLightAttenuation(
|
|
5914
|
+
lighting_getPointLight(i),
|
|
5915
|
+
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
5916
|
+
);
|
|
5917
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
5918
|
+
}
|
|
5919
|
+
}
|
|
5920
|
+
|
|
5921
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
5922
|
+
if (i < lighting.spotLightCount) {
|
|
5923
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
5924
|
+
let attenuation = getSpotLightAttenuation(
|
|
5925
|
+
lighting_getSpotLight(i),
|
|
5926
|
+
fragmentInputs.pbr_vPosition
|
|
5927
|
+
);
|
|
5928
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
#endif
|
|
5932
|
+
|
|
5933
|
+
#ifdef USE_IBL
|
|
5934
|
+
if (pbrMaterial.IBLenabled != 0) {
|
|
5935
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
5936
|
+
}
|
|
5937
|
+
#endif
|
|
5938
|
+
|
|
5939
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
5940
|
+
if (pbrMaterial.occlusionMapEnabled != 0) {
|
|
5941
|
+
let ao =
|
|
5942
|
+
textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
|
|
5943
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
5944
|
+
}
|
|
5945
|
+
#endif
|
|
5946
|
+
|
|
5947
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
5948
|
+
#ifdef HAS_EMISSIVEMAP
|
|
5949
|
+
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
5950
|
+
emissive *= SRGBtoLINEAR(
|
|
5951
|
+
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
5952
|
+
).rgb;
|
|
5953
|
+
}
|
|
5954
|
+
#endif
|
|
5955
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
5956
|
+
|
|
5957
|
+
#ifdef PBR_DEBUG
|
|
5958
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
5959
|
+
color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
5960
|
+
color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
5961
|
+
#endif
|
|
5962
|
+
|
|
5963
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
|
|
5964
|
+
}
|
|
5965
|
+
|
|
5966
|
+
var specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
5967
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
5968
|
+
if (pbrMaterial.specularIntensityMapEnabled != 0) {
|
|
5969
|
+
specularIntensity *= textureSample(
|
|
5970
|
+
pbr_specularIntensitySampler,
|
|
5971
|
+
pbr_specularIntensitySamplerSampler,
|
|
5972
|
+
fragmentInputs.pbr_vUV
|
|
5973
|
+
).a;
|
|
5974
|
+
}
|
|
5975
|
+
#endif
|
|
5976
|
+
|
|
5977
|
+
var specularFactor = pbrMaterial.specularColorFactor;
|
|
5978
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
5979
|
+
if (pbrMaterial.specularColorMapEnabled != 0) {
|
|
5980
|
+
specularFactor *= SRGBtoLINEAR(
|
|
5981
|
+
textureSample(
|
|
5982
|
+
pbr_specularColorSampler,
|
|
5983
|
+
pbr_specularColorSamplerSampler,
|
|
5984
|
+
fragmentInputs.pbr_vUV
|
|
5985
|
+
)
|
|
5986
|
+
).rgb;
|
|
5987
|
+
}
|
|
5988
|
+
#endif
|
|
5989
|
+
|
|
5990
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
5991
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
5992
|
+
if (pbrMaterial.transmissionMapEnabled != 0) {
|
|
5993
|
+
transmission *= textureSample(
|
|
5994
|
+
pbr_transmissionSampler,
|
|
5995
|
+
pbr_transmissionSamplerSampler,
|
|
5996
|
+
fragmentInputs.pbr_vUV
|
|
5997
|
+
).r;
|
|
5998
|
+
}
|
|
5999
|
+
#endif
|
|
6000
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
6001
|
+
var thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
6002
|
+
#ifdef HAS_THICKNESSMAP
|
|
6003
|
+
thickness *= textureSample(
|
|
6004
|
+
pbr_thicknessSampler,
|
|
6005
|
+
pbr_thicknessSamplerSampler,
|
|
6006
|
+
fragmentInputs.pbr_vUV
|
|
6007
|
+
).g;
|
|
6008
|
+
#endif
|
|
6009
|
+
|
|
6010
|
+
var clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
6011
|
+
var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
6012
|
+
#ifdef HAS_CLEARCOATMAP
|
|
6013
|
+
if (pbrMaterial.clearcoatMapEnabled != 0) {
|
|
6014
|
+
clearcoatFactor *= textureSample(
|
|
6015
|
+
pbr_clearcoatSampler,
|
|
6016
|
+
pbr_clearcoatSamplerSampler,
|
|
6017
|
+
fragmentInputs.pbr_vUV
|
|
6018
|
+
).r;
|
|
6019
|
+
}
|
|
6020
|
+
#endif
|
|
6021
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
6022
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
|
|
6023
|
+
clearcoatRoughness *= textureSample(
|
|
6024
|
+
pbr_clearcoatRoughnessSampler,
|
|
6025
|
+
pbr_clearcoatRoughnessSamplerSampler,
|
|
6026
|
+
fragmentInputs.pbr_vUV
|
|
6027
|
+
).g;
|
|
6028
|
+
}
|
|
6029
|
+
#endif
|
|
6030
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
6031
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
6032
|
+
let clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
6033
|
+
|
|
6034
|
+
var sheenColor = pbrMaterial.sheenColorFactor;
|
|
6035
|
+
var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
6036
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
6037
|
+
if (pbrMaterial.sheenColorMapEnabled != 0) {
|
|
6038
|
+
sheenColor *= SRGBtoLINEAR(
|
|
6039
|
+
textureSample(
|
|
6040
|
+
pbr_sheenColorSampler,
|
|
6041
|
+
pbr_sheenColorSamplerSampler,
|
|
6042
|
+
fragmentInputs.pbr_vUV
|
|
6043
|
+
)
|
|
6044
|
+
).rgb;
|
|
6045
|
+
}
|
|
6046
|
+
#endif
|
|
6047
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
6048
|
+
if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
|
|
6049
|
+
sheenRoughness *= textureSample(
|
|
6050
|
+
pbr_sheenRoughnessSampler,
|
|
6051
|
+
pbr_sheenRoughnessSamplerSampler,
|
|
6052
|
+
fragmentInputs.pbr_vUV
|
|
6053
|
+
).a;
|
|
6054
|
+
}
|
|
6055
|
+
#endif
|
|
6056
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
6057
|
+
|
|
6058
|
+
var iridescence = pbrMaterial.iridescenceFactor;
|
|
6059
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
6060
|
+
if (pbrMaterial.iridescenceMapEnabled != 0) {
|
|
6061
|
+
iridescence *= textureSample(
|
|
6062
|
+
pbr_iridescenceSampler,
|
|
6063
|
+
pbr_iridescenceSamplerSampler,
|
|
6064
|
+
fragmentInputs.pbr_vUV
|
|
6065
|
+
).r;
|
|
6066
|
+
}
|
|
6067
|
+
#endif
|
|
6068
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
6069
|
+
var iridescenceThickness = mix(
|
|
6070
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6071
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6072
|
+
0.5
|
|
6073
|
+
);
|
|
6074
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
6075
|
+
iridescenceThickness = mix(
|
|
6076
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6077
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6078
|
+
textureSample(
|
|
6079
|
+
pbr_iridescenceThicknessSampler,
|
|
6080
|
+
pbr_iridescenceThicknessSamplerSampler,
|
|
6081
|
+
fragmentInputs.pbr_vUV
|
|
6082
|
+
).g
|
|
6083
|
+
);
|
|
6084
|
+
#endif
|
|
6085
|
+
|
|
6086
|
+
var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
6087
|
+
var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
6088
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
6089
|
+
if (pbrMaterial.anisotropyMapEnabled != 0) {
|
|
6090
|
+
let anisotropySample = textureSample(
|
|
6091
|
+
pbr_anisotropySampler,
|
|
6092
|
+
pbr_anisotropySamplerSampler,
|
|
6093
|
+
fragmentInputs.pbr_vUV
|
|
6094
|
+
).rgb;
|
|
6095
|
+
anisotropyStrength *= anisotropySample.b;
|
|
6096
|
+
let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
6097
|
+
if (length(mappedDirection) > 0.0001) {
|
|
6098
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
6099
|
+
}
|
|
6100
|
+
}
|
|
6101
|
+
#endif
|
|
6102
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
6103
|
+
var anisotropyTangent =
|
|
6104
|
+
normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
6105
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
6106
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
6107
|
+
}
|
|
6108
|
+
let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
6109
|
+
perceptualRoughness = mix(
|
|
6110
|
+
perceptualRoughness,
|
|
6111
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
6112
|
+
anisotropyStrength
|
|
6113
|
+
);
|
|
6114
|
+
|
|
4126
6115
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
4127
6116
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
4128
6117
|
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
4129
6118
|
|
|
4130
|
-
let
|
|
4131
|
-
var
|
|
4132
|
-
|
|
4133
|
-
|
|
6119
|
+
let dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
6120
|
+
var dielectricSpecularF0 = min(
|
|
6121
|
+
vec3f(dielectricF0) * specularFactor * specularIntensity,
|
|
6122
|
+
vec3f(1.0)
|
|
6123
|
+
);
|
|
6124
|
+
let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
6125
|
+
dielectricSpecularF0 = mix(
|
|
6126
|
+
dielectricSpecularF0,
|
|
6127
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
6128
|
+
iridescence
|
|
6129
|
+
);
|
|
6130
|
+
var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
|
|
6131
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
6132
|
+
var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
6133
|
+
|
|
6134
|
+
let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
6135
|
+
diffuseColor *= baseLayerEnergy;
|
|
6136
|
+
specularColor *= baseLayerEnergy;
|
|
4134
6137
|
|
|
4135
6138
|
// Compute reflectance.
|
|
4136
6139
|
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -4142,11 +6145,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4142
6145
|
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
4143
6146
|
let specularEnvironmentR0 = specularColor;
|
|
4144
6147
|
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
4145
|
-
|
|
4146
|
-
let n = getNormal(); // normal at surface point
|
|
4147
|
-
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
4148
|
-
|
|
4149
|
-
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
4150
6148
|
let reflection = -normalize(reflect(v, n));
|
|
4151
6149
|
|
|
4152
6150
|
var pbrInfo = PBRInfo(
|
|
@@ -4169,13 +6167,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4169
6167
|
#ifdef USE_LIGHTS
|
|
4170
6168
|
// Apply ambient light
|
|
4171
6169
|
PBRInfo_setAmbientLight(&pbrInfo);
|
|
4172
|
-
color +=
|
|
6170
|
+
color += calculateMaterialLightColor(
|
|
6171
|
+
pbrInfo,
|
|
6172
|
+
lighting.ambientColor,
|
|
6173
|
+
clearcoatNormal,
|
|
6174
|
+
clearcoatFactor,
|
|
6175
|
+
clearcoatRoughness,
|
|
6176
|
+
sheenColor,
|
|
6177
|
+
sheenRoughness,
|
|
6178
|
+
anisotropyTangent,
|
|
6179
|
+
anisotropyStrength
|
|
6180
|
+
);
|
|
4173
6181
|
|
|
4174
6182
|
// Apply directional light
|
|
4175
6183
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
4176
6184
|
if (i < lighting.directionalLightCount) {
|
|
4177
6185
|
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
4178
|
-
color +=
|
|
6186
|
+
color += calculateMaterialLightColor(
|
|
6187
|
+
pbrInfo,
|
|
6188
|
+
lighting_getDirectionalLight(i).color,
|
|
6189
|
+
clearcoatNormal,
|
|
6190
|
+
clearcoatFactor,
|
|
6191
|
+
clearcoatRoughness,
|
|
6192
|
+
sheenColor,
|
|
6193
|
+
sheenRoughness,
|
|
6194
|
+
anisotropyTangent,
|
|
6195
|
+
anisotropyStrength
|
|
6196
|
+
);
|
|
4179
6197
|
}
|
|
4180
6198
|
}
|
|
4181
6199
|
|
|
@@ -4187,7 +6205,35 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4187
6205
|
lighting_getPointLight(i),
|
|
4188
6206
|
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
4189
6207
|
);
|
|
4190
|
-
color +=
|
|
6208
|
+
color += calculateMaterialLightColor(
|
|
6209
|
+
pbrInfo,
|
|
6210
|
+
lighting_getPointLight(i).color / attenuation,
|
|
6211
|
+
clearcoatNormal,
|
|
6212
|
+
clearcoatFactor,
|
|
6213
|
+
clearcoatRoughness,
|
|
6214
|
+
sheenColor,
|
|
6215
|
+
sheenRoughness,
|
|
6216
|
+
anisotropyTangent,
|
|
6217
|
+
anisotropyStrength
|
|
6218
|
+
);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
|
|
6222
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
6223
|
+
if (i < lighting.spotLightCount) {
|
|
6224
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
6225
|
+
let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
|
|
6226
|
+
color += calculateMaterialLightColor(
|
|
6227
|
+
pbrInfo,
|
|
6228
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
6229
|
+
clearcoatNormal,
|
|
6230
|
+
clearcoatFactor,
|
|
6231
|
+
clearcoatRoughness,
|
|
6232
|
+
sheenColor,
|
|
6233
|
+
sheenRoughness,
|
|
6234
|
+
anisotropyTangent,
|
|
6235
|
+
anisotropyStrength
|
|
6236
|
+
);
|
|
4191
6237
|
}
|
|
4192
6238
|
}
|
|
4193
6239
|
#endif
|
|
@@ -4195,7 +6241,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4195
6241
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
4196
6242
|
#ifdef USE_IBL
|
|
4197
6243
|
if (pbrMaterial.IBLenabled != 0) {
|
|
4198
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
6244
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
6245
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
6246
|
+
color += calculateClearcoatIBLContribution(
|
|
6247
|
+
pbrInfo,
|
|
6248
|
+
clearcoatNormal,
|
|
6249
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
6250
|
+
clearcoatFactor,
|
|
6251
|
+
clearcoatRoughness
|
|
6252
|
+
);
|
|
6253
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
4199
6254
|
}
|
|
4200
6255
|
#endif
|
|
4201
6256
|
|
|
@@ -4208,14 +6263,19 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4208
6263
|
}
|
|
4209
6264
|
#endif
|
|
4210
6265
|
|
|
6266
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
4211
6267
|
#ifdef HAS_EMISSIVEMAP
|
|
4212
6268
|
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
4213
|
-
|
|
6269
|
+
emissive *= SRGBtoLINEAR(
|
|
4214
6270
|
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
4215
|
-
).rgb
|
|
4216
|
-
color += emissive;
|
|
6271
|
+
).rgb;
|
|
4217
6272
|
}
|
|
4218
6273
|
#endif
|
|
6274
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
6275
|
+
|
|
6276
|
+
if (transmission > 0.0) {
|
|
6277
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
6278
|
+
}
|
|
4219
6279
|
|
|
4220
6280
|
// This section uses mix to override final color for reference app visualization
|
|
4221
6281
|
// of various parameters in the lighting equation.
|
|
@@ -4234,7 +6294,8 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
4234
6294
|
#endif
|
|
4235
6295
|
}
|
|
4236
6296
|
|
|
4237
|
-
|
|
6297
|
+
let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
6298
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
|
|
4238
6299
|
}
|
|
4239
6300
|
`
|
|
4240
6301
|
);
|
|
@@ -4259,11 +6320,12 @@ var wgslUniformBlock = (
|
|
|
4259
6320
|
camera: vec3<f32>
|
|
4260
6321
|
};
|
|
4261
6322
|
|
|
4262
|
-
@
|
|
6323
|
+
@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
|
|
4263
6324
|
`
|
|
4264
6325
|
);
|
|
4265
6326
|
var pbrProjection = {
|
|
4266
6327
|
name: "pbrProjection",
|
|
6328
|
+
bindingLayout: [{ name: "pbrProjection", group: 0 }],
|
|
4267
6329
|
source: wgslUniformBlock,
|
|
4268
6330
|
vs: uniformBlock,
|
|
4269
6331
|
fs: uniformBlock,
|
|
@@ -4281,8 +6343,75 @@ var pbrProjection = {
|
|
|
4281
6343
|
var pbrMaterial = {
|
|
4282
6344
|
props: {},
|
|
4283
6345
|
uniforms: {},
|
|
6346
|
+
defaultUniforms: {
|
|
6347
|
+
unlit: false,
|
|
6348
|
+
baseColorMapEnabled: false,
|
|
6349
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
6350
|
+
normalMapEnabled: false,
|
|
6351
|
+
normalScale: 1,
|
|
6352
|
+
emissiveMapEnabled: false,
|
|
6353
|
+
emissiveFactor: [0, 0, 0],
|
|
6354
|
+
metallicRoughnessValues: [1, 1],
|
|
6355
|
+
metallicRoughnessMapEnabled: false,
|
|
6356
|
+
occlusionMapEnabled: false,
|
|
6357
|
+
occlusionStrength: 1,
|
|
6358
|
+
alphaCutoffEnabled: false,
|
|
6359
|
+
alphaCutoff: 0.5,
|
|
6360
|
+
IBLenabled: false,
|
|
6361
|
+
scaleIBLAmbient: [1, 1],
|
|
6362
|
+
scaleDiffBaseMR: [0, 0, 0, 0],
|
|
6363
|
+
scaleFGDSpec: [0, 0, 0, 0],
|
|
6364
|
+
specularColorFactor: [1, 1, 1],
|
|
6365
|
+
specularIntensityFactor: 1,
|
|
6366
|
+
specularColorMapEnabled: false,
|
|
6367
|
+
specularIntensityMapEnabled: false,
|
|
6368
|
+
ior: 1.5,
|
|
6369
|
+
transmissionFactor: 0,
|
|
6370
|
+
transmissionMapEnabled: false,
|
|
6371
|
+
thicknessFactor: 0,
|
|
6372
|
+
attenuationDistance: 1e9,
|
|
6373
|
+
attenuationColor: [1, 1, 1],
|
|
6374
|
+
clearcoatFactor: 0,
|
|
6375
|
+
clearcoatRoughnessFactor: 0,
|
|
6376
|
+
clearcoatMapEnabled: false,
|
|
6377
|
+
clearcoatRoughnessMapEnabled: false,
|
|
6378
|
+
sheenColorFactor: [0, 0, 0],
|
|
6379
|
+
sheenRoughnessFactor: 0,
|
|
6380
|
+
sheenColorMapEnabled: false,
|
|
6381
|
+
sheenRoughnessMapEnabled: false,
|
|
6382
|
+
iridescenceFactor: 0,
|
|
6383
|
+
iridescenceIor: 1.3,
|
|
6384
|
+
iridescenceThicknessRange: [100, 400],
|
|
6385
|
+
iridescenceMapEnabled: false,
|
|
6386
|
+
anisotropyStrength: 0,
|
|
6387
|
+
anisotropyRotation: 0,
|
|
6388
|
+
anisotropyDirection: [1, 0],
|
|
6389
|
+
anisotropyMapEnabled: false,
|
|
6390
|
+
emissiveStrength: 1
|
|
6391
|
+
},
|
|
4284
6392
|
name: "pbrMaterial",
|
|
4285
|
-
|
|
6393
|
+
firstBindingSlot: 0,
|
|
6394
|
+
bindingLayout: [
|
|
6395
|
+
{ name: "pbrMaterial", group: 3 },
|
|
6396
|
+
{ name: "pbr_baseColorSampler", group: 3 },
|
|
6397
|
+
{ name: "pbr_normalSampler", group: 3 },
|
|
6398
|
+
{ name: "pbr_emissiveSampler", group: 3 },
|
|
6399
|
+
{ name: "pbr_metallicRoughnessSampler", group: 3 },
|
|
6400
|
+
{ name: "pbr_occlusionSampler", group: 3 },
|
|
6401
|
+
{ name: "pbr_specularColorSampler", group: 3 },
|
|
6402
|
+
{ name: "pbr_specularIntensitySampler", group: 3 },
|
|
6403
|
+
{ name: "pbr_transmissionSampler", group: 3 },
|
|
6404
|
+
{ name: "pbr_thicknessSampler", group: 3 },
|
|
6405
|
+
{ name: "pbr_clearcoatSampler", group: 3 },
|
|
6406
|
+
{ name: "pbr_clearcoatRoughnessSampler", group: 3 },
|
|
6407
|
+
{ name: "pbr_clearcoatNormalSampler", group: 3 },
|
|
6408
|
+
{ name: "pbr_sheenColorSampler", group: 3 },
|
|
6409
|
+
{ name: "pbr_sheenRoughnessSampler", group: 3 },
|
|
6410
|
+
{ name: "pbr_iridescenceSampler", group: 3 },
|
|
6411
|
+
{ name: "pbr_iridescenceThicknessSampler", group: 3 },
|
|
6412
|
+
{ name: "pbr_anisotropySampler", group: 3 }
|
|
6413
|
+
],
|
|
6414
|
+
dependencies: [lighting, ibl, pbrProjection],
|
|
4286
6415
|
source: source3,
|
|
4287
6416
|
vs: vs3,
|
|
4288
6417
|
fs: fs4,
|
|
@@ -4296,10 +6425,16 @@ var pbrMaterial = {
|
|
|
4296
6425
|
HAS_SPECULARCOLORMAP: false,
|
|
4297
6426
|
HAS_SPECULARINTENSITYMAP: false,
|
|
4298
6427
|
HAS_TRANSMISSIONMAP: false,
|
|
6428
|
+
HAS_THICKNESSMAP: false,
|
|
4299
6429
|
HAS_CLEARCOATMAP: false,
|
|
6430
|
+
HAS_CLEARCOATROUGHNESSMAP: false,
|
|
6431
|
+
HAS_CLEARCOATNORMALMAP: false,
|
|
4300
6432
|
HAS_SHEENCOLORMAP: false,
|
|
6433
|
+
HAS_SHEENROUGHNESSMAP: false,
|
|
4301
6434
|
HAS_IRIDESCENCEMAP: false,
|
|
6435
|
+
HAS_IRIDESCENCETHICKNESSMAP: false,
|
|
4302
6436
|
HAS_ANISOTROPYMAP: false,
|
|
6437
|
+
USE_MATERIAL_EXTENSIONS: false,
|
|
4303
6438
|
ALPHA_CUTOFF: false,
|
|
4304
6439
|
USE_IBL: false,
|
|
4305
6440
|
PBR_DEBUG: false
|
|
@@ -4325,14 +6460,6 @@ var pbrMaterial = {
|
|
|
4325
6460
|
alphaCutoffEnabled: "i32",
|
|
4326
6461
|
alphaCutoff: "f32",
|
|
4327
6462
|
// #ifdef ALPHA_CUTOFF
|
|
4328
|
-
// IBL
|
|
4329
|
-
IBLenabled: "i32",
|
|
4330
|
-
scaleIBLAmbient: "vec2<f32>",
|
|
4331
|
-
// #ifdef USE_IBL
|
|
4332
|
-
// debugging flags used for shader output of intermediate PBR variables
|
|
4333
|
-
// #ifdef PBR_DEBUG
|
|
4334
|
-
scaleDiffBaseMR: "vec4<f32>",
|
|
4335
|
-
scaleFGDSpec: "vec4<f32>",
|
|
4336
6463
|
specularColorFactor: "vec3<f32>",
|
|
4337
6464
|
specularIntensityFactor: "f32",
|
|
4338
6465
|
specularColorMapEnabled: "i32",
|
|
@@ -4346,9 +6473,11 @@ var pbrMaterial = {
|
|
|
4346
6473
|
clearcoatFactor: "f32",
|
|
4347
6474
|
clearcoatRoughnessFactor: "f32",
|
|
4348
6475
|
clearcoatMapEnabled: "i32",
|
|
6476
|
+
clearcoatRoughnessMapEnabled: "i32",
|
|
4349
6477
|
sheenColorFactor: "vec3<f32>",
|
|
4350
6478
|
sheenRoughnessFactor: "f32",
|
|
4351
6479
|
sheenColorMapEnabled: "i32",
|
|
6480
|
+
sheenRoughnessMapEnabled: "i32",
|
|
4352
6481
|
iridescenceFactor: "f32",
|
|
4353
6482
|
iridescenceIor: "f32",
|
|
4354
6483
|
iridescenceThicknessRange: "vec2<f32>",
|
|
@@ -4357,7 +6486,15 @@ var pbrMaterial = {
|
|
|
4357
6486
|
anisotropyRotation: "f32",
|
|
4358
6487
|
anisotropyDirection: "vec2<f32>",
|
|
4359
6488
|
anisotropyMapEnabled: "i32",
|
|
4360
|
-
emissiveStrength: "f32"
|
|
6489
|
+
emissiveStrength: "f32",
|
|
6490
|
+
// IBL
|
|
6491
|
+
IBLenabled: "i32",
|
|
6492
|
+
scaleIBLAmbient: "vec2<f32>",
|
|
6493
|
+
// #ifdef USE_IBL
|
|
6494
|
+
// debugging flags used for shader output of intermediate PBR variables
|
|
6495
|
+
// #ifdef PBR_DEBUG
|
|
6496
|
+
scaleDiffBaseMR: "vec4<f32>",
|
|
6497
|
+
scaleFGDSpec: "vec4<f32>"
|
|
4361
6498
|
}
|
|
4362
6499
|
};
|
|
4363
6500
|
//# sourceMappingURL=index.cjs.map
|