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