@luma.gl/shadertools 9.3.0-alpha.2 → 9.3.0-alpha.6

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.
Files changed (66) hide show
  1. package/dist/dist.dev.js +2114 -198
  2. package/dist/dist.min.js +315 -184
  3. package/dist/index.cjs +463 -199
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
  10. package/dist/lib/preprocessor/preprocessor.js +33 -7
  11. package/dist/lib/preprocessor/preprocessor.js.map +1 -1
  12. package/dist/lib/shader-assembler.d.ts.map +1 -1
  13. package/dist/lib/shader-assembler.js +8 -1
  14. package/dist/lib/shader-assembler.js.map +1 -1
  15. package/dist/lib/shader-module/shader-module.d.ts +1 -1
  16. package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
  17. package/dist/lib/utils/assert.d.ts.map +1 -1
  18. package/dist/lib/utils/assert.js +3 -1
  19. package/dist/lib/utils/assert.js.map +1 -1
  20. package/dist/modules/engine/skin/skin.d.ts +29 -0
  21. package/dist/modules/engine/skin/skin.d.ts.map +1 -0
  22. package/dist/modules/engine/skin/skin.js +88 -0
  23. package/dist/modules/engine/skin/skin.js.map +1 -0
  24. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  25. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  26. package/dist/modules/lighting/lights/lighting-glsl.js +20 -2
  27. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
  28. package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
  29. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
  30. package/dist/modules/lighting/lights/lighting-wgsl.js +63 -13
  31. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
  32. package/dist/modules/lighting/lights/lighting.d.ts +27 -3
  33. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  34. package/dist/modules/lighting/lights/lighting.js +32 -6
  35. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  36. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  37. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  38. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +106 -79
  39. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  40. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +20 -4
  41. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  42. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  43. package/dist/modules/lighting/pbr-material/pbr-projection.js +12 -1
  44. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  45. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -40
  46. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
  47. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +40 -76
  48. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
  49. package/dist/modules/math/random/random.d.ts +1 -1
  50. package/dist/modules/math/random/random.d.ts.map +1 -1
  51. package/dist/modules/math/random/random.js +2 -3
  52. package/dist/modules/math/random/random.js.map +1 -1
  53. package/package.json +2 -2
  54. package/src/index.ts +1 -0
  55. package/src/lib/preprocessor/preprocessor.ts +40 -7
  56. package/src/lib/shader-assembler.ts +8 -1
  57. package/src/lib/shader-module/shader-module.ts +1 -1
  58. package/src/lib/utils/assert.ts +3 -1
  59. package/src/modules/engine/skin/skin.ts +116 -0
  60. package/src/modules/lighting/lights/lighting-glsl.ts +20 -2
  61. package/src/modules/lighting/lights/lighting-wgsl.ts +63 -13
  62. package/src/modules/lighting/lights/lighting.ts +45 -9
  63. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +106 -79
  64. package/src/modules/lighting/pbr-material/pbr-projection.ts +13 -1
  65. package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +40 -77
  66. package/src/modules/math/random/random.ts +2 -3
@@ -71,7 +71,7 @@ export type ShaderModule<
71
71
  prevUniforms?: UniformsT
72
72
  ) => Partial<UniformsT & BindingsT>;
73
73
 
74
- defines?: Record<string, boolean>;
74
+ defines?: Record<string, boolean | number>;
75
75
  /** Injections */
76
76
  inject?: Record<string, string | {injection: string; order: number}>;
77
77
  dependencies?: ShaderModule<any, any>[];
@@ -6,6 +6,8 @@
6
6
  // message so keep it for now.
7
7
  export function assert(condition: unknown, message?: string): void {
8
8
  if (!condition) {
9
- throw new Error(message || 'shadertools: assertion failed.');
9
+ const error = new Error(message || 'shadertools: assertion failed.');
10
+ Error.captureStackTrace?.(error, assert);
11
+ throw error;
10
12
  }
11
13
  }
@@ -0,0 +1,116 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Matrix4} from '@math.gl/core';
6
+
7
+ import {ShaderModule} from '../../../lib/shader-module/shader-module';
8
+
9
+ const SKIN_MAX_JOINTS = 20;
10
+
11
+ export const source = /* wgsl */ `
12
+ struct skinUniforms {
13
+ jointMatrix: array<mat4x4<f32>, ${SKIN_MAX_JOINTS}>,
14
+ };
15
+
16
+ @binding(19) @group(0) var<uniform> skin: skinUniforms;
17
+
18
+ fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
19
+ return (weights.x * skin.jointMatrix[joints.x])
20
+ + (weights.y * skin.jointMatrix[joints.y])
21
+ + (weights.z * skin.jointMatrix[joints.z])
22
+ + (weights.w * skin.jointMatrix[joints.w]);
23
+ }
24
+ `;
25
+
26
+ export const vs = /* glsl */ `\
27
+
28
+ uniform skinUniforms {
29
+ mat4 jointMatrix[SKIN_MAX_JOINTS];
30
+ } skin;
31
+
32
+ mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
33
+ return (weights.x * skin.jointMatrix[joints.x])
34
+ + (weights.y * skin.jointMatrix[joints.y])
35
+ + (weights.z * skin.jointMatrix[joints.z])
36
+ + (weights.w * skin.jointMatrix[joints.w]);
37
+ }
38
+
39
+ `;
40
+
41
+ export const fs = /* glsl */ `\
42
+ `;
43
+
44
+ export type SkinProps = {
45
+ scenegraphsFromGLTF?: any;
46
+ };
47
+
48
+ export type SkinUniforms = {
49
+ jointMatrix?: any;
50
+ };
51
+
52
+ export const skin = {
53
+ props: {} as SkinProps,
54
+ uniforms: {} as SkinUniforms,
55
+
56
+ name: 'skin',
57
+ dependencies: [],
58
+ source,
59
+ vs,
60
+ fs,
61
+
62
+ defines: {
63
+ SKIN_MAX_JOINTS
64
+ },
65
+
66
+ getUniforms: (props: SkinProps = {}, prevUniforms?: SkinUniforms): SkinUniforms => {
67
+ const {scenegraphsFromGLTF} = props;
68
+
69
+ if (!scenegraphsFromGLTF?.gltf?.skins?.[0]) {
70
+ return {jointMatrix: []};
71
+ }
72
+
73
+ const {inverseBindMatrices, joints, skeleton} = scenegraphsFromGLTF.gltf.skins[0];
74
+
75
+ const matsib = [];
76
+ const countib = inverseBindMatrices.value.length / 16;
77
+ for (let i = 0; i < countib; i++) {
78
+ const slice = inverseBindMatrices.value.subarray(i * 16, i * 16 + 16);
79
+ matsib.push(new Matrix4(Array.from(slice)));
80
+ }
81
+
82
+ const top = scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(skeleton);
83
+ const matrices: Record<string, Matrix4> = {};
84
+ top.preorderTraversal((node: any, {worldMatrix}: any) => {
85
+ matrices[node.id] = worldMatrix;
86
+ });
87
+
88
+ const mats = new Float32Array(SKIN_MAX_JOINTS * 16); // 16 floats per 4x4 matrix
89
+ for (let i = 0; i < SKIN_MAX_JOINTS; ++i) {
90
+ const nodeIndex = joints[i];
91
+ if (nodeIndex === undefined) break;
92
+
93
+ const worldMat = matrices[scenegraphsFromGLTF.gltfNodeIndexToNodeMap.get(nodeIndex).id];
94
+ const invBindMat = matsib[i];
95
+
96
+ const Z = new Matrix4().copy(worldMat).multiplyRight(invBindMat);
97
+
98
+ const off = i * 16;
99
+
100
+ for (let j = 0; j < 16; j++) {
101
+ mats[off + j] = Z[j];
102
+ }
103
+ }
104
+
105
+ return {
106
+ jointMatrix: mats
107
+ };
108
+ },
109
+
110
+ uniformTypes: {
111
+ jointMatrix: 'mat4x4<f32>'
112
+ },
113
+ uniformSizes: {
114
+ jointMatrix: SKIN_MAX_JOINTS
115
+ }
116
+ } as const satisfies ShaderModule<SkinProps, SkinUniforms>;
@@ -44,6 +44,16 @@ uniform lightingUniforms {
44
44
  vec3 lightPosition2;
45
45
  vec3 lightDirection2;
46
46
  vec3 lightAttenuation2;
47
+
48
+ vec3 lightColor3;
49
+ vec3 lightPosition3;
50
+ vec3 lightDirection3;
51
+ vec3 lightAttenuation3;
52
+
53
+ vec3 lightColor4;
54
+ vec3 lightPosition4;
55
+ vec3 lightDirection4;
56
+ vec3 lightAttenuation4;
47
57
  } lighting;
48
58
 
49
59
  PointLight lighting_getPointLight(int index) {
@@ -53,8 +63,12 @@ PointLight lighting_getPointLight(int index) {
53
63
  case 1:
54
64
  return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
55
65
  case 2:
56
- default:
57
66
  return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
67
+ case 3:
68
+ return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
69
+ case 4:
70
+ default:
71
+ return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
58
72
  }
59
73
  }
60
74
 
@@ -65,8 +79,12 @@ DirectionalLight lighting_getDirectionalLight(int index) {
65
79
  case 1:
66
80
  return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
67
81
  case 2:
68
- default:
69
82
  return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
83
+ case 3:
84
+ return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
85
+ case 4:
86
+ default:
87
+ return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
70
88
  }
71
89
  }
72
90
 
@@ -4,6 +4,8 @@
4
4
 
5
5
  export const lightingUniformsWGSL = /* wgsl */ `\
6
6
  // #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
7
+ const MAX_LIGHTS: i32 = 5;
8
+
7
9
  struct AmbientLight {
8
10
  color: vec3<f32>,
9
11
  };
@@ -21,32 +23,80 @@ struct DirectionalLight {
21
23
 
22
24
  struct lightingUniforms {
23
25
  enabled: i32,
24
- pointLightCount: i32,
26
+ lightType: i32,
27
+
25
28
  directionalLightCount: i32,
29
+ pointLightCount: i32,
26
30
 
27
31
  ambientColor: vec3<f32>,
28
32
 
29
- // TODO - support multiple lights by uncommenting arrays below
30
- lightType: i32,
31
- lightColor: vec3<f32>,
32
- lightDirection: vec3<f32>,
33
- lightPosition: vec3<f32>,
34
- lightAttenuation: vec3<f32>,
35
-
36
- // AmbientLight ambientLight;
37
- // PointLight pointLight[MAX_LIGHTS];
38
- // DirectionalLight directionalLight[MAX_LIGHTS];
33
+ lightColor0: vec3<f32>,
34
+ lightPosition0: vec3<f32>,
35
+ lightDirection0: vec3<f32>,
36
+ lightAttenuation0: vec3<f32>,
37
+
38
+ lightColor1: vec3<f32>,
39
+ lightPosition1: vec3<f32>,
40
+ lightDirection1: vec3<f32>,
41
+ lightAttenuation1: vec3<f32>,
42
+
43
+ lightColor2: vec3<f32>,
44
+ lightPosition2: vec3<f32>,
45
+ lightDirection2: vec3<f32>,
46
+ lightAttenuation2: vec3<f32>,
47
+
48
+ lightColor3: vec3<f32>,
49
+ lightPosition3: vec3<f32>,
50
+ lightDirection3: vec3<f32>,
51
+ lightAttenuation3: vec3<f32>,
52
+
53
+ lightColor4: vec3<f32>,
54
+ lightPosition4: vec3<f32>,
55
+ lightDirection4: vec3<f32>,
56
+ lightAttenuation4: vec3<f32>,
39
57
  };
40
58
 
41
59
  // Binding 0:1 is reserved for lighting (Note: could go into separate bind group as it is stable across draw calls)
42
60
  @binding(1) @group(0) var<uniform> lighting : lightingUniforms;
43
61
 
44
62
  fn lighting_getPointLight(index: i32) -> PointLight {
45
- return PointLight(lighting.lightColor, lighting.lightPosition, lighting.lightAttenuation);
63
+ switch (index) {
64
+ case 0: {
65
+ return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);
66
+ }
67
+ case 1: {
68
+ return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
69
+ }
70
+ case 2: {
71
+ return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
72
+ }
73
+ case 3: {
74
+ return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
75
+ }
76
+ case 4, default: {
77
+ return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
78
+ }
79
+ }
46
80
  }
47
81
 
48
82
  fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
49
- return DirectionalLight(lighting.lightColor, lighting.lightDirection);
83
+ switch (index) {
84
+ case 0: {
85
+ return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);
86
+ }
87
+ case 1: {
88
+ return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
89
+ }
90
+ case 2: {
91
+ return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
92
+ }
93
+ case 3: {
94
+ return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
95
+ }
96
+ case 4, default: {
97
+ return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
98
+ }
99
+ }
50
100
  }
51
101
 
52
102
  fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
@@ -75,6 +75,14 @@ export type LightingUniforms = {
75
75
  lightPosition2: Readonly<NumberArray3>;
76
76
  lightDirection2: Readonly<NumberArray3>;
77
77
  lightAttenuation2: Readonly<NumberArray3>;
78
+ lightColor3: Readonly<NumberArray3>;
79
+ lightPosition3: Readonly<NumberArray3>;
80
+ lightDirection3: Readonly<NumberArray3>;
81
+ lightAttenuation3: Readonly<NumberArray3>;
82
+ lightColor4: Readonly<NumberArray3>;
83
+ lightPosition4: Readonly<NumberArray3>;
84
+ lightDirection4: Readonly<NumberArray3>;
85
+ lightAttenuation4: Readonly<NumberArray3>;
78
86
  };
79
87
 
80
88
  /** UBO ready lighting module */
@@ -111,7 +119,17 @@ export const lighting = {
111
119
  lightColor2: 'vec3<f32>',
112
120
  lightPosition2: 'vec3<f32>',
113
121
  lightDirection2: 'vec3<f32>',
114
- lightAttenuation2: 'vec3<f32>'
122
+ lightAttenuation2: 'vec3<f32>',
123
+
124
+ lightColor3: 'vec3<f32>',
125
+ lightPosition3: 'vec3<f32>',
126
+ lightDirection3: 'vec3<f32>',
127
+ lightAttenuation3: 'vec3<f32>',
128
+
129
+ lightColor4: 'vec3<f32>',
130
+ lightPosition4: 'vec3<f32>',
131
+ lightDirection4: 'vec3<f32>',
132
+ lightAttenuation4: 'vec3<f32>'
115
133
  },
116
134
 
117
135
  defaultUniforms: {
@@ -135,7 +153,15 @@ export const lighting = {
135
153
  lightColor2: [1, 1, 1],
136
154
  lightPosition2: [1, 1, 2],
137
155
  lightDirection2: [1, 1, 1],
138
- lightAttenuation2: [1, 0, 0]
156
+ lightAttenuation2: [1, 0, 0],
157
+ lightColor3: [1, 1, 1],
158
+ lightPosition3: [1, 1, 2],
159
+ lightDirection3: [1, 1, 1],
160
+ lightAttenuation3: [1, 0, 0],
161
+ lightColor4: [1, 1, 1],
162
+ lightPosition4: [1, 1, 2],
163
+ lightDirection4: [1, 1, 1],
164
+ lightAttenuation4: [1, 0, 0]
139
165
  },
140
166
  source: lightingUniformsWGSL,
141
167
  vs: lightingUniformsGLSL,
@@ -194,33 +220,43 @@ function getLightSourceUniforms({
194
220
 
195
221
  lightSourceUniforms.ambientColor = convertColor(ambientLight);
196
222
 
197
- let currentLight: 0 | 1 | 2 = 0;
223
+ let currentLight = 0;
224
+ let pointLightCount = 0;
225
+ let directionalLightCount = 0;
198
226
 
199
227
  for (const pointLight of pointLights) {
228
+ if (currentLight >= MAX_LIGHTS) {
229
+ break;
230
+ }
200
231
  lightSourceUniforms.lightType = LIGHT_TYPE.POINT;
201
232
 
202
- const i = currentLight as 0 | 1 | 2;
233
+ const i = currentLight as 0 | 1 | 2 | 3 | 4;
203
234
  lightSourceUniforms[`lightColor${i}`] = convertColor(pointLight);
204
235
  lightSourceUniforms[`lightPosition${i}`] = pointLight.position;
205
236
  lightSourceUniforms[`lightAttenuation${i}`] = pointLight.attenuation || [1, 0, 0];
206
237
  currentLight++;
238
+ pointLightCount++;
207
239
  }
208
240
 
209
241
  for (const directionalLight of directionalLights) {
242
+ if (currentLight >= MAX_LIGHTS) {
243
+ break;
244
+ }
210
245
  lightSourceUniforms.lightType = LIGHT_TYPE.DIRECTIONAL;
211
246
 
212
- const i = currentLight as 0 | 1 | 2;
247
+ const i = currentLight as 0 | 1 | 2 | 3 | 4;
213
248
  lightSourceUniforms[`lightColor${i}`] = convertColor(directionalLight);
214
249
  lightSourceUniforms[`lightDirection${i}`] = directionalLight.direction;
215
250
  currentLight++;
251
+ directionalLightCount++;
216
252
  }
217
253
 
218
- if (currentLight > MAX_LIGHTS) {
219
- log.warn('MAX_LIGHTS exceeded')();
254
+ if (pointLights.length + directionalLights.length > MAX_LIGHTS) {
255
+ log.warn(`MAX_LIGHTS exceeded, truncating to ${MAX_LIGHTS}`)();
220
256
  }
221
257
 
222
- lightSourceUniforms.directionalLightCount = directionalLights.length;
223
- lightSourceUniforms.pointLightCount = pointLights.length;
258
+ lightSourceUniforms.directionalLightCount = directionalLightCount;
259
+ lightSourceUniforms.pointLightCount = pointLightCount;
224
260
 
225
261
  return lightSourceUniforms;
226
262
  }