@luma.gl/shadertools 9.3.0-alpha.4 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +4657 -523
- package/dist/dist.min.js +1952 -301
- package/dist/index.cjs +2804 -406
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +35 -8
- 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 +20 -3
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js +112 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +12 -6
- 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 +30 -0
- package/dist/modules/engine/skin/skin.d.ts.map +1 -0
- package/dist/modules/engine/skin/skin.js +86 -0
- package/dist/modules/engine/skin/skin.js.map +1 -0
- 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 -37
- 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 +46 -18
- package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +104 -62
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +107 -68
- 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 +784 -101
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -45
- 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 +13 -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 -40
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +71 -76
- 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/dist/modules/math/random/random.d.ts +1 -1
- package/dist/modules/math/random/random.d.ts.map +1 -1
- package/dist/modules/math/random/random.js +2 -3
- package/dist/modules/math/random/random.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +20 -2
- package/src/lib/preprocessor/preprocessor.ts +44 -8
- package/src/lib/shader-assembler.ts +25 -3
- package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
- package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
- package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
- package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
- package/src/lib/shader-module/shader-module-uniform-layout.ts +194 -0
- package/src/lib/shader-module/shader-module.ts +17 -7
- 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 +114 -0
- 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 -37
- package/src/modules/lighting/lights/lighting-wgsl.ts +46 -18
- package/src/modules/lighting/lights/lighting.ts +198 -99
- 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 +784 -101
- package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
- package/src/modules/lighting/pbr-material/pbr-projection.ts +14 -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 +71 -77
- 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/src/modules/math/random/random.ts +2 -3
package/dist/index.cjs
CHANGED
|
@@ -47,19 +47,26 @@ __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,
|
|
57
62
|
picking: () => picking,
|
|
58
63
|
preprocess: () => preprocess,
|
|
59
64
|
random: () => random,
|
|
65
|
+
skin: () => skin,
|
|
60
66
|
toHalfFloat: () => toHalfFloat,
|
|
61
67
|
typeToChannelCount: () => typeToChannelCount,
|
|
62
|
-
typeToChannelSuffix: () => typeToChannelSuffix
|
|
68
|
+
typeToChannelSuffix: () => typeToChannelSuffix,
|
|
69
|
+
validateShaderModuleUniformLayout: () => validateShaderModuleUniformLayout
|
|
63
70
|
});
|
|
64
71
|
module.exports = __toCommonJS(dist_exports);
|
|
65
72
|
|
|
@@ -204,7 +211,7 @@ function getHookStage(hook) {
|
|
|
204
211
|
throw new Error(type);
|
|
205
212
|
}
|
|
206
213
|
}
|
|
207
|
-
function injectShader(
|
|
214
|
+
function injectShader(source4, stage, inject, injectStandardStubs = false) {
|
|
208
215
|
const isVertex = stage === "vertex";
|
|
209
216
|
for (const key in inject) {
|
|
210
217
|
const fragmentData = inject[key];
|
|
@@ -218,43 +225,43 @@ function injectShader(source3, stage, inject, injectStandardStubs = false) {
|
|
|
218
225
|
switch (key) {
|
|
219
226
|
case "vs:#decl":
|
|
220
227
|
if (isVertex) {
|
|
221
|
-
|
|
228
|
+
source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
|
|
222
229
|
}
|
|
223
230
|
break;
|
|
224
231
|
case "vs:#main-start":
|
|
225
232
|
if (isVertex) {
|
|
226
|
-
|
|
233
|
+
source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
|
|
227
234
|
}
|
|
228
235
|
break;
|
|
229
236
|
case "vs:#main-end":
|
|
230
237
|
if (isVertex) {
|
|
231
|
-
|
|
238
|
+
source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
|
|
232
239
|
}
|
|
233
240
|
break;
|
|
234
241
|
case "fs:#decl":
|
|
235
242
|
if (!isVertex) {
|
|
236
|
-
|
|
243
|
+
source4 = source4.replace(DECLARATION_INJECT_MARKER, fragmentString);
|
|
237
244
|
}
|
|
238
245
|
break;
|
|
239
246
|
case "fs:#main-start":
|
|
240
247
|
if (!isVertex) {
|
|
241
|
-
|
|
248
|
+
source4 = source4.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString);
|
|
242
249
|
}
|
|
243
250
|
break;
|
|
244
251
|
case "fs:#main-end":
|
|
245
252
|
if (!isVertex) {
|
|
246
|
-
|
|
253
|
+
source4 = source4.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match);
|
|
247
254
|
}
|
|
248
255
|
break;
|
|
249
256
|
default:
|
|
250
|
-
|
|
257
|
+
source4 = source4.replace(key, (match) => match + fragmentString);
|
|
251
258
|
}
|
|
252
259
|
}
|
|
253
|
-
|
|
260
|
+
source4 = source4.replace(DECLARATION_INJECT_MARKER, "");
|
|
254
261
|
if (injectStandardStubs) {
|
|
255
|
-
|
|
262
|
+
source4 = source4.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]);
|
|
256
263
|
}
|
|
257
|
-
return
|
|
264
|
+
return source4;
|
|
258
265
|
}
|
|
259
266
|
function combineInjects(injects) {
|
|
260
267
|
const result = {};
|
|
@@ -378,6 +385,114 @@ function resolveModules(modules) {
|
|
|
378
385
|
return getShaderDependencies(modules);
|
|
379
386
|
}
|
|
380
387
|
|
|
388
|
+
// dist/lib/shader-module/shader-module-uniform-layout.js
|
|
389
|
+
function getShaderModuleUniformBlockName(module2) {
|
|
390
|
+
return `${module2.name}Uniforms`;
|
|
391
|
+
}
|
|
392
|
+
function getShaderModuleUniformBlockFields(module2, stage) {
|
|
393
|
+
const shaderSource = stage === "wgsl" ? module2.source : stage === "vertex" ? module2.vs : module2.fs;
|
|
394
|
+
if (!shaderSource) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
const uniformBlockName = getShaderModuleUniformBlockName(module2);
|
|
398
|
+
return extractShaderUniformBlockFieldNames(shaderSource, stage === "wgsl" ? "wgsl" : "glsl", uniformBlockName);
|
|
399
|
+
}
|
|
400
|
+
function getShaderModuleUniformLayoutValidationResult(module2, stage) {
|
|
401
|
+
const expectedUniformNames = Object.keys(module2.uniformTypes || {});
|
|
402
|
+
if (!expectedUniformNames.length) {
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
const actualUniformNames = getShaderModuleUniformBlockFields(module2, stage);
|
|
406
|
+
if (!actualUniformNames) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
moduleName: module2.name,
|
|
411
|
+
uniformBlockName: getShaderModuleUniformBlockName(module2),
|
|
412
|
+
stage,
|
|
413
|
+
expectedUniformNames,
|
|
414
|
+
actualUniformNames,
|
|
415
|
+
matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function validateShaderModuleUniformLayout(module2, stage, options = {}) {
|
|
419
|
+
var _a, _b;
|
|
420
|
+
const validationResult = getShaderModuleUniformLayoutValidationResult(module2, stage);
|
|
421
|
+
if (!validationResult || validationResult.matches) {
|
|
422
|
+
return validationResult;
|
|
423
|
+
}
|
|
424
|
+
const message = formatShaderModuleUniformLayoutError(validationResult);
|
|
425
|
+
(_b = (_a = options.log) == null ? void 0 : _a.error) == null ? void 0 : _b.call(_a, message, validationResult)();
|
|
426
|
+
if (options.throwOnError !== false) {
|
|
427
|
+
assert(false, message);
|
|
428
|
+
}
|
|
429
|
+
return validationResult;
|
|
430
|
+
}
|
|
431
|
+
function extractShaderUniformBlockFieldNames(shaderSource, language, uniformBlockName) {
|
|
432
|
+
const sourceBody = language === "wgsl" ? extractWGSLStructBody(shaderSource, uniformBlockName) : extractGLSLUniformBlockBody(shaderSource, uniformBlockName);
|
|
433
|
+
if (!sourceBody) {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
const fieldNames = [];
|
|
437
|
+
for (const sourceLine of sourceBody.split("\n")) {
|
|
438
|
+
const line = sourceLine.replace(/\/\/.*$/, "").trim();
|
|
439
|
+
if (!line || line.startsWith("#")) {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const fieldMatch = language === "wgsl" ? line.match(/^([A-Za-z0-9_]+)\s*:/) : line.match(/^(?:uniform\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/);
|
|
443
|
+
if (fieldMatch) {
|
|
444
|
+
fieldNames.push(fieldMatch[1]);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return fieldNames;
|
|
448
|
+
}
|
|
449
|
+
function extractWGSLStructBody(shaderSource, uniformBlockName) {
|
|
450
|
+
const structMatch = new RegExp(`\\bstruct\\s+${uniformBlockName}\\b`, "m").exec(shaderSource);
|
|
451
|
+
if (!structMatch) {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
const openBraceIndex = shaderSource.indexOf("{", structMatch.index);
|
|
455
|
+
if (openBraceIndex < 0) {
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
let braceDepth = 0;
|
|
459
|
+
for (let index = openBraceIndex; index < shaderSource.length; index++) {
|
|
460
|
+
const character = shaderSource[index];
|
|
461
|
+
if (character === "{") {
|
|
462
|
+
braceDepth++;
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
if (character !== "}") {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
braceDepth--;
|
|
469
|
+
if (braceDepth === 0) {
|
|
470
|
+
return shaderSource.slice(openBraceIndex + 1, index);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
function extractGLSLUniformBlockBody(shaderSource, uniformBlockName) {
|
|
476
|
+
const sourceMatch = shaderSource.match(new RegExp(`uniform\\s+${uniformBlockName}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`, "m"));
|
|
477
|
+
return (sourceMatch == null ? void 0 : sourceMatch[1]) || null;
|
|
478
|
+
}
|
|
479
|
+
function areStringArraysEqual(leftValues, rightValues) {
|
|
480
|
+
if (leftValues.length !== rightValues.length) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {
|
|
484
|
+
if (leftValues[valueIndex] !== rightValues[valueIndex]) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
function formatShaderModuleUniformLayoutError(validationResult) {
|
|
491
|
+
return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${validationResult.uniformBlockName} does not match module.uniformTypes.
|
|
492
|
+
Expected: ${validationResult.expectedUniformNames.join(", ")}
|
|
493
|
+
Actual: ${validationResult.actualUniformNames.join(", ")}`;
|
|
494
|
+
}
|
|
495
|
+
|
|
381
496
|
// dist/lib/shader-assembly/platform-defines.js
|
|
382
497
|
function getPlatformShaderDefines(platformInfo) {
|
|
383
498
|
switch (platformInfo == null ? void 0 : platformInfo.gpu.toLowerCase()) {
|
|
@@ -434,19 +549,19 @@ function getPlatformShaderDefines(platformInfo) {
|
|
|
434
549
|
}
|
|
435
550
|
|
|
436
551
|
// dist/lib/shader-transpiler/transpile-glsl-shader.js
|
|
437
|
-
function transpileGLSLShader(
|
|
552
|
+
function transpileGLSLShader(source4, stage) {
|
|
438
553
|
var _a;
|
|
439
|
-
const sourceGLSLVersion = Number(((_a =
|
|
554
|
+
const sourceGLSLVersion = Number(((_a = source4.match(/^#version[ \t]+(\d+)/m)) == null ? void 0 : _a[1]) || 100);
|
|
440
555
|
if (sourceGLSLVersion !== 300) {
|
|
441
556
|
throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");
|
|
442
557
|
}
|
|
443
558
|
switch (stage) {
|
|
444
559
|
case "vertex":
|
|
445
|
-
|
|
446
|
-
return
|
|
560
|
+
source4 = convertShader(source4, ES300_VERTEX_REPLACEMENTS);
|
|
561
|
+
return source4;
|
|
447
562
|
case "fragment":
|
|
448
|
-
|
|
449
|
-
return
|
|
563
|
+
source4 = convertShader(source4, ES300_FRAGMENT_REPLACEMENTS);
|
|
564
|
+
return source4;
|
|
450
565
|
default:
|
|
451
566
|
throw new Error(stage);
|
|
452
567
|
}
|
|
@@ -470,11 +585,11 @@ var ES300_FRAGMENT_REPLACEMENTS = [
|
|
|
470
585
|
// `varying` keyword replaced with `in`
|
|
471
586
|
[makeVariableTextRegExp("varying"), "in $1"]
|
|
472
587
|
];
|
|
473
|
-
function convertShader(
|
|
588
|
+
function convertShader(source4, replacements) {
|
|
474
589
|
for (const [pattern, replacement] of replacements) {
|
|
475
|
-
|
|
590
|
+
source4 = source4.replace(pattern, replacement);
|
|
476
591
|
}
|
|
477
|
-
return
|
|
592
|
+
return source4;
|
|
478
593
|
}
|
|
479
594
|
function makeVariableTextRegExp(qualifier) {
|
|
480
595
|
return new RegExp(`\\b${qualifier}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`, "g");
|
|
@@ -536,11 +651,11 @@ function normalizeShaderHooks(hookFunctions) {
|
|
|
536
651
|
}
|
|
537
652
|
|
|
538
653
|
// dist/lib/glsl-utils/get-shader-info.js
|
|
539
|
-
function getShaderInfo(
|
|
654
|
+
function getShaderInfo(source4, defaultName) {
|
|
540
655
|
return {
|
|
541
|
-
name: getShaderName(
|
|
656
|
+
name: getShaderName(source4, defaultName),
|
|
542
657
|
language: "glsl",
|
|
543
|
-
version: getShaderVersion(
|
|
658
|
+
version: getShaderVersion(source4)
|
|
544
659
|
};
|
|
545
660
|
}
|
|
546
661
|
function getShaderName(shader, defaultName = "unnamed") {
|
|
@@ -548,9 +663,9 @@ function getShaderName(shader, defaultName = "unnamed") {
|
|
|
548
663
|
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
549
664
|
return match ? match[1] : defaultName;
|
|
550
665
|
}
|
|
551
|
-
function getShaderVersion(
|
|
666
|
+
function getShaderVersion(source4) {
|
|
552
667
|
let version = 100;
|
|
553
|
-
const words =
|
|
668
|
+
const words = source4.match(/[^\s]+/g);
|
|
554
669
|
if (words && words.length >= 2 && words[0] === "#version") {
|
|
555
670
|
const parsedVersion = parseInt(words[1], 10);
|
|
556
671
|
if (Number.isFinite(parsedVersion)) {
|
|
@@ -563,11 +678,158 @@ function getShaderVersion(source3) {
|
|
|
563
678
|
return version;
|
|
564
679
|
}
|
|
565
680
|
|
|
681
|
+
// dist/lib/shader-assembly/wgsl-binding-debug.js
|
|
682
|
+
var WGSL_BINDING_DEBUG_REGEXES = [
|
|
683
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g,
|
|
684
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g
|
|
685
|
+
];
|
|
686
|
+
function getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments = []) {
|
|
687
|
+
var _a;
|
|
688
|
+
const assignmentMap = /* @__PURE__ */ new Map();
|
|
689
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
690
|
+
assignmentMap.set(getBindingAssignmentKey(bindingAssignment.name, bindingAssignment.group, bindingAssignment.location), bindingAssignment.moduleName);
|
|
691
|
+
}
|
|
692
|
+
const rows = [];
|
|
693
|
+
for (const regex of WGSL_BINDING_DEBUG_REGEXES) {
|
|
694
|
+
regex.lastIndex = 0;
|
|
695
|
+
let match;
|
|
696
|
+
while (match = regex.exec(source4)) {
|
|
697
|
+
const isBindingFirst = regex === WGSL_BINDING_DEBUG_REGEXES[0];
|
|
698
|
+
const binding = Number(match[isBindingFirst ? 1 : 2]);
|
|
699
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
700
|
+
const accessDeclaration = (_a = match[3]) == null ? void 0 : _a.trim();
|
|
701
|
+
const name = match[4];
|
|
702
|
+
const resourceType = match[5].trim();
|
|
703
|
+
const moduleName = assignmentMap.get(getBindingAssignmentKey(name, group, binding));
|
|
704
|
+
rows.push(normalizeShaderBindingDebugRow({
|
|
705
|
+
name,
|
|
706
|
+
group,
|
|
707
|
+
binding,
|
|
708
|
+
owner: moduleName ? "module" : "application",
|
|
709
|
+
moduleName,
|
|
710
|
+
accessDeclaration,
|
|
711
|
+
resourceType
|
|
712
|
+
}));
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return rows.sort((left, right) => {
|
|
716
|
+
if (left.group !== right.group) {
|
|
717
|
+
return left.group - right.group;
|
|
718
|
+
}
|
|
719
|
+
if (left.binding !== right.binding) {
|
|
720
|
+
return left.binding - right.binding;
|
|
721
|
+
}
|
|
722
|
+
return left.name.localeCompare(right.name);
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
function normalizeShaderBindingDebugRow(row) {
|
|
726
|
+
const baseRow = {
|
|
727
|
+
name: row.name,
|
|
728
|
+
group: row.group,
|
|
729
|
+
binding: row.binding,
|
|
730
|
+
owner: row.owner,
|
|
731
|
+
kind: "unknown",
|
|
732
|
+
moduleName: row.moduleName,
|
|
733
|
+
resourceType: row.resourceType
|
|
734
|
+
};
|
|
735
|
+
if (row.accessDeclaration) {
|
|
736
|
+
const access = row.accessDeclaration.split(",").map((value) => value.trim());
|
|
737
|
+
if (access[0] === "uniform") {
|
|
738
|
+
return { ...baseRow, kind: "uniform", access: "uniform" };
|
|
739
|
+
}
|
|
740
|
+
if (access[0] === "storage") {
|
|
741
|
+
const storageAccess = access[1] || "read_write";
|
|
742
|
+
return {
|
|
743
|
+
...baseRow,
|
|
744
|
+
kind: storageAccess === "read" ? "read-only-storage" : "storage",
|
|
745
|
+
access: storageAccess
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
if (row.resourceType === "sampler" || row.resourceType === "sampler_comparison") {
|
|
750
|
+
return {
|
|
751
|
+
...baseRow,
|
|
752
|
+
kind: "sampler",
|
|
753
|
+
samplerKind: row.resourceType === "sampler_comparison" ? "comparison" : "filtering"
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
if (row.resourceType.startsWith("texture_storage_")) {
|
|
757
|
+
return {
|
|
758
|
+
...baseRow,
|
|
759
|
+
kind: "storage-texture",
|
|
760
|
+
access: getStorageTextureAccess(row.resourceType),
|
|
761
|
+
viewDimension: getTextureViewDimension(row.resourceType)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
if (row.resourceType.startsWith("texture_")) {
|
|
765
|
+
return {
|
|
766
|
+
...baseRow,
|
|
767
|
+
kind: "texture",
|
|
768
|
+
viewDimension: getTextureViewDimension(row.resourceType),
|
|
769
|
+
sampleType: getTextureSampleType(row.resourceType),
|
|
770
|
+
multisampled: row.resourceType.startsWith("texture_multisampled_")
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
return baseRow;
|
|
774
|
+
}
|
|
775
|
+
function getBindingAssignmentKey(name, group, binding) {
|
|
776
|
+
return `${group}:${binding}:${name}`;
|
|
777
|
+
}
|
|
778
|
+
function getTextureViewDimension(resourceType) {
|
|
779
|
+
if (resourceType.includes("cube_array")) {
|
|
780
|
+
return "cube-array";
|
|
781
|
+
}
|
|
782
|
+
if (resourceType.includes("2d_array")) {
|
|
783
|
+
return "2d-array";
|
|
784
|
+
}
|
|
785
|
+
if (resourceType.includes("cube")) {
|
|
786
|
+
return "cube";
|
|
787
|
+
}
|
|
788
|
+
if (resourceType.includes("3d")) {
|
|
789
|
+
return "3d";
|
|
790
|
+
}
|
|
791
|
+
if (resourceType.includes("2d")) {
|
|
792
|
+
return "2d";
|
|
793
|
+
}
|
|
794
|
+
if (resourceType.includes("1d")) {
|
|
795
|
+
return "1d";
|
|
796
|
+
}
|
|
797
|
+
return void 0;
|
|
798
|
+
}
|
|
799
|
+
function getTextureSampleType(resourceType) {
|
|
800
|
+
if (resourceType.startsWith("texture_depth_")) {
|
|
801
|
+
return "depth";
|
|
802
|
+
}
|
|
803
|
+
if (resourceType.includes("<i32>")) {
|
|
804
|
+
return "sint";
|
|
805
|
+
}
|
|
806
|
+
if (resourceType.includes("<u32>")) {
|
|
807
|
+
return "uint";
|
|
808
|
+
}
|
|
809
|
+
if (resourceType.includes("<f32>")) {
|
|
810
|
+
return "float";
|
|
811
|
+
}
|
|
812
|
+
return void 0;
|
|
813
|
+
}
|
|
814
|
+
function getStorageTextureAccess(resourceType) {
|
|
815
|
+
const match = /,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(resourceType);
|
|
816
|
+
return match == null ? void 0 : match[1];
|
|
817
|
+
}
|
|
818
|
+
|
|
566
819
|
// dist/lib/shader-assembly/assemble-shaders.js
|
|
567
820
|
var INJECT_SHADER_DECLARATIONS = `
|
|
568
821
|
|
|
569
822
|
${DECLARATION_INJECT_MARKER}
|
|
570
823
|
`;
|
|
824
|
+
var MODULE_WGSL_BINDING_DECLARATION_REGEXES = [
|
|
825
|
+
/@binding\(\s*(auto|\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
826
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(auto|\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
827
|
+
];
|
|
828
|
+
var WGSL_BINDING_DECLARATION_REGEXES = [
|
|
829
|
+
/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,
|
|
830
|
+
/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g
|
|
831
|
+
];
|
|
832
|
+
var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
|
|
571
833
|
var FRAGMENT_SHADER_PROLOGUE = (
|
|
572
834
|
/* glsl */
|
|
573
835
|
`precision highp float;
|
|
@@ -575,30 +837,33 @@ var FRAGMENT_SHADER_PROLOGUE = (
|
|
|
575
837
|
);
|
|
576
838
|
function assembleWGSLShader(options) {
|
|
577
839
|
const modules = getShaderModuleDependencies(options.modules || []);
|
|
840
|
+
const { source: source4, bindingAssignments } = assembleShaderWGSL(options.platformInfo, {
|
|
841
|
+
...options,
|
|
842
|
+
source: options.source,
|
|
843
|
+
stage: "vertex",
|
|
844
|
+
modules
|
|
845
|
+
});
|
|
578
846
|
return {
|
|
579
|
-
source:
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
modules
|
|
584
|
-
}),
|
|
585
|
-
getUniforms: assembleGetUniforms(modules)
|
|
847
|
+
source: source4,
|
|
848
|
+
getUniforms: assembleGetUniforms(modules),
|
|
849
|
+
bindingAssignments,
|
|
850
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(source4, bindingAssignments)
|
|
586
851
|
};
|
|
587
852
|
}
|
|
588
853
|
function assembleGLSLShaderPair(options) {
|
|
589
|
-
const { vs:
|
|
854
|
+
const { vs: vs4, fs: fs5 } = options;
|
|
590
855
|
const modules = getShaderModuleDependencies(options.modules || []);
|
|
591
856
|
return {
|
|
592
857
|
vs: assembleShaderGLSL(options.platformInfo, {
|
|
593
858
|
...options,
|
|
594
|
-
source:
|
|
859
|
+
source: vs4,
|
|
595
860
|
stage: "vertex",
|
|
596
861
|
modules
|
|
597
862
|
}),
|
|
598
863
|
fs: assembleShaderGLSL(options.platformInfo, {
|
|
599
864
|
...options,
|
|
600
865
|
// @ts-expect-error
|
|
601
|
-
source:
|
|
866
|
+
source: fs5,
|
|
602
867
|
stage: "fragment",
|
|
603
868
|
modules
|
|
604
869
|
}),
|
|
@@ -609,7 +874,7 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
609
874
|
var _a;
|
|
610
875
|
const {
|
|
611
876
|
// id,
|
|
612
|
-
source:
|
|
877
|
+
source: source4,
|
|
613
878
|
stage,
|
|
614
879
|
modules,
|
|
615
880
|
// defines = {},
|
|
@@ -617,8 +882,8 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
617
882
|
inject = {},
|
|
618
883
|
log: log2
|
|
619
884
|
} = options;
|
|
620
|
-
assert(typeof
|
|
621
|
-
const coreSource =
|
|
885
|
+
assert(typeof source4 === "string", "shader source must be a string");
|
|
886
|
+
const coreSource = source4;
|
|
622
887
|
let assembledSource = "";
|
|
623
888
|
const hookFunctionMap = normalizeShaderHooks(hookFunctions);
|
|
624
889
|
const hookInjections = {};
|
|
@@ -644,11 +909,20 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
644
909
|
}
|
|
645
910
|
}
|
|
646
911
|
const modulesToInject = modules;
|
|
912
|
+
const usedBindingsByGroup = getUsedBindingsByGroupFromApplicationWGSL(coreSource);
|
|
913
|
+
const reservedBindingKeysByGroup = reserveRegisteredModuleBindings(modulesToInject, options._bindingRegistry, usedBindingsByGroup);
|
|
914
|
+
const bindingAssignments = [];
|
|
647
915
|
for (const module2 of modulesToInject) {
|
|
648
916
|
if (log2) {
|
|
649
917
|
checkShaderModuleDeprecations(module2, coreSource, log2);
|
|
650
918
|
}
|
|
651
|
-
const
|
|
919
|
+
const relocation = relocateWGSLModuleBindings(getShaderModuleSource(module2, "wgsl", log2), module2, {
|
|
920
|
+
usedBindingsByGroup,
|
|
921
|
+
bindingRegistry: options._bindingRegistry,
|
|
922
|
+
reservedBindingKeysByGroup
|
|
923
|
+
});
|
|
924
|
+
bindingAssignments.push(...relocation.bindingAssignments);
|
|
925
|
+
const moduleSource = relocation.source;
|
|
652
926
|
assembledSource += moduleSource;
|
|
653
927
|
const injections = ((_a = module2.injections) == null ? void 0 : _a[stage]) || {};
|
|
654
928
|
for (const key in injections) {
|
|
@@ -667,18 +941,20 @@ function assembleShaderWGSL(platformInfo, options) {
|
|
|
667
941
|
assembledSource += INJECT_SHADER_DECLARATIONS;
|
|
668
942
|
assembledSource = injectShader(assembledSource, stage, declInjections);
|
|
669
943
|
assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections);
|
|
944
|
+
assembledSource += formatWGSLBindingAssignmentComments(bindingAssignments);
|
|
670
945
|
assembledSource += coreSource;
|
|
671
946
|
assembledSource = injectShader(assembledSource, stage, mainInjections);
|
|
672
|
-
|
|
947
|
+
assertNoUnresolvedAutoBindings(assembledSource);
|
|
948
|
+
return { source: assembledSource, bindingAssignments };
|
|
673
949
|
}
|
|
674
950
|
function assembleShaderGLSL(platformInfo, options) {
|
|
675
951
|
var _a;
|
|
676
|
-
const { source:
|
|
677
|
-
assert(typeof
|
|
678
|
-
const sourceVersion = language === "glsl" ? getShaderInfo(
|
|
952
|
+
const { source: source4, stage, language = "glsl", modules, defines = {}, hookFunctions = [], inject = {}, prologue = true, log: log2 } = options;
|
|
953
|
+
assert(typeof source4 === "string", "shader source must be a string");
|
|
954
|
+
const sourceVersion = language === "glsl" ? getShaderInfo(source4).version : -1;
|
|
679
955
|
const targetVersion = platformInfo.shaderLanguageVersion;
|
|
680
956
|
const sourceVersionDirective = sourceVersion === 100 ? "#version 100" : "#version 300 es";
|
|
681
|
-
const sourceLines =
|
|
957
|
+
const sourceLines = source4.split("\n");
|
|
682
958
|
const coreSource = sourceLines.slice(1).join("\n");
|
|
683
959
|
const allDefines = {};
|
|
684
960
|
modules.forEach((module2) => {
|
|
@@ -733,7 +1009,7 @@ ${getApplicationDefines(allDefines)}
|
|
|
733
1009
|
if (log2) {
|
|
734
1010
|
checkShaderModuleDeprecations(module2, coreSource, log2);
|
|
735
1011
|
}
|
|
736
|
-
const moduleSource = getShaderModuleSource(module2, stage);
|
|
1012
|
+
const moduleSource = getShaderModuleSource(module2, stage, log2);
|
|
737
1013
|
assembledSource += moduleSource;
|
|
738
1014
|
const injections = ((_a = module2.instance) == null ? void 0 : _a.normalizedInjections[stage]) || {};
|
|
739
1015
|
for (const key in injections) {
|
|
@@ -782,7 +1058,7 @@ function getApplicationDefines(defines = {}) {
|
|
|
782
1058
|
}
|
|
783
1059
|
return sourceText;
|
|
784
1060
|
}
|
|
785
|
-
function getShaderModuleSource(module2, stage) {
|
|
1061
|
+
function getShaderModuleSource(module2, stage, log2) {
|
|
786
1062
|
let moduleSource;
|
|
787
1063
|
switch (stage) {
|
|
788
1064
|
case "vertex":
|
|
@@ -800,40 +1076,227 @@ function getShaderModuleSource(module2, stage) {
|
|
|
800
1076
|
if (!module2.name) {
|
|
801
1077
|
throw new Error("Shader module must have a name");
|
|
802
1078
|
}
|
|
1079
|
+
validateShaderModuleUniformLayout(module2, stage, { log: log2 });
|
|
803
1080
|
const moduleName = module2.name.toUpperCase().replace(/[^0-9a-z]/gi, "_");
|
|
804
|
-
let
|
|
1081
|
+
let source4 = `// ----- MODULE ${module2.name} ---------------
|
|
805
1082
|
|
|
806
1083
|
`;
|
|
807
1084
|
if (stage !== "wgsl") {
|
|
808
|
-
|
|
1085
|
+
source4 += `#define MODULE_${moduleName}
|
|
809
1086
|
`;
|
|
810
1087
|
}
|
|
811
|
-
|
|
1088
|
+
source4 += `${moduleSource}
|
|
1089
|
+
`;
|
|
1090
|
+
return source4;
|
|
1091
|
+
}
|
|
1092
|
+
function getUsedBindingsByGroupFromApplicationWGSL(source4) {
|
|
1093
|
+
const usedBindingsByGroup = /* @__PURE__ */ new Map();
|
|
1094
|
+
for (const regex of WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1095
|
+
regex.lastIndex = 0;
|
|
1096
|
+
let match;
|
|
1097
|
+
while (match = regex.exec(source4)) {
|
|
1098
|
+
const isBindingFirst = regex === WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1099
|
+
const location = Number(match[isBindingFirst ? 1 : 2]);
|
|
1100
|
+
const group = Number(match[isBindingFirst ? 2 : 1]);
|
|
1101
|
+
const name = match[4];
|
|
1102
|
+
validateApplicationWGSLBinding(group, location, name);
|
|
1103
|
+
registerUsedBindingLocation(usedBindingsByGroup, group, location, `application binding "${name}"`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return usedBindingsByGroup;
|
|
1107
|
+
}
|
|
1108
|
+
function relocateWGSLModuleBindings(moduleSource, module2, context) {
|
|
1109
|
+
const bindingAssignments = [];
|
|
1110
|
+
const relocationState = {
|
|
1111
|
+
sawSupportedBindingDeclaration: false,
|
|
1112
|
+
nextHintedBindingLocation: typeof module2.firstBindingSlot === "number" ? module2.firstBindingSlot : null
|
|
1113
|
+
};
|
|
1114
|
+
let relocatedSource = relocateWGSLModuleBindingsWithRegex(moduleSource, MODULE_WGSL_BINDING_DECLARATION_REGEXES[0], { isBindingFirst: true, module: module2, context, bindingAssignments, relocationState });
|
|
1115
|
+
relocatedSource = relocateWGSLModuleBindingsWithRegex(relocatedSource, MODULE_WGSL_BINDING_DECLARATION_REGEXES[1], { isBindingFirst: false, module: module2, context, bindingAssignments, relocationState });
|
|
1116
|
+
if (moduleSource.includes("@binding(auto)") && !relocationState.sawSupportedBindingDeclaration) {
|
|
1117
|
+
throw new Error(`Unsupported @binding(auto) declaration form in module "${module2.name}". Use "@group(N) @binding(auto) var ..." or "@binding(auto) @group(N) var ..." on a single line.`);
|
|
1118
|
+
}
|
|
1119
|
+
return { source: relocatedSource, bindingAssignments };
|
|
1120
|
+
}
|
|
1121
|
+
function relocateWGSLModuleBindingsWithRegex(source4, regex, params) {
|
|
1122
|
+
return source4.replace(regex, (...replaceArguments) => relocateWGSLModuleBindingMatch(replaceArguments, params));
|
|
1123
|
+
}
|
|
1124
|
+
function relocateWGSLModuleBindingMatch(replaceArguments, params) {
|
|
1125
|
+
var _a, _b;
|
|
1126
|
+
const { isBindingFirst, module: module2, context, bindingAssignments, relocationState } = params;
|
|
1127
|
+
relocationState.sawSupportedBindingDeclaration = true;
|
|
1128
|
+
const match = replaceArguments[0];
|
|
1129
|
+
const bindingToken = replaceArguments[isBindingFirst ? 1 : 2];
|
|
1130
|
+
const groupToken = replaceArguments[isBindingFirst ? 2 : 1];
|
|
1131
|
+
const name = replaceArguments[4];
|
|
1132
|
+
const group = Number(groupToken);
|
|
1133
|
+
if (bindingToken === "auto") {
|
|
1134
|
+
const registryKey = getBindingRegistryKey(group, module2.name, name);
|
|
1135
|
+
const registryLocation = (_a = context.bindingRegistry) == null ? void 0 : _a.get(registryKey);
|
|
1136
|
+
const location2 = registryLocation !== void 0 ? registryLocation : relocationState.nextHintedBindingLocation === null ? allocateAutoBindingLocation(group, context.usedBindingsByGroup) : allocateAutoBindingLocation(group, context.usedBindingsByGroup, relocationState.nextHintedBindingLocation);
|
|
1137
|
+
validateModuleWGSLBinding(module2.name, group, location2, name);
|
|
1138
|
+
if (registryLocation !== void 0 && claimReservedBindingLocation(context.reservedBindingKeysByGroup, group, location2, registryKey)) {
|
|
1139
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location: location2 });
|
|
1140
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1141
|
+
}
|
|
1142
|
+
registerUsedBindingLocation(context.usedBindingsByGroup, group, location2, `module "${module2.name}" binding "${name}"`);
|
|
1143
|
+
(_b = context.bindingRegistry) == null ? void 0 : _b.set(registryKey, location2);
|
|
1144
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location: location2 });
|
|
1145
|
+
if (relocationState.nextHintedBindingLocation !== null && registryLocation === void 0) {
|
|
1146
|
+
relocationState.nextHintedBindingLocation = location2 + 1;
|
|
1147
|
+
}
|
|
1148
|
+
return match.replace(/@binding\(\s*auto\s*\)/, `@binding(${location2})`);
|
|
1149
|
+
}
|
|
1150
|
+
const location = Number(bindingToken);
|
|
1151
|
+
validateModuleWGSLBinding(module2.name, group, location, name);
|
|
1152
|
+
registerUsedBindingLocation(context.usedBindingsByGroup, group, location, `module "${module2.name}" binding "${name}"`);
|
|
1153
|
+
bindingAssignments.push({ moduleName: module2.name, name, group, location });
|
|
1154
|
+
return match;
|
|
1155
|
+
}
|
|
1156
|
+
function reserveRegisteredModuleBindings(modules, bindingRegistry, usedBindingsByGroup) {
|
|
1157
|
+
const reservedBindingKeysByGroup = /* @__PURE__ */ new Map();
|
|
1158
|
+
if (!bindingRegistry) {
|
|
1159
|
+
return reservedBindingKeysByGroup;
|
|
1160
|
+
}
|
|
1161
|
+
for (const module2 of modules) {
|
|
1162
|
+
for (const binding of getModuleWGSLBindingDeclarations(module2)) {
|
|
1163
|
+
const registryKey = getBindingRegistryKey(binding.group, module2.name, binding.name);
|
|
1164
|
+
const location = bindingRegistry.get(registryKey);
|
|
1165
|
+
if (location !== void 0) {
|
|
1166
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(binding.group) || /* @__PURE__ */ new Map();
|
|
1167
|
+
const existingReservation = reservedBindingKeys.get(location);
|
|
1168
|
+
if (existingReservation && existingReservation !== registryKey) {
|
|
1169
|
+
throw new Error(`Duplicate WGSL binding reservation for modules "${existingReservation}" and "${registryKey}": group ${binding.group}, binding ${location}.`);
|
|
1170
|
+
}
|
|
1171
|
+
registerUsedBindingLocation(usedBindingsByGroup, binding.group, location, `registered module binding "${registryKey}"`);
|
|
1172
|
+
reservedBindingKeys.set(location, registryKey);
|
|
1173
|
+
reservedBindingKeysByGroup.set(binding.group, reservedBindingKeys);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return reservedBindingKeysByGroup;
|
|
1178
|
+
}
|
|
1179
|
+
function claimReservedBindingLocation(reservedBindingKeysByGroup, group, location, registryKey) {
|
|
1180
|
+
const reservedBindingKeys = reservedBindingKeysByGroup.get(group);
|
|
1181
|
+
if (!reservedBindingKeys) {
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
const reservedKey = reservedBindingKeys.get(location);
|
|
1185
|
+
if (!reservedKey) {
|
|
1186
|
+
return false;
|
|
1187
|
+
}
|
|
1188
|
+
if (reservedKey !== registryKey) {
|
|
1189
|
+
throw new Error(`Registered module binding "${registryKey}" collided with "${reservedKey}": group ${group}, binding ${location}.`);
|
|
1190
|
+
}
|
|
1191
|
+
return true;
|
|
1192
|
+
}
|
|
1193
|
+
function getModuleWGSLBindingDeclarations(module2) {
|
|
1194
|
+
const declarations = [];
|
|
1195
|
+
const moduleSource = module2.source || "";
|
|
1196
|
+
for (const regex of MODULE_WGSL_BINDING_DECLARATION_REGEXES) {
|
|
1197
|
+
regex.lastIndex = 0;
|
|
1198
|
+
let match;
|
|
1199
|
+
while (match = regex.exec(moduleSource)) {
|
|
1200
|
+
const isBindingFirst = regex === MODULE_WGSL_BINDING_DECLARATION_REGEXES[0];
|
|
1201
|
+
declarations.push({
|
|
1202
|
+
name: match[4],
|
|
1203
|
+
group: Number(match[isBindingFirst ? 2 : 1])
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
return declarations;
|
|
1208
|
+
}
|
|
1209
|
+
function validateApplicationWGSLBinding(group, location, name) {
|
|
1210
|
+
if (group === 0 && location >= RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1211
|
+
throw new Error(`Application binding "${name}" in group 0 uses reserved binding ${location}. Application-owned explicit group-0 bindings must stay below ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT}.`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function validateModuleWGSLBinding(moduleName, group, location, name) {
|
|
1215
|
+
if (group === 0 && location < RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT) {
|
|
1216
|
+
throw new Error(`Module "${moduleName}" binding "${name}" in group 0 uses reserved application binding ${location}. Module-owned explicit group-0 bindings must be ${RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT} or higher.`);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function registerUsedBindingLocation(usedBindingsByGroup, group, location, label) {
|
|
1220
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1221
|
+
if (usedBindings.has(location)) {
|
|
1222
|
+
throw new Error(`Duplicate WGSL binding assignment for ${label}: group ${group}, binding ${location}.`);
|
|
1223
|
+
}
|
|
1224
|
+
usedBindings.add(location);
|
|
1225
|
+
usedBindingsByGroup.set(group, usedBindings);
|
|
1226
|
+
}
|
|
1227
|
+
function allocateAutoBindingLocation(group, usedBindingsByGroup, preferredBindingLocation) {
|
|
1228
|
+
const usedBindings = usedBindingsByGroup.get(group) || /* @__PURE__ */ new Set();
|
|
1229
|
+
let nextBinding = preferredBindingLocation ?? (group === 0 ? RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT : usedBindings.size > 0 ? Math.max(...usedBindings) + 1 : 0);
|
|
1230
|
+
while (usedBindings.has(nextBinding)) {
|
|
1231
|
+
nextBinding++;
|
|
1232
|
+
}
|
|
1233
|
+
return nextBinding;
|
|
1234
|
+
}
|
|
1235
|
+
function assertNoUnresolvedAutoBindings(source4) {
|
|
1236
|
+
if (/@binding\(\s*auto\s*\)/.test(source4)) {
|
|
1237
|
+
throw new Error("Unresolved @binding(auto) remained in assembled WGSL source.");
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
function formatWGSLBindingAssignmentComments(bindingAssignments) {
|
|
1241
|
+
if (bindingAssignments.length === 0) {
|
|
1242
|
+
return "";
|
|
1243
|
+
}
|
|
1244
|
+
let source4 = "// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------\n";
|
|
1245
|
+
for (const bindingAssignment of bindingAssignments) {
|
|
1246
|
+
source4 += `// ${bindingAssignment.moduleName}.${bindingAssignment.name} -> @group(${bindingAssignment.group}) @binding(${bindingAssignment.location})
|
|
812
1247
|
`;
|
|
813
|
-
|
|
1248
|
+
}
|
|
1249
|
+
source4 += "\n";
|
|
1250
|
+
return source4;
|
|
1251
|
+
}
|
|
1252
|
+
function getBindingRegistryKey(group, moduleName, bindingName) {
|
|
1253
|
+
return `${group}:${moduleName}:${bindingName}`;
|
|
814
1254
|
}
|
|
815
1255
|
|
|
816
1256
|
// dist/lib/preprocessor/preprocessor.js
|
|
817
|
-
var
|
|
1257
|
+
var DEFINE_NAME_PATTERN = "([a-zA-Z_][a-zA-Z0-9_]*)";
|
|
1258
|
+
var IFDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*$`);
|
|
1259
|
+
var IFNDEF_REGEXP = new RegExp(`^\\s*\\#\\s*ifndef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`);
|
|
1260
|
+
var ELSE_REGEXP = /^\s*\#\s*else\s*(?:\/\/.*)?$/;
|
|
818
1261
|
var ENDIF_REGEXP = /^\s*\#\s*endif\s*$/;
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
1262
|
+
var IFDEF_WITH_COMMENT_REGEXP = new RegExp(`^\\s*\\#\\s*ifdef\\s*${DEFINE_NAME_PATTERN}\\s*(?:\\/\\/.*)?$`);
|
|
1263
|
+
var ENDIF_WITH_COMMENT_REGEXP = /^\s*\#\s*endif\s*(?:\/\/.*)?$/;
|
|
1264
|
+
function preprocess(source4, options) {
|
|
1265
|
+
var _a, _b;
|
|
1266
|
+
const lines = source4.split("\n");
|
|
822
1267
|
const output = [];
|
|
1268
|
+
const conditionalStack = [];
|
|
823
1269
|
let conditional = true;
|
|
824
|
-
let currentDefine = null;
|
|
825
1270
|
for (const line of lines) {
|
|
826
|
-
const matchIf = line.match(IFDEF_REGEXP);
|
|
827
|
-
const
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1271
|
+
const matchIf = line.match(IFDEF_WITH_COMMENT_REGEXP) || line.match(IFDEF_REGEXP);
|
|
1272
|
+
const matchIfNot = line.match(IFNDEF_REGEXP);
|
|
1273
|
+
const matchElse = line.match(ELSE_REGEXP);
|
|
1274
|
+
const matchEnd = line.match(ENDIF_WITH_COMMENT_REGEXP) || line.match(ENDIF_REGEXP);
|
|
1275
|
+
if (matchIf || matchIfNot) {
|
|
1276
|
+
const defineName = (_a = matchIf || matchIfNot) == null ? void 0 : _a[1];
|
|
1277
|
+
const defineValue = Boolean((_b = options == null ? void 0 : options.defines) == null ? void 0 : _b[defineName]);
|
|
1278
|
+
const branchTaken = matchIf ? defineValue : !defineValue;
|
|
1279
|
+
const active = conditional && branchTaken;
|
|
1280
|
+
conditionalStack.push({ parentActive: conditional, branchTaken, active });
|
|
1281
|
+
conditional = active;
|
|
1282
|
+
} else if (matchElse) {
|
|
1283
|
+
const currentConditional = conditionalStack[conditionalStack.length - 1];
|
|
1284
|
+
if (!currentConditional) {
|
|
1285
|
+
throw new Error("Encountered #else without matching #ifdef or #ifndef");
|
|
1286
|
+
}
|
|
1287
|
+
currentConditional.active = currentConditional.parentActive && !currentConditional.branchTaken;
|
|
1288
|
+
currentConditional.branchTaken = true;
|
|
1289
|
+
conditional = currentConditional.active;
|
|
831
1290
|
} else if (matchEnd) {
|
|
832
|
-
|
|
1291
|
+
conditionalStack.pop();
|
|
1292
|
+
conditional = conditionalStack.length ? conditionalStack[conditionalStack.length - 1].active : true;
|
|
833
1293
|
} else if (conditional) {
|
|
834
1294
|
output.push(line);
|
|
835
1295
|
}
|
|
836
1296
|
}
|
|
1297
|
+
if (conditionalStack.length > 0) {
|
|
1298
|
+
throw new Error("Unterminated conditional block in shader source");
|
|
1299
|
+
}
|
|
837
1300
|
return output.join("\n");
|
|
838
1301
|
}
|
|
839
1302
|
|
|
@@ -843,6 +1306,8 @@ var _ShaderAssembler = class {
|
|
|
843
1306
|
_hookFunctions = [];
|
|
844
1307
|
/** Shader modules */
|
|
845
1308
|
_defaultModules = [];
|
|
1309
|
+
/** Stable per-run WGSL auto-binding assignments keyed by group/module/binding. */
|
|
1310
|
+
_wgslBindingRegistry = /* @__PURE__ */ new Map();
|
|
846
1311
|
/**
|
|
847
1312
|
* A default shader assembler instance - the natural place to register default modules and hooks
|
|
848
1313
|
* @returns
|
|
@@ -886,15 +1351,29 @@ var _ShaderAssembler = class {
|
|
|
886
1351
|
assembleWGSLShader(props) {
|
|
887
1352
|
const modules = this._getModuleList(props.modules);
|
|
888
1353
|
const hookFunctions = this._hookFunctions;
|
|
889
|
-
const { source:
|
|
1354
|
+
const { source: source4, getUniforms: getUniforms4, bindingAssignments } = assembleWGSLShader({
|
|
890
1355
|
...props,
|
|
891
1356
|
// @ts-expect-error
|
|
892
1357
|
source: props.source,
|
|
1358
|
+
_bindingRegistry: this._wgslBindingRegistry,
|
|
893
1359
|
modules,
|
|
894
1360
|
hookFunctions
|
|
895
1361
|
});
|
|
896
|
-
const
|
|
897
|
-
|
|
1362
|
+
const defines = {
|
|
1363
|
+
...modules.reduce((accumulator, module2) => {
|
|
1364
|
+
Object.assign(accumulator, module2.defines);
|
|
1365
|
+
return accumulator;
|
|
1366
|
+
}, {}),
|
|
1367
|
+
...props.defines
|
|
1368
|
+
};
|
|
1369
|
+
const preprocessedSource = props.platformInfo.shaderLanguage === "wgsl" ? preprocess(source4, { defines }) : source4;
|
|
1370
|
+
return {
|
|
1371
|
+
source: preprocessedSource,
|
|
1372
|
+
getUniforms: getUniforms4,
|
|
1373
|
+
modules,
|
|
1374
|
+
bindingAssignments,
|
|
1375
|
+
bindingTable: getShaderBindingDebugRowsFromWGSL(preprocessedSource, bindingAssignments)
|
|
1376
|
+
};
|
|
898
1377
|
}
|
|
899
1378
|
/**
|
|
900
1379
|
* Assemble a pair of shaders into a single shader program
|
|
@@ -1059,6 +1538,9 @@ function generateGLSLUniformDeclarations(module2, options) {
|
|
|
1059
1538
|
case "uniforms":
|
|
1060
1539
|
}
|
|
1061
1540
|
for (const [uniformName, uniformFormat] of Object.entries(module2.uniformTypes || {})) {
|
|
1541
|
+
if (typeof uniformFormat !== "string") {
|
|
1542
|
+
throw new Error(`Composite uniform types are not supported by GLSL shader generation: ${module2.name}.${uniformName}`);
|
|
1543
|
+
}
|
|
1062
1544
|
const glslUniformType = getGLSLUniformType(uniformFormat);
|
|
1063
1545
|
switch (options.uniforms) {
|
|
1064
1546
|
case "scoped-interface-blocks":
|
|
@@ -1119,6 +1601,9 @@ function generateWGSLUniformDeclarations(module2, options) {
|
|
|
1119
1601
|
const wgsl = [];
|
|
1120
1602
|
wgsl.push(`struct ${capitalize(module2.name)} {`);
|
|
1121
1603
|
for (const [uniformName, uniformFormat] of Object.entries((module2 == null ? void 0 : module2.uniformTypes) || {})) {
|
|
1604
|
+
if (typeof uniformFormat !== "string") {
|
|
1605
|
+
throw new Error(`Composite uniform types are not supported by WGSL shader generation: ${module2.name}.${uniformName}`);
|
|
1606
|
+
}
|
|
1122
1607
|
const wgslUniformType = uniformFormat;
|
|
1123
1608
|
wgsl.push(` ${uniformName} : ${wgslUniformType};`);
|
|
1124
1609
|
}
|
|
@@ -1248,9 +1733,8 @@ function fp64ifyMatrix4(matrix) {
|
|
|
1248
1733
|
// dist/modules/math/random/random.js
|
|
1249
1734
|
var source = (
|
|
1250
1735
|
/* wgsl */
|
|
1251
|
-
`fn random(scale: vec3f, seed:
|
|
1252
|
-
|
|
1253
|
-
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
|
1736
|
+
`fn random(scale: vec3f, seed: f32) -> f32 {
|
|
1737
|
+
return fract(sin(dot(scale + vec3f(seed), vec3f(12.9898, 78.233, 151.7182))) * 43758.5453 + seed);
|
|
1254
1738
|
}
|
|
1255
1739
|
`
|
|
1256
1740
|
);
|
|
@@ -1434,6 +1918,7 @@ var fp64arithmeticShader = (
|
|
|
1434
1918
|
`
|
|
1435
1919
|
uniform fp64arithmeticUniforms {
|
|
1436
1920
|
uniform float ONE;
|
|
1921
|
+
uniform float SPLIT;
|
|
1437
1922
|
} fp64;
|
|
1438
1923
|
|
|
1439
1924
|
/*
|
|
@@ -1443,6 +1928,12 @@ The purpose of this workaround is to prevent shader compilers from
|
|
|
1443
1928
|
optimizing away necessary arithmetic operations by swapping their sequences
|
|
1444
1929
|
or transform the equation to some 'equivalent' form.
|
|
1445
1930
|
|
|
1931
|
+
These helpers implement Dekker/Veltkamp-style error tracking. If the compiler
|
|
1932
|
+
folds constants or reassociates the arithmetic, the high/low split can stop
|
|
1933
|
+
tracking the rounding error correctly. That failure mode tends to look fine in
|
|
1934
|
+
simple coordinate setup, but then breaks down inside iterative arithmetic such
|
|
1935
|
+
as fp64 Mandelbrot loops.
|
|
1936
|
+
|
|
1446
1937
|
The method is to multiply an artifical variable, ONE, which will be known to
|
|
1447
1938
|
the compiler to be 1 only at runtime. The whole expression is then represented
|
|
1448
1939
|
as a polynomial with respective to ONE. In the coefficients of all terms, only one a
|
|
@@ -1451,17 +1942,23 @@ and one b should appear
|
|
|
1451
1942
|
err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE
|
|
1452
1943
|
*/
|
|
1453
1944
|
|
|
1454
|
-
|
|
1455
|
-
vec2 split(float a) {
|
|
1456
|
-
const float SPLIT = 4097.0;
|
|
1457
|
-
float t = a * SPLIT;
|
|
1945
|
+
float prevent_fp64_optimization(float value) {
|
|
1458
1946
|
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
1459
|
-
|
|
1460
|
-
float a_lo = a * fp64.ONE - a_hi;
|
|
1947
|
+
return value + fp64.ONE * 0.0;
|
|
1461
1948
|
#else
|
|
1462
|
-
|
|
1463
|
-
float a_lo = a - a_hi;
|
|
1949
|
+
return value;
|
|
1464
1950
|
#endif
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// Divide float number to high and low floats to extend fraction bits
|
|
1954
|
+
vec2 split(float a) {
|
|
1955
|
+
// Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker
|
|
1956
|
+
// split into a constant expression and reassociate the recovery steps.
|
|
1957
|
+
float split = prevent_fp64_optimization(fp64.SPLIT);
|
|
1958
|
+
float t = prevent_fp64_optimization(a * split);
|
|
1959
|
+
float temp = t - a;
|
|
1960
|
+
float a_hi = t - temp;
|
|
1961
|
+
float a_lo = a - a_hi;
|
|
1465
1962
|
return vec2(a_hi, a_lo);
|
|
1466
1963
|
}
|
|
1467
1964
|
|
|
@@ -1525,8 +2022,26 @@ vec2 twoProd(float a, float b) {
|
|
|
1525
2022
|
float prod = a * b;
|
|
1526
2023
|
vec2 a_fp64 = split(a);
|
|
1527
2024
|
vec2 b_fp64 = split(b);
|
|
1528
|
-
|
|
1529
|
-
|
|
2025
|
+
// twoProd is especially sensitive because mul_fp64 and div_fp64 both depend
|
|
2026
|
+
// on the split terms and cross terms staying in the original evaluation
|
|
2027
|
+
// order. If the compiler folds or reassociates them, the low part tends to
|
|
2028
|
+
// collapse to zero or NaN on some drivers.
|
|
2029
|
+
float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);
|
|
2030
|
+
float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);
|
|
2031
|
+
float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);
|
|
2032
|
+
float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);
|
|
2033
|
+
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
2034
|
+
float err1 = (highProduct - prod) * fp64.ONE;
|
|
2035
|
+
float err2 = crossProduct1 * fp64.ONE * fp64.ONE;
|
|
2036
|
+
float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
2037
|
+
float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
2038
|
+
#else
|
|
2039
|
+
float err1 = highProduct - prod;
|
|
2040
|
+
float err2 = crossProduct1;
|
|
2041
|
+
float err3 = crossProduct2;
|
|
2042
|
+
float err4 = lowProduct;
|
|
2043
|
+
#endif
|
|
2044
|
+
float err = ((err1 + err2) + err3) + err4;
|
|
1530
2045
|
return vec2(prod, err);
|
|
1531
2046
|
}
|
|
1532
2047
|
|
|
@@ -1602,6 +2117,218 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
1602
2117
|
`
|
|
1603
2118
|
);
|
|
1604
2119
|
|
|
2120
|
+
// dist/modules/math/fp64/fp64-arithmetic-wgsl.js
|
|
2121
|
+
var fp64arithmeticWGSL = (
|
|
2122
|
+
/* wgsl */
|
|
2123
|
+
`struct Fp64ArithmeticUniforms {
|
|
2124
|
+
ONE: f32,
|
|
2125
|
+
SPLIT: f32,
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
|
|
2129
|
+
|
|
2130
|
+
fn fp64_nan(seed: f32) -> f32 {
|
|
2131
|
+
let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
|
|
2132
|
+
return bitcast<f32>(nanBits);
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
fn fp64_runtime_zero() -> f32 {
|
|
2136
|
+
return fp64arithmetic.ONE * 0.0;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
fn prevent_fp64_optimization(value: f32) -> f32 {
|
|
2140
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2141
|
+
return value + fp64_runtime_zero();
|
|
2142
|
+
#else
|
|
2143
|
+
return value;
|
|
2144
|
+
#endif
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
fn split(a: f32) -> vec2f {
|
|
2148
|
+
let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
|
|
2149
|
+
let t = prevent_fp64_optimization(a * splitValue);
|
|
2150
|
+
let temp = prevent_fp64_optimization(t - a);
|
|
2151
|
+
let aHi = prevent_fp64_optimization(t - temp);
|
|
2152
|
+
let aLo = prevent_fp64_optimization(a - aHi);
|
|
2153
|
+
return vec2f(aHi, aLo);
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
fn split2(a: vec2f) -> vec2f {
|
|
2157
|
+
var b = split(a.x);
|
|
2158
|
+
b.y = b.y + a.y;
|
|
2159
|
+
return b;
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
fn quickTwoSum(a: f32, b: f32) -> vec2f {
|
|
2163
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2164
|
+
let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);
|
|
2165
|
+
let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);
|
|
2166
|
+
#else
|
|
2167
|
+
let sum = prevent_fp64_optimization(a + b);
|
|
2168
|
+
let err = prevent_fp64_optimization(b - (sum - a));
|
|
2169
|
+
#endif
|
|
2170
|
+
return vec2f(sum, err);
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
fn twoSum(a: f32, b: f32) -> vec2f {
|
|
2174
|
+
let s = prevent_fp64_optimization(a + b);
|
|
2175
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2176
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
2177
|
+
let err =
|
|
2178
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
2179
|
+
fp64arithmetic.ONE *
|
|
2180
|
+
fp64arithmetic.ONE *
|
|
2181
|
+
fp64arithmetic.ONE) +
|
|
2182
|
+
prevent_fp64_optimization(b - v);
|
|
2183
|
+
#else
|
|
2184
|
+
let v = prevent_fp64_optimization(s - a);
|
|
2185
|
+
let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);
|
|
2186
|
+
#endif
|
|
2187
|
+
return vec2f(s, err);
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
fn twoSub(a: f32, b: f32) -> vec2f {
|
|
2191
|
+
let s = prevent_fp64_optimization(a - b);
|
|
2192
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2193
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
2194
|
+
let err =
|
|
2195
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
2196
|
+
fp64arithmetic.ONE *
|
|
2197
|
+
fp64arithmetic.ONE *
|
|
2198
|
+
fp64arithmetic.ONE) -
|
|
2199
|
+
prevent_fp64_optimization(b + v);
|
|
2200
|
+
#else
|
|
2201
|
+
let v = prevent_fp64_optimization(s - a);
|
|
2202
|
+
let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);
|
|
2203
|
+
#endif
|
|
2204
|
+
return vec2f(s, err);
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
fn twoSqr(a: f32) -> vec2f {
|
|
2208
|
+
let prod = prevent_fp64_optimization(a * a);
|
|
2209
|
+
let aFp64 = split(a);
|
|
2210
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);
|
|
2211
|
+
let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);
|
|
2212
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);
|
|
2213
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2214
|
+
let err =
|
|
2215
|
+
(prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +
|
|
2216
|
+
crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +
|
|
2217
|
+
lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2218
|
+
#else
|
|
2219
|
+
let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);
|
|
2220
|
+
#endif
|
|
2221
|
+
return vec2f(prod, err);
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
fn twoProd(a: f32, b: f32) -> vec2f {
|
|
2225
|
+
let prod = prevent_fp64_optimization(a * b);
|
|
2226
|
+
let aFp64 = split(a);
|
|
2227
|
+
let bFp64 = split(b);
|
|
2228
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);
|
|
2229
|
+
let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);
|
|
2230
|
+
let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);
|
|
2231
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);
|
|
2232
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2233
|
+
let err1 = (highProduct - prod) * fp64arithmetic.ONE;
|
|
2234
|
+
let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2235
|
+
let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
2236
|
+
let err4 =
|
|
2237
|
+
lowProduct *
|
|
2238
|
+
fp64arithmetic.ONE *
|
|
2239
|
+
fp64arithmetic.ONE *
|
|
2240
|
+
fp64arithmetic.ONE *
|
|
2241
|
+
fp64arithmetic.ONE;
|
|
2242
|
+
#else
|
|
2243
|
+
let err1 = highProduct - prod;
|
|
2244
|
+
let err2 = crossProduct1;
|
|
2245
|
+
let err3 = crossProduct2;
|
|
2246
|
+
let err4 = lowProduct;
|
|
2247
|
+
#endif
|
|
2248
|
+
let err12InputA = prevent_fp64_optimization(err1);
|
|
2249
|
+
let err12InputB = prevent_fp64_optimization(err2);
|
|
2250
|
+
let err12 = prevent_fp64_optimization(err12InputA + err12InputB);
|
|
2251
|
+
let err123InputA = prevent_fp64_optimization(err12);
|
|
2252
|
+
let err123InputB = prevent_fp64_optimization(err3);
|
|
2253
|
+
let err123 = prevent_fp64_optimization(err123InputA + err123InputB);
|
|
2254
|
+
let err1234InputA = prevent_fp64_optimization(err123);
|
|
2255
|
+
let err1234InputB = prevent_fp64_optimization(err4);
|
|
2256
|
+
let err = prevent_fp64_optimization(err1234InputA + err1234InputB);
|
|
2257
|
+
return vec2f(prod, err);
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2261
|
+
var s = twoSum(a.x, b.x);
|
|
2262
|
+
let t = twoSum(a.y, b.y);
|
|
2263
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
2264
|
+
s = quickTwoSum(s.x, s.y);
|
|
2265
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
2266
|
+
s = quickTwoSum(s.x, s.y);
|
|
2267
|
+
return s;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2271
|
+
var s = twoSub(a.x, b.x);
|
|
2272
|
+
let t = twoSub(a.y, b.y);
|
|
2273
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
2274
|
+
s = quickTwoSum(s.x, s.y);
|
|
2275
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
2276
|
+
s = quickTwoSum(s.x, s.y);
|
|
2277
|
+
return s;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2281
|
+
var prod = twoProd(a.x, b.x);
|
|
2282
|
+
let crossProduct1 = prevent_fp64_optimization(a.x * b.y);
|
|
2283
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct1);
|
|
2284
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2285
|
+
prod = split2(prod);
|
|
2286
|
+
#endif
|
|
2287
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
2288
|
+
let crossProduct2 = prevent_fp64_optimization(a.y * b.x);
|
|
2289
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct2);
|
|
2290
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2291
|
+
prod = split2(prod);
|
|
2292
|
+
#endif
|
|
2293
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
2294
|
+
return prod;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
2298
|
+
let xn = prevent_fp64_optimization(1.0 / b.x);
|
|
2299
|
+
let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
|
|
2300
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);
|
|
2301
|
+
let prod = twoProd(xn, diff);
|
|
2302
|
+
return sum_fp64(yn, prod);
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
2306
|
+
if (a.x == 0.0 && a.y == 0.0) {
|
|
2307
|
+
return vec2f(0.0, 0.0);
|
|
2308
|
+
}
|
|
2309
|
+
if (a.x < 0.0) {
|
|
2310
|
+
let nanValue = fp64_nan(a.x);
|
|
2311
|
+
return vec2f(nanValue, nanValue);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
let x = prevent_fp64_optimization(1.0 / sqrt(a.x));
|
|
2315
|
+
let yn = prevent_fp64_optimization(a.x * x);
|
|
2316
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2317
|
+
let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;
|
|
2318
|
+
#else
|
|
2319
|
+
let ynSqr = twoSqr(yn);
|
|
2320
|
+
#endif
|
|
2321
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);
|
|
2322
|
+
let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);
|
|
2323
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
2324
|
+
return sum_fp64(split(yn), prod);
|
|
2325
|
+
#else
|
|
2326
|
+
return sum_fp64(vec2f(yn, 0.0), prod);
|
|
2327
|
+
#endif
|
|
2328
|
+
}
|
|
2329
|
+
`
|
|
2330
|
+
);
|
|
2331
|
+
|
|
1605
2332
|
// dist/modules/math/fp64/fp64-functions-glsl.js
|
|
1606
2333
|
var fp64functionShader = (
|
|
1607
2334
|
/* glsl */
|
|
@@ -2280,13 +3007,18 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
|
|
|
2280
3007
|
// dist/modules/math/fp64/fp64.js
|
|
2281
3008
|
var defaultUniforms = {
|
|
2282
3009
|
// Used in LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
2283
|
-
ONE: 1
|
|
3010
|
+
ONE: 1,
|
|
3011
|
+
// Runtime split factor for Dekker splitting. Keeping this as a uniform helps
|
|
3012
|
+
// prevent aggressive constant folding in shader compilers.
|
|
3013
|
+
SPLIT: 4097
|
|
2284
3014
|
};
|
|
2285
3015
|
var fp64arithmetic = {
|
|
2286
3016
|
name: "fp64arithmetic",
|
|
3017
|
+
source: fp64arithmeticWGSL,
|
|
3018
|
+
fs: fp64arithmeticShader,
|
|
2287
3019
|
vs: fp64arithmeticShader,
|
|
2288
3020
|
defaultUniforms,
|
|
2289
|
-
uniformTypes: { ONE: "f32" },
|
|
3021
|
+
uniformTypes: { ONE: "f32", SPLIT: "f32" },
|
|
2290
3022
|
// Additional Functions
|
|
2291
3023
|
fp64ify,
|
|
2292
3024
|
fp64LowPart,
|
|
@@ -2490,8 +3222,100 @@ function getUniforms(opts = {}, prevUniforms) {
|
|
|
2490
3222
|
return uniforms;
|
|
2491
3223
|
}
|
|
2492
3224
|
|
|
3225
|
+
// dist/modules/engine/skin/skin.js
|
|
3226
|
+
var import_core2 = require("@math.gl/core");
|
|
3227
|
+
var SKIN_MAX_JOINTS = 20;
|
|
3228
|
+
var source2 = (
|
|
3229
|
+
/* wgsl */
|
|
3230
|
+
`
|
|
3231
|
+
struct skinUniforms {
|
|
3232
|
+
jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
|
|
3233
|
+
};
|
|
3234
|
+
|
|
3235
|
+
@group(0) @binding(auto) var<uniform> skin: skinUniforms;
|
|
3236
|
+
|
|
3237
|
+
fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
3238
|
+
return (weights.x * skin.jointMatrix[joints.x])
|
|
3239
|
+
+ (weights.y * skin.jointMatrix[joints.y])
|
|
3240
|
+
+ (weights.z * skin.jointMatrix[joints.z])
|
|
3241
|
+
+ (weights.w * skin.jointMatrix[joints.w]);
|
|
3242
|
+
}
|
|
3243
|
+
`
|
|
3244
|
+
);
|
|
3245
|
+
var vs2 = (
|
|
3246
|
+
/* glsl */
|
|
3247
|
+
`
|
|
3248
|
+
uniform skinUniforms {
|
|
3249
|
+
mat4 jointMatrix[SKIN_MAX_JOINTS];
|
|
3250
|
+
} skin;
|
|
3251
|
+
|
|
3252
|
+
mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
|
|
3253
|
+
return (weights.x * skin.jointMatrix[joints.x])
|
|
3254
|
+
+ (weights.y * skin.jointMatrix[joints.y])
|
|
3255
|
+
+ (weights.z * skin.jointMatrix[joints.z])
|
|
3256
|
+
+ (weights.w * skin.jointMatrix[joints.w]);
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
`
|
|
3260
|
+
);
|
|
3261
|
+
var fs3 = (
|
|
3262
|
+
/* glsl */
|
|
3263
|
+
``
|
|
3264
|
+
);
|
|
3265
|
+
var skin = {
|
|
3266
|
+
props: {},
|
|
3267
|
+
uniforms: {},
|
|
3268
|
+
name: "skin",
|
|
3269
|
+
bindingLayout: [{ name: "skin", group: 0 }],
|
|
3270
|
+
dependencies: [],
|
|
3271
|
+
source: source2,
|
|
3272
|
+
vs: vs2,
|
|
3273
|
+
fs: fs3,
|
|
3274
|
+
defines: {
|
|
3275
|
+
SKIN_MAX_JOINTS
|
|
3276
|
+
},
|
|
3277
|
+
getUniforms: (props = {}, prevUniforms) => {
|
|
3278
|
+
var _a, _b;
|
|
3279
|
+
const { scenegraphsFromGLTF } = props;
|
|
3280
|
+
if (!((_b = (_a = scenegraphsFromGLTF == null ? void 0 : scenegraphsFromGLTF.gltf) == null ? void 0 : _a.skins) == null ? void 0 : _b[0])) {
|
|
3281
|
+
return { jointMatrix: [] };
|
|
3282
|
+
}
|
|
3283
|
+
const { inverseBindMatrices, joints, skeleton } = scenegraphsFromGLTF.gltf.skins[0];
|
|
3284
|
+
const matsib = [];
|
|
3285
|
+
const countib = inverseBindMatrices.value.length / 16;
|
|
3286
|
+
for (let i = 0; i < countib; i++) {
|
|
3287
|
+
const slice = inverseBindMatrices.value.subarray(i * 16, i * 16 + 16);
|
|
3288
|
+
matsib.push(new import_core2.Matrix4(Array.from(slice)));
|
|
3289
|
+
}
|
|
3290
|
+
const top = scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(skeleton);
|
|
3291
|
+
const matrices = {};
|
|
3292
|
+
top.preorderTraversal((node, { worldMatrix }) => {
|
|
3293
|
+
matrices[node.id] = worldMatrix;
|
|
3294
|
+
});
|
|
3295
|
+
const mats = new Float32Array(SKIN_MAX_JOINTS * 16);
|
|
3296
|
+
for (let i = 0; i < SKIN_MAX_JOINTS; ++i) {
|
|
3297
|
+
const nodeIndex = joints[i];
|
|
3298
|
+
if (nodeIndex === void 0)
|
|
3299
|
+
break;
|
|
3300
|
+
const worldMat = matrices[scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(nodeIndex).id];
|
|
3301
|
+
const invBindMat = matsib[i];
|
|
3302
|
+
const Z = new import_core2.Matrix4().copy(worldMat).multiplyRight(invBindMat);
|
|
3303
|
+
const off = i * 16;
|
|
3304
|
+
for (let j = 0; j < 16; j++) {
|
|
3305
|
+
mats[off + j] = Z[j];
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
return {
|
|
3309
|
+
jointMatrix: mats
|
|
3310
|
+
};
|
|
3311
|
+
},
|
|
3312
|
+
uniformTypes: {
|
|
3313
|
+
jointMatrix: ["mat4x4<f32>", SKIN_MAX_JOINTS]
|
|
3314
|
+
}
|
|
3315
|
+
};
|
|
3316
|
+
|
|
2493
3317
|
// dist/modules/lighting/lights/lighting.js
|
|
2494
|
-
var
|
|
3318
|
+
var import_core3 = require("@luma.gl/core");
|
|
2495
3319
|
|
|
2496
3320
|
// dist/modules/lighting/lights/lighting-glsl.js
|
|
2497
3321
|
var lightingUniformsGLSL = (
|
|
@@ -2509,59 +3333,51 @@ struct PointLight {
|
|
|
2509
3333
|
vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
|
|
2510
3334
|
};
|
|
2511
3335
|
|
|
3336
|
+
struct SpotLight {
|
|
3337
|
+
vec3 color;
|
|
3338
|
+
vec3 position;
|
|
3339
|
+
vec3 direction;
|
|
3340
|
+
vec3 attenuation;
|
|
3341
|
+
vec2 coneCos;
|
|
3342
|
+
};
|
|
3343
|
+
|
|
2512
3344
|
struct DirectionalLight {
|
|
2513
3345
|
vec3 color;
|
|
2514
3346
|
vec3 direction;
|
|
2515
3347
|
};
|
|
2516
3348
|
|
|
3349
|
+
struct UniformLight {
|
|
3350
|
+
vec3 color;
|
|
3351
|
+
vec3 position;
|
|
3352
|
+
vec3 direction;
|
|
3353
|
+
vec3 attenuation;
|
|
3354
|
+
vec2 coneCos;
|
|
3355
|
+
};
|
|
3356
|
+
|
|
2517
3357
|
uniform lightingUniforms {
|
|
2518
3358
|
int enabled;
|
|
2519
|
-
int lightType;
|
|
2520
|
-
|
|
2521
3359
|
int directionalLightCount;
|
|
2522
3360
|
int pointLightCount;
|
|
2523
|
-
|
|
3361
|
+
int spotLightCount;
|
|
2524
3362
|
vec3 ambientColor;
|
|
2525
|
-
|
|
2526
|
-
vec3 lightColor0;
|
|
2527
|
-
vec3 lightPosition0;
|
|
2528
|
-
vec3 lightDirection0;
|
|
2529
|
-
vec3 lightAttenuation0;
|
|
2530
|
-
|
|
2531
|
-
vec3 lightColor1;
|
|
2532
|
-
vec3 lightPosition1;
|
|
2533
|
-
vec3 lightDirection1;
|
|
2534
|
-
vec3 lightAttenuation1;
|
|
2535
|
-
|
|
2536
|
-
vec3 lightColor2;
|
|
2537
|
-
vec3 lightPosition2;
|
|
2538
|
-
vec3 lightDirection2;
|
|
2539
|
-
vec3 lightAttenuation2;
|
|
3363
|
+
UniformLight lights[5];
|
|
2540
3364
|
} lighting;
|
|
2541
3365
|
|
|
2542
3366
|
PointLight lighting_getPointLight(int index) {
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
|
|
2551
|
-
}
|
|
3367
|
+
UniformLight light = lighting.lights[index];
|
|
3368
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
SpotLight lighting_getSpotLight(int index) {
|
|
3372
|
+
UniformLight light = lighting.lights[lighting.pointLightCount + index];
|
|
3373
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
2552
3374
|
}
|
|
2553
3375
|
|
|
2554
3376
|
DirectionalLight lighting_getDirectionalLight(int index) {
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
2560
|
-
case 2:
|
|
2561
|
-
default:
|
|
2562
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
2563
|
-
}
|
|
2564
|
-
}
|
|
3377
|
+
UniformLight light =
|
|
3378
|
+
lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
3379
|
+
return DirectionalLight(light.color, light.direction);
|
|
3380
|
+
}
|
|
2565
3381
|
|
|
2566
3382
|
float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
2567
3383
|
return pointLight.attenuation.x
|
|
@@ -2569,6 +3385,20 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
|
2569
3385
|
+ pointLight.attenuation.z * distance * distance;
|
|
2570
3386
|
}
|
|
2571
3387
|
|
|
3388
|
+
float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {
|
|
3389
|
+
vec3 light_direction = normalize(positionWorldspace - spotLight.position);
|
|
3390
|
+
float coneFactor = smoothstep(
|
|
3391
|
+
spotLight.coneCos.y,
|
|
3392
|
+
spotLight.coneCos.x,
|
|
3393
|
+
dot(normalize(spotLight.direction), light_direction)
|
|
3394
|
+
);
|
|
3395
|
+
float distanceAttenuation = getPointLightAttenuation(
|
|
3396
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
3397
|
+
distance(spotLight.position, positionWorldspace)
|
|
3398
|
+
);
|
|
3399
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
3400
|
+
}
|
|
3401
|
+
|
|
2572
3402
|
// #endif
|
|
2573
3403
|
`
|
|
2574
3404
|
);
|
|
@@ -2577,6 +3407,8 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
|
2577
3407
|
var lightingUniformsWGSL = (
|
|
2578
3408
|
/* wgsl */
|
|
2579
3409
|
`// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
|
|
3410
|
+
const MAX_LIGHTS: i32 = 5;
|
|
3411
|
+
|
|
2580
3412
|
struct AmbientLight {
|
|
2581
3413
|
color: vec3<f32>,
|
|
2582
3414
|
};
|
|
@@ -2587,57 +3419,85 @@ struct PointLight {
|
|
|
2587
3419
|
attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
|
|
2588
3420
|
};
|
|
2589
3421
|
|
|
3422
|
+
struct SpotLight {
|
|
3423
|
+
color: vec3<f32>,
|
|
3424
|
+
position: vec3<f32>,
|
|
3425
|
+
direction: vec3<f32>,
|
|
3426
|
+
attenuation: vec3<f32>,
|
|
3427
|
+
coneCos: vec2<f32>,
|
|
3428
|
+
};
|
|
3429
|
+
|
|
2590
3430
|
struct DirectionalLight {
|
|
2591
3431
|
color: vec3<f32>,
|
|
2592
3432
|
direction: vec3<f32>,
|
|
2593
3433
|
};
|
|
2594
3434
|
|
|
3435
|
+
struct UniformLight {
|
|
3436
|
+
color: vec3<f32>,
|
|
3437
|
+
position: vec3<f32>,
|
|
3438
|
+
direction: vec3<f32>,
|
|
3439
|
+
attenuation: vec3<f32>,
|
|
3440
|
+
coneCos: vec2<f32>,
|
|
3441
|
+
};
|
|
3442
|
+
|
|
2595
3443
|
struct lightingUniforms {
|
|
2596
3444
|
enabled: i32,
|
|
2597
|
-
pointLightCount: i32,
|
|
2598
3445
|
directionalLightCount: i32,
|
|
2599
|
-
|
|
3446
|
+
pointLightCount: i32,
|
|
3447
|
+
spotLightCount: i32,
|
|
2600
3448
|
ambientColor: vec3<f32>,
|
|
2601
|
-
|
|
2602
|
-
// TODO - support multiple lights by uncommenting arrays below
|
|
2603
|
-
lightType: i32,
|
|
2604
|
-
lightColor: vec3<f32>,
|
|
2605
|
-
lightDirection: vec3<f32>,
|
|
2606
|
-
lightPosition: vec3<f32>,
|
|
2607
|
-
lightAttenuation: vec3<f32>,
|
|
2608
|
-
|
|
2609
|
-
// AmbientLight ambientLight;
|
|
2610
|
-
// PointLight pointLight[MAX_LIGHTS];
|
|
2611
|
-
// DirectionalLight directionalLight[MAX_LIGHTS];
|
|
3449
|
+
lights: array<UniformLight, 5>,
|
|
2612
3450
|
};
|
|
2613
3451
|
|
|
2614
|
-
|
|
2615
|
-
@binding(1) @group(0) var<uniform> lighting : lightingUniforms;
|
|
3452
|
+
@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
|
|
2616
3453
|
|
|
2617
3454
|
fn lighting_getPointLight(index: i32) -> PointLight {
|
|
2618
|
-
|
|
3455
|
+
let light = lighting.lights[index];
|
|
3456
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
fn lighting_getSpotLight(index: i32) -> SpotLight {
|
|
3460
|
+
let light = lighting.lights[lighting.pointLightCount + index];
|
|
3461
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
2619
3462
|
}
|
|
2620
3463
|
|
|
2621
3464
|
fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
|
|
2622
|
-
|
|
2623
|
-
|
|
3465
|
+
let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
3466
|
+
return DirectionalLight(light.color, light.direction);
|
|
3467
|
+
}
|
|
2624
3468
|
|
|
2625
3469
|
fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
2626
3470
|
return pointLight.attenuation.x
|
|
2627
3471
|
+ pointLight.attenuation.y * distance
|
|
2628
3472
|
+ pointLight.attenuation.z * distance * distance;
|
|
2629
3473
|
}
|
|
3474
|
+
|
|
3475
|
+
fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
|
|
3476
|
+
let lightDirection = normalize(positionWorldspace - spotLight.position);
|
|
3477
|
+
let coneFactor = smoothstep(
|
|
3478
|
+
spotLight.coneCos.y,
|
|
3479
|
+
spotLight.coneCos.x,
|
|
3480
|
+
dot(normalize(spotLight.direction), lightDirection)
|
|
3481
|
+
);
|
|
3482
|
+
let distanceAttenuation = getPointLightAttenuation(
|
|
3483
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
3484
|
+
distance(spotLight.position, positionWorldspace)
|
|
3485
|
+
);
|
|
3486
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
3487
|
+
}
|
|
2630
3488
|
`
|
|
2631
3489
|
);
|
|
2632
3490
|
|
|
2633
3491
|
// dist/modules/lighting/lights/lighting.js
|
|
2634
3492
|
var MAX_LIGHTS = 5;
|
|
2635
3493
|
var COLOR_FACTOR = 255;
|
|
2636
|
-
var
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
3494
|
+
var LIGHT_UNIFORM_TYPE = {
|
|
3495
|
+
color: "vec3<f32>",
|
|
3496
|
+
position: "vec3<f32>",
|
|
3497
|
+
direction: "vec3<f32>",
|
|
3498
|
+
attenuation: "vec3<f32>",
|
|
3499
|
+
coneCos: "vec2<f32>"
|
|
3500
|
+
};
|
|
2641
3501
|
var lighting = {
|
|
2642
3502
|
props: {},
|
|
2643
3503
|
uniforms: {},
|
|
@@ -2647,102 +3507,105 @@ var lighting = {
|
|
|
2647
3507
|
},
|
|
2648
3508
|
uniformTypes: {
|
|
2649
3509
|
enabled: "i32",
|
|
2650
|
-
lightType: "i32",
|
|
2651
3510
|
directionalLightCount: "i32",
|
|
2652
3511
|
pointLightCount: "i32",
|
|
3512
|
+
spotLightCount: "i32",
|
|
2653
3513
|
ambientColor: "vec3<f32>",
|
|
2654
|
-
|
|
2655
|
-
lightColor0: "vec3<f32>",
|
|
2656
|
-
lightPosition0: "vec3<f32>",
|
|
2657
|
-
// TODO - could combine direction and attenuation
|
|
2658
|
-
lightDirection0: "vec3<f32>",
|
|
2659
|
-
lightAttenuation0: "vec3<f32>",
|
|
2660
|
-
lightColor1: "vec3<f32>",
|
|
2661
|
-
lightPosition1: "vec3<f32>",
|
|
2662
|
-
lightDirection1: "vec3<f32>",
|
|
2663
|
-
lightAttenuation1: "vec3<f32>",
|
|
2664
|
-
lightColor2: "vec3<f32>",
|
|
2665
|
-
lightPosition2: "vec3<f32>",
|
|
2666
|
-
lightDirection2: "vec3<f32>",
|
|
2667
|
-
lightAttenuation2: "vec3<f32>"
|
|
2668
|
-
},
|
|
2669
|
-
defaultUniforms: {
|
|
2670
|
-
enabled: 1,
|
|
2671
|
-
lightType: LIGHT_TYPE.POINT,
|
|
2672
|
-
directionalLightCount: 0,
|
|
2673
|
-
pointLightCount: 0,
|
|
2674
|
-
ambientColor: [0.1, 0.1, 0.1],
|
|
2675
|
-
lightColor0: [1, 1, 1],
|
|
2676
|
-
lightPosition0: [1, 1, 2],
|
|
2677
|
-
// TODO - could combine direction and attenuation
|
|
2678
|
-
lightDirection0: [1, 1, 1],
|
|
2679
|
-
lightAttenuation0: [1, 0, 0],
|
|
2680
|
-
lightColor1: [1, 1, 1],
|
|
2681
|
-
lightPosition1: [1, 1, 2],
|
|
2682
|
-
lightDirection1: [1, 1, 1],
|
|
2683
|
-
lightAttenuation1: [1, 0, 0],
|
|
2684
|
-
lightColor2: [1, 1, 1],
|
|
2685
|
-
lightPosition2: [1, 1, 2],
|
|
2686
|
-
lightDirection2: [1, 1, 1],
|
|
2687
|
-
lightAttenuation2: [1, 0, 0]
|
|
3514
|
+
lights: [LIGHT_UNIFORM_TYPE, MAX_LIGHTS]
|
|
2688
3515
|
},
|
|
3516
|
+
defaultUniforms: createDefaultLightingUniforms(),
|
|
3517
|
+
bindingLayout: [{ name: "lighting", group: 2 }],
|
|
3518
|
+
firstBindingSlot: 0,
|
|
2689
3519
|
source: lightingUniformsWGSL,
|
|
2690
3520
|
vs: lightingUniformsGLSL,
|
|
2691
3521
|
fs: lightingUniformsGLSL,
|
|
2692
3522
|
getUniforms: getUniforms2
|
|
2693
3523
|
};
|
|
2694
|
-
function getUniforms2(props,
|
|
3524
|
+
function getUniforms2(props, _prevUniforms = {}) {
|
|
2695
3525
|
props = props ? { ...props } : props;
|
|
2696
3526
|
if (!props) {
|
|
2697
|
-
return
|
|
3527
|
+
return createDefaultLightingUniforms();
|
|
2698
3528
|
}
|
|
2699
3529
|
if (props.lights) {
|
|
2700
3530
|
props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
|
|
2701
3531
|
}
|
|
2702
|
-
const { ambientLight, pointLights, directionalLights } = props || {};
|
|
2703
|
-
const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
3532
|
+
const { ambientLight, pointLights, spotLights, directionalLights } = props || {};
|
|
3533
|
+
const hasLights = ambientLight || pointLights && pointLights.length > 0 || spotLights && spotLights.length > 0 || directionalLights && directionalLights.length > 0;
|
|
2704
3534
|
if (!hasLights) {
|
|
2705
|
-
return {
|
|
3535
|
+
return {
|
|
3536
|
+
...createDefaultLightingUniforms(),
|
|
3537
|
+
enabled: 0
|
|
3538
|
+
};
|
|
2706
3539
|
}
|
|
2707
3540
|
const uniforms = {
|
|
2708
|
-
...
|
|
2709
|
-
...
|
|
2710
|
-
...getLightSourceUniforms({ ambientLight, pointLights, directionalLights })
|
|
3541
|
+
...createDefaultLightingUniforms(),
|
|
3542
|
+
...getLightSourceUniforms({ ambientLight, pointLights, spotLights, directionalLights })
|
|
2711
3543
|
};
|
|
2712
3544
|
if (props.enabled !== void 0) {
|
|
2713
3545
|
uniforms.enabled = props.enabled ? 1 : 0;
|
|
2714
3546
|
}
|
|
2715
3547
|
return uniforms;
|
|
2716
3548
|
}
|
|
2717
|
-
function getLightSourceUniforms({ ambientLight, pointLights = [], directionalLights = [] }) {
|
|
2718
|
-
const
|
|
2719
|
-
lightSourceUniforms.ambientColor = convertColor(ambientLight);
|
|
3549
|
+
function getLightSourceUniforms({ ambientLight, pointLights = [], spotLights = [], directionalLights = [] }) {
|
|
3550
|
+
const lights = createDefaultLightUniforms();
|
|
2720
3551
|
let currentLight = 0;
|
|
3552
|
+
let pointLightCount = 0;
|
|
3553
|
+
let spotLightCount = 0;
|
|
3554
|
+
let directionalLightCount = 0;
|
|
2721
3555
|
for (const pointLight of pointLights) {
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
3556
|
+
if (currentLight >= MAX_LIGHTS) {
|
|
3557
|
+
break;
|
|
3558
|
+
}
|
|
3559
|
+
lights[currentLight] = {
|
|
3560
|
+
...lights[currentLight],
|
|
3561
|
+
color: convertColor(pointLight),
|
|
3562
|
+
position: pointLight.position,
|
|
3563
|
+
attenuation: pointLight.attenuation || [1, 0, 0]
|
|
3564
|
+
};
|
|
3565
|
+
currentLight++;
|
|
3566
|
+
pointLightCount++;
|
|
3567
|
+
}
|
|
3568
|
+
for (const spotLight of spotLights) {
|
|
3569
|
+
if (currentLight >= MAX_LIGHTS) {
|
|
3570
|
+
break;
|
|
3571
|
+
}
|
|
3572
|
+
lights[currentLight] = {
|
|
3573
|
+
...lights[currentLight],
|
|
3574
|
+
color: convertColor(spotLight),
|
|
3575
|
+
position: spotLight.position,
|
|
3576
|
+
direction: spotLight.direction,
|
|
3577
|
+
attenuation: spotLight.attenuation || [1, 0, 0],
|
|
3578
|
+
coneCos: getSpotConeCos(spotLight)
|
|
3579
|
+
};
|
|
2727
3580
|
currentLight++;
|
|
3581
|
+
spotLightCount++;
|
|
2728
3582
|
}
|
|
2729
3583
|
for (const directionalLight of directionalLights) {
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
3584
|
+
if (currentLight >= MAX_LIGHTS) {
|
|
3585
|
+
break;
|
|
3586
|
+
}
|
|
3587
|
+
lights[currentLight] = {
|
|
3588
|
+
...lights[currentLight],
|
|
3589
|
+
color: convertColor(directionalLight),
|
|
3590
|
+
direction: directionalLight.direction
|
|
3591
|
+
};
|
|
2734
3592
|
currentLight++;
|
|
3593
|
+
directionalLightCount++;
|
|
2735
3594
|
}
|
|
2736
|
-
if (
|
|
2737
|
-
|
|
3595
|
+
if (pointLights.length + spotLights.length + directionalLights.length > MAX_LIGHTS) {
|
|
3596
|
+
import_core3.log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
|
|
2738
3597
|
}
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
3598
|
+
return {
|
|
3599
|
+
ambientColor: convertColor(ambientLight),
|
|
3600
|
+
directionalLightCount,
|
|
3601
|
+
pointLightCount,
|
|
3602
|
+
spotLightCount,
|
|
3603
|
+
lights
|
|
3604
|
+
};
|
|
2742
3605
|
}
|
|
2743
3606
|
function extractLightTypes(lights) {
|
|
2744
|
-
var _a, _b;
|
|
2745
|
-
const lightSources = { pointLights: [], directionalLights: [] };
|
|
3607
|
+
var _a, _b, _c;
|
|
3608
|
+
const lightSources = { pointLights: [], spotLights: [], directionalLights: [] };
|
|
2746
3609
|
for (const light of lights || []) {
|
|
2747
3610
|
switch (light.type) {
|
|
2748
3611
|
case "ambient":
|
|
@@ -2754,6 +3617,9 @@ function extractLightTypes(lights) {
|
|
|
2754
3617
|
case "point":
|
|
2755
3618
|
(_b = lightSources.pointLights) == null ? void 0 : _b.push(light);
|
|
2756
3619
|
break;
|
|
3620
|
+
case "spot":
|
|
3621
|
+
(_c = lightSources.spotLights) == null ? void 0 : _c.push(light);
|
|
3622
|
+
break;
|
|
2757
3623
|
default:
|
|
2758
3624
|
}
|
|
2759
3625
|
}
|
|
@@ -2763,6 +3629,68 @@ function convertColor(colorDef = {}) {
|
|
|
2763
3629
|
const { color = [0, 0, 0], intensity = 1 } = colorDef;
|
|
2764
3630
|
return color.map((component) => component * intensity / COLOR_FACTOR);
|
|
2765
3631
|
}
|
|
3632
|
+
function createDefaultLightingUniforms() {
|
|
3633
|
+
return {
|
|
3634
|
+
enabled: 1,
|
|
3635
|
+
directionalLightCount: 0,
|
|
3636
|
+
pointLightCount: 0,
|
|
3637
|
+
spotLightCount: 0,
|
|
3638
|
+
ambientColor: [0.1, 0.1, 0.1],
|
|
3639
|
+
lights: createDefaultLightUniforms()
|
|
3640
|
+
};
|
|
3641
|
+
}
|
|
3642
|
+
function createDefaultLightUniforms() {
|
|
3643
|
+
return Array.from({ length: MAX_LIGHTS }, () => createDefaultLightUniform());
|
|
3644
|
+
}
|
|
3645
|
+
function createDefaultLightUniform() {
|
|
3646
|
+
return {
|
|
3647
|
+
color: [1, 1, 1],
|
|
3648
|
+
position: [1, 1, 2],
|
|
3649
|
+
direction: [1, 1, 1],
|
|
3650
|
+
attenuation: [1, 0, 0],
|
|
3651
|
+
coneCos: [1, 0]
|
|
3652
|
+
};
|
|
3653
|
+
}
|
|
3654
|
+
function getSpotConeCos(spotLight) {
|
|
3655
|
+
const innerConeAngle = spotLight.innerConeAngle ?? 0;
|
|
3656
|
+
const outerConeAngle = spotLight.outerConeAngle ?? Math.PI / 4;
|
|
3657
|
+
return [Math.cos(innerConeAngle), Math.cos(outerConeAngle)];
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
// dist/modules/lighting/ibl/ibl.js
|
|
3661
|
+
var iblWGSL = (
|
|
3662
|
+
/* wgsl */
|
|
3663
|
+
`#ifdef USE_IBL
|
|
3664
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
|
|
3665
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
|
|
3666
|
+
@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
|
|
3667
|
+
@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
|
|
3668
|
+
@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
|
|
3669
|
+
@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
|
|
3670
|
+
#endif
|
|
3671
|
+
`
|
|
3672
|
+
);
|
|
3673
|
+
var iblGLSL = (
|
|
3674
|
+
/* glsl */
|
|
3675
|
+
`#ifdef USE_IBL
|
|
3676
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
3677
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
3678
|
+
uniform sampler2D pbr_brdfLUT;
|
|
3679
|
+
#endif
|
|
3680
|
+
`
|
|
3681
|
+
);
|
|
3682
|
+
var ibl = {
|
|
3683
|
+
name: "ibl",
|
|
3684
|
+
firstBindingSlot: 32,
|
|
3685
|
+
bindingLayout: [
|
|
3686
|
+
{ name: "pbr_diffuseEnvSampler", group: 2 },
|
|
3687
|
+
{ name: "pbr_specularEnvSampler", group: 2 },
|
|
3688
|
+
{ name: "pbr_brdfLUT", group: 2 }
|
|
3689
|
+
],
|
|
3690
|
+
source: iblWGSL,
|
|
3691
|
+
vs: iblGLSL,
|
|
3692
|
+
fs: iblGLSL
|
|
3693
|
+
};
|
|
2766
3694
|
|
|
2767
3695
|
// dist/modules/lighting/no-material/dirlight.js
|
|
2768
3696
|
var SOURCE_WGSL = (
|
|
@@ -2778,7 +3706,7 @@ struct DirlightInputs {
|
|
|
2778
3706
|
normal: DirlightNormal,
|
|
2779
3707
|
};
|
|
2780
3708
|
|
|
2781
|
-
@
|
|
3709
|
+
@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;
|
|
2782
3710
|
|
|
2783
3711
|
// For vertex
|
|
2784
3712
|
fn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {
|
|
@@ -2823,6 +3751,8 @@ var dirlight = {
|
|
|
2823
3751
|
props: {},
|
|
2824
3752
|
uniforms: {},
|
|
2825
3753
|
name: "dirlight",
|
|
3754
|
+
bindingLayout: [{ name: "dirlight", group: 2 }],
|
|
3755
|
+
firstBindingSlot: 16,
|
|
2826
3756
|
dependencies: [],
|
|
2827
3757
|
source: SOURCE_WGSL,
|
|
2828
3758
|
vs: VS_GLSL,
|
|
@@ -2849,10 +3779,173 @@ function getUniforms3(opts = dirlight.defaultUniforms) {
|
|
|
2849
3779
|
return uniforms;
|
|
2850
3780
|
}
|
|
2851
3781
|
|
|
3782
|
+
// dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js
|
|
3783
|
+
var LAMBERT_WGSL = (
|
|
3784
|
+
/* wgsl */
|
|
3785
|
+
`struct lambertMaterialUniforms {
|
|
3786
|
+
unlit: u32,
|
|
3787
|
+
ambient: f32,
|
|
3788
|
+
diffuse: f32,
|
|
3789
|
+
};
|
|
3790
|
+
|
|
3791
|
+
@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;
|
|
3792
|
+
|
|
3793
|
+
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
3794
|
+
let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);
|
|
3795
|
+
return lambertian * lambertMaterial.diffuse * surfaceColor * color;
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
3799
|
+
var lightColor: vec3<f32> = surfaceColor;
|
|
3800
|
+
|
|
3801
|
+
if (lambertMaterial.unlit != 0u) {
|
|
3802
|
+
return surfaceColor;
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
if (lighting.enabled == 0) {
|
|
3806
|
+
return lightColor;
|
|
3807
|
+
}
|
|
3808
|
+
|
|
3809
|
+
lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
3810
|
+
|
|
3811
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
3812
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
3813
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
3814
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
3815
|
+
let light_attenuation = getPointLightAttenuation(
|
|
3816
|
+
pointLight,
|
|
3817
|
+
distance(light_position_worldspace, position_worldspace)
|
|
3818
|
+
);
|
|
3819
|
+
lightColor += lighting_getLightColor(
|
|
3820
|
+
surfaceColor,
|
|
3821
|
+
light_direction,
|
|
3822
|
+
normal_worldspace,
|
|
3823
|
+
pointLight.color / light_attenuation
|
|
3824
|
+
);
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
3828
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
3829
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
3830
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
3831
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
3832
|
+
lightColor += lighting_getLightColor(
|
|
3833
|
+
surfaceColor,
|
|
3834
|
+
light_direction,
|
|
3835
|
+
normal_worldspace,
|
|
3836
|
+
spotLight.color / light_attenuation
|
|
3837
|
+
);
|
|
3838
|
+
}
|
|
3839
|
+
|
|
3840
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
3841
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
3842
|
+
lightColor += lighting_getLightColor(
|
|
3843
|
+
surfaceColor,
|
|
3844
|
+
-directionalLight.direction,
|
|
3845
|
+
normal_worldspace,
|
|
3846
|
+
directionalLight.color
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3850
|
+
return lightColor;
|
|
3851
|
+
}
|
|
3852
|
+
`
|
|
3853
|
+
);
|
|
3854
|
+
|
|
3855
|
+
// dist/modules/lighting/lambert-material/lambert-shaders-glsl.js
|
|
3856
|
+
var LAMBERT_VS = (
|
|
3857
|
+
/* glsl */
|
|
3858
|
+
`uniform lambertMaterialUniforms {
|
|
3859
|
+
uniform bool unlit;
|
|
3860
|
+
uniform float ambient;
|
|
3861
|
+
uniform float diffuse;
|
|
3862
|
+
} material;
|
|
3863
|
+
`
|
|
3864
|
+
);
|
|
3865
|
+
var LAMBERT_FS = (
|
|
3866
|
+
/* glsl */
|
|
3867
|
+
`uniform lambertMaterialUniforms {
|
|
3868
|
+
uniform bool unlit;
|
|
3869
|
+
uniform float ambient;
|
|
3870
|
+
uniform float diffuse;
|
|
3871
|
+
} material;
|
|
3872
|
+
|
|
3873
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {
|
|
3874
|
+
float lambertian = max(dot(light_direction, normal_worldspace), 0.0);
|
|
3875
|
+
return lambertian * material.diffuse * surfaceColor * color;
|
|
3876
|
+
}
|
|
3877
|
+
|
|
3878
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
3879
|
+
vec3 lightColor = surfaceColor;
|
|
3880
|
+
|
|
3881
|
+
if (material.unlit) {
|
|
3882
|
+
return surfaceColor;
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3885
|
+
if (lighting.enabled == 0) {
|
|
3886
|
+
return lightColor;
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
lightColor = material.ambient * surfaceColor * lighting.ambientColor;
|
|
3890
|
+
|
|
3891
|
+
for (int i = 0; i < lighting.pointLightCount; i++) {
|
|
3892
|
+
PointLight pointLight = lighting_getPointLight(i);
|
|
3893
|
+
vec3 light_position_worldspace = pointLight.position;
|
|
3894
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
3895
|
+
float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));
|
|
3896
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
3900
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
3901
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
3902
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
3903
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
3904
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3907
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
3908
|
+
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
3909
|
+
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
return lightColor;
|
|
3913
|
+
}
|
|
3914
|
+
`
|
|
3915
|
+
);
|
|
3916
|
+
|
|
3917
|
+
// dist/modules/lighting/lambert-material/lambert-material.js
|
|
3918
|
+
var lambertMaterial = {
|
|
3919
|
+
name: "lambertMaterial",
|
|
3920
|
+
firstBindingSlot: 0,
|
|
3921
|
+
bindingLayout: [{ name: "lambertMaterial", group: 3 }],
|
|
3922
|
+
dependencies: [lighting],
|
|
3923
|
+
source: LAMBERT_WGSL,
|
|
3924
|
+
vs: LAMBERT_VS,
|
|
3925
|
+
fs: LAMBERT_FS,
|
|
3926
|
+
defines: {
|
|
3927
|
+
LIGHTING_FRAGMENT: true
|
|
3928
|
+
},
|
|
3929
|
+
uniformTypes: {
|
|
3930
|
+
unlit: "i32",
|
|
3931
|
+
ambient: "f32",
|
|
3932
|
+
diffuse: "f32"
|
|
3933
|
+
},
|
|
3934
|
+
defaultUniforms: {
|
|
3935
|
+
unlit: false,
|
|
3936
|
+
ambient: 0.35,
|
|
3937
|
+
diffuse: 0.6
|
|
3938
|
+
},
|
|
3939
|
+
getUniforms(props) {
|
|
3940
|
+
return { ...lambertMaterial.defaultUniforms, ...props };
|
|
3941
|
+
}
|
|
3942
|
+
};
|
|
3943
|
+
|
|
2852
3944
|
// dist/modules/lighting/phong-material/phong-shaders-glsl.js
|
|
2853
3945
|
var PHONG_VS = (
|
|
2854
3946
|
/* glsl */
|
|
2855
3947
|
`uniform phongMaterialUniforms {
|
|
3948
|
+
uniform bool unlit;
|
|
2856
3949
|
uniform float ambient;
|
|
2857
3950
|
uniform float diffuse;
|
|
2858
3951
|
uniform float shininess;
|
|
@@ -2862,9 +3955,8 @@ var PHONG_VS = (
|
|
|
2862
3955
|
);
|
|
2863
3956
|
var PHONG_FS = (
|
|
2864
3957
|
/* glsl */
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
uniform phongMaterialUniforms {
|
|
3958
|
+
`uniform phongMaterialUniforms {
|
|
3959
|
+
uniform bool unlit;
|
|
2868
3960
|
uniform float ambient;
|
|
2869
3961
|
uniform float diffuse;
|
|
2870
3962
|
uniform float shininess;
|
|
@@ -2886,6 +3978,10 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_d
|
|
|
2886
3978
|
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
2887
3979
|
vec3 lightColor = surfaceColor;
|
|
2888
3980
|
|
|
3981
|
+
if (material.unlit) {
|
|
3982
|
+
return surfaceColor;
|
|
3983
|
+
}
|
|
3984
|
+
|
|
2889
3985
|
if (lighting.enabled == 0) {
|
|
2890
3986
|
return lightColor;
|
|
2891
3987
|
}
|
|
@@ -2901,8 +3997,15 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
2901
3997
|
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
2902
3998
|
}
|
|
2903
3999
|
|
|
2904
|
-
int
|
|
2905
|
-
|
|
4000
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
4001
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
4002
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
4003
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
4004
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4005
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
2906
4009
|
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
2907
4010
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
2908
4011
|
}
|
|
@@ -2916,13 +4019,14 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
2916
4019
|
var PHONG_WGSL = (
|
|
2917
4020
|
/* wgsl */
|
|
2918
4021
|
`struct phongMaterialUniforms {
|
|
4022
|
+
unlit: u32,
|
|
2919
4023
|
ambient: f32,
|
|
2920
4024
|
diffuse: f32,
|
|
2921
4025
|
shininess: f32,
|
|
2922
4026
|
specularColor: vec3<f32>,
|
|
2923
4027
|
};
|
|
2924
4028
|
|
|
2925
|
-
@
|
|
4029
|
+
@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;
|
|
2926
4030
|
|
|
2927
4031
|
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
2928
4032
|
let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);
|
|
@@ -2939,6 +4043,10 @@ fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, v
|
|
|
2939
4043
|
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
2940
4044
|
var lightColor: vec3<f32> = surfaceColor;
|
|
2941
4045
|
|
|
4046
|
+
if (phongMaterial.unlit != 0u) {
|
|
4047
|
+
return surfaceColor;
|
|
4048
|
+
}
|
|
4049
|
+
|
|
2942
4050
|
if (lighting.enabled == 0) {
|
|
2943
4051
|
return lightColor;
|
|
2944
4052
|
}
|
|
@@ -2946,56 +4054,86 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
|
|
|
2946
4054
|
let view_direction: vec3<f32> = normalize(cameraPosition - position_worldspace);
|
|
2947
4055
|
lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
2948
4056
|
|
|
2949
|
-
|
|
2950
|
-
let pointLight: PointLight
|
|
4057
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
4058
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
2951
4059
|
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
2952
4060
|
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
4061
|
+
let light_attenuation = getPointLightAttenuation(
|
|
4062
|
+
pointLight,
|
|
4063
|
+
distance(light_position_worldspace, position_worldspace)
|
|
4064
|
+
);
|
|
4065
|
+
lightColor += lighting_getLightColor(
|
|
4066
|
+
surfaceColor,
|
|
4067
|
+
light_direction,
|
|
4068
|
+
view_direction,
|
|
4069
|
+
normal_worldspace,
|
|
4070
|
+
pointLight.color / light_attenuation
|
|
4071
|
+
);
|
|
2957
4072
|
}
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
4073
|
+
|
|
4074
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
4075
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
4076
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
4077
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
4078
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4079
|
+
lightColor += lighting_getLightColor(
|
|
4080
|
+
surfaceColor,
|
|
4081
|
+
light_direction,
|
|
4082
|
+
view_direction,
|
|
4083
|
+
normal_worldspace,
|
|
4084
|
+
spotLight.color / light_attenuation
|
|
4085
|
+
);
|
|
2969
4086
|
}
|
|
2970
4087
|
|
|
2971
|
-
for (
|
|
2972
|
-
|
|
2973
|
-
break;
|
|
2974
|
-
}
|
|
2975
|
-
DirectionalLight directionalLight = lighting.directionalLight[i];
|
|
4088
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
4089
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
2976
4090
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
2977
|
-
}
|
|
2978
|
-
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4093
|
+
return lightColor;
|
|
2979
4094
|
}
|
|
2980
4095
|
|
|
2981
4096
|
fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32>{
|
|
2982
4097
|
var lightColor = vec3<f32>(0, 0, 0);
|
|
2983
4098
|
let surfaceColor = vec3<f32>(0, 0, 0);
|
|
2984
4099
|
|
|
2985
|
-
if (lighting.enabled
|
|
4100
|
+
if (lighting.enabled != 0) {
|
|
2986
4101
|
let view_direction = normalize(cameraPosition - position_worldspace);
|
|
2987
4102
|
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
4103
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
4104
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
4105
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
4106
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
4107
|
+
let light_attenuation = getPointLightAttenuation(
|
|
4108
|
+
pointLight,
|
|
4109
|
+
distance(light_position_worldspace, position_worldspace)
|
|
4110
|
+
);
|
|
4111
|
+
lightColor += lighting_getLightColor(
|
|
4112
|
+
surfaceColor,
|
|
4113
|
+
light_direction,
|
|
4114
|
+
view_direction,
|
|
4115
|
+
normal_worldspace,
|
|
4116
|
+
pointLight.color / light_attenuation
|
|
4117
|
+
);
|
|
4118
|
+
}
|
|
4119
|
+
|
|
4120
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
4121
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
4122
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
4123
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
4124
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
4125
|
+
lightColor += lighting_getLightColor(
|
|
4126
|
+
surfaceColor,
|
|
4127
|
+
light_direction,
|
|
4128
|
+
view_direction,
|
|
4129
|
+
normal_worldspace,
|
|
4130
|
+
spotLight.color / light_attenuation
|
|
4131
|
+
);
|
|
4132
|
+
}
|
|
4133
|
+
|
|
4134
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
4135
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
2997
4136
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
2998
|
-
}
|
|
2999
4137
|
}
|
|
3000
4138
|
}
|
|
3001
4139
|
return lightColor;
|
|
@@ -3007,6 +4145,7 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
3007
4145
|
var gouraudMaterial = {
|
|
3008
4146
|
props: {},
|
|
3009
4147
|
name: "gouraudMaterial",
|
|
4148
|
+
bindingLayout: [{ name: "gouraudMaterial", group: 3 }],
|
|
3010
4149
|
// Note these are switched between phong and gouraud
|
|
3011
4150
|
vs: PHONG_FS.replace("phongMaterial", "gouraudMaterial"),
|
|
3012
4151
|
fs: PHONG_VS.replace("phongMaterial", "gouraudMaterial"),
|
|
@@ -3016,12 +4155,14 @@ var gouraudMaterial = {
|
|
|
3016
4155
|
},
|
|
3017
4156
|
dependencies: [lighting],
|
|
3018
4157
|
uniformTypes: {
|
|
4158
|
+
unlit: "i32",
|
|
3019
4159
|
ambient: "f32",
|
|
3020
4160
|
diffuse: "f32",
|
|
3021
4161
|
shininess: "f32",
|
|
3022
4162
|
specularColor: "vec3<f32>"
|
|
3023
4163
|
},
|
|
3024
4164
|
defaultUniforms: {
|
|
4165
|
+
unlit: false,
|
|
3025
4166
|
ambient: 0.35,
|
|
3026
4167
|
diffuse: 0.6,
|
|
3027
4168
|
shininess: 32,
|
|
@@ -3039,6 +4180,8 @@ var gouraudMaterial = {
|
|
|
3039
4180
|
// dist/modules/lighting/phong-material/phong-material.js
|
|
3040
4181
|
var phongMaterial = {
|
|
3041
4182
|
name: "phongMaterial",
|
|
4183
|
+
firstBindingSlot: 0,
|
|
4184
|
+
bindingLayout: [{ name: "phongMaterial", group: 3 }],
|
|
3042
4185
|
dependencies: [lighting],
|
|
3043
4186
|
// Note these are switched between phong and gouraud
|
|
3044
4187
|
source: PHONG_WGSL,
|
|
@@ -3048,12 +4191,14 @@ var phongMaterial = {
|
|
|
3048
4191
|
LIGHTING_FRAGMENT: true
|
|
3049
4192
|
},
|
|
3050
4193
|
uniformTypes: {
|
|
4194
|
+
unlit: "i32",
|
|
3051
4195
|
ambient: "f32",
|
|
3052
4196
|
diffuse: "f32",
|
|
3053
4197
|
shininess: "f32",
|
|
3054
4198
|
specularColor: "vec3<f32>"
|
|
3055
4199
|
},
|
|
3056
4200
|
defaultUniforms: {
|
|
4201
|
+
unlit: false,
|
|
3057
4202
|
ambient: 0.35,
|
|
3058
4203
|
diffuse: 0.6,
|
|
3059
4204
|
shininess: 32,
|
|
@@ -3069,7 +4214,7 @@ var phongMaterial = {
|
|
|
3069
4214
|
};
|
|
3070
4215
|
|
|
3071
4216
|
// dist/modules/lighting/pbr-material/pbr-material-glsl.js
|
|
3072
|
-
var
|
|
4217
|
+
var vs3 = (
|
|
3073
4218
|
/* glsl */
|
|
3074
4219
|
`out vec3 pbr_vPosition;
|
|
3075
4220
|
out vec2 pbr_vUV;
|
|
@@ -3106,7 +4251,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
|
|
|
3106
4251
|
}
|
|
3107
4252
|
`
|
|
3108
4253
|
);
|
|
3109
|
-
var
|
|
4254
|
+
var fs4 = (
|
|
3110
4255
|
/* glsl */
|
|
3111
4256
|
`precision highp float;
|
|
3112
4257
|
|
|
@@ -3150,10 +4295,12 @@ uniform pbrMaterialUniforms {
|
|
|
3150
4295
|
float clearcoatFactor;
|
|
3151
4296
|
float clearcoatRoughnessFactor;
|
|
3152
4297
|
bool clearcoatMapEnabled;
|
|
4298
|
+
bool clearcoatRoughnessMapEnabled;
|
|
3153
4299
|
|
|
3154
4300
|
vec3 sheenColorFactor;
|
|
3155
4301
|
float sheenRoughnessFactor;
|
|
3156
4302
|
bool sheenColorMapEnabled;
|
|
4303
|
+
bool sheenRoughnessMapEnabled;
|
|
3157
4304
|
|
|
3158
4305
|
float iridescenceFactor;
|
|
3159
4306
|
float iridescenceIor;
|
|
@@ -3203,26 +4350,33 @@ uniform sampler2D pbr_specularIntensitySampler;
|
|
|
3203
4350
|
#ifdef HAS_TRANSMISSIONMAP
|
|
3204
4351
|
uniform sampler2D pbr_transmissionSampler;
|
|
3205
4352
|
#endif
|
|
4353
|
+
#ifdef HAS_THICKNESSMAP
|
|
4354
|
+
uniform sampler2D pbr_thicknessSampler;
|
|
4355
|
+
#endif
|
|
3206
4356
|
#ifdef HAS_CLEARCOATMAP
|
|
3207
4357
|
uniform sampler2D pbr_clearcoatSampler;
|
|
4358
|
+
#endif
|
|
4359
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
3208
4360
|
uniform sampler2D pbr_clearcoatRoughnessSampler;
|
|
3209
4361
|
#endif
|
|
4362
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
4363
|
+
uniform sampler2D pbr_clearcoatNormalSampler;
|
|
4364
|
+
#endif
|
|
3210
4365
|
#ifdef HAS_SHEENCOLORMAP
|
|
3211
4366
|
uniform sampler2D pbr_sheenColorSampler;
|
|
4367
|
+
#endif
|
|
4368
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
3212
4369
|
uniform sampler2D pbr_sheenRoughnessSampler;
|
|
3213
4370
|
#endif
|
|
3214
4371
|
#ifdef HAS_IRIDESCENCEMAP
|
|
3215
4372
|
uniform sampler2D pbr_iridescenceSampler;
|
|
3216
4373
|
#endif
|
|
4374
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
4375
|
+
uniform sampler2D pbr_iridescenceThicknessSampler;
|
|
4376
|
+
#endif
|
|
3217
4377
|
#ifdef HAS_ANISOTROPYMAP
|
|
3218
4378
|
uniform sampler2D pbr_anisotropySampler;
|
|
3219
4379
|
#endif
|
|
3220
|
-
#ifdef USE_IBL
|
|
3221
|
-
uniform samplerCube pbr_diffuseEnvSampler;
|
|
3222
|
-
uniform samplerCube pbr_specularEnvSampler;
|
|
3223
|
-
uniform sampler2D pbr_brdfLUT;
|
|
3224
|
-
#endif
|
|
3225
|
-
|
|
3226
4380
|
// Inputs from vertex shader
|
|
3227
4381
|
|
|
3228
4382
|
in vec3 pbr_vPosition;
|
|
@@ -3259,6 +4413,8 @@ struct PBRInfo {
|
|
|
3259
4413
|
const float M_PI = 3.141592653589793;
|
|
3260
4414
|
const float c_MinRoughness = 0.04;
|
|
3261
4415
|
|
|
4416
|
+
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
|
|
4417
|
+
|
|
3262
4418
|
vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
3263
4419
|
{
|
|
3264
4420
|
#ifdef MANUAL_SRGB
|
|
@@ -3274,11 +4430,9 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
|
3274
4430
|
#endif //MANUAL_SRGB
|
|
3275
4431
|
}
|
|
3276
4432
|
|
|
3277
|
-
//
|
|
3278
|
-
|
|
3279
|
-
vec3 getNormal()
|
|
4433
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
4434
|
+
mat3 getTBN()
|
|
3280
4435
|
{
|
|
3281
|
-
// Retrieve the tangent space matrix
|
|
3282
4436
|
#ifndef HAS_TANGENTS
|
|
3283
4437
|
vec3 pos_dx = dFdx(pbr_vPosition);
|
|
3284
4438
|
vec3 pos_dy = dFdy(pbr_vPosition);
|
|
@@ -3299,9 +4453,21 @@ vec3 getNormal()
|
|
|
3299
4453
|
mat3 tbn = pbr_vTBN;
|
|
3300
4454
|
#endif
|
|
3301
4455
|
|
|
4456
|
+
return tbn;
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4459
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
4460
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
4461
|
+
vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
|
|
4462
|
+
{
|
|
4463
|
+
vec3 n = texture(normalSampler, pbr_vUV).rgb;
|
|
4464
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
vec3 getNormal(mat3 tbn)
|
|
4468
|
+
{
|
|
3302
4469
|
#ifdef HAS_NORMALMAP
|
|
3303
|
-
vec3 n =
|
|
3304
|
-
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
|
|
4470
|
+
vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
|
|
3305
4471
|
#else
|
|
3306
4472
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
3307
4473
|
vec3 n = normalize(tbn[2].xyz);
|
|
@@ -3310,6 +4476,15 @@ vec3 getNormal()
|
|
|
3310
4476
|
return n;
|
|
3311
4477
|
}
|
|
3312
4478
|
|
|
4479
|
+
vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
|
|
4480
|
+
{
|
|
4481
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
4482
|
+
return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
|
|
4483
|
+
#else
|
|
4484
|
+
return baseNormal;
|
|
4485
|
+
#endif
|
|
4486
|
+
}
|
|
4487
|
+
|
|
3313
4488
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
3314
4489
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
3315
4490
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -3385,30 +4560,198 @@ float microfacetDistribution(PBRInfo pbrInfo)
|
|
|
3385
4560
|
return roughnessSq / (M_PI * f * f);
|
|
3386
4561
|
}
|
|
3387
4562
|
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
pbrInfo.LdotH = 0.0;
|
|
3392
|
-
pbrInfo.VdotH = 1.0;
|
|
4563
|
+
float maxComponent(vec3 value)
|
|
4564
|
+
{
|
|
4565
|
+
return max(max(value.r, value.g), value.b);
|
|
3393
4566
|
}
|
|
3394
4567
|
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
4568
|
+
float getDielectricF0(float ior)
|
|
4569
|
+
{
|
|
4570
|
+
float clampedIor = max(ior, 1.0);
|
|
4571
|
+
float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
4572
|
+
return ratio * ratio;
|
|
4573
|
+
}
|
|
3400
4574
|
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
4575
|
+
vec2 normalizeDirection(vec2 direction)
|
|
4576
|
+
{
|
|
4577
|
+
float directionLength = length(direction);
|
|
4578
|
+
return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
|
|
3405
4579
|
}
|
|
3406
4580
|
|
|
3407
|
-
|
|
4581
|
+
vec2 rotateDirection(vec2 direction, float rotation)
|
|
4582
|
+
{
|
|
4583
|
+
float s = sin(rotation);
|
|
4584
|
+
float c = cos(rotation);
|
|
4585
|
+
return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
4586
|
+
}
|
|
4587
|
+
|
|
4588
|
+
vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
|
|
4589
|
+
{
|
|
4590
|
+
if (iridescence <= 0.0) {
|
|
4591
|
+
return vec3(1.0);
|
|
4592
|
+
}
|
|
4593
|
+
|
|
4594
|
+
float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
4595
|
+
vec3 thinFilmTint =
|
|
4596
|
+
0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
|
|
4597
|
+
return mix(vec3(1.0), thinFilmTint, iridescence);
|
|
4598
|
+
}
|
|
4599
|
+
|
|
4600
|
+
vec3 getVolumeAttenuation(float thickness)
|
|
4601
|
+
{
|
|
4602
|
+
if (thickness <= 0.0) {
|
|
4603
|
+
return vec3(1.0);
|
|
4604
|
+
}
|
|
4605
|
+
|
|
4606
|
+
vec3 attenuationCoefficient =
|
|
4607
|
+
-log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
|
|
4608
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
4609
|
+
return exp(-attenuationCoefficient * thickness);
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4612
|
+
PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
|
|
4613
|
+
{
|
|
4614
|
+
float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
4615
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
4616
|
+
float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
4617
|
+
|
|
4618
|
+
return PBRInfo(
|
|
4619
|
+
basePBRInfo.NdotL,
|
|
4620
|
+
NdotV,
|
|
4621
|
+
basePBRInfo.NdotH,
|
|
4622
|
+
basePBRInfo.LdotH,
|
|
4623
|
+
basePBRInfo.VdotH,
|
|
4624
|
+
perceptualRoughness,
|
|
4625
|
+
0.0,
|
|
4626
|
+
vec3(0.04),
|
|
4627
|
+
vec3(1.0),
|
|
4628
|
+
alphaRoughness,
|
|
4629
|
+
vec3(0.0),
|
|
4630
|
+
vec3(0.04),
|
|
4631
|
+
clearcoatNormal,
|
|
4632
|
+
basePBRInfo.v
|
|
4633
|
+
);
|
|
4634
|
+
}
|
|
4635
|
+
|
|
4636
|
+
vec3 calculateClearcoatContribution(
|
|
4637
|
+
PBRInfo pbrInfo,
|
|
4638
|
+
vec3 lightColor,
|
|
4639
|
+
vec3 clearcoatNormal,
|
|
4640
|
+
float clearcoatFactor,
|
|
4641
|
+
float clearcoatRoughness
|
|
4642
|
+
) {
|
|
4643
|
+
if (clearcoatFactor <= 0.0) {
|
|
4644
|
+
return vec3(0.0);
|
|
4645
|
+
}
|
|
4646
|
+
|
|
4647
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
4648
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
#ifdef USE_IBL
|
|
4652
|
+
vec3 calculateClearcoatIBLContribution(
|
|
4653
|
+
PBRInfo pbrInfo,
|
|
4654
|
+
vec3 clearcoatNormal,
|
|
4655
|
+
vec3 reflection,
|
|
4656
|
+
float clearcoatFactor,
|
|
4657
|
+
float clearcoatRoughness
|
|
4658
|
+
) {
|
|
4659
|
+
if (clearcoatFactor <= 0.0) {
|
|
4660
|
+
return vec3(0.0);
|
|
4661
|
+
}
|
|
4662
|
+
|
|
4663
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
4664
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
4665
|
+
}
|
|
4666
|
+
#endif
|
|
4667
|
+
|
|
4668
|
+
vec3 calculateSheenContribution(
|
|
4669
|
+
PBRInfo pbrInfo,
|
|
4670
|
+
vec3 lightColor,
|
|
4671
|
+
vec3 sheenColor,
|
|
4672
|
+
float sheenRoughness
|
|
4673
|
+
) {
|
|
4674
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
4675
|
+
return vec3(0.0);
|
|
4676
|
+
}
|
|
4677
|
+
|
|
4678
|
+
float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
4679
|
+
float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
4680
|
+
return pbrInfo.NdotL *
|
|
4681
|
+
lightColor *
|
|
4682
|
+
sheenColor *
|
|
4683
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
4684
|
+
sheenVisibility *
|
|
4685
|
+
(1.0 - pbrInfo.metalness);
|
|
4686
|
+
}
|
|
4687
|
+
|
|
4688
|
+
float calculateAnisotropyBoost(
|
|
4689
|
+
PBRInfo pbrInfo,
|
|
4690
|
+
vec3 anisotropyTangent,
|
|
4691
|
+
float anisotropyStrength
|
|
4692
|
+
) {
|
|
4693
|
+
if (anisotropyStrength <= 0.0) {
|
|
4694
|
+
return 1.0;
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
4698
|
+
float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
4699
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4702
|
+
vec3 calculateMaterialLightColor(
|
|
4703
|
+
PBRInfo pbrInfo,
|
|
4704
|
+
vec3 lightColor,
|
|
4705
|
+
vec3 clearcoatNormal,
|
|
4706
|
+
float clearcoatFactor,
|
|
4707
|
+
float clearcoatRoughness,
|
|
4708
|
+
vec3 sheenColor,
|
|
4709
|
+
float sheenRoughness,
|
|
4710
|
+
vec3 anisotropyTangent,
|
|
4711
|
+
float anisotropyStrength
|
|
4712
|
+
) {
|
|
4713
|
+
float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
4714
|
+
vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
4715
|
+
color += calculateClearcoatContribution(
|
|
4716
|
+
pbrInfo,
|
|
4717
|
+
lightColor,
|
|
4718
|
+
clearcoatNormal,
|
|
4719
|
+
clearcoatFactor,
|
|
4720
|
+
clearcoatRoughness
|
|
4721
|
+
);
|
|
4722
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
4723
|
+
return color;
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4726
|
+
void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
|
|
4727
|
+
pbrInfo.NdotL = 1.0;
|
|
4728
|
+
pbrInfo.NdotH = 0.0;
|
|
4729
|
+
pbrInfo.LdotH = 0.0;
|
|
4730
|
+
pbrInfo.VdotH = 1.0;
|
|
4731
|
+
}
|
|
4732
|
+
|
|
4733
|
+
void PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {
|
|
4734
|
+
vec3 n = pbrInfo.n;
|
|
4735
|
+
vec3 v = pbrInfo.v;
|
|
4736
|
+
vec3 l = normalize(lightDirection); // Vector from surface point to light
|
|
4737
|
+
vec3 h = normalize(l+v); // Half vector between both l and v
|
|
4738
|
+
|
|
4739
|
+
pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);
|
|
4740
|
+
pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);
|
|
4741
|
+
pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);
|
|
4742
|
+
pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);
|
|
4743
|
+
}
|
|
4744
|
+
|
|
4745
|
+
void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
|
|
3408
4746
|
vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
|
|
3409
4747
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
3410
4748
|
}
|
|
3411
4749
|
|
|
4750
|
+
void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
|
|
4751
|
+
vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
|
|
4752
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
4753
|
+
}
|
|
4754
|
+
|
|
3412
4755
|
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
|
|
3413
4756
|
// Calculate the shading terms for the microfacet specular shading model
|
|
3414
4757
|
vec3 F = specularReflection(pbrInfo);
|
|
@@ -3439,6 +4782,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3439
4782
|
|
|
3440
4783
|
vec3 color = vec3(0, 0, 0);
|
|
3441
4784
|
|
|
4785
|
+
float transmission = 0.0;
|
|
4786
|
+
|
|
3442
4787
|
if(pbrMaterial.unlit){
|
|
3443
4788
|
color.rgb = baseColor.rgb;
|
|
3444
4789
|
}
|
|
@@ -3457,14 +4802,252 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3457
4802
|
#endif
|
|
3458
4803
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
3459
4804
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
4805
|
+
mat3 tbn = getTBN();
|
|
4806
|
+
vec3 n = getNormal(tbn); // normal at surface point
|
|
4807
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
4808
|
+
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
4809
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
4810
|
+
bool useExtendedPBR =
|
|
4811
|
+
pbrMaterial.specularColorMapEnabled ||
|
|
4812
|
+
pbrMaterial.specularIntensityMapEnabled ||
|
|
4813
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
4814
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
|
|
4815
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
4816
|
+
pbrMaterial.transmissionMapEnabled ||
|
|
4817
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
4818
|
+
pbrMaterial.clearcoatMapEnabled ||
|
|
4819
|
+
pbrMaterial.clearcoatRoughnessMapEnabled ||
|
|
4820
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
4821
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
4822
|
+
pbrMaterial.sheenColorMapEnabled ||
|
|
4823
|
+
pbrMaterial.sheenRoughnessMapEnabled ||
|
|
4824
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
4825
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
4826
|
+
pbrMaterial.iridescenceMapEnabled ||
|
|
4827
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
4828
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
4829
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
4830
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
4831
|
+
pbrMaterial.anisotropyMapEnabled ||
|
|
4832
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
4833
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
4834
|
+
length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
|
|
4835
|
+
#else
|
|
4836
|
+
bool useExtendedPBR = false;
|
|
4837
|
+
#endif
|
|
4838
|
+
|
|
4839
|
+
if (!useExtendedPBR) {
|
|
4840
|
+
// Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
|
|
4841
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
4842
|
+
|
|
4843
|
+
vec3 f0 = vec3(0.04);
|
|
4844
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
|
4845
|
+
diffuseColor *= 1.0 - metallic;
|
|
4846
|
+
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
|
4847
|
+
|
|
4848
|
+
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
4849
|
+
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
4850
|
+
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
4851
|
+
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
4852
|
+
vec3 reflection = -normalize(reflect(v, n));
|
|
4853
|
+
|
|
4854
|
+
PBRInfo pbrInfo = PBRInfo(
|
|
4855
|
+
0.0, // NdotL
|
|
4856
|
+
NdotV,
|
|
4857
|
+
0.0, // NdotH
|
|
4858
|
+
0.0, // LdotH
|
|
4859
|
+
0.0, // VdotH
|
|
4860
|
+
perceptualRoughness,
|
|
4861
|
+
metallic,
|
|
4862
|
+
specularEnvironmentR0,
|
|
4863
|
+
specularEnvironmentR90,
|
|
4864
|
+
alphaRoughness,
|
|
4865
|
+
diffuseColor,
|
|
4866
|
+
specularColor,
|
|
4867
|
+
n,
|
|
4868
|
+
v
|
|
4869
|
+
);
|
|
4870
|
+
|
|
4871
|
+
#ifdef USE_LIGHTS
|
|
4872
|
+
PBRInfo_setAmbientLight(pbrInfo);
|
|
4873
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
4874
|
+
|
|
4875
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
4876
|
+
if (i < lighting.directionalLightCount) {
|
|
4877
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
4878
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
4883
|
+
if (i < lighting.pointLightCount) {
|
|
4884
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
4885
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
4886
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4890
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
4891
|
+
if (i < lighting.spotLightCount) {
|
|
4892
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
4893
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
4894
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
#endif
|
|
4898
|
+
|
|
4899
|
+
#ifdef USE_IBL
|
|
4900
|
+
if (pbrMaterial.IBLenabled) {
|
|
4901
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
4902
|
+
}
|
|
4903
|
+
#endif
|
|
4904
|
+
|
|
4905
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
4906
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
4907
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
4908
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
4909
|
+
}
|
|
4910
|
+
#endif
|
|
4911
|
+
|
|
4912
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
4913
|
+
#ifdef HAS_EMISSIVEMAP
|
|
4914
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
4915
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
4916
|
+
}
|
|
4917
|
+
#endif
|
|
4918
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
4919
|
+
|
|
4920
|
+
#ifdef PBR_DEBUG
|
|
4921
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
4922
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
4923
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
4924
|
+
#endif
|
|
4925
|
+
|
|
4926
|
+
return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
|
|
4927
|
+
}
|
|
4928
|
+
|
|
4929
|
+
float specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
4930
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
4931
|
+
if (pbrMaterial.specularIntensityMapEnabled) {
|
|
4932
|
+
specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
|
|
4933
|
+
}
|
|
4934
|
+
#endif
|
|
4935
|
+
|
|
4936
|
+
vec3 specularFactor = pbrMaterial.specularColorFactor;
|
|
4937
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
4938
|
+
if (pbrMaterial.specularColorMapEnabled) {
|
|
4939
|
+
specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
|
|
4940
|
+
}
|
|
4941
|
+
#endif
|
|
4942
|
+
|
|
4943
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
4944
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
4945
|
+
if (pbrMaterial.transmissionMapEnabled) {
|
|
4946
|
+
transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
|
|
4947
|
+
}
|
|
4948
|
+
#endif
|
|
4949
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
4950
|
+
float thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
4951
|
+
#ifdef HAS_THICKNESSMAP
|
|
4952
|
+
thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
|
|
4953
|
+
#endif
|
|
4954
|
+
|
|
4955
|
+
float clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
4956
|
+
float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
4957
|
+
#ifdef HAS_CLEARCOATMAP
|
|
4958
|
+
if (pbrMaterial.clearcoatMapEnabled) {
|
|
4959
|
+
clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
|
|
4960
|
+
}
|
|
4961
|
+
#endif
|
|
4962
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
4963
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled) {
|
|
4964
|
+
clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
|
|
4965
|
+
}
|
|
4966
|
+
#endif
|
|
4967
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
4968
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
4969
|
+
vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
4970
|
+
|
|
4971
|
+
vec3 sheenColor = pbrMaterial.sheenColorFactor;
|
|
4972
|
+
float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
4973
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
4974
|
+
if (pbrMaterial.sheenColorMapEnabled) {
|
|
4975
|
+
sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
|
|
4976
|
+
}
|
|
4977
|
+
#endif
|
|
4978
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
4979
|
+
if (pbrMaterial.sheenRoughnessMapEnabled) {
|
|
4980
|
+
sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
|
|
4981
|
+
}
|
|
4982
|
+
#endif
|
|
4983
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
4984
|
+
|
|
4985
|
+
float iridescence = pbrMaterial.iridescenceFactor;
|
|
4986
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
4987
|
+
if (pbrMaterial.iridescenceMapEnabled) {
|
|
4988
|
+
iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
|
|
4989
|
+
}
|
|
4990
|
+
#endif
|
|
4991
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
4992
|
+
float iridescenceThickness = mix(
|
|
4993
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
4994
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
4995
|
+
0.5
|
|
4996
|
+
);
|
|
4997
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
4998
|
+
iridescenceThickness = mix(
|
|
4999
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
5000
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
5001
|
+
texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
|
|
5002
|
+
);
|
|
5003
|
+
#endif
|
|
5004
|
+
|
|
5005
|
+
float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
5006
|
+
vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
5007
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
5008
|
+
if (pbrMaterial.anisotropyMapEnabled) {
|
|
5009
|
+
vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
|
|
5010
|
+
anisotropyStrength *= anisotropySample.b;
|
|
5011
|
+
vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
5012
|
+
if (length(mappedDirection) > 0.0001) {
|
|
5013
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
5014
|
+
}
|
|
5015
|
+
}
|
|
5016
|
+
#endif
|
|
5017
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
5018
|
+
vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
5019
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
5020
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
5021
|
+
}
|
|
5022
|
+
float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
5023
|
+
perceptualRoughness = mix(
|
|
5024
|
+
perceptualRoughness,
|
|
5025
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
5026
|
+
anisotropyStrength
|
|
5027
|
+
);
|
|
5028
|
+
|
|
3460
5029
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
3461
5030
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
3462
5031
|
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
3463
5032
|
|
|
3464
|
-
|
|
3465
|
-
vec3
|
|
3466
|
-
|
|
3467
|
-
|
|
5033
|
+
float dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
5034
|
+
vec3 dielectricSpecularF0 = min(
|
|
5035
|
+
vec3(dielectricF0) * specularFactor * specularIntensity,
|
|
5036
|
+
vec3(1.0)
|
|
5037
|
+
);
|
|
5038
|
+
vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
5039
|
+
dielectricSpecularF0 = mix(
|
|
5040
|
+
dielectricSpecularF0,
|
|
5041
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
5042
|
+
iridescence
|
|
5043
|
+
);
|
|
5044
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
|
|
5045
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
5046
|
+
vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
5047
|
+
|
|
5048
|
+
float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
5049
|
+
diffuseColor *= baseLayerEnergy;
|
|
5050
|
+
specularColor *= baseLayerEnergy;
|
|
3468
5051
|
|
|
3469
5052
|
// Compute reflectance.
|
|
3470
5053
|
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -3476,11 +5059,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3476
5059
|
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
3477
5060
|
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
3478
5061
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
3479
|
-
|
|
3480
|
-
vec3 n = getNormal(); // normal at surface point
|
|
3481
|
-
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
3482
|
-
|
|
3483
|
-
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
3484
5062
|
vec3 reflection = -normalize(reflect(v, n));
|
|
3485
5063
|
|
|
3486
5064
|
PBRInfo pbrInfo = PBRInfo(
|
|
@@ -3504,13 +5082,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3504
5082
|
#ifdef USE_LIGHTS
|
|
3505
5083
|
// Apply ambient light
|
|
3506
5084
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
3507
|
-
color +=
|
|
5085
|
+
color += calculateMaterialLightColor(
|
|
5086
|
+
pbrInfo,
|
|
5087
|
+
lighting.ambientColor,
|
|
5088
|
+
clearcoatNormal,
|
|
5089
|
+
clearcoatFactor,
|
|
5090
|
+
clearcoatRoughness,
|
|
5091
|
+
sheenColor,
|
|
5092
|
+
sheenRoughness,
|
|
5093
|
+
anisotropyTangent,
|
|
5094
|
+
anisotropyStrength
|
|
5095
|
+
);
|
|
3508
5096
|
|
|
3509
5097
|
// Apply directional light
|
|
3510
5098
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
3511
5099
|
if (i < lighting.directionalLightCount) {
|
|
3512
5100
|
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
3513
|
-
color +=
|
|
5101
|
+
color += calculateMaterialLightColor(
|
|
5102
|
+
pbrInfo,
|
|
5103
|
+
lighting_getDirectionalLight(i).color,
|
|
5104
|
+
clearcoatNormal,
|
|
5105
|
+
clearcoatFactor,
|
|
5106
|
+
clearcoatRoughness,
|
|
5107
|
+
sheenColor,
|
|
5108
|
+
sheenRoughness,
|
|
5109
|
+
anisotropyTangent,
|
|
5110
|
+
anisotropyStrength
|
|
5111
|
+
);
|
|
3514
5112
|
}
|
|
3515
5113
|
}
|
|
3516
5114
|
|
|
@@ -3519,7 +5117,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3519
5117
|
if (i < lighting.pointLightCount) {
|
|
3520
5118
|
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
3521
5119
|
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
3522
|
-
color +=
|
|
5120
|
+
color += calculateMaterialLightColor(
|
|
5121
|
+
pbrInfo,
|
|
5122
|
+
lighting_getPointLight(i).color / attenuation,
|
|
5123
|
+
clearcoatNormal,
|
|
5124
|
+
clearcoatFactor,
|
|
5125
|
+
clearcoatRoughness,
|
|
5126
|
+
sheenColor,
|
|
5127
|
+
sheenRoughness,
|
|
5128
|
+
anisotropyTangent,
|
|
5129
|
+
anisotropyStrength
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
|
|
5134
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
5135
|
+
if (i < lighting.spotLightCount) {
|
|
5136
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
5137
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
5138
|
+
color += calculateMaterialLightColor(
|
|
5139
|
+
pbrInfo,
|
|
5140
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
5141
|
+
clearcoatNormal,
|
|
5142
|
+
clearcoatFactor,
|
|
5143
|
+
clearcoatRoughness,
|
|
5144
|
+
sheenColor,
|
|
5145
|
+
sheenRoughness,
|
|
5146
|
+
anisotropyTangent,
|
|
5147
|
+
anisotropyStrength
|
|
5148
|
+
);
|
|
3523
5149
|
}
|
|
3524
5150
|
}
|
|
3525
5151
|
#endif
|
|
@@ -3527,7 +5153,16 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3527
5153
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
3528
5154
|
#ifdef USE_IBL
|
|
3529
5155
|
if (pbrMaterial.IBLenabled) {
|
|
3530
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
5156
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
5157
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
5158
|
+
color += calculateClearcoatIBLContribution(
|
|
5159
|
+
pbrInfo,
|
|
5160
|
+
clearcoatNormal,
|
|
5161
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
5162
|
+
clearcoatFactor,
|
|
5163
|
+
clearcoatRoughness
|
|
5164
|
+
);
|
|
5165
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
3531
5166
|
}
|
|
3532
5167
|
#endif
|
|
3533
5168
|
|
|
@@ -3539,12 +5174,17 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3539
5174
|
}
|
|
3540
5175
|
#endif
|
|
3541
5176
|
|
|
5177
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
3542
5178
|
#ifdef HAS_EMISSIVEMAP
|
|
3543
5179
|
if (pbrMaterial.emissiveMapEnabled) {
|
|
3544
|
-
|
|
3545
|
-
color += emissive;
|
|
5180
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
3546
5181
|
}
|
|
3547
5182
|
#endif
|
|
5183
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
5184
|
+
|
|
5185
|
+
if (transmission > 0.0) {
|
|
5186
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
5187
|
+
}
|
|
3548
5188
|
|
|
3549
5189
|
// This section uses mix to override final color for reference app visualization
|
|
3550
5190
|
// of various parameters in the lighting equation.
|
|
@@ -3564,68 +5204,109 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
3564
5204
|
|
|
3565
5205
|
}
|
|
3566
5206
|
|
|
3567
|
-
|
|
5207
|
+
float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
5208
|
+
return vec4(pow(color,vec3(1.0/2.2)), alpha);
|
|
3568
5209
|
}
|
|
3569
5210
|
`
|
|
3570
5211
|
);
|
|
3571
5212
|
|
|
3572
5213
|
// dist/modules/lighting/pbr-material/pbr-material-wgsl.js
|
|
3573
|
-
var
|
|
5214
|
+
var source3 = (
|
|
3574
5215
|
/* wgsl */
|
|
3575
5216
|
`struct PBRFragmentInputs {
|
|
3576
5217
|
pbr_vPosition: vec3f,
|
|
3577
5218
|
pbr_vUV: vec2f,
|
|
3578
|
-
pbr_vTBN:
|
|
5219
|
+
pbr_vTBN: mat3x3f,
|
|
3579
5220
|
pbr_vNormal: vec3f
|
|
3580
5221
|
};
|
|
3581
5222
|
|
|
3582
|
-
var fragmentInputs: PBRFragmentInputs;
|
|
5223
|
+
var<private> fragmentInputs: PBRFragmentInputs;
|
|
3583
5224
|
|
|
3584
5225
|
fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
|
|
3585
5226
|
{
|
|
3586
5227
|
var pos: vec4f = pbrProjection.modelMatrix * position;
|
|
3587
|
-
fragmentInputs.pbr_vPosition =
|
|
5228
|
+
fragmentInputs.pbr_vPosition = pos.xyz / pos.w;
|
|
5229
|
+
fragmentInputs.pbr_vNormal = vec3f(0.0, 0.0, 1.0);
|
|
5230
|
+
fragmentInputs.pbr_vTBN = mat3x3f(
|
|
5231
|
+
vec3f(1.0, 0.0, 0.0),
|
|
5232
|
+
vec3f(0.0, 1.0, 0.0),
|
|
5233
|
+
vec3f(0.0, 0.0, 1.0)
|
|
5234
|
+
);
|
|
5235
|
+
fragmentInputs.pbr_vUV = vec2f(0.0, 0.0);
|
|
3588
5236
|
|
|
3589
5237
|
#ifdef HAS_NORMALS
|
|
5238
|
+
let normalW: vec3f = normalize((pbrProjection.normalMatrix * vec4f(normal.xyz, 0.0)).xyz);
|
|
5239
|
+
fragmentInputs.pbr_vNormal = normalW;
|
|
3590
5240
|
#ifdef HAS_TANGENTS
|
|
3591
|
-
let
|
|
3592
|
-
let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
|
|
5241
|
+
let tangentW: vec3f = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
|
|
3593
5242
|
let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;
|
|
3594
|
-
fragmentInputs.pbr_vTBN =
|
|
3595
|
-
#else // HAS_TANGENTS != 1
|
|
3596
|
-
fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
|
|
5243
|
+
fragmentInputs.pbr_vTBN = mat3x3f(tangentW, bitangentW, normalW);
|
|
3597
5244
|
#endif
|
|
3598
5245
|
#endif
|
|
3599
5246
|
|
|
3600
5247
|
#ifdef HAS_UV
|
|
3601
5248
|
fragmentInputs.pbr_vUV = uv;
|
|
3602
|
-
#else
|
|
3603
|
-
fragmentInputs.pbr_vUV = vec2(0.,0.);
|
|
3604
5249
|
#endif
|
|
3605
5250
|
}
|
|
3606
5251
|
|
|
3607
5252
|
struct pbrMaterialUniforms {
|
|
3608
5253
|
// Material is unlit
|
|
3609
|
-
unlit:
|
|
5254
|
+
unlit: u32,
|
|
3610
5255
|
|
|
3611
5256
|
// Base color map
|
|
3612
|
-
baseColorMapEnabled:
|
|
5257
|
+
baseColorMapEnabled: u32,
|
|
3613
5258
|
baseColorFactor: vec4f,
|
|
3614
5259
|
|
|
3615
|
-
normalMapEnabled :
|
|
5260
|
+
normalMapEnabled : u32,
|
|
3616
5261
|
normalScale: f32, // #ifdef HAS_NORMALMAP
|
|
3617
5262
|
|
|
3618
|
-
emissiveMapEnabled:
|
|
5263
|
+
emissiveMapEnabled: u32,
|
|
3619
5264
|
emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP
|
|
3620
5265
|
|
|
3621
5266
|
metallicRoughnessValues: vec2f,
|
|
3622
|
-
metallicRoughnessMapEnabled:
|
|
5267
|
+
metallicRoughnessMapEnabled: u32,
|
|
3623
5268
|
|
|
3624
5269
|
occlusionMapEnabled: i32,
|
|
3625
5270
|
occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP
|
|
3626
5271
|
|
|
3627
5272
|
alphaCutoffEnabled: i32,
|
|
3628
5273
|
alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
|
|
5274
|
+
|
|
5275
|
+
specularColorFactor: vec3f,
|
|
5276
|
+
specularIntensityFactor: f32,
|
|
5277
|
+
specularColorMapEnabled: i32,
|
|
5278
|
+
specularIntensityMapEnabled: i32,
|
|
5279
|
+
|
|
5280
|
+
ior: f32,
|
|
5281
|
+
|
|
5282
|
+
transmissionFactor: f32,
|
|
5283
|
+
transmissionMapEnabled: i32,
|
|
5284
|
+
|
|
5285
|
+
thicknessFactor: f32,
|
|
5286
|
+
attenuationDistance: f32,
|
|
5287
|
+
attenuationColor: vec3f,
|
|
5288
|
+
|
|
5289
|
+
clearcoatFactor: f32,
|
|
5290
|
+
clearcoatRoughnessFactor: f32,
|
|
5291
|
+
clearcoatMapEnabled: i32,
|
|
5292
|
+
clearcoatRoughnessMapEnabled: i32,
|
|
5293
|
+
|
|
5294
|
+
sheenColorFactor: vec3f,
|
|
5295
|
+
sheenRoughnessFactor: f32,
|
|
5296
|
+
sheenColorMapEnabled: i32,
|
|
5297
|
+
sheenRoughnessMapEnabled: i32,
|
|
5298
|
+
|
|
5299
|
+
iridescenceFactor: f32,
|
|
5300
|
+
iridescenceIor: f32,
|
|
5301
|
+
iridescenceThicknessRange: vec2f,
|
|
5302
|
+
iridescenceMapEnabled: i32,
|
|
5303
|
+
|
|
5304
|
+
anisotropyStrength: f32,
|
|
5305
|
+
anisotropyRotation: f32,
|
|
5306
|
+
anisotropyDirection: vec2f,
|
|
5307
|
+
anisotropyMapEnabled: i32,
|
|
5308
|
+
|
|
5309
|
+
emissiveStrength: f32,
|
|
3629
5310
|
|
|
3630
5311
|
// IBL
|
|
3631
5312
|
IBLenabled: i32,
|
|
@@ -3634,34 +5315,81 @@ struct pbrMaterialUniforms {
|
|
|
3634
5315
|
// debugging flags used for shader output of intermediate PBR variables
|
|
3635
5316
|
// #ifdef PBR_DEBUG
|
|
3636
5317
|
scaleDiffBaseMR: vec4f,
|
|
3637
|
-
scaleFGDSpec: vec4f
|
|
5318
|
+
scaleFGDSpec: vec4f,
|
|
3638
5319
|
// #endif
|
|
3639
5320
|
}
|
|
3640
5321
|
|
|
3641
|
-
@
|
|
5322
|
+
@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
|
|
3642
5323
|
|
|
3643
5324
|
// Samplers
|
|
3644
5325
|
#ifdef HAS_BASECOLORMAP
|
|
3645
|
-
|
|
5326
|
+
@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
|
|
5327
|
+
@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
|
|
3646
5328
|
#endif
|
|
3647
5329
|
#ifdef HAS_NORMALMAP
|
|
3648
|
-
|
|
5330
|
+
@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
|
|
5331
|
+
@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
|
|
3649
5332
|
#endif
|
|
3650
5333
|
#ifdef HAS_EMISSIVEMAP
|
|
3651
|
-
|
|
5334
|
+
@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
|
|
5335
|
+
@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
|
|
3652
5336
|
#endif
|
|
3653
5337
|
#ifdef HAS_METALROUGHNESSMAP
|
|
3654
|
-
|
|
5338
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
|
|
5339
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
|
|
3655
5340
|
#endif
|
|
3656
5341
|
#ifdef HAS_OCCLUSIONMAP
|
|
3657
|
-
|
|
5342
|
+
@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
|
|
5343
|
+
@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
|
|
3658
5344
|
#endif
|
|
3659
|
-
#ifdef
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
5345
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
5346
|
+
@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
|
|
5347
|
+
@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
|
|
5348
|
+
#endif
|
|
5349
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
5350
|
+
@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
|
|
5351
|
+
@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
|
|
5352
|
+
#endif
|
|
5353
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
5354
|
+
@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
|
|
5355
|
+
@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
|
|
5356
|
+
#endif
|
|
5357
|
+
#ifdef HAS_THICKNESSMAP
|
|
5358
|
+
@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
|
|
5359
|
+
@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
|
|
5360
|
+
#endif
|
|
5361
|
+
#ifdef HAS_CLEARCOATMAP
|
|
5362
|
+
@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
|
|
5363
|
+
@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
|
|
5364
|
+
#endif
|
|
5365
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
5366
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
|
|
5367
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
|
|
5368
|
+
#endif
|
|
5369
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
5370
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
|
|
5371
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
|
|
5372
|
+
#endif
|
|
5373
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
5374
|
+
@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
|
|
5375
|
+
@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
|
|
5376
|
+
#endif
|
|
5377
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
5378
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
|
|
5379
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
|
|
5380
|
+
#endif
|
|
5381
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
5382
|
+
@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
|
|
5383
|
+
@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
|
|
5384
|
+
#endif
|
|
5385
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
5386
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
|
|
5387
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
|
|
5388
|
+
#endif
|
|
5389
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
5390
|
+
@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
|
|
5391
|
+
@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
|
|
3663
5392
|
#endif
|
|
3664
|
-
|
|
3665
5393
|
// Encapsulate the various inputs used by the various functions in the shading equation
|
|
3666
5394
|
// We store values in this struct to simplify the integration of alternative implementations
|
|
3667
5395
|
// of the shading terms, outlined in the Readme.MD Appendix.
|
|
@@ -3687,80 +5415,130 @@ const c_MinRoughness = 0.04;
|
|
|
3687
5415
|
|
|
3688
5416
|
fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
|
|
3689
5417
|
{
|
|
5418
|
+
var linOut: vec3f = srgbIn.xyz;
|
|
3690
5419
|
#ifdef MANUAL_SRGB
|
|
5420
|
+
let bLess: vec3f = step(vec3f(0.04045), srgbIn.xyz);
|
|
5421
|
+
linOut = mix(
|
|
5422
|
+
srgbIn.xyz / vec3f(12.92),
|
|
5423
|
+
pow((srgbIn.xyz + vec3f(0.055)) / vec3f(1.055), vec3f(2.4)),
|
|
5424
|
+
bLess
|
|
5425
|
+
);
|
|
3691
5426
|
#ifdef SRGB_FAST_APPROXIMATION
|
|
3692
|
-
|
|
3693
|
-
#
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
#endif //SRGB_FAST_APPROXIMATION
|
|
3697
|
-
return vec4f(linOut,srgbIn.w);;
|
|
3698
|
-
#else //MANUAL_SRGB
|
|
3699
|
-
return srgbIn;
|
|
3700
|
-
#endif //MANUAL_SRGB
|
|
5427
|
+
linOut = pow(srgbIn.xyz, vec3f(2.2));
|
|
5428
|
+
#endif
|
|
5429
|
+
#endif
|
|
5430
|
+
return vec4f(linOut, srgbIn.w);
|
|
3701
5431
|
}
|
|
3702
5432
|
|
|
3703
|
-
//
|
|
3704
|
-
|
|
3705
|
-
fn getNormal() -> vec3f
|
|
5433
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
5434
|
+
fn getTBN() -> mat3x3f
|
|
3706
5435
|
{
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
var
|
|
3712
|
-
var tex_dy: vec3f = dFdy(vec3(fragmentInputs.pbr_vUV, 0.0));
|
|
3713
|
-
var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
|
|
5436
|
+
let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
|
|
5437
|
+
let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
|
|
5438
|
+
let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
|
|
5439
|
+
let tex_dy: vec3f = dpdy(vec3f(fragmentInputs.pbr_vUV, 0.0));
|
|
5440
|
+
var t: vec3f = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);
|
|
3714
5441
|
|
|
3715
|
-
#ifdef HAS_NORMALS
|
|
3716
|
-
var ng: vec3f = normalize(fragmentInputs.pbr_vNormal);
|
|
3717
|
-
#else
|
|
3718
5442
|
var ng: vec3f = cross(pos_dx, pos_dy);
|
|
5443
|
+
#ifdef HAS_NORMALS
|
|
5444
|
+
ng = normalize(fragmentInputs.pbr_vNormal);
|
|
3719
5445
|
#endif
|
|
3720
|
-
|
|
3721
5446
|
t = normalize(t - ng * dot(ng, t));
|
|
3722
5447
|
var b: vec3f = normalize(cross(ng, t));
|
|
3723
|
-
var tbn:
|
|
3724
|
-
#
|
|
3725
|
-
|
|
5448
|
+
var tbn: mat3x3f = mat3x3f(t, b, ng);
|
|
5449
|
+
#ifdef HAS_TANGENTS
|
|
5450
|
+
tbn = fragmentInputs.pbr_vTBN;
|
|
3726
5451
|
#endif
|
|
3727
5452
|
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
5453
|
+
return tbn;
|
|
5454
|
+
}
|
|
5455
|
+
|
|
5456
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
5457
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
5458
|
+
fn getMappedNormal(
|
|
5459
|
+
normalSampler: texture_2d<f32>,
|
|
5460
|
+
normalSamplerBinding: sampler,
|
|
5461
|
+
tbn: mat3x3f,
|
|
5462
|
+
normalScale: f32
|
|
5463
|
+
) -> vec3f
|
|
5464
|
+
{
|
|
5465
|
+
let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
|
|
5466
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
fn getNormal(tbn: mat3x3f) -> vec3f
|
|
5470
|
+
{
|
|
3732
5471
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
3733
|
-
|
|
5472
|
+
var n: vec3f = normalize(tbn[2].xyz);
|
|
5473
|
+
#ifdef HAS_NORMALMAP
|
|
5474
|
+
n = getMappedNormal(
|
|
5475
|
+
pbr_normalSampler,
|
|
5476
|
+
pbr_normalSamplerSampler,
|
|
5477
|
+
tbn,
|
|
5478
|
+
pbrMaterial.normalScale
|
|
5479
|
+
);
|
|
3734
5480
|
#endif
|
|
3735
5481
|
|
|
3736
5482
|
return n;
|
|
3737
5483
|
}
|
|
3738
5484
|
|
|
5485
|
+
fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
|
|
5486
|
+
{
|
|
5487
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
5488
|
+
return getMappedNormal(
|
|
5489
|
+
pbr_clearcoatNormalSampler,
|
|
5490
|
+
pbr_clearcoatNormalSamplerSampler,
|
|
5491
|
+
tbn,
|
|
5492
|
+
1.0
|
|
5493
|
+
);
|
|
5494
|
+
#else
|
|
5495
|
+
return baseNormal;
|
|
5496
|
+
#endif
|
|
5497
|
+
}
|
|
5498
|
+
|
|
3739
5499
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
3740
5500
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
3741
5501
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
3742
5502
|
#ifdef USE_IBL
|
|
3743
|
-
fn getIBLContribution(PBRInfo
|
|
5503
|
+
fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
|
|
3744
5504
|
{
|
|
3745
|
-
|
|
3746
|
-
|
|
5505
|
+
let mipCount: f32 = 9.0; // resolution of 512x512
|
|
5506
|
+
let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
|
|
3747
5507
|
// retrieve a scale and bias to F0. See [1], Figure 3
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
5508
|
+
let brdf = SRGBtoLINEAR(
|
|
5509
|
+
textureSampleLevel(
|
|
5510
|
+
pbr_brdfLUT,
|
|
5511
|
+
pbr_brdfLUTSampler,
|
|
5512
|
+
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
|
|
5513
|
+
0.0
|
|
5514
|
+
)
|
|
5515
|
+
).rgb;
|
|
5516
|
+
let diffuseLight =
|
|
5517
|
+
SRGBtoLINEAR(
|
|
5518
|
+
textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
|
|
5519
|
+
).rgb;
|
|
5520
|
+
var specularLight = SRGBtoLINEAR(
|
|
5521
|
+
textureSampleLevel(
|
|
5522
|
+
pbr_specularEnvSampler,
|
|
5523
|
+
pbr_specularEnvSamplerSampler,
|
|
5524
|
+
reflection,
|
|
5525
|
+
0.0
|
|
5526
|
+
)
|
|
5527
|
+
).rgb;
|
|
3752
5528
|
#ifdef USE_TEX_LOD
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
5529
|
+
specularLight = SRGBtoLINEAR(
|
|
5530
|
+
textureSampleLevel(
|
|
5531
|
+
pbr_specularEnvSampler,
|
|
5532
|
+
pbr_specularEnvSamplerSampler,
|
|
5533
|
+
reflection,
|
|
5534
|
+
lod
|
|
5535
|
+
)
|
|
5536
|
+
).rgb;
|
|
3756
5537
|
#endif
|
|
3757
5538
|
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
// For presentation, this allows us to disable IBL terms
|
|
3762
|
-
diffuse *= pbrMaterial.scaleIBLAmbient.x;
|
|
3763
|
-
specular *= pbrMaterial.scaleIBLAmbient.y;
|
|
5539
|
+
let diffuse = diffuseLight * pbrInfo.diffuseColor * pbrMaterial.scaleIBLAmbient.x;
|
|
5540
|
+
let specular =
|
|
5541
|
+
specularLight * (pbrInfo.specularColor * brdf.x + brdf.y) * pbrMaterial.scaleIBLAmbient.y;
|
|
3764
5542
|
|
|
3765
5543
|
return diffuse + specular;
|
|
3766
5544
|
}
|
|
@@ -3804,7 +5582,173 @@ fn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {
|
|
|
3804
5582
|
fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
|
|
3805
5583
|
let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
|
|
3806
5584
|
let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
|
|
3807
|
-
return roughnessSq / (
|
|
5585
|
+
return roughnessSq / (M_PI * f * f);
|
|
5586
|
+
}
|
|
5587
|
+
|
|
5588
|
+
fn maxComponent(value: vec3f) -> f32 {
|
|
5589
|
+
return max(max(value.r, value.g), value.b);
|
|
5590
|
+
}
|
|
5591
|
+
|
|
5592
|
+
fn getDielectricF0(ior: f32) -> f32 {
|
|
5593
|
+
let clampedIor = max(ior, 1.0);
|
|
5594
|
+
let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
5595
|
+
return ratio * ratio;
|
|
5596
|
+
}
|
|
5597
|
+
|
|
5598
|
+
fn normalizeDirection(direction: vec2f) -> vec2f {
|
|
5599
|
+
let directionLength = length(direction);
|
|
5600
|
+
if (directionLength > 0.0001) {
|
|
5601
|
+
return direction / directionLength;
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
return vec2f(1.0, 0.0);
|
|
5605
|
+
}
|
|
5606
|
+
|
|
5607
|
+
fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
|
|
5608
|
+
let s = sin(rotation);
|
|
5609
|
+
let c = cos(rotation);
|
|
5610
|
+
return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
5611
|
+
}
|
|
5612
|
+
|
|
5613
|
+
fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
|
|
5614
|
+
if (iridescence <= 0.0) {
|
|
5615
|
+
return vec3f(1.0);
|
|
5616
|
+
}
|
|
5617
|
+
|
|
5618
|
+
let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
5619
|
+
let thinFilmTint =
|
|
5620
|
+
0.5 +
|
|
5621
|
+
0.5 *
|
|
5622
|
+
cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
|
|
5623
|
+
return mix(vec3f(1.0), thinFilmTint, iridescence);
|
|
5624
|
+
}
|
|
5625
|
+
|
|
5626
|
+
fn getVolumeAttenuation(thickness: f32) -> vec3f {
|
|
5627
|
+
if (thickness <= 0.0) {
|
|
5628
|
+
return vec3f(1.0);
|
|
5629
|
+
}
|
|
5630
|
+
|
|
5631
|
+
let attenuationCoefficient =
|
|
5632
|
+
-log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
|
|
5633
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
5634
|
+
return exp(-attenuationCoefficient * thickness);
|
|
5635
|
+
}
|
|
5636
|
+
|
|
5637
|
+
fn createClearcoatPBRInfo(
|
|
5638
|
+
basePBRInfo: PBRInfo,
|
|
5639
|
+
clearcoatNormal: vec3f,
|
|
5640
|
+
clearcoatRoughness: f32
|
|
5641
|
+
) -> PBRInfo {
|
|
5642
|
+
let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
5643
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5644
|
+
let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
5645
|
+
|
|
5646
|
+
return PBRInfo(
|
|
5647
|
+
basePBRInfo.NdotL,
|
|
5648
|
+
NdotV,
|
|
5649
|
+
basePBRInfo.NdotH,
|
|
5650
|
+
basePBRInfo.LdotH,
|
|
5651
|
+
basePBRInfo.VdotH,
|
|
5652
|
+
perceptualRoughness,
|
|
5653
|
+
0.0,
|
|
5654
|
+
vec3f(0.04),
|
|
5655
|
+
vec3f(1.0),
|
|
5656
|
+
alphaRoughness,
|
|
5657
|
+
vec3f(0.0),
|
|
5658
|
+
vec3f(0.04),
|
|
5659
|
+
clearcoatNormal,
|
|
5660
|
+
basePBRInfo.v
|
|
5661
|
+
);
|
|
5662
|
+
}
|
|
5663
|
+
|
|
5664
|
+
fn calculateClearcoatContribution(
|
|
5665
|
+
pbrInfo: PBRInfo,
|
|
5666
|
+
lightColor: vec3f,
|
|
5667
|
+
clearcoatNormal: vec3f,
|
|
5668
|
+
clearcoatFactor: f32,
|
|
5669
|
+
clearcoatRoughness: f32
|
|
5670
|
+
) -> vec3f {
|
|
5671
|
+
if (clearcoatFactor <= 0.0) {
|
|
5672
|
+
return vec3f(0.0);
|
|
5673
|
+
}
|
|
5674
|
+
|
|
5675
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
5676
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
5677
|
+
}
|
|
5678
|
+
|
|
5679
|
+
#ifdef USE_IBL
|
|
5680
|
+
fn calculateClearcoatIBLContribution(
|
|
5681
|
+
pbrInfo: PBRInfo,
|
|
5682
|
+
clearcoatNormal: vec3f,
|
|
5683
|
+
reflection: vec3f,
|
|
5684
|
+
clearcoatFactor: f32,
|
|
5685
|
+
clearcoatRoughness: f32
|
|
5686
|
+
) -> vec3f {
|
|
5687
|
+
if (clearcoatFactor <= 0.0) {
|
|
5688
|
+
return vec3f(0.0);
|
|
5689
|
+
}
|
|
5690
|
+
|
|
5691
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
5692
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
5693
|
+
}
|
|
5694
|
+
#endif
|
|
5695
|
+
|
|
5696
|
+
fn calculateSheenContribution(
|
|
5697
|
+
pbrInfo: PBRInfo,
|
|
5698
|
+
lightColor: vec3f,
|
|
5699
|
+
sheenColor: vec3f,
|
|
5700
|
+
sheenRoughness: f32
|
|
5701
|
+
) -> vec3f {
|
|
5702
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
5703
|
+
return vec3f(0.0);
|
|
5704
|
+
}
|
|
5705
|
+
|
|
5706
|
+
let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
5707
|
+
let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
5708
|
+
return pbrInfo.NdotL *
|
|
5709
|
+
lightColor *
|
|
5710
|
+
sheenColor *
|
|
5711
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
5712
|
+
sheenVisibility *
|
|
5713
|
+
(1.0 - pbrInfo.metalness);
|
|
5714
|
+
}
|
|
5715
|
+
|
|
5716
|
+
fn calculateAnisotropyBoost(
|
|
5717
|
+
pbrInfo: PBRInfo,
|
|
5718
|
+
anisotropyTangent: vec3f,
|
|
5719
|
+
anisotropyStrength: f32
|
|
5720
|
+
) -> f32 {
|
|
5721
|
+
if (anisotropyStrength <= 0.0) {
|
|
5722
|
+
return 1.0;
|
|
5723
|
+
}
|
|
5724
|
+
|
|
5725
|
+
let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
5726
|
+
let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
5727
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
5728
|
+
}
|
|
5729
|
+
|
|
5730
|
+
fn calculateMaterialLightColor(
|
|
5731
|
+
pbrInfo: PBRInfo,
|
|
5732
|
+
lightColor: vec3f,
|
|
5733
|
+
clearcoatNormal: vec3f,
|
|
5734
|
+
clearcoatFactor: f32,
|
|
5735
|
+
clearcoatRoughness: f32,
|
|
5736
|
+
sheenColor: vec3f,
|
|
5737
|
+
sheenRoughness: f32,
|
|
5738
|
+
anisotropyTangent: vec3f,
|
|
5739
|
+
anisotropyStrength: f32
|
|
5740
|
+
) -> vec3f {
|
|
5741
|
+
let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
5742
|
+
var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
5743
|
+
color += calculateClearcoatContribution(
|
|
5744
|
+
pbrInfo,
|
|
5745
|
+
lightColor,
|
|
5746
|
+
clearcoatNormal,
|
|
5747
|
+
clearcoatFactor,
|
|
5748
|
+
clearcoatRoughness
|
|
5749
|
+
);
|
|
5750
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
5751
|
+
return color;
|
|
3808
5752
|
}
|
|
3809
5753
|
|
|
3810
5754
|
fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
|
|
@@ -3831,6 +5775,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
|
|
|
3831
5775
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
3832
5776
|
}
|
|
3833
5777
|
|
|
5778
|
+
fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
|
|
5779
|
+
let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
|
|
5780
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
5781
|
+
}
|
|
5782
|
+
|
|
3834
5783
|
fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
|
|
3835
5784
|
// Calculate the shading terms for the microfacet specular shading model
|
|
3836
5785
|
let F = specularReflection(pbrInfo);
|
|
@@ -3846,11 +5795,11 @@ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
|
|
|
3846
5795
|
|
|
3847
5796
|
fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
3848
5797
|
// The albedo may be defined from a base texture or a flat color
|
|
3849
|
-
var baseColor: vec4<f32
|
|
5798
|
+
var baseColor: vec4<f32> = pbrMaterial.baseColorFactor;
|
|
3850
5799
|
#ifdef HAS_BASECOLORMAP
|
|
3851
|
-
baseColor = SRGBtoLINEAR(
|
|
3852
|
-
|
|
3853
|
-
|
|
5800
|
+
baseColor = SRGBtoLINEAR(
|
|
5801
|
+
textureSample(pbr_baseColorSampler, pbr_baseColorSamplerSampler, fragmentInputs.pbr_vUV)
|
|
5802
|
+
) * pbrMaterial.baseColorFactor;
|
|
3854
5803
|
#endif
|
|
3855
5804
|
|
|
3856
5805
|
#ifdef ALPHA_CUTOFF
|
|
@@ -3860,8 +5809,9 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3860
5809
|
#endif
|
|
3861
5810
|
|
|
3862
5811
|
var color = vec3<f32>(0.0, 0.0, 0.0);
|
|
5812
|
+
var transmission = 0.0;
|
|
3863
5813
|
|
|
3864
|
-
if (pbrMaterial.unlit) {
|
|
5814
|
+
if (pbrMaterial.unlit != 0u) {
|
|
3865
5815
|
color = baseColor.rgb;
|
|
3866
5816
|
} else {
|
|
3867
5817
|
// Metallic and Roughness material properties are packed together
|
|
@@ -3872,20 +5822,318 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3872
5822
|
#ifdef HAS_METALROUGHNESSMAP
|
|
3873
5823
|
// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
|
|
3874
5824
|
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
|
|
3875
|
-
let mrSample = textureSample(
|
|
5825
|
+
let mrSample = textureSample(
|
|
5826
|
+
pbr_metallicRoughnessSampler,
|
|
5827
|
+
pbr_metallicRoughnessSamplerSampler,
|
|
5828
|
+
fragmentInputs.pbr_vUV
|
|
5829
|
+
);
|
|
3876
5830
|
perceptualRoughness = mrSample.g * perceptualRoughness;
|
|
3877
5831
|
metallic = mrSample.b * metallic;
|
|
3878
5832
|
#endif
|
|
3879
5833
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
3880
5834
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
5835
|
+
let tbn = getTBN();
|
|
5836
|
+
let n = getNormal(tbn); // normal at surface point
|
|
5837
|
+
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
5838
|
+
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
5839
|
+
var useExtendedPBR = false;
|
|
5840
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
5841
|
+
useExtendedPBR =
|
|
5842
|
+
pbrMaterial.specularColorMapEnabled != 0 ||
|
|
5843
|
+
pbrMaterial.specularIntensityMapEnabled != 0 ||
|
|
5844
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
5845
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
|
|
5846
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
5847
|
+
pbrMaterial.transmissionMapEnabled != 0 ||
|
|
5848
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
5849
|
+
pbrMaterial.clearcoatMapEnabled != 0 ||
|
|
5850
|
+
pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
|
|
5851
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
5852
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
5853
|
+
pbrMaterial.sheenColorMapEnabled != 0 ||
|
|
5854
|
+
pbrMaterial.sheenRoughnessMapEnabled != 0 ||
|
|
5855
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
5856
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
5857
|
+
pbrMaterial.iridescenceMapEnabled != 0 ||
|
|
5858
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
5859
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
5860
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
5861
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
5862
|
+
pbrMaterial.anisotropyMapEnabled != 0 ||
|
|
5863
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
5864
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
5865
|
+
length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
|
|
5866
|
+
#endif
|
|
5867
|
+
|
|
5868
|
+
if (!useExtendedPBR) {
|
|
5869
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
5870
|
+
|
|
5871
|
+
let f0 = vec3<f32>(0.04);
|
|
5872
|
+
var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
|
|
5873
|
+
diffuseColor *= 1.0 - metallic;
|
|
5874
|
+
let specularColor = mix(f0, baseColor.rgb, metallic);
|
|
5875
|
+
|
|
5876
|
+
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
5877
|
+
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
5878
|
+
let specularEnvironmentR0 = specularColor;
|
|
5879
|
+
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
5880
|
+
let reflection = -normalize(reflect(v, n));
|
|
5881
|
+
|
|
5882
|
+
var pbrInfo = PBRInfo(
|
|
5883
|
+
0.0, // NdotL
|
|
5884
|
+
NdotV,
|
|
5885
|
+
0.0, // NdotH
|
|
5886
|
+
0.0, // LdotH
|
|
5887
|
+
0.0, // VdotH
|
|
5888
|
+
perceptualRoughness,
|
|
5889
|
+
metallic,
|
|
5890
|
+
specularEnvironmentR0,
|
|
5891
|
+
specularEnvironmentR90,
|
|
5892
|
+
alphaRoughness,
|
|
5893
|
+
diffuseColor,
|
|
5894
|
+
specularColor,
|
|
5895
|
+
n,
|
|
5896
|
+
v
|
|
5897
|
+
);
|
|
5898
|
+
|
|
5899
|
+
#ifdef USE_LIGHTS
|
|
5900
|
+
PBRInfo_setAmbientLight(&pbrInfo);
|
|
5901
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
5902
|
+
|
|
5903
|
+
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
5904
|
+
if (i < lighting.directionalLightCount) {
|
|
5905
|
+
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
5906
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
|
|
5910
|
+
for (var i = 0; i < lighting.pointLightCount; i++) {
|
|
5911
|
+
if (i < lighting.pointLightCount) {
|
|
5912
|
+
PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
|
|
5913
|
+
let attenuation = getPointLightAttenuation(
|
|
5914
|
+
lighting_getPointLight(i),
|
|
5915
|
+
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
5916
|
+
);
|
|
5917
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
5918
|
+
}
|
|
5919
|
+
}
|
|
5920
|
+
|
|
5921
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
5922
|
+
if (i < lighting.spotLightCount) {
|
|
5923
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
5924
|
+
let attenuation = getSpotLightAttenuation(
|
|
5925
|
+
lighting_getSpotLight(i),
|
|
5926
|
+
fragmentInputs.pbr_vPosition
|
|
5927
|
+
);
|
|
5928
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
#endif
|
|
5932
|
+
|
|
5933
|
+
#ifdef USE_IBL
|
|
5934
|
+
if (pbrMaterial.IBLenabled != 0) {
|
|
5935
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
5936
|
+
}
|
|
5937
|
+
#endif
|
|
5938
|
+
|
|
5939
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
5940
|
+
if (pbrMaterial.occlusionMapEnabled != 0) {
|
|
5941
|
+
let ao =
|
|
5942
|
+
textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
|
|
5943
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
5944
|
+
}
|
|
5945
|
+
#endif
|
|
5946
|
+
|
|
5947
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
5948
|
+
#ifdef HAS_EMISSIVEMAP
|
|
5949
|
+
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
5950
|
+
emissive *= SRGBtoLINEAR(
|
|
5951
|
+
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
5952
|
+
).rgb;
|
|
5953
|
+
}
|
|
5954
|
+
#endif
|
|
5955
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
5956
|
+
|
|
5957
|
+
#ifdef PBR_DEBUG
|
|
5958
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
5959
|
+
color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
5960
|
+
color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
5961
|
+
#endif
|
|
5962
|
+
|
|
5963
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
|
|
5964
|
+
}
|
|
5965
|
+
|
|
5966
|
+
var specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
5967
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
5968
|
+
if (pbrMaterial.specularIntensityMapEnabled != 0) {
|
|
5969
|
+
specularIntensity *= textureSample(
|
|
5970
|
+
pbr_specularIntensitySampler,
|
|
5971
|
+
pbr_specularIntensitySamplerSampler,
|
|
5972
|
+
fragmentInputs.pbr_vUV
|
|
5973
|
+
).a;
|
|
5974
|
+
}
|
|
5975
|
+
#endif
|
|
5976
|
+
|
|
5977
|
+
var specularFactor = pbrMaterial.specularColorFactor;
|
|
5978
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
5979
|
+
if (pbrMaterial.specularColorMapEnabled != 0) {
|
|
5980
|
+
specularFactor *= SRGBtoLINEAR(
|
|
5981
|
+
textureSample(
|
|
5982
|
+
pbr_specularColorSampler,
|
|
5983
|
+
pbr_specularColorSamplerSampler,
|
|
5984
|
+
fragmentInputs.pbr_vUV
|
|
5985
|
+
)
|
|
5986
|
+
).rgb;
|
|
5987
|
+
}
|
|
5988
|
+
#endif
|
|
5989
|
+
|
|
5990
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
5991
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
5992
|
+
if (pbrMaterial.transmissionMapEnabled != 0) {
|
|
5993
|
+
transmission *= textureSample(
|
|
5994
|
+
pbr_transmissionSampler,
|
|
5995
|
+
pbr_transmissionSamplerSampler,
|
|
5996
|
+
fragmentInputs.pbr_vUV
|
|
5997
|
+
).r;
|
|
5998
|
+
}
|
|
5999
|
+
#endif
|
|
6000
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
6001
|
+
var thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
6002
|
+
#ifdef HAS_THICKNESSMAP
|
|
6003
|
+
thickness *= textureSample(
|
|
6004
|
+
pbr_thicknessSampler,
|
|
6005
|
+
pbr_thicknessSamplerSampler,
|
|
6006
|
+
fragmentInputs.pbr_vUV
|
|
6007
|
+
).g;
|
|
6008
|
+
#endif
|
|
6009
|
+
|
|
6010
|
+
var clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
6011
|
+
var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
6012
|
+
#ifdef HAS_CLEARCOATMAP
|
|
6013
|
+
if (pbrMaterial.clearcoatMapEnabled != 0) {
|
|
6014
|
+
clearcoatFactor *= textureSample(
|
|
6015
|
+
pbr_clearcoatSampler,
|
|
6016
|
+
pbr_clearcoatSamplerSampler,
|
|
6017
|
+
fragmentInputs.pbr_vUV
|
|
6018
|
+
).r;
|
|
6019
|
+
}
|
|
6020
|
+
#endif
|
|
6021
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
6022
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
|
|
6023
|
+
clearcoatRoughness *= textureSample(
|
|
6024
|
+
pbr_clearcoatRoughnessSampler,
|
|
6025
|
+
pbr_clearcoatRoughnessSamplerSampler,
|
|
6026
|
+
fragmentInputs.pbr_vUV
|
|
6027
|
+
).g;
|
|
6028
|
+
}
|
|
6029
|
+
#endif
|
|
6030
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
6031
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
6032
|
+
let clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
6033
|
+
|
|
6034
|
+
var sheenColor = pbrMaterial.sheenColorFactor;
|
|
6035
|
+
var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
6036
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
6037
|
+
if (pbrMaterial.sheenColorMapEnabled != 0) {
|
|
6038
|
+
sheenColor *= SRGBtoLINEAR(
|
|
6039
|
+
textureSample(
|
|
6040
|
+
pbr_sheenColorSampler,
|
|
6041
|
+
pbr_sheenColorSamplerSampler,
|
|
6042
|
+
fragmentInputs.pbr_vUV
|
|
6043
|
+
)
|
|
6044
|
+
).rgb;
|
|
6045
|
+
}
|
|
6046
|
+
#endif
|
|
6047
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
6048
|
+
if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
|
|
6049
|
+
sheenRoughness *= textureSample(
|
|
6050
|
+
pbr_sheenRoughnessSampler,
|
|
6051
|
+
pbr_sheenRoughnessSamplerSampler,
|
|
6052
|
+
fragmentInputs.pbr_vUV
|
|
6053
|
+
).a;
|
|
6054
|
+
}
|
|
6055
|
+
#endif
|
|
6056
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
6057
|
+
|
|
6058
|
+
var iridescence = pbrMaterial.iridescenceFactor;
|
|
6059
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
6060
|
+
if (pbrMaterial.iridescenceMapEnabled != 0) {
|
|
6061
|
+
iridescence *= textureSample(
|
|
6062
|
+
pbr_iridescenceSampler,
|
|
6063
|
+
pbr_iridescenceSamplerSampler,
|
|
6064
|
+
fragmentInputs.pbr_vUV
|
|
6065
|
+
).r;
|
|
6066
|
+
}
|
|
6067
|
+
#endif
|
|
6068
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
6069
|
+
var iridescenceThickness = mix(
|
|
6070
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6071
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6072
|
+
0.5
|
|
6073
|
+
);
|
|
6074
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
6075
|
+
iridescenceThickness = mix(
|
|
6076
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
6077
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
6078
|
+
textureSample(
|
|
6079
|
+
pbr_iridescenceThicknessSampler,
|
|
6080
|
+
pbr_iridescenceThicknessSamplerSampler,
|
|
6081
|
+
fragmentInputs.pbr_vUV
|
|
6082
|
+
).g
|
|
6083
|
+
);
|
|
6084
|
+
#endif
|
|
6085
|
+
|
|
6086
|
+
var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
6087
|
+
var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
6088
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
6089
|
+
if (pbrMaterial.anisotropyMapEnabled != 0) {
|
|
6090
|
+
let anisotropySample = textureSample(
|
|
6091
|
+
pbr_anisotropySampler,
|
|
6092
|
+
pbr_anisotropySamplerSampler,
|
|
6093
|
+
fragmentInputs.pbr_vUV
|
|
6094
|
+
).rgb;
|
|
6095
|
+
anisotropyStrength *= anisotropySample.b;
|
|
6096
|
+
let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
6097
|
+
if (length(mappedDirection) > 0.0001) {
|
|
6098
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
6099
|
+
}
|
|
6100
|
+
}
|
|
6101
|
+
#endif
|
|
6102
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
6103
|
+
var anisotropyTangent =
|
|
6104
|
+
normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
6105
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
6106
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
6107
|
+
}
|
|
6108
|
+
let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
6109
|
+
perceptualRoughness = mix(
|
|
6110
|
+
perceptualRoughness,
|
|
6111
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
6112
|
+
anisotropyStrength
|
|
6113
|
+
);
|
|
6114
|
+
|
|
3881
6115
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
3882
6116
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
3883
6117
|
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
3884
6118
|
|
|
3885
|
-
let
|
|
3886
|
-
var
|
|
3887
|
-
|
|
3888
|
-
|
|
6119
|
+
let dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
6120
|
+
var dielectricSpecularF0 = min(
|
|
6121
|
+
vec3f(dielectricF0) * specularFactor * specularIntensity,
|
|
6122
|
+
vec3f(1.0)
|
|
6123
|
+
);
|
|
6124
|
+
let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
6125
|
+
dielectricSpecularF0 = mix(
|
|
6126
|
+
dielectricSpecularF0,
|
|
6127
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
6128
|
+
iridescence
|
|
6129
|
+
);
|
|
6130
|
+
var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
|
|
6131
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
6132
|
+
var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
6133
|
+
|
|
6134
|
+
let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
6135
|
+
diffuseColor *= baseLayerEnergy;
|
|
6136
|
+
specularColor *= baseLayerEnergy;
|
|
3889
6137
|
|
|
3890
6138
|
// Compute reflectance.
|
|
3891
6139
|
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -3897,11 +6145,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3897
6145
|
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
3898
6146
|
let specularEnvironmentR0 = specularColor;
|
|
3899
6147
|
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
3900
|
-
|
|
3901
|
-
let n = getNormal(); // normal at surface point
|
|
3902
|
-
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
3903
|
-
|
|
3904
|
-
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
3905
6148
|
let reflection = -normalize(reflect(v, n));
|
|
3906
6149
|
|
|
3907
6150
|
var pbrInfo = PBRInfo(
|
|
@@ -3924,13 +6167,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3924
6167
|
#ifdef USE_LIGHTS
|
|
3925
6168
|
// Apply ambient light
|
|
3926
6169
|
PBRInfo_setAmbientLight(&pbrInfo);
|
|
3927
|
-
color +=
|
|
6170
|
+
color += calculateMaterialLightColor(
|
|
6171
|
+
pbrInfo,
|
|
6172
|
+
lighting.ambientColor,
|
|
6173
|
+
clearcoatNormal,
|
|
6174
|
+
clearcoatFactor,
|
|
6175
|
+
clearcoatRoughness,
|
|
6176
|
+
sheenColor,
|
|
6177
|
+
sheenRoughness,
|
|
6178
|
+
anisotropyTangent,
|
|
6179
|
+
anisotropyStrength
|
|
6180
|
+
);
|
|
3928
6181
|
|
|
3929
6182
|
// Apply directional light
|
|
3930
6183
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
3931
6184
|
if (i < lighting.directionalLightCount) {
|
|
3932
6185
|
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
3933
|
-
color +=
|
|
6186
|
+
color += calculateMaterialLightColor(
|
|
6187
|
+
pbrInfo,
|
|
6188
|
+
lighting_getDirectionalLight(i).color,
|
|
6189
|
+
clearcoatNormal,
|
|
6190
|
+
clearcoatFactor,
|
|
6191
|
+
clearcoatRoughness,
|
|
6192
|
+
sheenColor,
|
|
6193
|
+
sheenRoughness,
|
|
6194
|
+
anisotropyTangent,
|
|
6195
|
+
anisotropyStrength
|
|
6196
|
+
);
|
|
3934
6197
|
}
|
|
3935
6198
|
}
|
|
3936
6199
|
|
|
@@ -3942,32 +6205,77 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3942
6205
|
lighting_getPointLight(i),
|
|
3943
6206
|
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
3944
6207
|
);
|
|
3945
|
-
color +=
|
|
6208
|
+
color += calculateMaterialLightColor(
|
|
6209
|
+
pbrInfo,
|
|
6210
|
+
lighting_getPointLight(i).color / attenuation,
|
|
6211
|
+
clearcoatNormal,
|
|
6212
|
+
clearcoatFactor,
|
|
6213
|
+
clearcoatRoughness,
|
|
6214
|
+
sheenColor,
|
|
6215
|
+
sheenRoughness,
|
|
6216
|
+
anisotropyTangent,
|
|
6217
|
+
anisotropyStrength
|
|
6218
|
+
);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
|
|
6222
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
6223
|
+
if (i < lighting.spotLightCount) {
|
|
6224
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
6225
|
+
let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
|
|
6226
|
+
color += calculateMaterialLightColor(
|
|
6227
|
+
pbrInfo,
|
|
6228
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
6229
|
+
clearcoatNormal,
|
|
6230
|
+
clearcoatFactor,
|
|
6231
|
+
clearcoatRoughness,
|
|
6232
|
+
sheenColor,
|
|
6233
|
+
sheenRoughness,
|
|
6234
|
+
anisotropyTangent,
|
|
6235
|
+
anisotropyStrength
|
|
6236
|
+
);
|
|
3946
6237
|
}
|
|
3947
6238
|
}
|
|
3948
6239
|
#endif
|
|
3949
6240
|
|
|
3950
6241
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
3951
6242
|
#ifdef USE_IBL
|
|
3952
|
-
if (pbrMaterial.IBLenabled) {
|
|
3953
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
6243
|
+
if (pbrMaterial.IBLenabled != 0) {
|
|
6244
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
6245
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
6246
|
+
color += calculateClearcoatIBLContribution(
|
|
6247
|
+
pbrInfo,
|
|
6248
|
+
clearcoatNormal,
|
|
6249
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
6250
|
+
clearcoatFactor,
|
|
6251
|
+
clearcoatRoughness
|
|
6252
|
+
);
|
|
6253
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
3954
6254
|
}
|
|
3955
6255
|
#endif
|
|
3956
6256
|
|
|
3957
6257
|
// Apply optional PBR terms for additional (optional) shading
|
|
3958
6258
|
#ifdef HAS_OCCLUSIONMAP
|
|
3959
|
-
if (pbrMaterial.occlusionMapEnabled) {
|
|
3960
|
-
let ao =
|
|
6259
|
+
if (pbrMaterial.occlusionMapEnabled != 0) {
|
|
6260
|
+
let ao =
|
|
6261
|
+
textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
|
|
3961
6262
|
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
3962
6263
|
}
|
|
3963
6264
|
#endif
|
|
3964
6265
|
|
|
6266
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
3965
6267
|
#ifdef HAS_EMISSIVEMAP
|
|
3966
|
-
if (pbrMaterial.emissiveMapEnabled) {
|
|
3967
|
-
|
|
3968
|
-
|
|
6268
|
+
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
6269
|
+
emissive *= SRGBtoLINEAR(
|
|
6270
|
+
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
6271
|
+
).rgb;
|
|
3969
6272
|
}
|
|
3970
6273
|
#endif
|
|
6274
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
6275
|
+
|
|
6276
|
+
if (transmission > 0.0) {
|
|
6277
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
6278
|
+
}
|
|
3971
6279
|
|
|
3972
6280
|
// This section uses mix to override final color for reference app visualization
|
|
3973
6281
|
// of various parameters in the lighting equation.
|
|
@@ -3986,7 +6294,8 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
3986
6294
|
#endif
|
|
3987
6295
|
}
|
|
3988
6296
|
|
|
3989
|
-
|
|
6297
|
+
let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
6298
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
|
|
3990
6299
|
}
|
|
3991
6300
|
`
|
|
3992
6301
|
);
|
|
@@ -4002,8 +6311,22 @@ var uniformBlock = (
|
|
|
4002
6311
|
} pbrProjection;
|
|
4003
6312
|
`
|
|
4004
6313
|
);
|
|
6314
|
+
var wgslUniformBlock = (
|
|
6315
|
+
/* wgsl */
|
|
6316
|
+
`struct pbrProjectionUniforms {
|
|
6317
|
+
modelViewProjectionMatrix: mat4x4<f32>,
|
|
6318
|
+
modelMatrix: mat4x4<f32>,
|
|
6319
|
+
normalMatrix: mat4x4<f32>,
|
|
6320
|
+
camera: vec3<f32>
|
|
6321
|
+
};
|
|
6322
|
+
|
|
6323
|
+
@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
|
|
6324
|
+
`
|
|
6325
|
+
);
|
|
4005
6326
|
var pbrProjection = {
|
|
4006
6327
|
name: "pbrProjection",
|
|
6328
|
+
bindingLayout: [{ name: "pbrProjection", group: 0 }],
|
|
6329
|
+
source: wgslUniformBlock,
|
|
4007
6330
|
vs: uniformBlock,
|
|
4008
6331
|
fs: uniformBlock,
|
|
4009
6332
|
// TODO why is this needed?
|
|
@@ -4012,7 +6335,7 @@ var pbrProjection = {
|
|
|
4012
6335
|
modelViewProjectionMatrix: "mat4x4<f32>",
|
|
4013
6336
|
modelMatrix: "mat4x4<f32>",
|
|
4014
6337
|
normalMatrix: "mat4x4<f32>",
|
|
4015
|
-
camera: "vec3<
|
|
6338
|
+
camera: "vec3<f32>"
|
|
4016
6339
|
}
|
|
4017
6340
|
};
|
|
4018
6341
|
|
|
@@ -4020,11 +6343,78 @@ var pbrProjection = {
|
|
|
4020
6343
|
var pbrMaterial = {
|
|
4021
6344
|
props: {},
|
|
4022
6345
|
uniforms: {},
|
|
6346
|
+
defaultUniforms: {
|
|
6347
|
+
unlit: false,
|
|
6348
|
+
baseColorMapEnabled: false,
|
|
6349
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
6350
|
+
normalMapEnabled: false,
|
|
6351
|
+
normalScale: 1,
|
|
6352
|
+
emissiveMapEnabled: false,
|
|
6353
|
+
emissiveFactor: [0, 0, 0],
|
|
6354
|
+
metallicRoughnessValues: [1, 1],
|
|
6355
|
+
metallicRoughnessMapEnabled: false,
|
|
6356
|
+
occlusionMapEnabled: false,
|
|
6357
|
+
occlusionStrength: 1,
|
|
6358
|
+
alphaCutoffEnabled: false,
|
|
6359
|
+
alphaCutoff: 0.5,
|
|
6360
|
+
IBLenabled: false,
|
|
6361
|
+
scaleIBLAmbient: [1, 1],
|
|
6362
|
+
scaleDiffBaseMR: [0, 0, 0, 0],
|
|
6363
|
+
scaleFGDSpec: [0, 0, 0, 0],
|
|
6364
|
+
specularColorFactor: [1, 1, 1],
|
|
6365
|
+
specularIntensityFactor: 1,
|
|
6366
|
+
specularColorMapEnabled: false,
|
|
6367
|
+
specularIntensityMapEnabled: false,
|
|
6368
|
+
ior: 1.5,
|
|
6369
|
+
transmissionFactor: 0,
|
|
6370
|
+
transmissionMapEnabled: false,
|
|
6371
|
+
thicknessFactor: 0,
|
|
6372
|
+
attenuationDistance: 1e9,
|
|
6373
|
+
attenuationColor: [1, 1, 1],
|
|
6374
|
+
clearcoatFactor: 0,
|
|
6375
|
+
clearcoatRoughnessFactor: 0,
|
|
6376
|
+
clearcoatMapEnabled: false,
|
|
6377
|
+
clearcoatRoughnessMapEnabled: false,
|
|
6378
|
+
sheenColorFactor: [0, 0, 0],
|
|
6379
|
+
sheenRoughnessFactor: 0,
|
|
6380
|
+
sheenColorMapEnabled: false,
|
|
6381
|
+
sheenRoughnessMapEnabled: false,
|
|
6382
|
+
iridescenceFactor: 0,
|
|
6383
|
+
iridescenceIor: 1.3,
|
|
6384
|
+
iridescenceThicknessRange: [100, 400],
|
|
6385
|
+
iridescenceMapEnabled: false,
|
|
6386
|
+
anisotropyStrength: 0,
|
|
6387
|
+
anisotropyRotation: 0,
|
|
6388
|
+
anisotropyDirection: [1, 0],
|
|
6389
|
+
anisotropyMapEnabled: false,
|
|
6390
|
+
emissiveStrength: 1
|
|
6391
|
+
},
|
|
4023
6392
|
name: "pbrMaterial",
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
6393
|
+
firstBindingSlot: 0,
|
|
6394
|
+
bindingLayout: [
|
|
6395
|
+
{ name: "pbrMaterial", group: 3 },
|
|
6396
|
+
{ name: "pbr_baseColorSampler", group: 3 },
|
|
6397
|
+
{ name: "pbr_normalSampler", group: 3 },
|
|
6398
|
+
{ name: "pbr_emissiveSampler", group: 3 },
|
|
6399
|
+
{ name: "pbr_metallicRoughnessSampler", group: 3 },
|
|
6400
|
+
{ name: "pbr_occlusionSampler", group: 3 },
|
|
6401
|
+
{ name: "pbr_specularColorSampler", group: 3 },
|
|
6402
|
+
{ name: "pbr_specularIntensitySampler", group: 3 },
|
|
6403
|
+
{ name: "pbr_transmissionSampler", group: 3 },
|
|
6404
|
+
{ name: "pbr_thicknessSampler", group: 3 },
|
|
6405
|
+
{ name: "pbr_clearcoatSampler", group: 3 },
|
|
6406
|
+
{ name: "pbr_clearcoatRoughnessSampler", group: 3 },
|
|
6407
|
+
{ name: "pbr_clearcoatNormalSampler", group: 3 },
|
|
6408
|
+
{ name: "pbr_sheenColorSampler", group: 3 },
|
|
6409
|
+
{ name: "pbr_sheenRoughnessSampler", group: 3 },
|
|
6410
|
+
{ name: "pbr_iridescenceSampler", group: 3 },
|
|
6411
|
+
{ name: "pbr_iridescenceThicknessSampler", group: 3 },
|
|
6412
|
+
{ name: "pbr_anisotropySampler", group: 3 }
|
|
6413
|
+
],
|
|
6414
|
+
dependencies: [lighting, ibl, pbrProjection],
|
|
6415
|
+
source: source3,
|
|
6416
|
+
vs: vs3,
|
|
6417
|
+
fs: fs4,
|
|
4028
6418
|
defines: {
|
|
4029
6419
|
LIGHTING_FRAGMENT: true,
|
|
4030
6420
|
HAS_NORMALMAP: false,
|
|
@@ -4035,10 +6425,16 @@ var pbrMaterial = {
|
|
|
4035
6425
|
HAS_SPECULARCOLORMAP: false,
|
|
4036
6426
|
HAS_SPECULARINTENSITYMAP: false,
|
|
4037
6427
|
HAS_TRANSMISSIONMAP: false,
|
|
6428
|
+
HAS_THICKNESSMAP: false,
|
|
4038
6429
|
HAS_CLEARCOATMAP: false,
|
|
6430
|
+
HAS_CLEARCOATROUGHNESSMAP: false,
|
|
6431
|
+
HAS_CLEARCOATNORMALMAP: false,
|
|
4039
6432
|
HAS_SHEENCOLORMAP: false,
|
|
6433
|
+
HAS_SHEENROUGHNESSMAP: false,
|
|
4040
6434
|
HAS_IRIDESCENCEMAP: false,
|
|
6435
|
+
HAS_IRIDESCENCETHICKNESSMAP: false,
|
|
4041
6436
|
HAS_ANISOTROPYMAP: false,
|
|
6437
|
+
USE_MATERIAL_EXTENSIONS: false,
|
|
4042
6438
|
ALPHA_CUTOFF: false,
|
|
4043
6439
|
USE_IBL: false,
|
|
4044
6440
|
PBR_DEBUG: false
|
|
@@ -4064,14 +6460,6 @@ var pbrMaterial = {
|
|
|
4064
6460
|
alphaCutoffEnabled: "i32",
|
|
4065
6461
|
alphaCutoff: "f32",
|
|
4066
6462
|
// #ifdef ALPHA_CUTOFF
|
|
4067
|
-
// IBL
|
|
4068
|
-
IBLenabled: "i32",
|
|
4069
|
-
scaleIBLAmbient: "vec2<f32>",
|
|
4070
|
-
// #ifdef USE_IBL
|
|
4071
|
-
// debugging flags used for shader output of intermediate PBR variables
|
|
4072
|
-
// #ifdef PBR_DEBUG
|
|
4073
|
-
scaleDiffBaseMR: "vec4<f32>",
|
|
4074
|
-
scaleFGDSpec: "vec4<f32>",
|
|
4075
6463
|
specularColorFactor: "vec3<f32>",
|
|
4076
6464
|
specularIntensityFactor: "f32",
|
|
4077
6465
|
specularColorMapEnabled: "i32",
|
|
@@ -4085,9 +6473,11 @@ var pbrMaterial = {
|
|
|
4085
6473
|
clearcoatFactor: "f32",
|
|
4086
6474
|
clearcoatRoughnessFactor: "f32",
|
|
4087
6475
|
clearcoatMapEnabled: "i32",
|
|
6476
|
+
clearcoatRoughnessMapEnabled: "i32",
|
|
4088
6477
|
sheenColorFactor: "vec3<f32>",
|
|
4089
6478
|
sheenRoughnessFactor: "f32",
|
|
4090
6479
|
sheenColorMapEnabled: "i32",
|
|
6480
|
+
sheenRoughnessMapEnabled: "i32",
|
|
4091
6481
|
iridescenceFactor: "f32",
|
|
4092
6482
|
iridescenceIor: "f32",
|
|
4093
6483
|
iridescenceThicknessRange: "vec2<f32>",
|
|
@@ -4096,7 +6486,15 @@ var pbrMaterial = {
|
|
|
4096
6486
|
anisotropyRotation: "f32",
|
|
4097
6487
|
anisotropyDirection: "vec2<f32>",
|
|
4098
6488
|
anisotropyMapEnabled: "i32",
|
|
4099
|
-
emissiveStrength: "f32"
|
|
6489
|
+
emissiveStrength: "f32",
|
|
6490
|
+
// IBL
|
|
6491
|
+
IBLenabled: "i32",
|
|
6492
|
+
scaleIBLAmbient: "vec2<f32>",
|
|
6493
|
+
// #ifdef USE_IBL
|
|
6494
|
+
// debugging flags used for shader output of intermediate PBR variables
|
|
6495
|
+
// #ifdef PBR_DEBUG
|
|
6496
|
+
scaleDiffBaseMR: "vec4<f32>",
|
|
6497
|
+
scaleFGDSpec: "vec4<f32>"
|
|
4100
6498
|
}
|
|
4101
6499
|
};
|
|
4102
6500
|
//# sourceMappingURL=index.cjs.map
|