@luma.gl/shadertools 9.3.5 → 9.4.0-alpha.1
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 +6555 -2373
- package/dist/dist.min.js +2984 -237
- package/dist/index.cjs +4356 -268
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts +11 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +47 -2
- package/dist/lib/preprocessor/preprocessor.js.map +1 -1
- package/dist/lib/shader-assembler.d.ts +10 -10
- package/dist/lib/shader-assembler.d.ts.map +1 -1
- package/dist/lib/shader-assembler.js +36 -20
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +28 -7
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +133 -15
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/platform-info.d.ts +2 -0
- package/dist/lib/shader-assembly/platform-info.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-hooks.d.ts +1 -1
- package/dist/lib/shader-assembly/shader-hooks.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-hooks.js +6 -3
- package/dist/lib/shader-assembly/shader-hooks.js.map +1 -1
- package/dist/lib/shader-assembly/shader-injections.d.ts +4 -1
- package/dist/lib/shader-assembly/shader-injections.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-injections.js +68 -11
- package/dist/lib/shader-assembly/shader-injections.js.map +1 -1
- package/dist/lib/shader-assembly/shader-plugin-varyings.d.ts +15 -0
- package/dist/lib/shader-assembly/shader-plugin-varyings.d.ts.map +1 -0
- package/dist/lib/shader-assembly/shader-plugin-varyings.js +412 -0
- package/dist/lib/shader-assembly/shader-plugin-varyings.js.map +1 -0
- package/dist/lib/shader-assembly/shader-plugin-vertex-inputs.d.ts +12 -0
- package/dist/lib/shader-assembly/shader-plugin-vertex-inputs.d.ts.map +1 -0
- package/dist/lib/shader-assembly/shader-plugin-vertex-inputs.js +237 -0
- package/dist/lib/shader-assembly/shader-plugin-vertex-inputs.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +3 -0
- 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/shader-module/shader-pass-pipeline.d.ts +14 -0
- package/dist/lib/shader-module/shader-pass-pipeline.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-pass-pipeline.js +5 -0
- package/dist/lib/shader-module/shader-pass-pipeline.js.map +1 -0
- package/dist/lib/shader-module/shader-pass.d.ts +21 -4
- package/dist/lib/shader-module/shader-pass.d.ts.map +1 -1
- package/dist/lib/shader-plugin.d.ts +68 -0
- package/dist/lib/shader-plugin.d.ts.map +1 -0
- package/dist/lib/shader-plugin.js +98 -0
- package/dist/lib/shader-plugin.js.map +1 -0
- package/dist/lib/utils/assert.js +1 -1
- package/dist/lib/utils/assert.js.map +1 -1
- package/dist/modules/color/float-colors.d.ts +111 -5
- package/dist/modules/color/float-colors.d.ts.map +1 -1
- package/dist/modules/color/float-colors.js +200 -34
- package/dist/modules/color/float-colors.js.map +1 -1
- package/dist/modules/engine/clip/clip.d.ts +12 -0
- package/dist/modules/engine/clip/clip.d.ts.map +1 -0
- package/dist/modules/engine/clip/clip.js +129 -0
- package/dist/modules/engine/clip/clip.js.map +1 -0
- package/dist/modules/engine/filter/filter.d.ts +12 -0
- package/dist/modules/engine/filter/filter.d.ts.map +1 -0
- package/dist/modules/engine/filter/filter.js +88 -0
- package/dist/modules/engine/filter/filter.js.map +1 -0
- package/dist/modules/geospatial/dggs/dggs-wgsl.d.ts +3 -0
- package/dist/modules/geospatial/dggs/dggs-wgsl.d.ts.map +1 -0
- package/dist/modules/geospatial/dggs/dggs-wgsl.js +1892 -0
- package/dist/modules/geospatial/dggs/dggs-wgsl.js.map +1 -0
- package/dist/modules/geospatial/dggs/dggs.d.ts +6 -0
- package/dist/modules/geospatial/dggs/dggs.d.ts.map +1 -0
- package/dist/modules/geospatial/dggs/dggs.js +10 -0
- package/dist/modules/geospatial/dggs/dggs.js.map +1 -0
- package/dist/modules/lighting/water-material/water-material.d.ts +28 -0
- package/dist/modules/lighting/water-material/water-material.d.ts.map +1 -0
- package/dist/modules/lighting/water-material/water-material.js +179 -0
- package/dist/modules/lighting/water-material/water-material.js.map +1 -0
- package/dist/modules/lighting/water-material/water-shaders-glsl.d.ts +3 -0
- package/dist/modules/lighting/water-material/water-shaders-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/water-material/water-shaders-glsl.js +232 -0
- package/dist/modules/lighting/water-material/water-shaders-glsl.js.map +1 -0
- package/dist/modules/lighting/water-material/water-shaders-wgsl.d.ts +2 -0
- package/dist/modules/lighting/water-material/water-shaders-wgsl.d.ts.map +1 -0
- package/dist/modules/lighting/water-material/water-shaders-wgsl.js +230 -0
- package/dist/modules/lighting/water-material/water-shaders-wgsl.js.map +1 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +268 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +50 -3
- package/src/lib/preprocessor/preprocessor.ts +68 -3
- package/src/lib/shader-assembler.ts +49 -20
- package/src/lib/shader-assembly/assemble-shaders.ts +242 -30
- package/src/lib/shader-assembly/platform-info.ts +2 -0
- package/src/lib/shader-assembly/shader-hooks.ts +7 -3
- package/src/lib/shader-assembly/shader-injections.ts +96 -11
- package/src/lib/shader-assembly/shader-plugin-varyings.ts +524 -0
- package/src/lib/shader-assembly/shader-plugin-vertex-inputs.ts +279 -0
- package/src/lib/shader-module/shader-module.ts +3 -0
- package/src/lib/shader-module/shader-pass-pipeline.ts +19 -0
- package/src/lib/shader-module/shader-pass.ts +29 -4
- package/src/lib/shader-plugin.ts +214 -0
- package/src/lib/utils/assert.ts +1 -1
- package/src/modules/color/float-colors.ts +272 -37
- package/src/modules/engine/clip/clip.ts +149 -0
- package/src/modules/engine/filter/filter.ts +107 -0
- package/src/modules/geospatial/dggs/dggs-wgsl.ts +1892 -0
- package/src/modules/geospatial/dggs/dggs.ts +12 -0
- package/src/modules/lighting/water-material/water-material.ts +234 -0
- package/src/modules/lighting/water-material/water-shaders-glsl.ts +233 -0
- package/src/modules/lighting/water-material/water-shaders-wgsl.ts +230 -0
- package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +268 -0
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import type {Binding} from '@luma.gl/core';
|
|
5
6
|
import {ShaderModule} from '../../lib/shader-module/shader-module';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
/** Props for semantic color normalization helpers. */
|
|
9
|
+
export type ColorsProps = {
|
|
8
10
|
/**
|
|
9
11
|
* When true, semantic colors are interpreted as 0-255 byte-style values and normalized in shader code.
|
|
10
12
|
* When false, semantic colors are interpreted directly as floats.
|
|
@@ -12,61 +14,214 @@ export type FloatColorsProps = {
|
|
|
12
14
|
useByteColors?: boolean;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
/** Uniforms consumed by semantic color normalization helpers. */
|
|
18
|
+
export type ColorsUniforms = {
|
|
16
19
|
/** Controls whether shader helpers normalize semantic colors from byte space. */
|
|
17
20
|
useByteColors: boolean;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
/** Backward-compatible props alias for shaders that import `floatColors`. */
|
|
24
|
+
export type FloatColorsProps = ColorsProps;
|
|
25
|
+
/** Backward-compatible uniform alias for shaders that import `floatColors`. */
|
|
26
|
+
export type FloatColorsUniforms = ColorsUniforms;
|
|
27
|
+
|
|
28
|
+
/** Packed storage color formats decoded by `storageColors`. */
|
|
29
|
+
export type StorageColorFormat = 'rgba8unorm' | 'rgba16float' | 'rgba32float';
|
|
30
|
+
|
|
31
|
+
/** Numeric WGSL tags written to `storageColors.format`. */
|
|
32
|
+
export const STORAGE_COLOR_FORMAT = {
|
|
33
|
+
RGBA8UNORM: 0,
|
|
34
|
+
RGBA16FLOAT: 1,
|
|
35
|
+
RGBA32FLOAT: 2
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
/** Numeric WGSL tag for one packed storage color format. */
|
|
39
|
+
export type StorageColorFormatValue =
|
|
40
|
+
(typeof STORAGE_COLOR_FORMAT)[keyof typeof STORAGE_COLOR_FORMAT];
|
|
41
|
+
|
|
42
|
+
/** Bytes occupied by one tightly packed storage color row. */
|
|
43
|
+
export const STORAGE_COLOR_FORMAT_BYTE_LENGTHS: Record<StorageColorFormat, number> = {
|
|
44
|
+
rgba8unorm: 4,
|
|
45
|
+
rgba16float: 8,
|
|
46
|
+
rgba32float: 16
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** Default byte stride for one tightly packed storage color row. */
|
|
50
|
+
export const STORAGE_COLOR_DEFAULT_BYTE_STRIDES: Record<StorageColorFormat, number> = {
|
|
51
|
+
...STORAGE_COLOR_FORMAT_BYTE_LENGTHS
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Props for reading packed color rows from a read-only storage buffer. */
|
|
55
|
+
export type StorageColorsProps = {
|
|
56
|
+
/** Storage buffer containing raw packed color words. */
|
|
57
|
+
colorBuffer?: Binding;
|
|
58
|
+
/** Per-row storage color representation. Defaults to `rgba8unorm`. */
|
|
59
|
+
format?: StorageColorFormat | StorageColorFormatValue;
|
|
60
|
+
/** Byte offset to the first color. Must be 4-byte aligned. Defaults to `0`. */
|
|
61
|
+
byteOffset?: number;
|
|
62
|
+
/** Bytes between color rows. Must be 4-byte aligned. Defaults to the packed format size. */
|
|
63
|
+
byteStride?: number;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** Uniforms consumed by the packed storage color reader. */
|
|
67
|
+
export type StorageColorsUniforms = {
|
|
68
|
+
/** Numeric `STORAGE_COLOR_FORMAT` tag used by WGSL. */
|
|
69
|
+
format: StorageColorFormatValue;
|
|
70
|
+
/** Uint32 words between storage color rows. */
|
|
71
|
+
wordStride: number;
|
|
72
|
+
/** Uint32 word offset to the first storage color row. */
|
|
73
|
+
wordOffset: number;
|
|
74
|
+
/** Reserved field retaining a 16-byte uniform block. */
|
|
75
|
+
_padding: number;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** Bindings consumed by the packed storage color reader. */
|
|
79
|
+
export type StorageColorsBindings = {
|
|
80
|
+
/** Raw packed storage color buffer exposed as `array<u32>`. */
|
|
81
|
+
storageColorsBuffer?: Binding;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const STORAGE_COLOR_FORMAT_BY_NAME: Record<StorageColorFormat, StorageColorFormatValue> = {
|
|
85
|
+
rgba8unorm: STORAGE_COLOR_FORMAT.RGBA8UNORM,
|
|
86
|
+
rgba16float: STORAGE_COLOR_FORMAT.RGBA16FLOAT,
|
|
87
|
+
rgba32float: STORAGE_COLOR_FORMAT.RGBA32FLOAT
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const STORAGE_COLOR_FORMAT_NAME_BY_VALUE: Record<StorageColorFormatValue, StorageColorFormat> = {
|
|
91
|
+
[STORAGE_COLOR_FORMAT.RGBA8UNORM]: 'rgba8unorm',
|
|
92
|
+
[STORAGE_COLOR_FORMAT.RGBA16FLOAT]: 'rgba16float',
|
|
93
|
+
[STORAGE_COLOR_FORMAT.RGBA32FLOAT]: 'rgba32float'
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const COLORS_UNIFORM_TYPES = {
|
|
97
|
+
useByteColors: 'f32'
|
|
98
|
+
} as const;
|
|
99
|
+
|
|
100
|
+
const COLORS_DEFAULT_UNIFORMS = {
|
|
101
|
+
useByteColors: true
|
|
102
|
+
} as const;
|
|
103
|
+
|
|
104
|
+
const STORAGE_COLORS_UNIFORM_TYPES = {
|
|
105
|
+
format: 'u32',
|
|
106
|
+
wordStride: 'u32',
|
|
107
|
+
wordOffset: 'u32',
|
|
108
|
+
_padding: 'u32'
|
|
109
|
+
} as const;
|
|
110
|
+
|
|
111
|
+
const STORAGE_COLORS_DEFAULT_UNIFORMS = {
|
|
112
|
+
format: STORAGE_COLOR_FORMAT.RGBA8UNORM,
|
|
113
|
+
wordStride: STORAGE_COLOR_DEFAULT_BYTE_STRIDES.rgba8unorm / Uint32Array.BYTES_PER_ELEMENT,
|
|
114
|
+
wordOffset: 0,
|
|
115
|
+
_padding: 0
|
|
116
|
+
} as const satisfies StorageColorsUniforms;
|
|
117
|
+
|
|
118
|
+
const COLORS_GLSL = buildGLSLColorModuleSource('colors');
|
|
119
|
+
const FLOAT_COLORS_GLSL = buildGLSLColorModuleSource('floatColors');
|
|
120
|
+
const COLORS_WGSL = buildWGSLColorModuleSource('colors');
|
|
121
|
+
const FLOAT_COLORS_WGSL = buildWGSLColorModuleSource('floatColors');
|
|
122
|
+
|
|
123
|
+
const STORAGE_COLORS_WGSL = /* wgsl */ `\
|
|
124
|
+
struct storageColorsUniforms {
|
|
125
|
+
format: u32,
|
|
126
|
+
wordStride: u32,
|
|
127
|
+
wordOffset: u32,
|
|
128
|
+
_padding: u32
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
@group(0) @binding(auto) var<uniform> storageColors : storageColorsUniforms;
|
|
132
|
+
@group(0) @binding(auto) var<storage, read> storageColorsBuffer : array<u32>;
|
|
133
|
+
|
|
134
|
+
const STORAGE_COLOR_FORMAT_RGBA8UNORM : u32 = ${STORAGE_COLOR_FORMAT.RGBA8UNORM}u;
|
|
135
|
+
const STORAGE_COLOR_FORMAT_RGBA16FLOAT : u32 = ${STORAGE_COLOR_FORMAT.RGBA16FLOAT}u;
|
|
136
|
+
|
|
137
|
+
fn storageColors_getWordIndex(rowIndex: u32) -> u32 {
|
|
138
|
+
return storageColors.wordOffset + rowIndex * storageColors.wordStride;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
fn storageColors_readRgba8UnormColor(wordIndex: u32) -> vec4<f32> {
|
|
142
|
+
return unpack4x8unorm(storageColorsBuffer[wordIndex]);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn storageColors_readRgba16FloatColor(wordIndex: u32) -> vec4<f32> {
|
|
146
|
+
let redGreen = unpack2x16float(storageColorsBuffer[wordIndex]);
|
|
147
|
+
let blueAlpha = unpack2x16float(storageColorsBuffer[wordIndex + 1u]);
|
|
148
|
+
return vec4<f32>(redGreen.x, redGreen.y, blueAlpha.x, blueAlpha.y);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fn storageColors_readRgba32FloatColor(wordIndex: u32) -> vec4<f32> {
|
|
152
|
+
return vec4<f32>(
|
|
153
|
+
bitcast<f32>(storageColorsBuffer[wordIndex]),
|
|
154
|
+
bitcast<f32>(storageColorsBuffer[wordIndex + 1u]),
|
|
155
|
+
bitcast<f32>(storageColorsBuffer[wordIndex + 2u]),
|
|
156
|
+
bitcast<f32>(storageColorsBuffer[wordIndex + 3u])
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fn storageColors_readColor(rowIndex: u32) -> vec4<f32> {
|
|
161
|
+
let wordIndex = storageColors_getWordIndex(rowIndex);
|
|
162
|
+
if (storageColors.format == STORAGE_COLOR_FORMAT_RGBA8UNORM) {
|
|
163
|
+
return storageColors_readRgba8UnormColor(wordIndex);
|
|
164
|
+
}
|
|
165
|
+
if (storageColors.format == STORAGE_COLOR_FORMAT_RGBA16FLOAT) {
|
|
166
|
+
return storageColors_readRgba16FloatColor(wordIndex);
|
|
167
|
+
}
|
|
168
|
+
return storageColors_readRgba32FloatColor(wordIndex);
|
|
169
|
+
}
|
|
170
|
+
`;
|
|
171
|
+
|
|
172
|
+
function buildGLSLColorModuleSource(primaryPrefix: string): string {
|
|
173
|
+
return /* glsl */ `\
|
|
174
|
+
layout(std140) uniform ${primaryPrefix}Uniforms {
|
|
22
175
|
float useByteColors;
|
|
23
|
-
}
|
|
176
|
+
} ${primaryPrefix};
|
|
24
177
|
|
|
25
|
-
vec3
|
|
26
|
-
return
|
|
178
|
+
vec3 ${primaryPrefix}_normalize(vec3 inputColor) {
|
|
179
|
+
return ${primaryPrefix}.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;
|
|
27
180
|
}
|
|
28
181
|
|
|
29
|
-
vec4
|
|
30
|
-
return
|
|
182
|
+
vec4 ${primaryPrefix}_normalize(vec4 inputColor) {
|
|
183
|
+
return ${primaryPrefix}.useByteColors > 0.5 ? inputColor / 255.0 : inputColor;
|
|
31
184
|
}
|
|
32
185
|
|
|
33
|
-
vec4
|
|
186
|
+
vec4 ${primaryPrefix}_premultiplyAlpha(vec4 inputColor) {
|
|
34
187
|
return vec4(inputColor.rgb * inputColor.a, inputColor.a);
|
|
35
188
|
}
|
|
36
189
|
|
|
37
|
-
vec4
|
|
190
|
+
vec4 ${primaryPrefix}_unpremultiplyAlpha(vec4 inputColor) {
|
|
38
191
|
return inputColor.a > 0.0 ? vec4(inputColor.rgb / inputColor.a, inputColor.a) : vec4(0.0);
|
|
39
192
|
}
|
|
40
193
|
|
|
41
|
-
vec4
|
|
42
|
-
return
|
|
194
|
+
vec4 ${primaryPrefix}_premultiply_alpha(vec4 inputColor) {
|
|
195
|
+
return ${primaryPrefix}_premultiplyAlpha(inputColor);
|
|
43
196
|
}
|
|
44
197
|
|
|
45
|
-
vec4
|
|
46
|
-
return
|
|
198
|
+
vec4 ${primaryPrefix}_unpremultiply_alpha(vec4 inputColor) {
|
|
199
|
+
return ${primaryPrefix}_unpremultiplyAlpha(inputColor);
|
|
47
200
|
}
|
|
48
201
|
`;
|
|
202
|
+
}
|
|
49
203
|
|
|
50
|
-
|
|
51
|
-
|
|
204
|
+
function buildWGSLColorModuleSource(primaryPrefix: string): string {
|
|
205
|
+
return /* wgsl */ `\
|
|
206
|
+
struct ${primaryPrefix}Uniforms {
|
|
52
207
|
useByteColors: f32
|
|
53
208
|
};
|
|
54
209
|
|
|
55
|
-
@group(0) @binding(auto) var<uniform>
|
|
210
|
+
@group(0) @binding(auto) var<uniform> ${primaryPrefix} : ${primaryPrefix}Uniforms;
|
|
56
211
|
|
|
57
|
-
fn
|
|
58
|
-
return select(inputColor, inputColor / 255.0,
|
|
212
|
+
fn ${primaryPrefix}_normalize(inputColor: vec3<f32>) -> vec3<f32> {
|
|
213
|
+
return select(inputColor, inputColor / 255.0, ${primaryPrefix}.useByteColors > 0.5);
|
|
59
214
|
}
|
|
60
215
|
|
|
61
|
-
fn
|
|
62
|
-
return select(inputColor, inputColor / 255.0,
|
|
216
|
+
fn ${primaryPrefix}_normalize4(inputColor: vec4<f32>) -> vec4<f32> {
|
|
217
|
+
return select(inputColor, inputColor / 255.0, ${primaryPrefix}.useByteColors > 0.5);
|
|
63
218
|
}
|
|
64
219
|
|
|
65
|
-
fn
|
|
220
|
+
fn ${primaryPrefix}_premultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {
|
|
66
221
|
return vec4<f32>(inputColor.rgb * inputColor.a, inputColor.a);
|
|
67
222
|
}
|
|
68
223
|
|
|
69
|
-
fn
|
|
224
|
+
fn ${primaryPrefix}_unpremultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {
|
|
70
225
|
return select(
|
|
71
226
|
vec4<f32>(0.0),
|
|
72
227
|
vec4<f32>(inputColor.rgb / inputColor.a, inputColor.a),
|
|
@@ -74,26 +229,106 @@ fn floatColors_unpremultiplyAlpha(inputColor: vec4<f32>) -> vec4<f32> {
|
|
|
74
229
|
);
|
|
75
230
|
}
|
|
76
231
|
|
|
77
|
-
fn
|
|
78
|
-
return
|
|
232
|
+
fn ${primaryPrefix}_premultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {
|
|
233
|
+
return ${primaryPrefix}_premultiplyAlpha(inputColor);
|
|
79
234
|
}
|
|
80
235
|
|
|
81
|
-
fn
|
|
82
|
-
return
|
|
236
|
+
fn ${primaryPrefix}_unpremultiply_alpha(inputColor: vec4<f32>) -> vec4<f32> {
|
|
237
|
+
return ${primaryPrefix}_unpremultiplyAlpha(inputColor);
|
|
83
238
|
}
|
|
84
239
|
`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function getStorageColorsUniforms(props: StorageColorsProps = {}): StorageColorsUniforms {
|
|
243
|
+
const format = resolveStorageColorFormat(props.format);
|
|
244
|
+
const formatName = STORAGE_COLOR_FORMAT_NAME_BY_VALUE[format];
|
|
245
|
+
const byteStride = props.byteStride ?? STORAGE_COLOR_DEFAULT_BYTE_STRIDES[formatName];
|
|
246
|
+
const byteOffset = props.byteOffset ?? 0;
|
|
247
|
+
const minimumByteStride = STORAGE_COLOR_FORMAT_BYTE_LENGTHS[formatName];
|
|
248
|
+
|
|
249
|
+
validateStorageColorByteAlignment('byteStride', byteStride);
|
|
250
|
+
validateStorageColorByteAlignment('byteOffset', byteOffset);
|
|
251
|
+
if (byteStride < minimumByteStride) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`storageColors byteStride must be at least ${minimumByteStride} for ${formatName}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
format,
|
|
259
|
+
wordStride: byteStride / Uint32Array.BYTES_PER_ELEMENT,
|
|
260
|
+
wordOffset: byteOffset / Uint32Array.BYTES_PER_ELEMENT,
|
|
261
|
+
_padding: 0
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function resolveStorageColorFormat(
|
|
266
|
+
format: StorageColorsProps['format'] = 'rgba8unorm'
|
|
267
|
+
): StorageColorFormatValue {
|
|
268
|
+
if (typeof format === 'number') {
|
|
269
|
+
if (format in STORAGE_COLOR_FORMAT_NAME_BY_VALUE) {
|
|
270
|
+
return format as StorageColorFormatValue;
|
|
271
|
+
}
|
|
272
|
+
} else if (format in STORAGE_COLOR_FORMAT_BY_NAME) {
|
|
273
|
+
return STORAGE_COLOR_FORMAT_BY_NAME[format];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
throw new Error(
|
|
277
|
+
`storageColors format must be one of ${Object.keys(STORAGE_COLOR_FORMAT_BY_NAME).join(', ')}`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
85
280
|
|
|
281
|
+
function validateStorageColorByteAlignment(name: string, value: number): void {
|
|
282
|
+
if (!Number.isInteger(value) || value < 0 || value % Uint32Array.BYTES_PER_ELEMENT !== 0) {
|
|
283
|
+
throw new Error(`storageColors ${name} must be a non-negative 4-byte aligned integer`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** Semantic color normalization helpers named `colors_*`. */
|
|
288
|
+
export const colors = {
|
|
289
|
+
name: 'colors',
|
|
290
|
+
props: {} as ColorsProps,
|
|
291
|
+
uniforms: {} as ColorsUniforms,
|
|
292
|
+
vs: COLORS_GLSL,
|
|
293
|
+
fs: COLORS_GLSL,
|
|
294
|
+
source: COLORS_WGSL,
|
|
295
|
+
uniformTypes: COLORS_UNIFORM_TYPES,
|
|
296
|
+
defaultUniforms: COLORS_DEFAULT_UNIFORMS
|
|
297
|
+
} as const satisfies ShaderModule<ColorsProps, ColorsUniforms>;
|
|
298
|
+
|
|
299
|
+
/** Legacy semantic color normalization helpers named `floatColors_*`. */
|
|
86
300
|
export const floatColors = {
|
|
87
301
|
name: 'floatColors',
|
|
88
302
|
props: {} as FloatColorsProps,
|
|
89
303
|
uniforms: {} as FloatColorsUniforms,
|
|
90
|
-
vs:
|
|
91
|
-
fs:
|
|
92
|
-
source:
|
|
93
|
-
uniformTypes:
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
defaultUniforms: {
|
|
97
|
-
useByteColors: true
|
|
98
|
-
}
|
|
304
|
+
vs: FLOAT_COLORS_GLSL,
|
|
305
|
+
fs: FLOAT_COLORS_GLSL,
|
|
306
|
+
source: FLOAT_COLORS_WGSL,
|
|
307
|
+
uniformTypes: COLORS_UNIFORM_TYPES,
|
|
308
|
+
defaultUniforms: COLORS_DEFAULT_UNIFORMS
|
|
99
309
|
} as const satisfies ShaderModule<FloatColorsProps, FloatColorsUniforms>;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* WGSL reader for packed RGBA storage rows.
|
|
313
|
+
*
|
|
314
|
+
* Include {@link colors} separately when semantic color normalization helpers are also needed.
|
|
315
|
+
*/
|
|
316
|
+
export const storageColors = {
|
|
317
|
+
name: 'storageColors',
|
|
318
|
+
props: {} as StorageColorsProps,
|
|
319
|
+
uniforms: {} as StorageColorsUniforms,
|
|
320
|
+
bindings: {} as StorageColorsBindings,
|
|
321
|
+
source: STORAGE_COLORS_WGSL,
|
|
322
|
+
uniformTypes: STORAGE_COLORS_UNIFORM_TYPES,
|
|
323
|
+
defaultUniforms: STORAGE_COLORS_DEFAULT_UNIFORMS,
|
|
324
|
+
bindingLayout: [
|
|
325
|
+
{name: 'storageColors', group: 0},
|
|
326
|
+
{name: 'storageColorsBuffer', group: 0}
|
|
327
|
+
],
|
|
328
|
+
getUniforms(props: StorageColorsProps = {}) {
|
|
329
|
+
return {
|
|
330
|
+
...getStorageColorsUniforms(props),
|
|
331
|
+
...(props.colorBuffer ? {storageColorsBuffer: props.colorBuffer} : {})
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
} as const satisfies ShaderModule<StorageColorsProps, StorageColorsUniforms, StorageColorsBindings>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {ShaderModule} from '../../../lib/shader-module/shader-module';
|
|
6
|
+
import type {ShaderPlugin} from '../../../lib/shader-plugin';
|
|
7
|
+
|
|
8
|
+
export type ClipShaderPluginProps = {
|
|
9
|
+
/** Enables clipping. Defaults to true. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
/** Inclusive lower and exclusive upper bounds. Defaults to [0, 0, 1, 1]. */
|
|
12
|
+
bounds?: readonly [number, number, number, number];
|
|
13
|
+
/** Clips whole instances by their anchor or individual fragments. Defaults to geometry. */
|
|
14
|
+
mode?: 'instance' | 'geometry';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type ClipUniforms = {
|
|
18
|
+
enabled: number;
|
|
19
|
+
mode: number;
|
|
20
|
+
bounds: readonly [number, number, number, number];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const CLIP_MODE_GEOMETRY = 0;
|
|
24
|
+
const CLIP_MODE_INSTANCE = 1;
|
|
25
|
+
|
|
26
|
+
const clipShaderModule = {
|
|
27
|
+
name: 'clip',
|
|
28
|
+
props: {} as ClipShaderPluginProps,
|
|
29
|
+
uniforms: {} as ClipUniforms,
|
|
30
|
+
bindingLayout: [{name: 'clip', group: 2}],
|
|
31
|
+
uniformTypes: {
|
|
32
|
+
enabled: 'i32',
|
|
33
|
+
mode: 'i32',
|
|
34
|
+
bounds: 'vec4<f32>'
|
|
35
|
+
},
|
|
36
|
+
defaultUniforms: {
|
|
37
|
+
enabled: 1,
|
|
38
|
+
mode: CLIP_MODE_GEOMETRY,
|
|
39
|
+
bounds: [0, 0, 1, 1]
|
|
40
|
+
},
|
|
41
|
+
vs: /* glsl */ `\
|
|
42
|
+
layout(std140) uniform clipUniforms {
|
|
43
|
+
highp int enabled;
|
|
44
|
+
highp int mode;
|
|
45
|
+
highp vec4 bounds;
|
|
46
|
+
} clipState;
|
|
47
|
+
|
|
48
|
+
bool clip_isInBounds(vec2 coordinates) {
|
|
49
|
+
return coordinates.x >= clipState.bounds.x &&
|
|
50
|
+
coordinates.y >= clipState.bounds.y &&
|
|
51
|
+
coordinates.x < clipState.bounds.z &&
|
|
52
|
+
coordinates.y < clipState.bounds.w;
|
|
53
|
+
}
|
|
54
|
+
`,
|
|
55
|
+
fs: /* glsl */ `\
|
|
56
|
+
layout(std140) uniform clipUniforms {
|
|
57
|
+
highp int enabled;
|
|
58
|
+
highp int mode;
|
|
59
|
+
highp vec4 bounds;
|
|
60
|
+
} clipState;
|
|
61
|
+
|
|
62
|
+
bool clip_isInBounds(vec2 coordinates) {
|
|
63
|
+
return coordinates.x >= clipState.bounds.x &&
|
|
64
|
+
coordinates.y >= clipState.bounds.y &&
|
|
65
|
+
coordinates.x < clipState.bounds.z &&
|
|
66
|
+
coordinates.y < clipState.bounds.w;
|
|
67
|
+
}
|
|
68
|
+
`,
|
|
69
|
+
source: /* wgsl */ `\
|
|
70
|
+
struct ClipUniforms {
|
|
71
|
+
enabled: i32,
|
|
72
|
+
mode: i32,
|
|
73
|
+
bounds: vec4<f32>,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
@group(2) @binding(auto) var<uniform> clipUniforms: ClipUniforms;
|
|
77
|
+
|
|
78
|
+
fn clip_isInBounds(coordinates: vec2<f32>) -> bool {
|
|
79
|
+
return coordinates.x >= clipUniforms.bounds.x &&
|
|
80
|
+
coordinates.y >= clipUniforms.bounds.y &&
|
|
81
|
+
coordinates.x < clipUniforms.bounds.z &&
|
|
82
|
+
coordinates.y < clipUniforms.bounds.w;
|
|
83
|
+
}
|
|
84
|
+
`,
|
|
85
|
+
getUniforms(props: ClipShaderPluginProps = {}): Partial<ClipUniforms> {
|
|
86
|
+
const uniforms: Partial<ClipUniforms> = {};
|
|
87
|
+
if (props.enabled !== undefined) {
|
|
88
|
+
uniforms.enabled = Number(props.enabled);
|
|
89
|
+
}
|
|
90
|
+
if (props.mode !== undefined) {
|
|
91
|
+
uniforms.mode = props.mode === 'instance' ? CLIP_MODE_INSTANCE : CLIP_MODE_GEOMETRY;
|
|
92
|
+
}
|
|
93
|
+
if (props.bounds !== undefined) {
|
|
94
|
+
uniforms.bounds = props.bounds;
|
|
95
|
+
}
|
|
96
|
+
return uniforms;
|
|
97
|
+
}
|
|
98
|
+
} as const satisfies ShaderModule<ClipShaderPluginProps, ClipUniforms, {}>;
|
|
99
|
+
|
|
100
|
+
/** Coordinate-system-neutral instance and geometry clipping. */
|
|
101
|
+
export const clipShaderPlugin: ShaderPlugin = {
|
|
102
|
+
name: 'clip',
|
|
103
|
+
modules: [clipShaderModule],
|
|
104
|
+
varyings: {
|
|
105
|
+
clipCoordinates: {type: 'vec2<f32>', interpolation: 'smooth'}
|
|
106
|
+
},
|
|
107
|
+
glsl: {
|
|
108
|
+
injections: [
|
|
109
|
+
{
|
|
110
|
+
target: 'vs:CLIP_POSITION',
|
|
111
|
+
injection: `\
|
|
112
|
+
clipCoordinates = geometryCoordinates;
|
|
113
|
+
if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_INSTANCE} &&
|
|
114
|
+
!clip_isInBounds(instanceCoordinates)) {
|
|
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: `\
|
|
133
|
+
clipCoordinates = geometryCoordinates;
|
|
134
|
+
if (clipUniforms.enabled != 0 && clipUniforms.mode == ${CLIP_MODE_INSTANCE} &&
|
|
135
|
+
!clip_isInBounds(instanceCoordinates)) {
|
|
136
|
+
*position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
|
|
137
|
+
}`
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
target: 'fs:CLIP_COLOR',
|
|
141
|
+
injection: `\
|
|
142
|
+
if (clipUniforms.enabled != 0 && clipUniforms.mode == ${CLIP_MODE_GEOMETRY} &&
|
|
143
|
+
!clip_isInBounds(clipCoordinates)) {
|
|
144
|
+
discard;
|
|
145
|
+
}`
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {ShaderModule} from '../../../lib/shader-module/shader-module';
|
|
6
|
+
import type {ShaderPlugin} from '../../../lib/shader-plugin';
|
|
7
|
+
|
|
8
|
+
export type FilterShaderPluginProps = {
|
|
9
|
+
/** Enables range filtering. Defaults to true. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
/** Inclusive minimum accepted value. Defaults to 0. */
|
|
12
|
+
min?: number;
|
|
13
|
+
/** Inclusive maximum accepted value. Defaults to 1. */
|
|
14
|
+
max?: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type FilterUniforms = {
|
|
18
|
+
enabled: number;
|
|
19
|
+
min: number;
|
|
20
|
+
max: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const filterShaderModule = {
|
|
24
|
+
name: 'filter',
|
|
25
|
+
props: {} as FilterShaderPluginProps,
|
|
26
|
+
uniforms: {} as FilterUniforms,
|
|
27
|
+
bindingLayout: [{name: 'filter', group: 2}],
|
|
28
|
+
uniformTypes: {
|
|
29
|
+
enabled: 'i32',
|
|
30
|
+
min: 'f32',
|
|
31
|
+
max: 'f32'
|
|
32
|
+
},
|
|
33
|
+
defaultUniforms: {
|
|
34
|
+
enabled: 1,
|
|
35
|
+
min: 0,
|
|
36
|
+
max: 1
|
|
37
|
+
},
|
|
38
|
+
vs: /* glsl */ `\
|
|
39
|
+
layout(std140) uniform filterUniforms {
|
|
40
|
+
int enabled;
|
|
41
|
+
float min;
|
|
42
|
+
float max;
|
|
43
|
+
} filterState;
|
|
44
|
+
|
|
45
|
+
bool filter_isVisible(float value) {
|
|
46
|
+
return filterState.enabled == 0 || (value >= filterState.min && value <= filterState.max);
|
|
47
|
+
}
|
|
48
|
+
`,
|
|
49
|
+
source: /* wgsl */ `\
|
|
50
|
+
struct FilterUniforms {
|
|
51
|
+
enabled: i32,
|
|
52
|
+
min: f32,
|
|
53
|
+
max: f32,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
@group(2) @binding(auto) var<uniform> filterUniforms: FilterUniforms;
|
|
57
|
+
|
|
58
|
+
fn filter_isVisible(value: f32) -> bool {
|
|
59
|
+
return filterUniforms.enabled == 0 ||
|
|
60
|
+
(value >= filterUniforms.min && value <= filterUniforms.max);
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
getUniforms(props: FilterShaderPluginProps = {}): Partial<FilterUniforms> {
|
|
64
|
+
const uniforms: Partial<FilterUniforms> = {};
|
|
65
|
+
if (props.enabled !== undefined) {
|
|
66
|
+
uniforms.enabled = Number(props.enabled);
|
|
67
|
+
}
|
|
68
|
+
if (props.min !== undefined) {
|
|
69
|
+
uniforms.min = props.min;
|
|
70
|
+
}
|
|
71
|
+
if (props.max !== undefined) {
|
|
72
|
+
uniforms.max = props.max;
|
|
73
|
+
}
|
|
74
|
+
return uniforms;
|
|
75
|
+
}
|
|
76
|
+
} as const satisfies ShaderModule<FilterShaderPluginProps, FilterUniforms>;
|
|
77
|
+
|
|
78
|
+
/** Scalar inclusive-range filtering for shaders that expose the `FILTER_POSITION` vertex hook. */
|
|
79
|
+
export const filterShaderPlugin: ShaderPlugin = {
|
|
80
|
+
name: 'filter',
|
|
81
|
+
modules: [filterShaderModule],
|
|
82
|
+
vertexInputs: {
|
|
83
|
+
filterValues: 'f32'
|
|
84
|
+
},
|
|
85
|
+
glsl: {
|
|
86
|
+
injections: [
|
|
87
|
+
{
|
|
88
|
+
target: 'vs:FILTER_POSITION',
|
|
89
|
+
injection: `\
|
|
90
|
+
if (!filter_isVisible(filterValues)) {
|
|
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: `\
|
|
101
|
+
if (!filter_isVisible(filterValues)) {
|
|
102
|
+
*position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
|
|
103
|
+
}`
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
};
|