@luma.gl/shaders 10.0.0-alpha.6 → 10.0.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.
Files changed (109) hide show
  1. package/dist/dist.dev.js +236 -141
  2. package/dist/dist.min.js +130 -125
  3. package/dist/glsl.cjs.map +1 -1
  4. package/dist/index.cjs.map +2 -2
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/glsl-shader-assembler.cjs +1 -1
  9. package/dist/lib/glsl-shader-assembler.js +1 -1
  10. package/dist/lib/glsl-shader-assembler.js.map +1 -1
  11. package/dist/lib/preprocessor/preprocessor.cjs +21 -0
  12. package/dist/lib/preprocessor/preprocessor.js +21 -0
  13. package/dist/lib/preprocessor/preprocessor.js.map +1 -1
  14. package/dist/lib/shader-assembly/assemble-glsl-shaders.cjs +12 -20
  15. package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts +3 -2
  16. package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts.map +1 -1
  17. package/dist/lib/shader-assembly/assemble-glsl-shaders.js +13 -21
  18. package/dist/lib/shader-assembly/assemble-glsl-shaders.js.map +1 -1
  19. package/dist/lib/shader-assembly/assemble-wgsl-shaders.cjs +7 -7
  20. package/dist/lib/shader-assembly/assemble-wgsl-shaders.js +8 -8
  21. package/dist/lib/shader-assembly/assemble-wgsl-shaders.js.map +1 -1
  22. package/dist/lib/shader-assembly/shader-assembly-types.d.ts +11 -7
  23. package/dist/lib/shader-assembly/shader-assembly-types.d.ts.map +1 -1
  24. package/dist/lib/shader-assembly/shader-hooks.cjs +23 -4
  25. package/dist/lib/shader-assembly/shader-hooks.d.ts +1 -1
  26. package/dist/lib/shader-assembly/shader-hooks.d.ts.map +1 -1
  27. package/dist/lib/shader-assembly/shader-hooks.js +27 -4
  28. package/dist/lib/shader-assembly/shader-hooks.js.map +1 -1
  29. package/dist/lib/shader-assembly/shader-injections.d.ts +2 -0
  30. package/dist/lib/shader-assembly/shader-injections.d.ts.map +1 -1
  31. package/dist/lib/shader-assembly/shader-injections.js.map +1 -1
  32. package/dist/lib/shader-assembly/shader-plugin-varyings.cjs +39 -22
  33. package/dist/lib/shader-assembly/shader-plugin-varyings.d.ts +5 -5
  34. package/dist/lib/shader-assembly/shader-plugin-varyings.d.ts.map +1 -1
  35. package/dist/lib/shader-assembly/shader-plugin-varyings.js +45 -19
  36. package/dist/lib/shader-assembly/shader-plugin-varyings.js.map +1 -1
  37. package/dist/lib/shader-generator/glsl/generate-glsl.d.ts +1 -1
  38. package/dist/lib/shader-generator/glsl/generate-glsl.d.ts.map +1 -1
  39. package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts +1 -1
  40. package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
  41. package/dist/lib/shader-plugin.cjs +94 -34
  42. package/dist/lib/shader-plugin.d.ts +55 -37
  43. package/dist/lib/shader-plugin.d.ts.map +1 -1
  44. package/dist/lib/shader-plugin.js +103 -35
  45. package/dist/lib/shader-plugin.js.map +1 -1
  46. package/dist/lib/wgsl-shader-assembler.cjs +1 -1
  47. package/dist/lib/wgsl-shader-assembler.js +1 -1
  48. package/dist/lib/wgsl-shader-assembler.js.map +1 -1
  49. package/dist/modules/engine/clip/clip.cjs +20 -30
  50. package/dist/modules/engine/clip/clip.d.ts.map +1 -1
  51. package/dist/modules/engine/clip/clip.js +21 -31
  52. package/dist/modules/engine/clip/clip.js.map +1 -1
  53. package/dist/modules/engine/filter/filter.cjs +10 -18
  54. package/dist/modules/engine/filter/filter.d.ts.map +1 -1
  55. package/dist/modules/engine/filter/filter.js +10 -18
  56. package/dist/modules/engine/filter/filter.js.map +1 -1
  57. package/dist/modules/lighting/lights/lighting.d.ts +1 -1
  58. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  59. package/dist/modules/lighting/pbr-material/pbr-material-glsl.cjs +2 -2
  60. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
  61. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
  62. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +2 -2
  63. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.cjs +2 -2
  64. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  65. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  66. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +2 -2
  67. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +2 -2
  68. package/dist/modules/math/fp64/fp64.cjs +1 -1
  69. package/dist/modules/math/fp64/fp64.d.ts +1 -1
  70. package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
  71. package/dist/modules/math/fp64/fp64.js +1 -1
  72. package/dist/modules/math/fp64/fp64.js.map +1 -1
  73. package/dist/types/texture-formats.d.ts +1 -1
  74. package/dist/types/texture-formats.d.ts.map +1 -1
  75. package/dist/types.cjs +27 -16
  76. package/dist/types.d.ts +7 -7
  77. package/dist/types.d.ts.map +1 -1
  78. package/dist/types.js +2 -7
  79. package/dist/types.js.map +1 -1
  80. package/dist/wgsl.cjs +20 -4
  81. package/dist/wgsl.cjs.map +1 -1
  82. package/dist/wgsl.d.ts +1 -1
  83. package/dist/wgsl.d.ts.map +1 -1
  84. package/dist/wgsl.js +1 -1
  85. package/dist/wgsl.js.map +1 -1
  86. package/package.json +3 -3
  87. package/src/index.ts +5 -4
  88. package/src/lib/glsl-shader-assembler.ts +1 -1
  89. package/src/lib/preprocessor/preprocessor.ts +25 -0
  90. package/src/lib/shader-assembly/assemble-glsl-shaders.ts +19 -23
  91. package/src/lib/shader-assembly/assemble-wgsl-shaders.ts +9 -9
  92. package/src/lib/shader-assembly/shader-assembly-types.ts +11 -7
  93. package/src/lib/shader-assembly/shader-hooks.ts +33 -4
  94. package/src/lib/shader-assembly/shader-injections.ts +2 -0
  95. package/src/lib/shader-assembly/shader-plugin-varyings.ts +58 -27
  96. package/src/lib/shader-generator/glsl/generate-glsl.ts +1 -1
  97. package/src/lib/shader-generator/wgsl/generate-wgsl.ts +1 -1
  98. package/src/lib/shader-module/shader-module-dependencies.ts +1 -1
  99. package/src/lib/shader-plugin.ts +154 -77
  100. package/src/lib/wgsl-shader-assembler.ts +1 -1
  101. package/src/modules/engine/clip/clip.ts +21 -31
  102. package/src/modules/engine/filter/filter.ts +10 -18
  103. package/src/modules/lighting/lights/lighting.ts +1 -1
  104. package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +2 -2
  105. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +2 -2
  106. package/src/modules/math/fp64/fp64.ts +1 -1
  107. package/src/types/texture-formats.ts +2 -0
  108. package/src/types.ts +75 -7
  109. package/src/wgsl.ts +12 -1
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
4
 
5
+ import type {ShaderHook} from './shader-assembly/shader-hooks';
5
6
  import type {ShaderInjection} from './shader-assembly/shader-injections';
6
7
  import type {ShaderModule} from './shader-module/shader-module';
7
8
  import {shaderTypeDecoder, type AttributeShaderType} from '../types';
@@ -17,135 +18,158 @@ export type ShaderPluginInjectionTarget =
17
18
  | `vs:${string}`
18
19
  | `fs:${string}`;
19
20
 
21
+ /** Explicit stage and unqualified target for plugin object declarations. */
22
+ export type ShaderPluginTarget = {
23
+ /** Shader stage containing this extension point. */
24
+ stage: 'vertex' | 'fragment';
25
+ /** Unqualified hook name or structural anchor such as #main-start. */
26
+ target: string;
27
+ };
28
+
29
+ /** Hook function declared by a plugin, with parameter signatures per language. */
30
+ export type ShaderPluginHook = ShaderPluginTarget & {
31
+ /** GLSL parameter list, including parentheses. */
32
+ glsl?: string;
33
+ /** WGSL parameter list, including parentheses. */
34
+ wgsl?: string;
35
+ };
36
+
20
37
  /** Named shader source injection contributed by a ShaderPlugin. */
21
- export type ShaderPluginInjection = {
22
- /** Named shader anchor or hook that receives this source. */
23
- target: ShaderPluginInjectionTarget;
24
- /** Shader source to inject at the target. */
25
- injection: string;
38
+ export type ShaderPluginInjection = ShaderPluginTarget & {
39
+ /** GLSL source for this target. Omit to skip this injection when assembling GLSL. */
40
+ glsl?: string;
41
+ /** WGSL source for this target. Omit to skip this injection when assembling WGSL. */
42
+ wgsl?: string;
26
43
  /** Relative injection order within the target. */
27
44
  order?: number;
28
45
  };
29
46
 
30
- /** Portable interpolation modes for ShaderPlugin varyings. */
31
- export type ShaderPluginVaryingInterpolation = 'smooth' | 'flat';
47
+ /** Portable interpolation modes for ShaderPlugin inter-stage variables. */
48
+ export type ShaderPluginInterStageVariableInterpolation = 'smooth' | 'flat';
32
49
 
33
50
  /** Cross-stage value contributed by a ShaderPlugin. */
34
- export type ShaderPluginVarying = {
51
+ export type ShaderPluginInterStageVariable = {
35
52
  /** Portable scalar or vector shader type. */
36
53
  type: AttributeShaderType;
37
54
  /** Defaults to smooth for floating-point types and flat for integer types. */
38
- interpolation?: ShaderPluginVaryingInterpolation;
55
+ interpolation?: ShaderPluginInterStageVariableInterpolation;
39
56
  };
40
57
 
41
- /** Fully normalized ShaderPlugin varying declaration. */
42
- export type ResolvedShaderPluginVarying = {
58
+ /** Fully normalized ShaderPlugin inter-stage variable declaration. */
59
+ export type ResolvedShaderPluginInterStageVariable = {
43
60
  type: AttributeShaderType;
44
- interpolation: ShaderPluginVaryingInterpolation;
61
+ interpolation: ShaderPluginInterStageVariableInterpolation;
45
62
  };
46
63
 
47
- /** Shared or backend-specific shader assembly contributions. */
48
- export type ShaderPluginVariant = {
49
- /** Shader modules added to shader assembly. */
50
- modules?: ShaderModule[];
51
- /** Boolean preprocessor defines added to shader assembly. */
52
- defines?: Record<string, boolean>;
53
- /** Named code injections added to shader assembly. */
54
- injections?: ShaderPluginInjection[];
64
+ /** Reusable shader assembly descriptor with one portable interface and language-specific source. */
65
+ export type ShaderPlugin = {
66
+ /** Stable plugin identifier. */
67
+ name: string;
68
+ /** Primary shader module. Supporting modules belong in its dependencies; omit for injection-only plugins. */
69
+ module?: ShaderModule<any, any, any>;
70
+ /** Boolean or numeric preprocessor defines added to shader assembly. */
71
+ defines?: Record<string, boolean | number>;
72
+ /** Named injections as explicit-stage objects or optionally language-qualified string keys. */
73
+ injections?: ShaderPluginInjection[] | Record<string, string>;
74
+ /** Callable extension points as explicit-stage objects or optionally language-qualified signatures. */
75
+ hooks?: (ShaderPluginHook | string)[];
55
76
  /** Shader-facing vertex inputs added by this plugin. Buffer ownership remains with the caller. */
56
77
  vertexInputs?: Record<string, AttributeShaderType>;
57
78
  /** Values transported from the selected vertex entry point to the fragment entry point. */
58
- varyings?: Record<string, ShaderPluginVarying>;
59
- };
60
-
61
- /** Reusable cross-backend shader assembly descriptor. */
62
- export type ShaderPlugin = ShaderPluginVariant & {
63
- /** Stable plugin identifier. */
64
- name: string;
65
- /** GLSL-only shader assembly contributions. */
66
- glsl?: ShaderPluginVariant;
67
- /** WGSL-only shader assembly contributions. */
68
- wgsl?: ShaderPluginVariant;
79
+ interStageVariables?: Record<string, ShaderPluginInterStageVariable>;
69
80
  };
70
81
 
71
82
  /** ShaderPlugin contributions resolved for one shader language. */
72
83
  export type ResolvedShaderPlugins = {
73
84
  /** Resolved shader modules in plugin declaration order. */
74
85
  modules: ShaderModule[];
75
- /** Resolved boolean preprocessor defines. */
76
- defines: Record<string, boolean>;
86
+ /** Language-selected hook declarations. */
87
+ hooks: ShaderHook[];
88
+ /** Resolved boolean or numeric preprocessor defines. */
89
+ defines: Record<string, boolean | number>;
77
90
  /** Resolved named code injections grouped by target. */
78
91
  injections: Record<string, ShaderInjection[]>;
79
92
  /** Resolved shader-facing vertex inputs in plugin declaration order. */
80
93
  vertexInputs: Record<string, AttributeShaderType>;
81
- /** Resolved cross-stage varyings in plugin declaration order. */
82
- varyings: Record<string, ResolvedShaderPluginVarying>;
94
+ /** Resolved inter-stage variables in plugin declaration order. */
95
+ interStageVariables: Record<string, ResolvedShaderPluginInterStageVariable>;
83
96
  };
84
97
 
85
98
  const SHADER_PLUGIN_INJECTION_TARGET_REGEX =
86
99
  /^(vs|fs):(?:#(?:decl|main-start|main-end)|[A-Za-z_][\w-]*)$/;
87
100
 
88
- /** Resolve shared and backend-specific contributions from shader plugins. */
101
+ /** Resolve plugin interfaces and select injection source for one shader language. */
89
102
  export function resolveShaderPlugins(
90
103
  plugins: readonly ShaderPlugin[] = [],
91
104
  shaderLanguage: 'glsl' | 'wgsl'
92
105
  ): ResolvedShaderPlugins {
93
- const modules: ShaderModule[] = [];
94
- const defines: Record<string, boolean> = {};
95
- const injections: Record<string, ShaderInjection[]> = {};
96
- const vertexInputs: Record<string, AttributeShaderType> = {};
97
- const varyings: Record<string, ResolvedShaderPluginVarying> = {};
106
+ const resolved: ResolvedShaderPlugins = {
107
+ modules: [],
108
+ hooks: [],
109
+ defines: {},
110
+ injections: {},
111
+ vertexInputs: {},
112
+ interStageVariables: {}
113
+ };
98
114
 
99
115
  for (const plugin of plugins) {
100
- appendShaderPluginVariant({modules, defines, injections, vertexInputs, varyings}, plugin);
101
- appendShaderPluginVariant(
102
- {modules, defines, injections, vertexInputs, varyings},
103
- plugin[shaderLanguage]
104
- );
116
+ appendShaderPlugin(resolved, plugin, shaderLanguage);
105
117
  }
118
+ const {vertexInputs, interStageVariables} = resolved;
106
119
 
107
- for (const name of Object.keys(varyings)) {
120
+ for (const name of Object.keys(interStageVariables)) {
108
121
  if (vertexInputs[name]) {
109
122
  throw new Error(`ShaderPlugin name "${name}" cannot be both a vertex input and a varying`);
110
123
  }
111
124
  }
112
125
 
113
- return {modules, defines, injections, vertexInputs, varyings};
126
+ return resolved;
114
127
  }
115
128
 
116
- /** Preserve explicit module inputs while appending plugin modules by first-seen name. */
129
+ /**
130
+ * Preserve explicit module inputs while appending plugin modules by first-seen name.
131
+ * Optional diagnostics report distinct descriptors sharing a name, without changing selection.
132
+ * Descriptor identity is checked; equivalent independently-created descriptors also report a conflict.
133
+ */
117
134
  export function mergeShaderPluginModules(
118
135
  modules: readonly ShaderModule[] = [],
119
- pluginModules: readonly ShaderModule[] = []
136
+ pluginModules: readonly ShaderModule[] = [],
137
+ options: {onConflict?: (name: string, selected: ShaderModule, ignored: ShaderModule) => void} = {}
120
138
  ): ShaderModule[] {
121
139
  const mergedModules: ShaderModule[] = [...modules];
122
- const seenModuleNames = new Set(mergedModules.map(module => module.name));
140
+ const selectedModules = new Map<string, ShaderModule>();
141
+ for (const module of mergedModules) {
142
+ const selected = selectedModules.get(module.name);
143
+ if (selected && selected !== module) options.onConflict?.(module.name, selected, module);
144
+ if (!selected) selectedModules.set(module.name, module);
145
+ }
123
146
 
124
147
  for (const pluginModule of pluginModules) {
125
- if (!seenModuleNames.has(pluginModule.name)) {
148
+ const selected = selectedModules.get(pluginModule.name);
149
+ if (selected && selected !== pluginModule) {
150
+ options.onConflict?.(pluginModule.name, selected, pluginModule);
151
+ }
152
+ if (!selected) {
126
153
  mergedModules.push(pluginModule);
127
- seenModuleNames.add(pluginModule.name);
154
+ selectedModules.set(pluginModule.name, pluginModule);
128
155
  }
129
156
  }
130
157
 
131
158
  return mergedModules;
132
159
  }
133
160
 
134
- function appendShaderPluginVariant(
161
+ function appendShaderPlugin(
135
162
  resolved: ResolvedShaderPlugins,
136
- variant: ShaderPluginVariant | undefined
163
+ plugin: ShaderPlugin,
164
+ shaderLanguage: 'glsl' | 'wgsl'
137
165
  ): void {
138
- if (!variant) {
139
- return;
140
- }
141
-
142
- if (variant.modules?.length) {
143
- resolved.modules.push(...variant.modules);
166
+ if (plugin.module) {
167
+ resolved.modules.push(plugin.module);
144
168
  }
145
- if (variant.defines) {
146
- Object.assign(resolved.defines, variant.defines);
169
+ if (plugin.defines) {
170
+ Object.assign(resolved.defines, plugin.defines);
147
171
  }
148
- for (const [name, type] of Object.entries(variant.vertexInputs || {})) {
172
+ for (const [name, type] of Object.entries(plugin.vertexInputs || {})) {
149
173
  assertShaderPluginInterfaceName(name, 'vertex input');
150
174
  const existingType = resolved.vertexInputs[name];
151
175
  if (existingType && existingType !== type) {
@@ -155,10 +179,10 @@ function appendShaderPluginVariant(
155
179
  }
156
180
  resolved.vertexInputs[name] = type;
157
181
  }
158
- for (const [name, varying] of Object.entries(variant.varyings || {})) {
182
+ for (const [name, varying] of Object.entries(plugin.interStageVariables || {})) {
159
183
  assertShaderPluginInterfaceName(name, 'varying');
160
- const normalizedVarying = normalizeShaderPluginVarying(name, varying);
161
- const existingVarying = resolved.varyings[name];
184
+ const normalizedVarying = normalizeShaderPluginInterStageVariable(name, varying);
185
+ const existingVarying = resolved.interStageVariables[name];
162
186
  if (
163
187
  existingVarying &&
164
188
  (existingVarying.type !== normalizedVarying.type ||
@@ -170,17 +194,58 @@ function appendShaderPluginVariant(
170
194
  `"${normalizedVarying.type}/${normalizedVarying.interpolation}"`
171
195
  );
172
196
  }
173
- resolved.varyings[name] = normalizedVarying;
197
+ resolved.interStageVariables[name] = normalizedVarying;
174
198
  }
175
199
 
176
- for (const injection of variant.injections || []) {
177
- assertNamedShaderPluginInjectionTarget(injection.target);
178
- if (!resolved.injections[injection.target]) {
179
- resolved.injections[injection.target] = [];
200
+ for (const hook of plugin.hooks || []) {
201
+ const declarationSource =
202
+ typeof hook === 'string' ? selectShaderLanguage(hook, shaderLanguage) : undefined;
203
+ if (typeof hook === 'string' && declarationSource === undefined) continue;
204
+ const signature =
205
+ typeof hook === 'string'
206
+ ? declarationSource!.slice(declarationSource!.indexOf('('))
207
+ : hook[shaderLanguage];
208
+ if (signature === undefined) continue;
209
+ const target =
210
+ typeof hook === 'string' ? declarationSource!.split('(')[0] : getShaderPluginTarget(hook);
211
+ if (!/^(vs|fs):[A-Za-z_][A-Za-z0-9_]*$/.test(target) || !/^\([^]*\)$/.test(signature.trim())) {
212
+ throw new Error(`Invalid ShaderPlugin hook ${target}`);
213
+ }
214
+ const declaration = {hook: `${target}${signature.trim()}`};
215
+ const existing = resolved.hooks.find(value => value.hook.split('(')[0] === target);
216
+ if (existing && existing.hook !== declaration.hook) {
217
+ throw new Error(`Conflicting ShaderPlugin hook ${target}`);
218
+ }
219
+ if (!existing) resolved.hooks.push(declaration);
220
+ }
221
+ const pluginInjections = Array.isArray(plugin.injections)
222
+ ? plugin.injections
223
+ : Object.entries(plugin.injections || {}).flatMap(([key, source]): ShaderPluginInjection[] => {
224
+ const target = selectShaderLanguage(key, shaderLanguage);
225
+ if (target === undefined) return [];
226
+ const [stage, ...name] = target.split(':');
227
+ if (stage !== 'vs' && stage !== 'fs')
228
+ throw new Error(`Invalid ShaderPlugin injection ${key}`);
229
+ return [
230
+ {
231
+ stage: stage === 'vs' ? ('vertex' as const) : ('fragment' as const),
232
+ target: name.join(':'),
233
+ [shaderLanguage]: source
234
+ }
235
+ ];
236
+ });
237
+ for (const injection of pluginInjections) {
238
+ const source = injection[shaderLanguage];
239
+ if (source === undefined) continue;
240
+ const target = getShaderPluginTarget(injection);
241
+ assertNamedShaderPluginInjectionTarget(target);
242
+ if (!resolved.injections[target]) {
243
+ resolved.injections[target] = [];
180
244
  }
181
- const injections = resolved.injections[injection.target];
245
+ const injections = resolved.injections[target];
182
246
  injections.push({
183
- injection: injection.injection,
247
+ pluginName: plugin.name,
248
+ injection: source,
184
249
  order: injection.order ?? 0
185
250
  });
186
251
  }
@@ -192,10 +257,10 @@ function assertShaderPluginInterfaceName(name: string, kind: 'vertex input' | 'v
192
257
  }
193
258
  }
194
259
 
195
- function normalizeShaderPluginVarying(
260
+ function normalizeShaderPluginInterStageVariable(
196
261
  name: string,
197
- varying: ShaderPluginVarying
198
- ): ResolvedShaderPluginVarying {
262
+ varying: ShaderPluginInterStageVariable
263
+ ): ResolvedShaderPluginInterStageVariable {
199
264
  const {primitiveType} = shaderTypeDecoder.getAttributeShaderTypeInfo(varying.type);
200
265
  const integerType = primitiveType === 'i32' || primitiveType === 'u32';
201
266
  const interpolation = varying.interpolation || (integerType ? 'flat' : 'smooth');
@@ -212,3 +277,15 @@ function assertNamedShaderPluginInjectionTarget(target: ShaderPluginInjectionTar
212
277
  );
213
278
  }
214
279
  }
280
+
281
+ function getShaderPluginTarget(value: ShaderPluginTarget): ShaderPluginInjectionTarget {
282
+ if ((value.stage !== 'vertex' && value.stage !== 'fragment') || value.target.includes(':')) {
283
+ throw new Error('ShaderPlugin object targets require an explicit stage and unqualified target');
284
+ }
285
+ return `${value.stage === 'vertex' ? 'vs' : 'fs'}:${value.target}` as ShaderPluginInjectionTarget;
286
+ }
287
+
288
+ function selectShaderLanguage(value: string, language: 'glsl' | 'wgsl'): string | undefined {
289
+ const match = /^(glsl|wgsl):([\s\S]+)$/.exec(value);
290
+ return match ? (match[1] === language ? match[2] : undefined) : value;
291
+ }
@@ -36,7 +36,7 @@ export class WGSLShaderAssembler extends ShaderAssembler {
36
36
  entryPoints: ShaderTranspilerEntryPoints;
37
37
  } {
38
38
  const modules = this._getModuleList(props.modules); // Combine with default modules
39
- const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions
39
+ const hookFunctions = [...this._hookFunctions, ...(props.hookFunctions || [])];
40
40
  const translated = this._transpileShader(
41
41
  props,
42
42
  modules,
@@ -100,50 +100,40 @@ fn clip_isInBounds(coordinates: vec2<f32>) -> bool {
100
100
  /** Coordinate-system-neutral instance and geometry clipping. */
101
101
  export const clipShaderPlugin: ShaderPlugin = {
102
102
  name: 'clip',
103
- modules: [clipShaderModule],
104
- varyings: {
103
+ module: clipShaderModule,
104
+ interStageVariables: {
105
105
  clipCoordinates: {type: 'vec2<f32>', interpolation: 'smooth'}
106
106
  },
107
- glsl: {
108
- injections: [
109
- {
110
- target: 'vs:CLIP_POSITION',
111
- injection: `\
107
+ injections: [
108
+ {
109
+ stage: 'vertex',
110
+ target: 'CLIP_POSITION',
111
+ glsl: `\
112
112
  clipCoordinates = geometryCoordinates;
113
113
  if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_INSTANCE} &&
114
114
  !clip_isInBounds(instanceCoordinates)) {
115
115
  position = vec4(2.0, 2.0, 2.0, 1.0);
116
- }`
117
- },
118
- {
119
- target: 'fs:CLIP_COLOR',
120
- injection: `\
121
- if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_GEOMETRY} &&
122
- !clip_isInBounds(clipCoordinates)) {
123
- discard;
124
- }`
125
- }
126
- ]
127
- },
128
- wgsl: {
129
- injections: [
130
- {
131
- target: 'vs:CLIP_POSITION',
132
- injection: `\
116
+ }`,
117
+ wgsl: `\
133
118
  clipCoordinates = geometryCoordinates;
134
119
  if (clipUniforms.enabled != 0 && clipUniforms.mode == ${CLIP_MODE_INSTANCE} &&
135
120
  !clip_isInBounds(instanceCoordinates)) {
136
121
  *position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
137
122
  }`
138
- },
139
- {
140
- target: 'fs:CLIP_COLOR',
141
- injection: `\
123
+ },
124
+ {
125
+ stage: 'fragment',
126
+ target: 'CLIP_COLOR',
127
+ glsl: `\
128
+ if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_GEOMETRY} &&
129
+ !clip_isInBounds(clipCoordinates)) {
130
+ discard;
131
+ }`,
132
+ wgsl: `\
142
133
  if (clipUniforms.enabled != 0 && clipUniforms.mode == ${CLIP_MODE_GEOMETRY} &&
143
134
  !clip_isInBounds(clipCoordinates)) {
144
135
  discard;
145
136
  }`
146
- }
147
- ]
148
- }
137
+ }
138
+ ]
149
139
  };
@@ -78,30 +78,22 @@ fn filter_isVisible(value: f32) -> bool {
78
78
  /** Scalar inclusive-range filtering for shaders that expose the `FILTER_POSITION` vertex hook. */
79
79
  export const filterShaderPlugin: ShaderPlugin = {
80
80
  name: 'filter',
81
- modules: [filterShaderModule],
81
+ module: filterShaderModule,
82
82
  vertexInputs: {
83
83
  filterValues: 'f32'
84
84
  },
85
- glsl: {
86
- injections: [
87
- {
88
- target: 'vs:FILTER_POSITION',
89
- injection: `\
85
+ injections: [
86
+ {
87
+ stage: 'vertex',
88
+ target: 'FILTER_POSITION',
89
+ glsl: `\
90
90
  if (!filter_isVisible(filterValues)) {
91
91
  position = vec4(2.0, 2.0, 2.0, 1.0);
92
- }`
93
- }
94
- ]
95
- },
96
- wgsl: {
97
- injections: [
98
- {
99
- target: 'vs:FILTER_POSITION',
100
- injection: `\
92
+ }`,
93
+ wgsl: `\
101
94
  if (!filter_isVisible(filterValues)) {
102
95
  *position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
103
96
  }`
104
- }
105
- ]
106
- }
97
+ }
98
+ ]
107
99
  };
@@ -49,7 +49,7 @@ export type PointLight = {
49
49
  export type DirectionalLight = {
50
50
  /** Discriminator used to identify directional lights in `lights: Light[]`. */
51
51
  type: 'directional';
52
- /** World-space light direction. */
52
+ /** World-space direction in which light travels. */
53
53
  direction: Readonly<NumberArray3>;
54
54
  /** RGB light color in the existing `0..255` convention used by luma.gl materials. */
55
55
  color?: Readonly<NumberArray3>;
@@ -1249,7 +1249,7 @@ vec4 pbr_filterColorWithSpotShadows(vec4 vertexColor, vec4 spotVisibility)
1249
1249
 
1250
1250
  for(int i = 0; i < lighting.directionalLightCount; i++) {
1251
1251
  if (i < lighting.directionalLightCount) {
1252
- PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
1252
+ PBRInfo_setDirectionalLight(pbrInfo, -lighting_getDirectionalLight(i).direction);
1253
1253
  color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
1254
1254
  }
1255
1255
  }
@@ -1537,7 +1537,7 @@ vec4 pbr_filterColorWithSpotShadows(vec4 vertexColor, vec4 spotVisibility)
1537
1537
  // Apply directional light
1538
1538
  for(int i = 0; i < lighting.directionalLightCount; i++) {
1539
1539
  if (i < lighting.directionalLightCount) {
1540
- PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
1540
+ PBRInfo_setDirectionalLight(pbrInfo, -lighting_getDirectionalLight(i).direction);
1541
1541
  color += calculateMaterialLightColor(
1542
1542
  pbrInfo,
1543
1543
  lighting_getDirectionalLight(i).color,
@@ -1468,7 +1468,7 @@ fn pbr_filterColorWithSpotShadows(vertexColor: vec4<f32>, spotVisibility: vec4f)
1468
1468
 
1469
1469
  for (var i = 0; i < lighting.directionalLightCount; i++) {
1470
1470
  if (i < lighting.directionalLightCount) {
1471
- PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
1471
+ PBRInfo_setDirectionalLight(&pbrInfo, -lighting_getDirectionalLight(i).direction);
1472
1472
  color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
1473
1473
  }
1474
1474
  }
@@ -1828,7 +1828,7 @@ fn pbr_filterColorWithSpotShadows(vertexColor: vec4<f32>, spotVisibility: vec4f)
1828
1828
  // Apply directional light
1829
1829
  for (var i = 0; i < lighting.directionalLightCount; i++) {
1830
1830
  if (i < lighting.directionalLightCount) {
1831
- PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
1831
+ PBRInfo_setDirectionalLight(&pbrInfo, -lighting_getDirectionalLight(i).direction);
1832
1832
  color += calculateMaterialLightColor(
1833
1833
  pbrInfo,
1834
1834
  lighting_getDirectionalLight(i).color,
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {ShaderModule} from '../../../lib/shader-module/shader-module';
6
6
 
7
- import {fp64ify, fp64LowPart, fp64ifyMatrix4} from '../../../modules/math/fp64/fp64-utils';
7
+ import {fp64ify, fp64LowPart, fp64ifyMatrix4} from './fp64-utils';
8
8
  import {fp64arithmeticShader} from './fp64-arithmetic-glsl';
9
9
  import {fp64arithmeticWGSL} from './fp64-arithmetic-wgsl';
10
10
  import {fp64functionShader} from './fp64-functions-glsl';
@@ -85,6 +85,8 @@ export type TextureFormatCompressed =
85
85
  | 'pvrtc-rgba4unorm-webgl'
86
86
  | 'pvrtc-rgb2unorm-webgl'
87
87
  | 'pvrtc-rgba2unorm-webgl'
88
+ | 'etc1-rgb-unorm-webgl'
89
+ // Legacy misspelling retained for compatibility.
88
90
  | 'etc1-rbg-unorm-webgl'
89
91
  | 'atc-rgb-unorm-webgl'
90
92
  | 'atc-rgba-unorm-webgl'
package/src/types.ts CHANGED
@@ -35,13 +35,81 @@ export type UniformFormat =
35
35
  | 'mat4x3<f32>'
36
36
  | 'mat4x4<f32>';
37
37
 
38
- export * from './types/primitive-data-types';
39
- export * from './types/shader-types';
40
- export * from './types/shader-type-decoder';
41
- export * from './types/shader-block-layout';
42
- export * from './types/shader-layout';
43
- export * from './types/texture-formats';
44
- export * from './types/sampler-props';
38
+ export {type PrimitiveDataType} from './types/primitive-data-types';
39
+ export {
40
+ type AttributeShaderType,
41
+ type VariableShaderType,
42
+ type CompositeShaderType,
43
+ type StructShaderType,
44
+ type ArrayShaderType,
45
+ type AttributeShaderTypeAlias,
46
+ type VariableShaderTypeAlias,
47
+ type AttributeShaderTypeT,
48
+ type VariableShaderTypeT,
49
+ type AttributeShaderTypeAliasT,
50
+ type VariableShaderTypeAliasT
51
+ } from './types/shader-types';
52
+ export {
53
+ getVariableShaderTypeInfo,
54
+ getAttributeShaderTypeInfo,
55
+ makeShaderAttributeType,
56
+ resolveAttributeShaderTypeAlias,
57
+ resolveVariableShaderTypeAlias,
58
+ type VariableShaderTypeInfo,
59
+ type AttributeShaderTypeInfo,
60
+ ShaderTypeDecoder,
61
+ shaderTypeDecoder,
62
+ WGSL_ATTRIBUTE_TYPE_ALIAS_MAP,
63
+ WGSL_VARIABLE_TYPE_ALIAS_MAP
64
+ } from './types/shader-type-decoder';
65
+ export {
66
+ makeShaderBlockLayout,
67
+ getLeafLayoutInfo,
68
+ isCompositeShaderTypeStruct,
69
+ type ShaderBlockLayoutEntry,
70
+ type ShaderBlockLayoutOptions,
71
+ type ShaderBlockLayout
72
+ } from './types/shader-block-layout';
73
+ export {
74
+ type ShaderLayout,
75
+ type ComputeShaderLayout,
76
+ type AttributeDeclaration,
77
+ type BindingDeclaration,
78
+ type UniformBufferBindingLayout,
79
+ type UniformBlockLayout,
80
+ type UniformInfo,
81
+ type StorageBufferBindingLayout,
82
+ type TextureBindingLayout,
83
+ type ExternalTextureBindingLayout,
84
+ type SamplerBindingLayout,
85
+ type StorageTextureBindingLayout,
86
+ type VaryingBinding,
87
+ type UniformBlockBinding,
88
+ type UniformBinding
89
+ } from './types/shader-layout';
90
+ export {
91
+ type TextureFormat,
92
+ type TextureFormatDepthStencil,
93
+ type TextureFormatColor,
94
+ type TextureFormatColorUncompressed,
95
+ type TextureFormatUnorm8,
96
+ type TextureFormatSnorm8,
97
+ type TextureFormatUint8,
98
+ type TextureFormatSint8,
99
+ type TextureFormatUnorm16,
100
+ type TextureFormatSnorm16,
101
+ type TextureFormatUint16,
102
+ type TextureFormatSint16,
103
+ type TextureFormatFloat16,
104
+ type TextureFormatUint32,
105
+ type TextureFormatSint32,
106
+ type TextureFormatFloat32,
107
+ type TextureFormatPacked16,
108
+ type TextureFormatPacked32,
109
+ type TextureFormatCompressed,
110
+ type CompressedTextureFormat
111
+ } from './types/texture-formats';
112
+ export {type CompareFunction, type SamplerProps} from './types/sampler-props';
45
113
  export {alignTo} from './types/align-to';
46
114
 
47
115
  /** Resource values remain opaque until an execution adapter binds them. */
package/src/wgsl.ts CHANGED
@@ -20,4 +20,15 @@ export {
20
20
  type ShaderBindingDebugRow
21
21
  } from './lib/shader-assembly/wgsl-binding-debug';
22
22
 
23
- export * from './lib/shader-assembly/wgsl-binding-scan';
23
+ export {
24
+ maskWGSLComments,
25
+ getWGSLBindingDeclarationMatches,
26
+ replaceWGSLBindingDeclarationMatches,
27
+ hasWGSLAutoBinding,
28
+ getFirstWGSLAutoBindingDeclarationMatch,
29
+ WGSL_BINDABLE_VARIABLE_PATTERN,
30
+ MODULE_WGSL_BINDING_DECLARATION_REGEXES,
31
+ WGSL_BINDING_DECLARATION_REGEXES,
32
+ WGSL_EXPLICIT_BINDING_DECLARATION_REGEXES,
33
+ type WGSLBindingDeclarationMatch
34
+ } from './lib/shader-assembly/wgsl-binding-scan';