@luma.gl/shaders 10.0.0-alpha.10 → 10.0.0-alpha.11
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 +1776 -58
- package/dist/dist.min.js +1394 -147
- package/dist/index.cjs +35 -0
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -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/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/package.json +3 -3
- package/src/index.ts +48 -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/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
|
@@ -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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/shaders",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.11",
|
|
4
4
|
"description": "Shader module system for luma.gl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@math.gl/core": "~5.0.0-beta.
|
|
64
|
+
"@math.gl/core": "~5.0.0-beta.5"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "abf0b44182fb51a73368e71f1166ca1cf4de63d6"
|
|
67
67
|
}
|
package/src/index.ts
CHANGED
|
@@ -168,6 +168,7 @@ export {lighting} from './modules/lighting/lights/lighting';
|
|
|
168
168
|
export type {IBLBindings} from './modules/lighting/ibl/ibl';
|
|
169
169
|
export {ibl} from './modules/lighting/ibl/ibl';
|
|
170
170
|
export {dirlight} from './modules/lighting/no-material/dirlight';
|
|
171
|
+
export {unlitMaterial} from './modules/lighting/unlit-material/unlit-material';
|
|
171
172
|
export type {LambertMaterialProps} from './modules/lighting/lambert-material/lambert-material';
|
|
172
173
|
export {lambertMaterial} from './modules/lighting/lambert-material/lambert-material';
|
|
173
174
|
export type {GouraudMaterialProps} from './modules/lighting/gouraud-material/gouraud-material';
|
|
@@ -257,3 +258,50 @@ export {
|
|
|
257
258
|
type AreaLight,
|
|
258
259
|
type AreaLightingProps
|
|
259
260
|
} from './modules/lighting/area-lighting/area-lighting';
|
|
261
|
+
|
|
262
|
+
export {
|
|
263
|
+
pbrEnvironmentFilter,
|
|
264
|
+
PBR_ENVIRONMENT_FRAGMENT_GLSL,
|
|
265
|
+
PBR_ENVIRONMENT_FRAGMENT_WGSL
|
|
266
|
+
} from './modules/lighting/prefiltered-environment/prefiltered-environment';
|
|
267
|
+
export type {
|
|
268
|
+
PBREnvironmentFilterProps,
|
|
269
|
+
PBREnvironmentFilterUniforms,
|
|
270
|
+
PBREnvironmentFilterBindings
|
|
271
|
+
} from './modules/lighting/prefiltered-environment/prefiltered-environment';
|
|
272
|
+
|
|
273
|
+
export {shadow} from './modules/lighting/shadow/shadow';
|
|
274
|
+
export type {ShadowBindings, ShadowUniforms} from './modules/lighting/shadow/shadow';
|
|
275
|
+
export type {
|
|
276
|
+
DirectionalShadowLight,
|
|
277
|
+
SpotShadowLight,
|
|
278
|
+
PointShadowLight,
|
|
279
|
+
ShadowProps,
|
|
280
|
+
ShadowTexture,
|
|
281
|
+
ShadowBiasProps
|
|
282
|
+
} from './modules/lighting/shadow/shadow-types';
|
|
283
|
+
|
|
284
|
+
export {pbrShadow} from './modules/lighting/pbr-shadow/pbr-shadow';
|
|
285
|
+
export type {PBRShadowProps, PBRShadowUniforms} from './modules/lighting/pbr-shadow/pbr-shadow';
|
|
286
|
+
|
|
287
|
+
export {pbrSurface} from './modules/lighting/pbr-surface/pbr-surface';
|
|
288
|
+
export type {PBRSurfaceProps, PBRSurfaceUniforms} from './modules/lighting/pbr-surface/pbr-surface';
|
|
289
|
+
|
|
290
|
+
export {
|
|
291
|
+
contactShadowTrace,
|
|
292
|
+
contactShadowBilateralBlur,
|
|
293
|
+
contactShadowComposite
|
|
294
|
+
} from './modules/lighting/contact-shadow/contact-shadow';
|
|
295
|
+
export type {
|
|
296
|
+
ContactTraceUniforms,
|
|
297
|
+
ContactBlurUniforms,
|
|
298
|
+
ContactShadowBindings,
|
|
299
|
+
ContactShadowProps
|
|
300
|
+
} from './modules/lighting/contact-shadow/contact-shadow';
|
|
301
|
+
|
|
302
|
+
export {pbrContactShadow} from './modules/lighting/pbr-contact-shadow/pbr-contact-shadow';
|
|
303
|
+
export type {PBRContactShadowProps} from './modules/lighting/pbr-contact-shadow/pbr-contact-shadow';
|
|
304
|
+
|
|
305
|
+
export {clusteredLightGrid} from './modules/lighting/clustered-light-grid/clustered-light-grid';
|
|
306
|
+
export {pbrAmbientOcclusion} from './modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion';
|
|
307
|
+
export type {PBRAmbientOcclusionProps} from './modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
|
|
3
|
+
|
|
4
|
+
import type {ShaderModule} from '../../../lib/shader-module/shader-module';
|
|
5
|
+
|
|
6
|
+
/** Renderer-independent lookup for top-left normalized screen coordinates and positive view depth. */
|
|
7
|
+
export const clusteredLightGrid = {
|
|
8
|
+
name: 'clusteredLightGrid',
|
|
9
|
+
source: /* wgsl */ `
|
|
10
|
+
fn clusteredLightGrid_getIndex(coordinates: vec2f, viewDepth: f32, dimensions: vec3u, nearPlane: f32, farPlane: f32) -> u32 {
|
|
11
|
+
let tile = min(vec2u(clamp(coordinates, vec2f(0.0), vec2f(0.999999)) * vec2f(dimensions.xy)), dimensions.xy - vec2u(1));
|
|
12
|
+
let normalizedDepth = clamp(log(clamp(viewDepth, nearPlane, farPlane) / nearPlane) / log(farPlane / nearPlane), 0.0, 0.999999);
|
|
13
|
+
let depthSlice = min(u32(normalizedDepth * f32(dimensions.z)), dimensions.z - 1u);
|
|
14
|
+
return (depthSlice * dimensions.y + tile.y) * dimensions.x + tile.x;
|
|
15
|
+
}
|
|
16
|
+
`
|
|
17
|
+
} as const satisfies ShaderModule;
|