@luma.gl/shaders 10.0.0-alpha.10 → 10.0.0-alpha.12
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 +1923 -60
- package/dist/dist.min.js +1499 -148
- package/dist/glsl.cjs.map +1 -1
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.cjs +40 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts +6 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts.map +1 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js +15 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js.map +1 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.cjs +348 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts +188 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.js +307 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.js.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.cjs +93 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.d.ts +35 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.d.ts.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.js +71 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.js.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap.cjs +89 -0
- package/dist/modules/lighting/lightmap/lightmap.d.ts +405 -0
- package/dist/modules/lighting/lightmap/lightmap.d.ts.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap.js +67 -0
- package/dist/modules/lighting/lightmap/lightmap.js.map +1 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.cjs +87 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts +21 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js +61 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js.map +1 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.cjs +87 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts +21 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js +61 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js.map +1 -0
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.cjs +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.cjs +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +3 -3
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.cjs +97 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts +15 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.js +69 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.js.map +1 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.cjs +114 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts +15 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.js +88 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.js.map +1 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.cjs +379 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts +41 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts.map +1 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js +345 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow-glsl.cjs +228 -0
- package/dist/modules/lighting/shadow/shadow-glsl.d.ts +3 -0
- package/dist/modules/lighting/shadow/shadow-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow-glsl.js +204 -0
- package/dist/modules/lighting/shadow/shadow-glsl.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow-types.cjs +15 -0
- package/dist/modules/lighting/shadow/shadow-types.d.ts +63 -0
- package/dist/modules/lighting/shadow/shadow-types.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow-types.js +5 -0
- package/dist/modules/lighting/shadow/shadow-types.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow.cjs +458 -0
- package/dist/modules/lighting/shadow/shadow.d.ts +117 -0
- package/dist/modules/lighting/shadow/shadow.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow.js +450 -0
- package/dist/modules/lighting/shadow/shadow.js.map +1 -0
- package/dist/modules/lighting/unlit-material/unlit-material.cjs +60 -0
- package/dist/modules/lighting/unlit-material/unlit-material.d.ts +9 -0
- package/dist/modules/lighting/unlit-material/unlit-material.d.ts.map +1 -0
- package/dist/modules/lighting/unlit-material/unlit-material.js +40 -0
- package/dist/modules/lighting/unlit-material/unlit-material.js.map +1 -0
- package/dist/types/shader-type-decoder.cjs +12 -2
- package/dist/types/shader-type-decoder.d.ts +7 -7
- package/dist/types/shader-type-decoder.d.ts.map +1 -1
- package/dist/types/shader-type-decoder.js +13 -2
- package/dist/types/shader-type-decoder.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/wgsl.cjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +52 -0
- package/src/modules/lighting/clustered-light-grid/clustered-light-grid.ts +17 -0
- package/src/modules/lighting/contact-shadow/contact-shadow.ts +365 -0
- package/src/modules/lighting/lightmap/lightmap-filter.ts +73 -0
- package/src/modules/lighting/lightmap/lightmap.ts +76 -0
- package/src/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.ts +78 -0
- package/src/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.ts +78 -0
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +33 -11
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +33 -11
- package/src/modules/lighting/pbr-shadow/pbr-shadow.ts +85 -0
- package/src/modules/lighting/pbr-surface/pbr-surface.ts +103 -0
- package/src/modules/lighting/prefiltered-environment/prefiltered-environment.ts +370 -0
- package/src/modules/lighting/shadow/shadow-glsl.ts +204 -0
- package/src/modules/lighting/shadow/shadow-types.ts +68 -0
- package/src/modules/lighting/shadow/shadow.ts +536 -0
- package/src/modules/lighting/unlit-material/unlit-material.ts +44 -0
- package/src/types/shader-type-decoder.ts +22 -9
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
|
|
4
|
+
import { SHADOW_GLSL } from "./shadow-glsl.js";
|
|
5
|
+
const MAX_CASCADES = 4;
|
|
6
|
+
const MAX_SPOT_LIGHTS = 4;
|
|
7
|
+
const MAX_POINT_LIGHTS = 4;
|
|
8
|
+
const MAX_POINT_MATRICES = 24;
|
|
9
|
+
const DIRECTIONAL_LIGHT_UNIFORM_TYPE = {
|
|
10
|
+
direction: 'vec3<f32>',
|
|
11
|
+
strength: 'f32',
|
|
12
|
+
normalBias: 'f32',
|
|
13
|
+
sourceAngularRadius: 'f32',
|
|
14
|
+
cascadeBlendFraction: 'f32',
|
|
15
|
+
farFadeFraction: 'f32',
|
|
16
|
+
shadowDistance: 'f32'
|
|
17
|
+
};
|
|
18
|
+
const SPOT_LIGHT_UNIFORM_TYPE = {
|
|
19
|
+
position: 'vec3<f32>',
|
|
20
|
+
range: 'f32',
|
|
21
|
+
direction: 'vec3<f32>',
|
|
22
|
+
outerConeCos: 'f32',
|
|
23
|
+
sourceRadius: 'f32',
|
|
24
|
+
normalBias: 'f32',
|
|
25
|
+
strength: 'f32',
|
|
26
|
+
nearPlane: 'f32'
|
|
27
|
+
};
|
|
28
|
+
const POINT_LIGHT_UNIFORM_TYPE = {
|
|
29
|
+
position: 'vec3<f32>',
|
|
30
|
+
range: 'f32',
|
|
31
|
+
sourceRadius: 'f32',
|
|
32
|
+
normalBias: 'f32',
|
|
33
|
+
strength: 'f32',
|
|
34
|
+
nearPlane: 'f32'
|
|
35
|
+
};
|
|
36
|
+
const SHADOW_WGSL = /* wgsl */ `\
|
|
37
|
+
const SHADOW_PI: f32 = 3.141592653589793;
|
|
38
|
+
|
|
39
|
+
struct DirectionalShadowLightUniform {
|
|
40
|
+
direction: vec3f,
|
|
41
|
+
strength: f32,
|
|
42
|
+
normalBias: f32,
|
|
43
|
+
sourceAngularRadius: f32,
|
|
44
|
+
cascadeBlendFraction: f32,
|
|
45
|
+
farFadeFraction: f32,
|
|
46
|
+
shadowDistance: f32,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
struct SpotShadowLightUniform {
|
|
50
|
+
position: vec3f,
|
|
51
|
+
range: f32,
|
|
52
|
+
direction: vec3f,
|
|
53
|
+
outerConeCos: f32,
|
|
54
|
+
sourceRadius: f32,
|
|
55
|
+
normalBias: f32,
|
|
56
|
+
strength: f32,
|
|
57
|
+
nearPlane: f32,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
struct PointShadowLightUniform {
|
|
61
|
+
position: vec3f,
|
|
62
|
+
range: f32,
|
|
63
|
+
sourceRadius: f32,
|
|
64
|
+
normalBias: f32,
|
|
65
|
+
strength: f32,
|
|
66
|
+
nearPlane: f32,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
struct ShadowUniforms {
|
|
70
|
+
directionalLightCount: i32,
|
|
71
|
+
spotLightCount: i32,
|
|
72
|
+
pointLightCount: i32,
|
|
73
|
+
cascadeCount: i32,
|
|
74
|
+
blockerSampleCount: i32,
|
|
75
|
+
filterSampleCount: i32,
|
|
76
|
+
cascadeSplits: vec4f,
|
|
77
|
+
directionalViewProjectionMatrices: array<mat4x4f, 4>,
|
|
78
|
+
spotViewProjectionMatrices: array<mat4x4f, 4>,
|
|
79
|
+
pointViewProjectionMatrices: array<mat4x4f, 24>,
|
|
80
|
+
directionalLights: array<DirectionalShadowLightUniform, 1>,
|
|
81
|
+
spotLights: array<SpotShadowLightUniform, 4>,
|
|
82
|
+
pointLights: array<PointShadowLightUniform, 4>,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
@group(2) @binding(auto) var<uniform> shadow: ShadowUniforms;
|
|
86
|
+
@group(2) @binding(auto) var directionalShadowTexture: texture_depth_2d_array;
|
|
87
|
+
@group(2) @binding(auto) var spotShadowTexture: texture_depth_2d_array;
|
|
88
|
+
@group(2) @binding(auto) var pointShadowTexture: texture_depth_cube_array;
|
|
89
|
+
@group(2) @binding(auto) var directionalShadowTextureSampler: sampler;
|
|
90
|
+
@group(2) @binding(auto) var shadowComparisonSampler: sampler_comparison;
|
|
91
|
+
|
|
92
|
+
fn shadow_hash(position: vec3f) -> f32 {
|
|
93
|
+
return fract(sin(dot(position, vec3f(12.9898, 78.233, 37.719))) * 43758.5453);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fn shadow_diskSample(index: i32, count: i32, rotation: f32) -> vec2f {
|
|
97
|
+
let fraction = (f32(index) + 0.5) / max(f32(count), 1.0);
|
|
98
|
+
let angle = f32(index) * 2.39996323 + rotation;
|
|
99
|
+
return sqrt(fraction) * vec2f(cos(angle), sin(angle));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fn shadow_project(matrix: mat4x4f, worldPosition: vec3f) -> vec3f {
|
|
103
|
+
let clip = matrix * vec4f(worldPosition, 1.0);
|
|
104
|
+
let ndc = clip.xyz / max(abs(clip.w), 0.00001);
|
|
105
|
+
return vec3f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5, ndc.z);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
fn shadow_validProjection(projected: vec3f) -> bool {
|
|
109
|
+
return all(projected.xy >= vec2f(0.0)) && all(projected.xy <= vec2f(1.0)) &&
|
|
110
|
+
projected.z >= 0.0 && projected.z <= 1.0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fn shadow_directionalCascadeIndex(viewDepth: f32) -> i32 {
|
|
114
|
+
var cascadeIndex = 0;
|
|
115
|
+
for (var index: i32 = 0; index < 4; index++) {
|
|
116
|
+
if (index >= shadow.cascadeCount) { break; }
|
|
117
|
+
cascadeIndex = index;
|
|
118
|
+
if (viewDepth <= shadow.cascadeSplits[index]) { break; }
|
|
119
|
+
}
|
|
120
|
+
return cascadeIndex;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fn shadow_getDirectionalCascadeIndex(viewDepth: f32) -> i32 {
|
|
124
|
+
if (shadow.directionalLightCount == 0) { return -1; }
|
|
125
|
+
return shadow_directionalCascadeIndex(viewDepth);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fn shadow_directionalPCSS(cascadeIndex: i32, worldPosition: vec3f, viewDepth: f32) -> f32 {
|
|
129
|
+
let projected = shadow_project(shadow.directionalViewProjectionMatrices[cascadeIndex], worldPosition);
|
|
130
|
+
if (!shadow_validProjection(projected)) { return 1.0; }
|
|
131
|
+
let dimensions = vec2f(textureDimensions(directionalShadowTexture));
|
|
132
|
+
let texel = 1.0 / dimensions;
|
|
133
|
+
let light = shadow.directionalLights[0];
|
|
134
|
+
let rotation = shadow_hash(worldPosition) * 2.0 * SHADOW_PI;
|
|
135
|
+
let searchRadius = max(texel.x, light.sourceAngularRadius * viewDepth / max(light.shadowDistance, 0.001));
|
|
136
|
+
var blockerDepth = 0.0;
|
|
137
|
+
var blockerCount = 0.0;
|
|
138
|
+
for (var index: i32 = 0; index < 24; index++) {
|
|
139
|
+
if (index >= shadow.blockerSampleCount) { break; }
|
|
140
|
+
let offset = shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius;
|
|
141
|
+
let sampleDepth = textureSampleLevel(
|
|
142
|
+
directionalShadowTexture,
|
|
143
|
+
directionalShadowTextureSampler,
|
|
144
|
+
clamp(projected.xy + offset, vec2f(0.0), vec2f(1.0)),
|
|
145
|
+
cascadeIndex,
|
|
146
|
+
0
|
|
147
|
+
);
|
|
148
|
+
if (sampleDepth < projected.z) {
|
|
149
|
+
blockerDepth += sampleDepth;
|
|
150
|
+
blockerCount += 1.0;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (blockerCount == 0.0) { return 1.0; }
|
|
154
|
+
let averageBlocker = blockerDepth / blockerCount;
|
|
155
|
+
let penumbra = clamp((projected.z - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);
|
|
156
|
+
let filterRadius = max(texel.x, searchRadius * (1.0 + penumbra * 18.0));
|
|
157
|
+
var visibility = 0.0;
|
|
158
|
+
for (var index: i32 = 0; index < 48; index++) {
|
|
159
|
+
if (index >= shadow.filterSampleCount) { break; }
|
|
160
|
+
let offset = shadow_diskSample(index, shadow.filterSampleCount, rotation) * filterRadius;
|
|
161
|
+
visibility += textureSampleCompareLevel(
|
|
162
|
+
directionalShadowTexture,
|
|
163
|
+
shadowComparisonSampler,
|
|
164
|
+
clamp(projected.xy + offset, vec2f(0.0), vec2f(1.0)),
|
|
165
|
+
cascadeIndex,
|
|
166
|
+
projected.z
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return visibility / max(f32(shadow.filterSampleCount), 1.0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fn shadow_getDirectionalFactor(worldPosition: vec3f, worldNormal: vec3f, viewDepth: f32) -> f32 {
|
|
173
|
+
if (shadow.directionalLightCount == 0 || viewDepth <= 0.0) { return 1.0; }
|
|
174
|
+
let light = shadow.directionalLights[0];
|
|
175
|
+
if (viewDepth >= light.shadowDistance) { return 1.0; }
|
|
176
|
+
let biasedPosition = worldPosition + normalize(worldNormal) * light.normalBias;
|
|
177
|
+
let cascadeIndex = shadow_directionalCascadeIndex(viewDepth);
|
|
178
|
+
var visibility = shadow_directionalPCSS(cascadeIndex, biasedPosition, viewDepth);
|
|
179
|
+
if (cascadeIndex + 1 < shadow.cascadeCount) {
|
|
180
|
+
var cascadeStart = 0.0;
|
|
181
|
+
if (cascadeIndex > 0) { cascadeStart = shadow.cascadeSplits[cascadeIndex - 1]; }
|
|
182
|
+
let cascadeEnd = shadow.cascadeSplits[cascadeIndex];
|
|
183
|
+
let blendWidth = max((cascadeEnd - cascadeStart) * light.cascadeBlendFraction, 0.0001);
|
|
184
|
+
let blend = smoothstep(cascadeEnd - blendWidth, cascadeEnd, viewDepth);
|
|
185
|
+
if (blend > 0.0) {
|
|
186
|
+
visibility = mix(
|
|
187
|
+
visibility,
|
|
188
|
+
shadow_directionalPCSS(cascadeIndex + 1, biasedPosition, viewDepth),
|
|
189
|
+
blend
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
let fadeWidth = max(light.shadowDistance * light.farFadeFraction, 0.0001);
|
|
194
|
+
let farFade = smoothstep(light.shadowDistance - fadeWidth, light.shadowDistance, viewDepth);
|
|
195
|
+
visibility = mix(visibility, 1.0, farFade);
|
|
196
|
+
return mix(1.0, visibility, light.strength);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
fn shadow_spotPCSS(lightIndex: i32, worldPosition: vec3f) -> f32 {
|
|
200
|
+
let projected = shadow_project(shadow.spotViewProjectionMatrices[lightIndex], worldPosition);
|
|
201
|
+
if (!shadow_validProjection(projected)) { return 1.0; }
|
|
202
|
+
let light = shadow.spotLights[lightIndex];
|
|
203
|
+
let dimensions = vec2f(textureDimensions(spotShadowTexture));
|
|
204
|
+
let texel = 1.0 / dimensions;
|
|
205
|
+
let distanceToLight = length(worldPosition - light.position);
|
|
206
|
+
let searchRadius = max(texel.x, light.sourceRadius / max(distanceToLight, 0.001) * 0.5);
|
|
207
|
+
let rotation = shadow_hash(worldPosition) * 2.0 * SHADOW_PI;
|
|
208
|
+
var blockerDepth = 0.0;
|
|
209
|
+
var blockerCount = 0.0;
|
|
210
|
+
for (var index: i32 = 0; index < 24; index++) {
|
|
211
|
+
if (index >= shadow.blockerSampleCount) { break; }
|
|
212
|
+
let offset = shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius;
|
|
213
|
+
let sampleDepth = textureSampleLevel(
|
|
214
|
+
spotShadowTexture,
|
|
215
|
+
directionalShadowTextureSampler,
|
|
216
|
+
clamp(projected.xy + offset, vec2f(0.0), vec2f(1.0)),
|
|
217
|
+
lightIndex,
|
|
218
|
+
0
|
|
219
|
+
);
|
|
220
|
+
if (sampleDepth < projected.z) { blockerDepth += sampleDepth; blockerCount += 1.0; }
|
|
221
|
+
}
|
|
222
|
+
if (blockerCount == 0.0) { return 1.0; }
|
|
223
|
+
let averageBlocker = blockerDepth / blockerCount;
|
|
224
|
+
let penumbra = clamp((projected.z - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);
|
|
225
|
+
let filterRadius = max(texel.x, searchRadius * (1.0 + penumbra * 16.0));
|
|
226
|
+
var visibility = 0.0;
|
|
227
|
+
for (var index: i32 = 0; index < 48; index++) {
|
|
228
|
+
if (index >= shadow.filterSampleCount) { break; }
|
|
229
|
+
let offset = shadow_diskSample(index, shadow.filterSampleCount, rotation) * filterRadius;
|
|
230
|
+
visibility += textureSampleCompareLevel(
|
|
231
|
+
spotShadowTexture,
|
|
232
|
+
shadowComparisonSampler,
|
|
233
|
+
clamp(projected.xy + offset, vec2f(0.0), vec2f(1.0)),
|
|
234
|
+
lightIndex,
|
|
235
|
+
projected.z
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return visibility / max(f32(shadow.filterSampleCount), 1.0);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
fn shadow_getSpotFactor(lightIndex: i32, worldPosition: vec3f, worldNormal: vec3f) -> f32 {
|
|
242
|
+
if (lightIndex < 0 || lightIndex >= shadow.spotLightCount) { return 1.0; }
|
|
243
|
+
let light = shadow.spotLights[lightIndex];
|
|
244
|
+
let fromLight = worldPosition - light.position;
|
|
245
|
+
let distanceToLight = length(fromLight);
|
|
246
|
+
let coneCos = dot(normalize(fromLight), normalize(light.direction));
|
|
247
|
+
if (distanceToLight >= light.range || coneCos < light.outerConeCos) { return 1.0; }
|
|
248
|
+
let biasedPosition = worldPosition + normalize(worldNormal) * light.normalBias;
|
|
249
|
+
return mix(1.0, shadow_spotPCSS(lightIndex, biasedPosition), light.strength);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
fn shadow_pointReferenceDepth(majorDistance: f32, nearPlane: f32, farPlane: f32) -> f32 {
|
|
253
|
+
// Match the cube-face projection and stored WebGPU depth in [0, 1].
|
|
254
|
+
return farPlane / (farPlane - nearPlane) -
|
|
255
|
+
(farPlane * nearPlane) / ((farPlane - nearPlane) * majorDistance);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
fn shadow_pointBasis(direction: vec3f) -> mat2x3f {
|
|
259
|
+
let reference = select(vec3f(0.0, 1.0, 0.0), vec3f(0.0, 0.0, 1.0), abs(direction.y) > 0.99);
|
|
260
|
+
let tangent = normalize(cross(direction, reference));
|
|
261
|
+
return mat2x3f(tangent, normalize(cross(direction, tangent)));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
fn shadow_getPointFactor(lightIndex: i32, worldPosition: vec3f, worldNormal: vec3f) -> f32 {
|
|
265
|
+
if (lightIndex < 0 || lightIndex >= shadow.pointLightCount) { return 1.0; }
|
|
266
|
+
let light = shadow.pointLights[lightIndex];
|
|
267
|
+
let biasedPosition = worldPosition + normalize(worldNormal) * light.normalBias;
|
|
268
|
+
let fromLight = biasedPosition - light.position;
|
|
269
|
+
let distanceToLight = length(fromLight);
|
|
270
|
+
if (distanceToLight >= light.range || distanceToLight <= light.nearPlane) { return 1.0; }
|
|
271
|
+
let direction = normalize(fromLight);
|
|
272
|
+
let majorDistance = max(max(abs(fromLight.x), abs(fromLight.y)), abs(fromLight.z));
|
|
273
|
+
let referenceDepth = shadow_pointReferenceDepth(majorDistance, light.nearPlane, light.range);
|
|
274
|
+
let searchRadius = light.sourceRadius / max(distanceToLight, 0.001);
|
|
275
|
+
let rotation = shadow_hash(worldPosition) * 2.0 * SHADOW_PI;
|
|
276
|
+
let basis = shadow_pointBasis(direction);
|
|
277
|
+
var blockerDepth = 0.0;
|
|
278
|
+
var blockerCount = 0.0;
|
|
279
|
+
for (var index: i32 = 0; index < 24; index++) {
|
|
280
|
+
if (index >= shadow.blockerSampleCount) { break; }
|
|
281
|
+
let disk = shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius;
|
|
282
|
+
let sampleDirection = normalize(direction + basis[0] * disk.x + basis[1] * disk.y);
|
|
283
|
+
let sampleDepth = textureSampleLevel(
|
|
284
|
+
pointShadowTexture,
|
|
285
|
+
directionalShadowTextureSampler,
|
|
286
|
+
sampleDirection,
|
|
287
|
+
lightIndex,
|
|
288
|
+
0
|
|
289
|
+
);
|
|
290
|
+
if (sampleDepth < referenceDepth) { blockerDepth += sampleDepth; blockerCount += 1.0; }
|
|
291
|
+
}
|
|
292
|
+
if (blockerCount == 0.0) { return 1.0; }
|
|
293
|
+
let averageBlocker = blockerDepth / blockerCount;
|
|
294
|
+
let penumbra = clamp((referenceDepth - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);
|
|
295
|
+
let filterRadius = searchRadius * (1.0 + penumbra * 12.0);
|
|
296
|
+
var visibility = 0.0;
|
|
297
|
+
for (var index: i32 = 0; index < 48; index++) {
|
|
298
|
+
if (index >= shadow.filterSampleCount) { break; }
|
|
299
|
+
let disk = shadow_diskSample(index, shadow.filterSampleCount, rotation) * filterRadius;
|
|
300
|
+
let sampleDirection = normalize(direction + basis[0] * disk.x + basis[1] * disk.y);
|
|
301
|
+
visibility += textureSampleCompareLevel(
|
|
302
|
+
pointShadowTexture,
|
|
303
|
+
shadowComparisonSampler,
|
|
304
|
+
sampleDirection,
|
|
305
|
+
lightIndex,
|
|
306
|
+
referenceDepth
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
visibility /= max(f32(shadow.filterSampleCount), 1.0);
|
|
310
|
+
return mix(1.0, visibility, light.strength);
|
|
311
|
+
}
|
|
312
|
+
`;
|
|
313
|
+
/** Backend-aware shadow sampling module. Applications explicitly apply factors to direct-light terms. */
|
|
314
|
+
export const shadow = {
|
|
315
|
+
name: 'shadow',
|
|
316
|
+
source: SHADOW_WGSL,
|
|
317
|
+
fs: SHADOW_GLSL,
|
|
318
|
+
props: {},
|
|
319
|
+
uniforms: {},
|
|
320
|
+
bindings: {},
|
|
321
|
+
uniformTypes: {
|
|
322
|
+
directionalLightCount: 'i32',
|
|
323
|
+
spotLightCount: 'i32',
|
|
324
|
+
pointLightCount: 'i32',
|
|
325
|
+
cascadeCount: 'i32',
|
|
326
|
+
blockerSampleCount: 'i32',
|
|
327
|
+
filterSampleCount: 'i32',
|
|
328
|
+
cascadeSplits: 'vec4<f32>',
|
|
329
|
+
directionalViewProjectionMatrices: ['mat4x4<f32>', MAX_CASCADES],
|
|
330
|
+
spotViewProjectionMatrices: ['mat4x4<f32>', MAX_SPOT_LIGHTS],
|
|
331
|
+
pointViewProjectionMatrices: ['mat4x4<f32>', MAX_POINT_MATRICES],
|
|
332
|
+
directionalLights: [DIRECTIONAL_LIGHT_UNIFORM_TYPE, 1],
|
|
333
|
+
spotLights: [SPOT_LIGHT_UNIFORM_TYPE, MAX_SPOT_LIGHTS],
|
|
334
|
+
pointLights: [POINT_LIGHT_UNIFORM_TYPE, MAX_POINT_LIGHTS]
|
|
335
|
+
},
|
|
336
|
+
bindingLayout: [
|
|
337
|
+
{ name: 'shadow', group: 2 },
|
|
338
|
+
{ name: 'directionalShadowTexture', group: 2 },
|
|
339
|
+
{ name: 'spotShadowTexture', group: 2 },
|
|
340
|
+
{ name: 'pointShadowTexture', group: 2 },
|
|
341
|
+
{ name: 'shadowComparisonSampler', group: 2 }
|
|
342
|
+
],
|
|
343
|
+
getUniforms(props) {
|
|
344
|
+
if (!props.directionalLights ||
|
|
345
|
+
!props.spotLights ||
|
|
346
|
+
!props.pointLights ||
|
|
347
|
+
!props.cascadeSplits ||
|
|
348
|
+
!props.directionalViewProjectionMatrices ||
|
|
349
|
+
!props.spotViewProjectionMatrices ||
|
|
350
|
+
!props.pointViewProjectionMatrices ||
|
|
351
|
+
!props.directionalShadowTexture ||
|
|
352
|
+
!props.spotShadowTexture ||
|
|
353
|
+
!props.pointShadowTexture ||
|
|
354
|
+
!props.nonFilteringSampler ||
|
|
355
|
+
!props.comparisonSampler) {
|
|
356
|
+
return {};
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
directionalLightCount: props.directionalLights.length,
|
|
360
|
+
spotLightCount: props.spotLights.length,
|
|
361
|
+
pointLightCount: props.pointLights.length,
|
|
362
|
+
cascadeCount: props.cascadeCount,
|
|
363
|
+
blockerSampleCount: props.blockerSampleCount,
|
|
364
|
+
filterSampleCount: props.filterSampleCount,
|
|
365
|
+
cascadeSplits: props.cascadeSplits,
|
|
366
|
+
directionalViewProjectionMatrices: props.directionalViewProjectionMatrices,
|
|
367
|
+
spotViewProjectionMatrices: props.spotViewProjectionMatrices,
|
|
368
|
+
pointViewProjectionMatrices: props.pointViewProjectionMatrices,
|
|
369
|
+
directionalLights: padDirectionalLights(props.directionalLights),
|
|
370
|
+
spotLights: padSpotLights(props.spotLights),
|
|
371
|
+
pointLights: padPointLights(props.pointLights),
|
|
372
|
+
directionalShadowTexture: props.directionalShadowTexture,
|
|
373
|
+
spotShadowTexture: props.spotShadowTexture,
|
|
374
|
+
pointShadowTexture: props.pointShadowTexture,
|
|
375
|
+
...(props.directionalShadowTexture.device.type === 'webgpu'
|
|
376
|
+
? { shadowComparisonSampler: props.comparisonSampler }
|
|
377
|
+
: {})
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
function padDirectionalLights(lights) {
|
|
382
|
+
const light = lights[0];
|
|
383
|
+
return [
|
|
384
|
+
light
|
|
385
|
+
? {
|
|
386
|
+
direction: light.direction,
|
|
387
|
+
strength: light.strength ?? 1,
|
|
388
|
+
normalBias: light.normalBias ?? 0.04,
|
|
389
|
+
sourceAngularRadius: light.sourceAngularRadius ?? 0.00465,
|
|
390
|
+
cascadeBlendFraction: light.cascadeBlendFraction ?? 0.1,
|
|
391
|
+
farFadeFraction: light.farFadeFraction ?? 0.1,
|
|
392
|
+
shadowDistance: light.shadowDistance ?? 1
|
|
393
|
+
}
|
|
394
|
+
: {
|
|
395
|
+
direction: [0, 1, 0],
|
|
396
|
+
strength: 0,
|
|
397
|
+
normalBias: 0,
|
|
398
|
+
sourceAngularRadius: 0,
|
|
399
|
+
cascadeBlendFraction: 0,
|
|
400
|
+
farFadeFraction: 0,
|
|
401
|
+
shadowDistance: 1
|
|
402
|
+
}
|
|
403
|
+
];
|
|
404
|
+
}
|
|
405
|
+
function padSpotLights(lights) {
|
|
406
|
+
return padArray(lights.map(light => ({
|
|
407
|
+
position: light.position,
|
|
408
|
+
range: light.range,
|
|
409
|
+
direction: light.direction,
|
|
410
|
+
outerConeCos: Math.cos(light.outerConeAngle),
|
|
411
|
+
sourceRadius: light.sourceRadius ?? 0.2,
|
|
412
|
+
normalBias: light.normalBias ?? 0.025,
|
|
413
|
+
strength: light.strength ?? 1,
|
|
414
|
+
nearPlane: light.nearPlane ?? 0.1
|
|
415
|
+
})), MAX_SPOT_LIGHTS, {
|
|
416
|
+
position: [0, 0, 0],
|
|
417
|
+
range: 1,
|
|
418
|
+
direction: [0, -1, 0],
|
|
419
|
+
outerConeCos: 1,
|
|
420
|
+
sourceRadius: 0,
|
|
421
|
+
normalBias: 0,
|
|
422
|
+
strength: 0,
|
|
423
|
+
nearPlane: 0.1
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
function padPointLights(lights) {
|
|
427
|
+
return padArray(lights.map(light => ({
|
|
428
|
+
position: light.position,
|
|
429
|
+
range: light.range,
|
|
430
|
+
sourceRadius: light.sourceRadius ?? 0.2,
|
|
431
|
+
normalBias: light.normalBias ?? 0.025,
|
|
432
|
+
strength: light.strength ?? 1,
|
|
433
|
+
nearPlane: light.nearPlane ?? 0.1
|
|
434
|
+
})), MAX_POINT_LIGHTS, {
|
|
435
|
+
position: [0, 0, 0],
|
|
436
|
+
range: 1,
|
|
437
|
+
sourceRadius: 0,
|
|
438
|
+
normalBias: 0,
|
|
439
|
+
strength: 0,
|
|
440
|
+
nearPlane: 0.1
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function padArray(values, length, fallback) {
|
|
444
|
+
const result = values.slice(0, length);
|
|
445
|
+
while (result.length < length) {
|
|
446
|
+
result.push(fallback);
|
|
447
|
+
}
|
|
448
|
+
return result;
|
|
449
|
+
}
|
|
450
|
+
//# sourceMappingURL=shadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow.js","sourceRoot":"","sources":["../../../../src/modules/lighting/shadow/shadow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var unlit_material_exports = {};
|
|
19
|
+
__export(unlit_material_exports, {
|
|
20
|
+
unlitMaterial: () => unlitMaterial
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(unlit_material_exports);
|
|
23
|
+
const SOURCE_WGSL = (
|
|
24
|
+
/* wgsl */
|
|
25
|
+
`fn unlitMaterial_getColor(surfaceColor: vec4<f32>) -> vec4<f32> {
|
|
26
|
+
return surfaceColor;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Compatibility with the aggregate Phong/Gouraud material evaluation function.
|
|
30
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, positionWorldspace: vec3<f32>, normalWorldspace: vec3<f32>) -> vec3<f32> {
|
|
31
|
+
return surfaceColor;
|
|
32
|
+
}
|
|
33
|
+
`
|
|
34
|
+
);
|
|
35
|
+
const SOURCE_GLSL = (
|
|
36
|
+
/* glsl */
|
|
37
|
+
`vec4 unlitMaterial_getColor(vec4 surfaceColor) {
|
|
38
|
+
return surfaceColor;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Compatibility with the aggregate Phong/Gouraud material evaluation function.
|
|
42
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positionWorldspace, vec3 normalWorldspace) {
|
|
43
|
+
return surfaceColor;
|
|
44
|
+
}
|
|
45
|
+
`
|
|
46
|
+
);
|
|
47
|
+
const unlitMaterial = {
|
|
48
|
+
name: "unlitMaterial",
|
|
49
|
+
source: SOURCE_WGSL,
|
|
50
|
+
vs: SOURCE_GLSL,
|
|
51
|
+
fs: SOURCE_GLSL,
|
|
52
|
+
dependencies: [],
|
|
53
|
+
bindingLayout: [],
|
|
54
|
+
uniformTypes: {},
|
|
55
|
+
defaultUniforms: {}
|
|
56
|
+
};
|
|
57
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
58
|
+
0 && (module.exports = {
|
|
59
|
+
unlitMaterial
|
|
60
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ShaderModule } from "../../../lib/shader-module/shader-module.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preserves surface RGBA without lighting dependencies, uniforms, or bindings.
|
|
4
|
+
* Use instead of a lit material module when lighting is never needed. The caller
|
|
5
|
+
* supplies color/texture sampling and remains responsible for output color space
|
|
6
|
+
* and alpha conventions. Available in both vertex and fragment stages.
|
|
7
|
+
*/
|
|
8
|
+
export declare const unlitMaterial: ShaderModule<Record<string, never>>;
|
|
9
|
+
//# sourceMappingURL=unlit-material.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-material.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/unlit-material/unlit-material.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAC,oDAAiD;AAwB3E;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAS7D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
|
|
4
|
+
const SOURCE_WGSL = /* wgsl */ `\
|
|
5
|
+
fn unlitMaterial_getColor(surfaceColor: vec4<f32>) -> vec4<f32> {
|
|
6
|
+
return surfaceColor;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Compatibility with the aggregate Phong/Gouraud material evaluation function.
|
|
10
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, positionWorldspace: vec3<f32>, normalWorldspace: vec3<f32>) -> vec3<f32> {
|
|
11
|
+
return surfaceColor;
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
const SOURCE_GLSL = /* glsl */ `\
|
|
15
|
+
vec4 unlitMaterial_getColor(vec4 surfaceColor) {
|
|
16
|
+
return surfaceColor;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Compatibility with the aggregate Phong/Gouraud material evaluation function.
|
|
20
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positionWorldspace, vec3 normalWorldspace) {
|
|
21
|
+
return surfaceColor;
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
/**
|
|
25
|
+
* Preserves surface RGBA without lighting dependencies, uniforms, or bindings.
|
|
26
|
+
* Use instead of a lit material module when lighting is never needed. The caller
|
|
27
|
+
* supplies color/texture sampling and remains responsible for output color space
|
|
28
|
+
* and alpha conventions. Available in both vertex and fragment stages.
|
|
29
|
+
*/
|
|
30
|
+
export const unlitMaterial = {
|
|
31
|
+
name: 'unlitMaterial',
|
|
32
|
+
source: SOURCE_WGSL,
|
|
33
|
+
vs: SOURCE_GLSL,
|
|
34
|
+
fs: SOURCE_GLSL,
|
|
35
|
+
dependencies: [],
|
|
36
|
+
bindingLayout: [],
|
|
37
|
+
uniformTypes: {},
|
|
38
|
+
defaultUniforms: {}
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=unlit-material.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-material.js","sourceRoot":"","sources":["../../../../src/modules/lighting/unlit-material/unlit-material.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,4DAA4D;AAI5D,MAAM,WAAW,GAAG,UAAU,CAAC;;;;;;;;;CAS9B,CAAC;AAEF,MAAM,WAAW,GAAG,UAAU,CAAC;;;;;;;;;CAS9B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAwC;IAChE,IAAI,EAAE,eAAe;IACrB,MAAM,EAAE,WAAW;IACnB,EAAE,EAAE,WAAW;IACf,EAAE,EAAE,WAAW;IACf,YAAY,EAAE,EAAE;IAChB,aAAa,EAAE,EAAE;IACjB,YAAY,EAAE,EAAE;IAChB,eAAe,EAAE,EAAE;CACpB,CAAC"}
|
|
@@ -36,8 +36,13 @@ function getVariableShaderTypeInfo(format) {
|
|
|
36
36
|
}
|
|
37
37
|
return decoded;
|
|
38
38
|
}
|
|
39
|
+
const attributeShaderTypeInfoCache = /* @__PURE__ */ new Map();
|
|
39
40
|
function getAttributeShaderTypeInfo(attributeType) {
|
|
40
41
|
const resolvedAttributeType = resolveAttributeShaderTypeAlias(attributeType);
|
|
42
|
+
const cached = attributeShaderTypeInfoCache.get(resolvedAttributeType);
|
|
43
|
+
if (cached) {
|
|
44
|
+
return cached;
|
|
45
|
+
}
|
|
41
46
|
const decoded = TYPE_INFO[resolvedAttributeType];
|
|
42
47
|
if (!decoded) {
|
|
43
48
|
throw new Error(`Unsupported attribute shader type: ${attributeType}`);
|
|
@@ -46,13 +51,15 @@ function getAttributeShaderTypeInfo(attributeType) {
|
|
|
46
51
|
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
47
52
|
const signed = primitiveType !== "u32";
|
|
48
53
|
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
49
|
-
|
|
54
|
+
const result = Object.freeze({
|
|
50
55
|
primitiveType,
|
|
51
56
|
components,
|
|
52
57
|
byteLength,
|
|
53
58
|
integer,
|
|
54
59
|
signed
|
|
55
|
-
};
|
|
60
|
+
});
|
|
61
|
+
attributeShaderTypeInfoCache.set(resolvedAttributeType, result);
|
|
62
|
+
return result;
|
|
56
63
|
}
|
|
57
64
|
class ShaderTypeDecoder {
|
|
58
65
|
getVariableShaderTypeInfo(format) {
|
|
@@ -161,6 +168,9 @@ const UNIFORM_FORMATS = {
|
|
|
161
168
|
"mat4x3<u32>": { type: "u32", components: 12 },
|
|
162
169
|
"mat4x4<u32>": { type: "u32", components: 16 }
|
|
163
170
|
};
|
|
171
|
+
for (const info of Object.values(UNIFORM_FORMATS)) {
|
|
172
|
+
Object.freeze(info);
|
|
173
|
+
}
|
|
164
174
|
const WGSL_ATTRIBUTE_TYPE_ALIAS_MAP = {
|
|
165
175
|
vec2i: "vec2<i32>",
|
|
166
176
|
vec3i: "vec3<i32>",
|
|
@@ -2,21 +2,21 @@ import { type PrimitiveDataType } from "./primitive-data-types.js";
|
|
|
2
2
|
import { type VariableShaderType, type AttributeShaderType, type VariableShaderTypeAlias, type AttributeShaderTypeAlias } from "./shader-types.js";
|
|
3
3
|
/** Information extracted from a VariableShaderType constant */
|
|
4
4
|
export type VariableShaderTypeInfo = {
|
|
5
|
-
type: PrimitiveDataType;
|
|
6
|
-
components: number;
|
|
5
|
+
readonly type: PrimitiveDataType;
|
|
6
|
+
readonly components: number;
|
|
7
7
|
};
|
|
8
8
|
/** Information extracted from a AttributeShaderType constant */
|
|
9
9
|
export type AttributeShaderTypeInfo = {
|
|
10
10
|
/** WGSL-style primitive data type, f32, i32, u32 */
|
|
11
|
-
primitiveType: PrimitiveDataType;
|
|
11
|
+
readonly primitiveType: PrimitiveDataType;
|
|
12
12
|
/** Whether this is a normalized integer (that must be used as float) */
|
|
13
|
-
components: 1 | 2 | 3 | 4;
|
|
13
|
+
readonly components: 1 | 2 | 3 | 4;
|
|
14
14
|
/** Length in bytes of the data for one vertex */
|
|
15
|
-
byteLength?: number;
|
|
15
|
+
readonly byteLength?: number;
|
|
16
16
|
/** Whether this is for integer or float vert */
|
|
17
|
-
integer: boolean;
|
|
17
|
+
readonly integer: boolean;
|
|
18
18
|
/** Whether this data type is signed */
|
|
19
|
-
signed: boolean;
|
|
19
|
+
readonly signed: boolean;
|
|
20
20
|
};
|
|
21
21
|
/** Split a uniform type string into type and components */
|
|
22
22
|
export declare function getVariableShaderTypeInfo(format: VariableShaderType | VariableShaderTypeAlias): VariableShaderTypeInfo;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-type-decoder.d.ts","sourceRoot":"","sources":["../../src/types/shader-type-decoder.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,iBAAiB,EAAC,kCAA+B;AAC9D,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,0BAAuB;AAExB,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"shader-type-decoder.d.ts","sourceRoot":"","sources":["../../src/types/shader-type-decoder.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,iBAAiB,EAAC,kCAA+B;AAC9D,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,0BAAuB;AAExB,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,uBAAuB,GAAG;IACpC,oDAAoD;IACpD,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,kBAAkB,GAAG,uBAAuB,GACnD,sBAAsB,CAOxB;AAID,2FAA2F;AAC3F,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,mBAAmB,GAAG,wBAAwB,GAC5D,uBAAuB,CAwBzB;AAED,qBAAa,iBAAiB;IAC5B,yBAAyB,CACvB,MAAM,EAAE,kBAAkB,GAAG,uBAAuB,GACnD,sBAAsB;IAIzB,0BAA0B,CACxB,aAAa,EAAE,mBAAmB,GAAG,wBAAwB,GAC5D,uBAAuB;IAI1B,uBAAuB,CACrB,aAAa,EAAE,iBAAiB,EAChC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACxB,mBAAmB;IAItB,+BAA+B,CAC7B,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,GACpD,mBAAmB;IAItB,8BAA8B,CAC5B,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,GAClD,kBAAkB;CAGtB;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,iBAAiB,EAChC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACxB,mBAAmB,CAErB;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,GACpD,mBAAmB,CAErB;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,GAClD,kBAAkB,CAEpB;AAED,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,mBAA0B,CAAC;AAkGzD,yEAAyE;AACzE,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,wBAAwB,EAAE,mBAAmB,CAe7F,CAAC;AAEJ,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,uBAAuB,EAAE,kBAAkB,CAoD5F,CAAC"}
|