@luma.gl/shadertools 9.3.0-alpha.6 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +2550 -330
- package/dist/dist.min.js +1803 -283
- package/dist/index.cjs +2495 -358
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +4 -3
- package/dist/lib/preprocessor/preprocessor.js.map +1 -1
- package/dist/lib/shader-assembler.d.ts +10 -0
- package/dist/lib/shader-assembler.d.ts.map +1 -1
- package/dist/lib/shader-assembler.js +12 -2
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js +112 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +11 -5
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js.map +1 -1
- package/dist/lib/utils/uniform-types.d.ts +11 -7
- package/dist/lib/utils/uniform-types.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.d.ts +3 -0
- package/dist/modules/engine/picking/picking.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.js +3 -0
- package/dist/modules/engine/picking/picking.js.map +1 -1
- package/dist/modules/engine/skin/skin.d.ts +7 -6
- package/dist/modules/engine/skin/skin.d.ts.map +1 -1
- package/dist/modules/engine/skin/skin.js +3 -5
- package/dist/modules/engine/skin/skin.js.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
- package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
- package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
- package/dist/modules/lighting/ibl/ibl.js +33 -0
- package/dist/modules/lighting/ibl/ibl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
- package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.js +43 -55
- package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.js +43 -65
- package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +104 -86
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +96 -83
- package/dist/modules/lighting/lights/lighting.js.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.d.ts +7 -2
- package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.js +3 -1
- package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +524 -28
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +706 -50
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -61
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +85 -9
- package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js +2 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +4 -0
- package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +15 -4
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +36 -5
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +41 -10
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
- package/dist/modules/math/fp64/fp64.d.ts +1 -0
- package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64.js +8 -2
- package/dist/modules/math/fp64/fp64.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +19 -2
- package/src/lib/preprocessor/preprocessor.ts +6 -3
- package/src/lib/shader-assembler.ts +17 -2
- package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
- package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
- package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
- package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
- package/src/lib/shader-module/shader-module-uniform-layout.ts +194 -0
- package/src/lib/shader-module/shader-module.ts +16 -6
- package/src/lib/utils/uniform-types.ts +24 -9
- package/src/modules/engine/picking/picking.ts +3 -0
- package/src/modules/engine/skin/skin.ts +3 -5
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
- package/src/modules/lighting/ibl/ibl.ts +44 -0
- package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
- package/src/modules/lighting/lights/lighting-glsl.ts +43 -55
- package/src/modules/lighting/lights/lighting-wgsl.ts +43 -65
- package/src/modules/lighting/lights/lighting.ts +186 -123
- package/src/modules/lighting/no-material/dirlight.ts +3 -1
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +524 -28
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +706 -50
- package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
- package/src/modules/lighting/pbr-material/pbr-projection.ts +2 -1
- package/src/modules/lighting/phong-material/phong-material.ts +5 -0
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +15 -4
- package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +36 -5
- package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +41 -10
- package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
- package/src/modules/math/fp64/fp64.ts +9 -3
|
@@ -32,7 +32,13 @@ function generateGLSLUniformDeclarations(
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
for (const [uniformName, uniformFormat] of Object.entries(module.uniformTypes || {})) {
|
|
35
|
-
|
|
35
|
+
if (typeof uniformFormat !== 'string') {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Composite uniform types are not supported by GLSL shader generation: ${module.name}.${uniformName}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const glslUniformType = getGLSLUniformType(uniformFormat as UniformFormat);
|
|
36
42
|
switch (options.uniforms) {
|
|
37
43
|
case 'scoped-interface-blocks':
|
|
38
44
|
// => uniform UniformBlockName {
|
|
@@ -23,6 +23,12 @@ export function generateWGSLUniformDeclarations(
|
|
|
23
23
|
wgsl.push(`struct ${capitalize(module.name)} {`);
|
|
24
24
|
|
|
25
25
|
for (const [uniformName, uniformFormat] of Object.entries(module?.uniformTypes || {})) {
|
|
26
|
+
if (typeof uniformFormat !== 'string') {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Composite uniform types are not supported by WGSL shader generation: ${module.name}.${uniformName}`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
const wgslUniformType = uniformFormat;
|
|
27
33
|
wgsl.push(` ${uniformName} : ${wgslUniformType};`);
|
|
28
34
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {ShaderModule} from './shader-module';
|
|
6
|
+
import {assert} from '../utils/assert';
|
|
7
|
+
|
|
8
|
+
export type ShaderModuleUniformLayoutStage = 'vertex' | 'fragment' | 'wgsl';
|
|
9
|
+
|
|
10
|
+
export type ShaderModuleUniformLayoutValidationResult = {
|
|
11
|
+
moduleName: string;
|
|
12
|
+
uniformBlockName: string;
|
|
13
|
+
stage: ShaderModuleUniformLayoutStage;
|
|
14
|
+
expectedUniformNames: string[];
|
|
15
|
+
actualUniformNames: string[];
|
|
16
|
+
matches: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type Logger = {
|
|
20
|
+
error?: (...args: unknown[]) => () => unknown;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function getShaderModuleUniformBlockName(module: ShaderModule): string {
|
|
24
|
+
return `${module.name}Uniforms`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getShaderModuleUniformBlockFields(
|
|
28
|
+
module: ShaderModule,
|
|
29
|
+
stage: ShaderModuleUniformLayoutStage
|
|
30
|
+
): string[] | null {
|
|
31
|
+
const shaderSource =
|
|
32
|
+
stage === 'wgsl' ? module.source : stage === 'vertex' ? module.vs : module.fs;
|
|
33
|
+
|
|
34
|
+
if (!shaderSource) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const uniformBlockName = getShaderModuleUniformBlockName(module);
|
|
39
|
+
return extractShaderUniformBlockFieldNames(
|
|
40
|
+
shaderSource,
|
|
41
|
+
stage === 'wgsl' ? 'wgsl' : 'glsl',
|
|
42
|
+
uniformBlockName
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getShaderModuleUniformLayoutValidationResult(
|
|
47
|
+
module: ShaderModule,
|
|
48
|
+
stage: ShaderModuleUniformLayoutStage
|
|
49
|
+
): ShaderModuleUniformLayoutValidationResult | null {
|
|
50
|
+
const expectedUniformNames = Object.keys(module.uniformTypes || {});
|
|
51
|
+
if (!expectedUniformNames.length) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const actualUniformNames = getShaderModuleUniformBlockFields(module, stage);
|
|
56
|
+
if (!actualUniformNames) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
moduleName: module.name,
|
|
62
|
+
uniformBlockName: getShaderModuleUniformBlockName(module),
|
|
63
|
+
stage,
|
|
64
|
+
expectedUniformNames,
|
|
65
|
+
actualUniformNames,
|
|
66
|
+
matches: areStringArraysEqual(expectedUniformNames, actualUniformNames)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function validateShaderModuleUniformLayout(
|
|
71
|
+
module: ShaderModule,
|
|
72
|
+
stage: ShaderModuleUniformLayoutStage,
|
|
73
|
+
options: {
|
|
74
|
+
log?: Logger;
|
|
75
|
+
throwOnError?: boolean;
|
|
76
|
+
} = {}
|
|
77
|
+
): ShaderModuleUniformLayoutValidationResult | null {
|
|
78
|
+
const validationResult = getShaderModuleUniformLayoutValidationResult(module, stage);
|
|
79
|
+
if (!validationResult || validationResult.matches) {
|
|
80
|
+
return validationResult;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const message = formatShaderModuleUniformLayoutError(validationResult);
|
|
84
|
+
options.log?.error?.(message, validationResult)();
|
|
85
|
+
|
|
86
|
+
if (options.throwOnError !== false) {
|
|
87
|
+
assert(false, message);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return validationResult;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function extractShaderUniformBlockFieldNames(
|
|
94
|
+
shaderSource: string,
|
|
95
|
+
language: 'glsl' | 'wgsl',
|
|
96
|
+
uniformBlockName: string
|
|
97
|
+
): string[] | null {
|
|
98
|
+
const sourceBody =
|
|
99
|
+
language === 'wgsl'
|
|
100
|
+
? extractWGSLStructBody(shaderSource, uniformBlockName)
|
|
101
|
+
: extractGLSLUniformBlockBody(shaderSource, uniformBlockName);
|
|
102
|
+
|
|
103
|
+
if (!sourceBody) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const fieldNames: string[] = [];
|
|
108
|
+
|
|
109
|
+
for (const sourceLine of sourceBody.split('\n')) {
|
|
110
|
+
const line = sourceLine.replace(/\/\/.*$/, '').trim();
|
|
111
|
+
if (!line || line.startsWith('#')) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const fieldMatch =
|
|
116
|
+
language === 'wgsl'
|
|
117
|
+
? line.match(/^([A-Za-z0-9_]+)\s*:/)
|
|
118
|
+
: line.match(
|
|
119
|
+
/^(?:uniform\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (fieldMatch) {
|
|
123
|
+
fieldNames.push(fieldMatch[1]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return fieldNames;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function extractWGSLStructBody(shaderSource: string, uniformBlockName: string): string | null {
|
|
131
|
+
const structMatch = new RegExp(`\\bstruct\\s+${uniformBlockName}\\b`, 'm').exec(shaderSource);
|
|
132
|
+
if (!structMatch) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const openBraceIndex = shaderSource.indexOf('{', structMatch.index);
|
|
137
|
+
if (openBraceIndex < 0) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let braceDepth = 0;
|
|
142
|
+
for (let index = openBraceIndex; index < shaderSource.length; index++) {
|
|
143
|
+
const character = shaderSource[index];
|
|
144
|
+
if (character === '{') {
|
|
145
|
+
braceDepth++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (character !== '}') {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
braceDepth--;
|
|
153
|
+
if (braceDepth === 0) {
|
|
154
|
+
return shaderSource.slice(openBraceIndex + 1, index);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function extractGLSLUniformBlockBody(
|
|
162
|
+
shaderSource: string,
|
|
163
|
+
uniformBlockName: string
|
|
164
|
+
): string | null {
|
|
165
|
+
const sourceMatch = shaderSource.match(
|
|
166
|
+
new RegExp(`uniform\\s+${uniformBlockName}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`, 'm')
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return sourceMatch?.[1] || null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function areStringArraysEqual(leftValues: string[], rightValues: string[]): boolean {
|
|
173
|
+
if (leftValues.length !== rightValues.length) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
for (let valueIndex = 0; valueIndex < leftValues.length; valueIndex++) {
|
|
178
|
+
if (leftValues[valueIndex] !== rightValues[valueIndex]) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function formatShaderModuleUniformLayoutError(
|
|
187
|
+
validationResult: ShaderModuleUniformLayoutValidationResult
|
|
188
|
+
): string {
|
|
189
|
+
return `${validationResult.moduleName}: ${validationResult.stage} shader uniform block ${
|
|
190
|
+
validationResult.uniformBlockName
|
|
191
|
+
} does not match module.uniformTypes.\nExpected: ${validationResult.expectedUniformNames.join(
|
|
192
|
+
', '
|
|
193
|
+
)}\nActual: ${validationResult.actualUniformNames.join(', ')}`;
|
|
194
|
+
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
makePropValidators,
|
|
10
10
|
getValidatedProperties
|
|
11
11
|
} from '../filters/prop-types';
|
|
12
|
-
import type {
|
|
12
|
+
import type {ShaderModuleUniformValue, UniformTypes, UniformValue} from '../utils/uniform-types';
|
|
13
13
|
import {ShaderInjection, normalizeInjections} from '../shader-assembly/shader-injections';
|
|
14
14
|
|
|
15
15
|
// To avoid dependency on core module, do not import `Binding` type.
|
|
@@ -22,6 +22,11 @@ export type UniformInfo = {
|
|
|
22
22
|
format?: UniformFormat;
|
|
23
23
|
} & PropType;
|
|
24
24
|
|
|
25
|
+
export type ShaderModuleBindingLayout = {
|
|
26
|
+
name: string;
|
|
27
|
+
group: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
25
30
|
// Helper types
|
|
26
31
|
type BindingKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? never : K}[keyof T];
|
|
27
32
|
type UniformKeys<T> = {[K in keyof T]: T[K] extends UniformValue ? K : never}[keyof T];
|
|
@@ -37,7 +42,7 @@ export type PickUniforms<T> = {[K in UniformKeys<Required<T>>]: T[K]};
|
|
|
37
42
|
*/
|
|
38
43
|
export type ShaderModule<
|
|
39
44
|
PropsT extends Record<string, any> = Record<string, any>,
|
|
40
|
-
UniformsT extends Record<string,
|
|
45
|
+
UniformsT extends Record<string, ShaderModuleUniformValue> = PickUniforms<PropsT>,
|
|
41
46
|
BindingsT extends Record<string, Binding> = PickBindings<PropsT>
|
|
42
47
|
> = {
|
|
43
48
|
/** Used for type inference not for values */
|
|
@@ -46,6 +51,10 @@ export type ShaderModule<
|
|
|
46
51
|
uniforms?: UniformsT;
|
|
47
52
|
/** Used for type inference, not currently used for values */
|
|
48
53
|
bindings?: BindingsT;
|
|
54
|
+
/** Logical bind-group assignment for bindings declared by this module */
|
|
55
|
+
bindingLayout?: readonly ShaderModuleBindingLayout[];
|
|
56
|
+
/** Preferred starting binding slot for this module's WGSL `@binding(auto)` declarations. */
|
|
57
|
+
firstBindingSlot?: number;
|
|
49
58
|
|
|
50
59
|
name: string;
|
|
51
60
|
|
|
@@ -58,8 +67,6 @@ export type ShaderModule<
|
|
|
58
67
|
|
|
59
68
|
/** Uniform shader types @note: Both order and types MUST match uniform block declarations in shader */
|
|
60
69
|
uniformTypes?: Required<UniformTypes<UniformsT>>; // Record<keyof UniformsT, UniformFormat>;
|
|
61
|
-
/** Uniform shader array sizes (default 1) */
|
|
62
|
-
uniformSizes?: Required<UniformSizes<UniformsT>>;
|
|
63
70
|
/** Uniform JS prop types */
|
|
64
71
|
propTypes?: Record<keyof UniformsT, UniformInfo>;
|
|
65
72
|
/** Default uniform values */
|
|
@@ -152,12 +159,15 @@ export function initializeShaderModule(module: ShaderModule): void {
|
|
|
152
159
|
|
|
153
160
|
/** Convert module props to uniforms */
|
|
154
161
|
export function getShaderModuleUniforms<
|
|
155
|
-
ShaderModuleT extends ShaderModule<
|
|
162
|
+
ShaderModuleT extends ShaderModule<
|
|
163
|
+
Record<string, unknown>,
|
|
164
|
+
Record<string, ShaderModuleUniformValue>
|
|
165
|
+
>
|
|
156
166
|
>(
|
|
157
167
|
module: ShaderModuleT,
|
|
158
168
|
props?: ShaderModuleT['props'],
|
|
159
169
|
oldUniforms?: ShaderModuleT['uniforms']
|
|
160
|
-
): Record<string, Binding |
|
|
170
|
+
): Record<string, Binding | ShaderModuleUniformValue> {
|
|
161
171
|
initializeShaderModule(module);
|
|
162
172
|
|
|
163
173
|
const uniforms = oldUniforms || {...module.defaultUniforms};
|
|
@@ -14,6 +14,8 @@ import type {
|
|
|
14
14
|
NumberArray16
|
|
15
15
|
} from '@math.gl/core';
|
|
16
16
|
|
|
17
|
+
import type {CompositeShaderType} from '@luma.gl/core';
|
|
18
|
+
|
|
17
19
|
/*
|
|
18
20
|
* Allowed types to be used for uniform values
|
|
19
21
|
*
|
|
@@ -37,7 +39,18 @@ export type UniformValue = Readonly<
|
|
|
37
39
|
| Matrix4
|
|
38
40
|
>;
|
|
39
41
|
|
|
40
|
-
type
|
|
42
|
+
export type ShaderModuleUniformValue =
|
|
43
|
+
| UniformValue
|
|
44
|
+
| ShaderModuleUniformStruct
|
|
45
|
+
| ShaderModuleUniformArray;
|
|
46
|
+
|
|
47
|
+
export type ShaderModuleUniformStruct = {
|
|
48
|
+
[name: string]: ShaderModuleUniformValue | undefined;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type ShaderModuleUniformArray = ReadonlyArray<ShaderModuleUniformValue | undefined>;
|
|
52
|
+
|
|
53
|
+
type UniformLeafType<ValueT extends UniformValue> = ValueT extends number | boolean
|
|
41
54
|
? 'f32' | 'i32' | 'u32'
|
|
42
55
|
: ValueT extends Readonly<NumberArray2 | Vector2>
|
|
43
56
|
? 'vec2<f32>' | 'vec2<i32>' | 'vec2<u32>'
|
|
@@ -57,14 +70,16 @@ type UniformType<ValueT extends UniformValue> = ValueT extends number | boolean
|
|
|
57
70
|
? 'mat4x4<f32>'
|
|
58
71
|
: never;
|
|
59
72
|
|
|
60
|
-
type
|
|
61
|
-
|
|
62
|
-
|
|
73
|
+
type UniformType<ValueT> = ValueT extends UniformValue
|
|
74
|
+
? UniformLeafType<ValueT>
|
|
75
|
+
: ValueT extends ReadonlyArray<infer ElementT>
|
|
76
|
+
? readonly [UniformType<NonNullable<ElementT>>, number]
|
|
77
|
+
: ValueT extends Record<string, unknown>
|
|
78
|
+
? {[name in keyof ValueT]-?: UniformType<NonNullable<ValueT[name]>>}
|
|
79
|
+
: never;
|
|
63
80
|
|
|
64
|
-
|
|
65
|
-
[name in keyof PropsT]: UniformType<PropsT[name]>;
|
|
66
|
-
};
|
|
81
|
+
type UniformProps = Record<string, unknown>;
|
|
67
82
|
|
|
68
|
-
export type
|
|
69
|
-
[name in keyof PropsT]
|
|
83
|
+
export type UniformTypes<PropsT extends UniformProps> = {
|
|
84
|
+
[name in keyof PropsT]-?: UniformType<NonNullable<PropsT[name]>> & CompositeShaderType;
|
|
70
85
|
};
|
|
@@ -183,6 +183,9 @@ vec4 picking_filterColor(vec4 color) {
|
|
|
183
183
|
`;
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
|
+
* Deprecated legacy picking module retained for compatibility with existing
|
|
187
|
+
* shadertools users such as deck.gl. Keep the shader contract stable.
|
|
188
|
+
*
|
|
186
189
|
* Provides support for color-coding-based picking and highlighting.
|
|
187
190
|
* In particular, supports picking a specific instance in an instanced
|
|
188
191
|
* draw call and highlighting an instance based on its picking color,
|
|
@@ -13,7 +13,7 @@ struct skinUniforms {
|
|
|
13
13
|
jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
@
|
|
16
|
+
@group(0) @binding(auto) var<uniform> skin: skinUniforms;
|
|
17
17
|
|
|
18
18
|
fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
19
19
|
return (weights.x * skin.jointMatrix[joints.x])
|
|
@@ -54,6 +54,7 @@ export const skin = {
|
|
|
54
54
|
uniforms: {} as SkinUniforms,
|
|
55
55
|
|
|
56
56
|
name: 'skin',
|
|
57
|
+
bindingLayout: [{name: 'skin', group: 0}],
|
|
57
58
|
dependencies: [],
|
|
58
59
|
source,
|
|
59
60
|
vs,
|
|
@@ -108,9 +109,6 @@ export const skin = {
|
|
|
108
109
|
},
|
|
109
110
|
|
|
110
111
|
uniformTypes: {
|
|
111
|
-
jointMatrix: 'mat4x4<f32>'
|
|
112
|
-
},
|
|
113
|
-
uniformSizes: {
|
|
114
|
-
jointMatrix: SKIN_MAX_JOINTS
|
|
112
|
+
jointMatrix: ['mat4x4<f32>', SKIN_MAX_JOINTS]
|
|
115
113
|
}
|
|
116
114
|
} as const satisfies ShaderModule<SkinProps, SkinUniforms>;
|
|
@@ -9,6 +9,7 @@ import {PHONG_VS, PHONG_FS} from '../phong-material/phong-shaders-glsl';
|
|
|
9
9
|
import {PHONG_WGSL} from '../phong-material/phong-shaders-wgsl';
|
|
10
10
|
|
|
11
11
|
export type GouraudMaterialProps = {
|
|
12
|
+
unlit?: boolean;
|
|
12
13
|
ambient?: number;
|
|
13
14
|
diffuse?: number;
|
|
14
15
|
/** Specularity exponent */
|
|
@@ -21,6 +22,7 @@ export const gouraudMaterial: ShaderModule<GouraudMaterialProps> = {
|
|
|
21
22
|
props: {} as GouraudMaterialProps,
|
|
22
23
|
|
|
23
24
|
name: 'gouraudMaterial',
|
|
25
|
+
bindingLayout: [{name: 'gouraudMaterial', group: 3}],
|
|
24
26
|
// Note these are switched between phong and gouraud
|
|
25
27
|
vs: PHONG_FS.replace('phongMaterial', 'gouraudMaterial'),
|
|
26
28
|
fs: PHONG_VS.replace('phongMaterial', 'gouraudMaterial'),
|
|
@@ -30,12 +32,14 @@ export const gouraudMaterial: ShaderModule<GouraudMaterialProps> = {
|
|
|
30
32
|
},
|
|
31
33
|
dependencies: [lighting],
|
|
32
34
|
uniformTypes: {
|
|
35
|
+
unlit: 'i32',
|
|
33
36
|
ambient: 'f32',
|
|
34
37
|
diffuse: 'f32',
|
|
35
38
|
shininess: 'f32',
|
|
36
39
|
specularColor: 'vec3<f32>'
|
|
37
40
|
},
|
|
38
41
|
defaultUniforms: {
|
|
42
|
+
unlit: false,
|
|
39
43
|
ambient: 0.35,
|
|
40
44
|
diffuse: 0.6,
|
|
41
45
|
shininess: 32,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {Texture} from '@luma.gl/core';
|
|
6
|
+
import {ShaderModule} from '../../../lib/shader-module/shader-module';
|
|
7
|
+
|
|
8
|
+
export type IBLBindings = {
|
|
9
|
+
pbr_diffuseEnvSampler?: Texture | null;
|
|
10
|
+
pbr_specularEnvSampler?: Texture | null;
|
|
11
|
+
pbr_brdfLUT?: Texture | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const iblWGSL = /* wgsl */ `\
|
|
15
|
+
#ifdef USE_IBL
|
|
16
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
|
|
17
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
|
|
18
|
+
@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
|
|
19
|
+
@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
|
|
20
|
+
@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
|
|
21
|
+
@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
|
|
22
|
+
#endif
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
export const iblGLSL = /* glsl */ `\
|
|
26
|
+
#ifdef USE_IBL
|
|
27
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
28
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
29
|
+
uniform sampler2D pbr_brdfLUT;
|
|
30
|
+
#endif
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const ibl = {
|
|
34
|
+
name: 'ibl',
|
|
35
|
+
firstBindingSlot: 32,
|
|
36
|
+
bindingLayout: [
|
|
37
|
+
{name: 'pbr_diffuseEnvSampler', group: 2},
|
|
38
|
+
{name: 'pbr_specularEnvSampler', group: 2},
|
|
39
|
+
{name: 'pbr_brdfLUT', group: 2}
|
|
40
|
+
],
|
|
41
|
+
source: iblWGSL,
|
|
42
|
+
vs: iblGLSL,
|
|
43
|
+
fs: iblGLSL
|
|
44
|
+
} as const satisfies ShaderModule<IBLBindings, {}, IBLBindings>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {ShaderModule} from '../../../lib/shader-module/shader-module';
|
|
6
|
+
import {lighting} from '../lights/lighting';
|
|
7
|
+
import {LAMBERT_WGSL} from './lambert-shaders-wgsl';
|
|
8
|
+
import {LAMBERT_VS, LAMBERT_FS} from './lambert-shaders-glsl';
|
|
9
|
+
|
|
10
|
+
/** Uniform props for the built-in diffuse-only Lambert material model. */
|
|
11
|
+
export type LambertMaterialProps = {
|
|
12
|
+
unlit?: boolean;
|
|
13
|
+
ambient?: number;
|
|
14
|
+
diffuse?: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** A matte material model that applies diffuse-only Lambert lighting per fragment. */
|
|
18
|
+
export const lambertMaterial: ShaderModule<LambertMaterialProps> = {
|
|
19
|
+
name: 'lambertMaterial',
|
|
20
|
+
firstBindingSlot: 0,
|
|
21
|
+
bindingLayout: [{name: 'lambertMaterial', group: 3}],
|
|
22
|
+
dependencies: [lighting],
|
|
23
|
+
source: LAMBERT_WGSL,
|
|
24
|
+
vs: LAMBERT_VS,
|
|
25
|
+
fs: LAMBERT_FS,
|
|
26
|
+
defines: {
|
|
27
|
+
LIGHTING_FRAGMENT: true
|
|
28
|
+
},
|
|
29
|
+
uniformTypes: {
|
|
30
|
+
unlit: 'i32',
|
|
31
|
+
ambient: 'f32',
|
|
32
|
+
diffuse: 'f32'
|
|
33
|
+
},
|
|
34
|
+
defaultUniforms: {
|
|
35
|
+
unlit: false,
|
|
36
|
+
ambient: 0.35,
|
|
37
|
+
diffuse: 0.6
|
|
38
|
+
},
|
|
39
|
+
getUniforms(props?: LambertMaterialProps) {
|
|
40
|
+
return {...lambertMaterial.defaultUniforms, ...props};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
export const LAMBERT_VS = /* glsl */ `\
|
|
6
|
+
uniform lambertMaterialUniforms {
|
|
7
|
+
uniform bool unlit;
|
|
8
|
+
uniform float ambient;
|
|
9
|
+
uniform float diffuse;
|
|
10
|
+
} material;
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
export const LAMBERT_FS = /* glsl */ `\
|
|
14
|
+
uniform lambertMaterialUniforms {
|
|
15
|
+
uniform bool unlit;
|
|
16
|
+
uniform float ambient;
|
|
17
|
+
uniform float diffuse;
|
|
18
|
+
} material;
|
|
19
|
+
|
|
20
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {
|
|
21
|
+
float lambertian = max(dot(light_direction, normal_worldspace), 0.0);
|
|
22
|
+
return lambertian * material.diffuse * surfaceColor * color;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
26
|
+
vec3 lightColor = surfaceColor;
|
|
27
|
+
|
|
28
|
+
if (material.unlit) {
|
|
29
|
+
return surfaceColor;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (lighting.enabled == 0) {
|
|
33
|
+
return lightColor;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
lightColor = material.ambient * surfaceColor * lighting.ambientColor;
|
|
37
|
+
|
|
38
|
+
for (int i = 0; i < lighting.pointLightCount; i++) {
|
|
39
|
+
PointLight pointLight = lighting_getPointLight(i);
|
|
40
|
+
vec3 light_position_worldspace = pointLight.position;
|
|
41
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
42
|
+
float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));
|
|
43
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
47
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
48
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
49
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
50
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
51
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
55
|
+
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
56
|
+
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return lightColor;
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
export const LAMBERT_WGSL = /* wgsl */ `\
|
|
6
|
+
struct lambertMaterialUniforms {
|
|
7
|
+
unlit: u32,
|
|
8
|
+
ambient: f32,
|
|
9
|
+
diffuse: f32,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;
|
|
13
|
+
|
|
14
|
+
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
15
|
+
let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);
|
|
16
|
+
return lambertian * lambertMaterial.diffuse * surfaceColor * color;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
20
|
+
var lightColor: vec3<f32> = surfaceColor;
|
|
21
|
+
|
|
22
|
+
if (lambertMaterial.unlit != 0u) {
|
|
23
|
+
return surfaceColor;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (lighting.enabled == 0) {
|
|
27
|
+
return lightColor;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
31
|
+
|
|
32
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
33
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
34
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
35
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
36
|
+
let light_attenuation = getPointLightAttenuation(
|
|
37
|
+
pointLight,
|
|
38
|
+
distance(light_position_worldspace, position_worldspace)
|
|
39
|
+
);
|
|
40
|
+
lightColor += lighting_getLightColor(
|
|
41
|
+
surfaceColor,
|
|
42
|
+
light_direction,
|
|
43
|
+
normal_worldspace,
|
|
44
|
+
pointLight.color / light_attenuation
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
49
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
50
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
51
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
52
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
53
|
+
lightColor += lighting_getLightColor(
|
|
54
|
+
surfaceColor,
|
|
55
|
+
light_direction,
|
|
56
|
+
normal_worldspace,
|
|
57
|
+
spotLight.color / light_attenuation
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
62
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
63
|
+
lightColor += lighting_getLightColor(
|
|
64
|
+
surfaceColor,
|
|
65
|
+
-directionalLight.direction,
|
|
66
|
+
normal_worldspace,
|
|
67
|
+
directionalLight.color
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return lightColor;
|
|
72
|
+
}
|
|
73
|
+
`;
|