@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.
Files changed (89) hide show
  1. package/dist/dist.dev.js +1776 -58
  2. package/dist/dist.min.js +1394 -147
  3. package/dist/index.cjs +35 -0
  4. package/dist/index.cjs.map +3 -3
  5. package/dist/index.d.ts +17 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +9 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.cjs +40 -0
  10. package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts +6 -0
  11. package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts.map +1 -0
  12. package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js +15 -0
  13. package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js.map +1 -0
  14. package/dist/modules/lighting/contact-shadow/contact-shadow.cjs +348 -0
  15. package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts +188 -0
  16. package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts.map +1 -0
  17. package/dist/modules/lighting/contact-shadow/contact-shadow.js +307 -0
  18. package/dist/modules/lighting/contact-shadow/contact-shadow.js.map +1 -0
  19. package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.cjs +87 -0
  20. package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts +21 -0
  21. package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts.map +1 -0
  22. package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js +61 -0
  23. package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js.map +1 -0
  24. package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.cjs +87 -0
  25. package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts +21 -0
  26. package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts.map +1 -0
  27. package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js +61 -0
  28. package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js.map +1 -0
  29. package/dist/modules/lighting/pbr-material/pbr-material-glsl.cjs +33 -11
  30. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +2 -2
  31. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
  32. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +33 -11
  33. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
  34. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.cjs +33 -11
  35. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
  36. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  37. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +33 -11
  38. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  39. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +3 -3
  40. package/dist/modules/lighting/pbr-shadow/pbr-shadow.cjs +97 -0
  41. package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts +15 -0
  42. package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts.map +1 -0
  43. package/dist/modules/lighting/pbr-shadow/pbr-shadow.js +69 -0
  44. package/dist/modules/lighting/pbr-shadow/pbr-shadow.js.map +1 -0
  45. package/dist/modules/lighting/pbr-surface/pbr-surface.cjs +114 -0
  46. package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts +15 -0
  47. package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts.map +1 -0
  48. package/dist/modules/lighting/pbr-surface/pbr-surface.js +88 -0
  49. package/dist/modules/lighting/pbr-surface/pbr-surface.js.map +1 -0
  50. package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.cjs +379 -0
  51. package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts +41 -0
  52. package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts.map +1 -0
  53. package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js +345 -0
  54. package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js.map +1 -0
  55. package/dist/modules/lighting/shadow/shadow-glsl.cjs +228 -0
  56. package/dist/modules/lighting/shadow/shadow-glsl.d.ts +3 -0
  57. package/dist/modules/lighting/shadow/shadow-glsl.d.ts.map +1 -0
  58. package/dist/modules/lighting/shadow/shadow-glsl.js +204 -0
  59. package/dist/modules/lighting/shadow/shadow-glsl.js.map +1 -0
  60. package/dist/modules/lighting/shadow/shadow-types.cjs +15 -0
  61. package/dist/modules/lighting/shadow/shadow-types.d.ts +63 -0
  62. package/dist/modules/lighting/shadow/shadow-types.d.ts.map +1 -0
  63. package/dist/modules/lighting/shadow/shadow-types.js +5 -0
  64. package/dist/modules/lighting/shadow/shadow-types.js.map +1 -0
  65. package/dist/modules/lighting/shadow/shadow.cjs +458 -0
  66. package/dist/modules/lighting/shadow/shadow.d.ts +117 -0
  67. package/dist/modules/lighting/shadow/shadow.d.ts.map +1 -0
  68. package/dist/modules/lighting/shadow/shadow.js +450 -0
  69. package/dist/modules/lighting/shadow/shadow.js.map +1 -0
  70. package/dist/modules/lighting/unlit-material/unlit-material.cjs +60 -0
  71. package/dist/modules/lighting/unlit-material/unlit-material.d.ts +9 -0
  72. package/dist/modules/lighting/unlit-material/unlit-material.d.ts.map +1 -0
  73. package/dist/modules/lighting/unlit-material/unlit-material.js +40 -0
  74. package/dist/modules/lighting/unlit-material/unlit-material.js.map +1 -0
  75. package/package.json +3 -3
  76. package/src/index.ts +48 -0
  77. package/src/modules/lighting/clustered-light-grid/clustered-light-grid.ts +17 -0
  78. package/src/modules/lighting/contact-shadow/contact-shadow.ts +365 -0
  79. package/src/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.ts +78 -0
  80. package/src/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.ts +78 -0
  81. package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +33 -11
  82. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +33 -11
  83. package/src/modules/lighting/pbr-shadow/pbr-shadow.ts +85 -0
  84. package/src/modules/lighting/pbr-surface/pbr-surface.ts +103 -0
  85. package/src/modules/lighting/prefiltered-environment/prefiltered-environment.ts +370 -0
  86. package/src/modules/lighting/shadow/shadow-glsl.ts +204 -0
  87. package/src/modules/lighting/shadow/shadow-types.ts +68 -0
  88. package/src/modules/lighting/shadow/shadow.ts +536 -0
  89. package/src/modules/lighting/unlit-material/unlit-material.ts +44 -0
@@ -0,0 +1,345 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
+ const GLSL_UNIFORMS = /* glsl */ `\
5
+ layout(std140) uniform pbrEnvironmentFilterUniforms {
6
+ int face;
7
+ float roughness;
8
+ int mode;
9
+ int sampleCount;
10
+ int sourceEncoding;
11
+ } pbrEnvironmentFilter;
12
+
13
+ uniform sampler2D pbrEnvironmentSource;
14
+ `;
15
+ const WGSL_UNIFORMS = /* wgsl */ `\
16
+ struct PBREnvironmentFilterUniforms {
17
+ face: i32,
18
+ roughness: f32,
19
+ mode: i32,
20
+ sampleCount: i32,
21
+ sourceEncoding: i32,
22
+ };
23
+
24
+ @group(0) @binding(auto) var<uniform> pbrEnvironmentFilter: PBREnvironmentFilterUniforms;
25
+ @group(0) @binding(auto) var pbrEnvironmentSource: texture_2d<f32>;
26
+ @group(0) @binding(auto) var pbrEnvironmentSourceSampler: sampler;
27
+ `;
28
+ export const pbrEnvironmentFilter = {
29
+ name: 'pbrEnvironmentFilter',
30
+ bindingLayout: [
31
+ { name: 'pbrEnvironmentFilter', group: 0 },
32
+ { name: 'pbrEnvironmentSource', group: 0 }
33
+ ],
34
+ fs: GLSL_UNIFORMS,
35
+ source: WGSL_UNIFORMS,
36
+ getUniforms: (properties) => properties,
37
+ uniformTypes: {
38
+ face: 'i32',
39
+ roughness: 'f32',
40
+ mode: 'i32',
41
+ sampleCount: 'i32',
42
+ sourceEncoding: 'i32'
43
+ },
44
+ defaultUniforms: {
45
+ face: 0,
46
+ roughness: 0,
47
+ mode: 0,
48
+ sampleCount: 64,
49
+ sourceEncoding: 0
50
+ }
51
+ };
52
+ export const PBR_ENVIRONMENT_FRAGMENT_GLSL = /* glsl */ `\
53
+ #version 300 es
54
+ precision highp float;
55
+ precision highp int;
56
+
57
+ in vec2 uv;
58
+ out vec4 fragmentColor;
59
+
60
+ const float ENVIRONMENT_PI = 3.141592653589793;
61
+
62
+ vec2 getEnvironmentHammersley(uint index, uint sampleCount)
63
+ {
64
+ uint reversedBits = (index << 16u) | (index >> 16u);
65
+ reversedBits = ((reversedBits & 0x55555555u) << 1u) |
66
+ ((reversedBits & 0xAAAAAAAAu) >> 1u);
67
+ reversedBits = ((reversedBits & 0x33333333u) << 2u) |
68
+ ((reversedBits & 0xCCCCCCCCu) >> 2u);
69
+ reversedBits = ((reversedBits & 0x0F0F0F0Fu) << 4u) |
70
+ ((reversedBits & 0xF0F0F0F0u) >> 4u);
71
+ reversedBits = ((reversedBits & 0x00FF00FFu) << 8u) |
72
+ ((reversedBits & 0xFF00FF00u) >> 8u);
73
+ return vec2(
74
+ float(index) / float(sampleCount),
75
+ float(reversedBits) * 2.3283064365386963e-10
76
+ );
77
+ }
78
+
79
+ vec3 getEnvironmentFaceDirection(int face, vec2 textureCoordinate)
80
+ {
81
+ vec2 coordinate = textureCoordinate * 2.0 - 1.0;
82
+ if (face == 0) return normalize(vec3(1.0, -coordinate.y, -coordinate.x));
83
+ if (face == 1) return normalize(vec3(-1.0, -coordinate.y, coordinate.x));
84
+ if (face == 2) return normalize(vec3(coordinate.x, 1.0, coordinate.y));
85
+ if (face == 3) return normalize(vec3(coordinate.x, -1.0, -coordinate.y));
86
+ if (face == 4) return normalize(vec3(coordinate.x, -coordinate.y, 1.0));
87
+ return normalize(vec3(-coordinate.x, -coordinate.y, -1.0));
88
+ }
89
+
90
+ mat3 getEnvironmentTangentBasis(vec3 normal)
91
+ {
92
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
93
+ vec3 tangent = normalize(cross(up, normal));
94
+ return mat3(tangent, cross(normal, tangent), normal);
95
+ }
96
+
97
+ vec3 sampleEnvironmentDirection(vec3 direction)
98
+ {
99
+ vec3 normalizedDirection = normalize(direction);
100
+ vec2 textureCoordinate = vec2(
101
+ atan(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,
102
+ acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI
103
+ );
104
+ vec3 color = texture(pbrEnvironmentSource, textureCoordinate).rgb;
105
+ if (pbrEnvironmentFilter.sourceEncoding == 1) {
106
+ vec3 lower = color / 12.92;
107
+ vec3 upper = pow((color + 0.055) / 1.055, vec3(2.4));
108
+ color = mix(lower, upper, step(vec3(0.04045), color));
109
+ }
110
+ return color;
111
+ }
112
+
113
+ vec3 importanceSampleEnvironment(vec2 sequence, vec3 normal, float roughness)
114
+ {
115
+ float alpha = max(roughness * roughness, 0.0001);
116
+ float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
117
+ float cosine = sqrt(
118
+ (1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)
119
+ );
120
+ float sine = sqrt(max(1.0 - cosine * cosine, 0.0));
121
+ vec3 halfVector = vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine);
122
+ return normalize(getEnvironmentTangentBasis(normal) * halfVector);
123
+ }
124
+
125
+ float getEnvironmentGeometry(float normalDotDirection, float roughness)
126
+ {
127
+ float alpha = roughness * roughness;
128
+ float factor = alpha * 0.5;
129
+ return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);
130
+ }
131
+
132
+ vec2 integrateEnvironmentBRDF(vec2 textureCoordinate, int sampleCount)
133
+ {
134
+ float normalDotView = max(textureCoordinate.x, 0.001);
135
+ float roughness = 1.0 - textureCoordinate.y;
136
+ vec3 viewDirection = vec3(sqrt(max(1.0 - normalDotView * normalDotView, 0.0)), 0.0, normalDotView);
137
+ vec2 integration = vec2(0.0);
138
+
139
+ for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {
140
+ if (sampleIndex >= sampleCount) break;
141
+ vec3 halfVector = importanceSampleEnvironment(
142
+ getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount)),
143
+ vec3(0.0, 0.0, 1.0),
144
+ roughness
145
+ );
146
+ vec3 lightDirection = normalize(2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection);
147
+ float normalDotLight = max(lightDirection.z, 0.0);
148
+ float normalDotHalf = max(halfVector.z, 0.0);
149
+ float viewDotHalf = max(dot(viewDirection, halfVector), 0.0);
150
+ if (normalDotLight > 0.0) {
151
+ float visibility = getEnvironmentGeometry(normalDotView, roughness) *
152
+ getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /
153
+ max(normalDotHalf * normalDotView, 0.0001);
154
+ float fresnel = pow(1.0 - viewDotHalf, 5.0);
155
+ integration += vec2(1.0 - fresnel, fresnel) * visibility;
156
+ }
157
+ }
158
+ return integration / float(sampleCount);
159
+ }
160
+
161
+ vec3 integrateEnvironmentDirection(vec3 normal, int sampleCount)
162
+ {
163
+ vec3 accumulatedColor = vec3(0.0);
164
+ float accumulatedWeight = 0.0;
165
+
166
+ for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {
167
+ if (sampleIndex >= sampleCount) break;
168
+ vec2 sequence = getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount));
169
+ vec3 direction;
170
+ float sampleWeight;
171
+
172
+ if (pbrEnvironmentFilter.mode == 1) {
173
+ float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
174
+ float cosine = sqrt(1.0 - sequence.y);
175
+ float sine = sqrt(sequence.y);
176
+ direction = normalize(
177
+ getEnvironmentTangentBasis(normal) *
178
+ vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine)
179
+ );
180
+ sampleWeight = 1.0;
181
+ } else {
182
+ vec3 halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);
183
+ direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);
184
+ sampleWeight = max(dot(normal, direction), 0.0);
185
+ }
186
+
187
+ accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;
188
+ accumulatedWeight += sampleWeight;
189
+ }
190
+
191
+ return accumulatedColor / max(accumulatedWeight, 0.0001);
192
+ }
193
+
194
+ void main(void)
195
+ {
196
+ int sampleCount = max(pbrEnvironmentFilter.sampleCount, 1);
197
+ if (pbrEnvironmentFilter.mode == 2) {
198
+ fragmentColor = vec4(integrateEnvironmentBRDF(uv, sampleCount), 0.0, 1.0);
199
+ return;
200
+ }
201
+
202
+ vec3 direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, uv);
203
+ fragmentColor = vec4(integrateEnvironmentDirection(direction, sampleCount), 1.0);
204
+ }
205
+ `;
206
+ export const PBR_ENVIRONMENT_FRAGMENT_WGSL = /* wgsl */ `\
207
+ const ENVIRONMENT_PI: f32 = 3.141592653589793;
208
+
209
+ fn getEnvironmentHammersley(index: u32, sampleCount: u32) -> vec2f {
210
+ return vec2f(f32(index) / f32(sampleCount), f32(reverseBits(index)) * 2.3283064365386963e-10);
211
+ }
212
+
213
+ fn getEnvironmentFaceDirection(face: i32, textureCoordinate: vec2f) -> vec3f {
214
+ let coordinate = textureCoordinate * 2.0 - 1.0;
215
+ if (face == 0) { return normalize(vec3f(1.0, -coordinate.y, -coordinate.x)); }
216
+ if (face == 1) { return normalize(vec3f(-1.0, -coordinate.y, coordinate.x)); }
217
+ if (face == 2) { return normalize(vec3f(coordinate.x, 1.0, coordinate.y)); }
218
+ if (face == 3) { return normalize(vec3f(coordinate.x, -1.0, -coordinate.y)); }
219
+ if (face == 4) { return normalize(vec3f(coordinate.x, -coordinate.y, 1.0)); }
220
+ return normalize(vec3f(-coordinate.x, -coordinate.y, -1.0));
221
+ }
222
+
223
+ fn getEnvironmentTangentBasis(normal: vec3f) -> mat3x3f {
224
+ var up = vec3f(1.0, 0.0, 0.0);
225
+ if (abs(normal.z) < 0.999) {
226
+ up = vec3f(0.0, 0.0, 1.0);
227
+ }
228
+ let tangent = normalize(cross(up, normal));
229
+ return mat3x3f(tangent, cross(normal, tangent), normal);
230
+ }
231
+
232
+ fn sampleEnvironmentDirection(direction: vec3f) -> vec3f {
233
+ let normalizedDirection = normalize(direction);
234
+ let textureCoordinate = vec2f(
235
+ atan2(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,
236
+ acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI
237
+ );
238
+ var color = textureSampleLevel(
239
+ pbrEnvironmentSource,
240
+ pbrEnvironmentSourceSampler,
241
+ textureCoordinate,
242
+ 0.0
243
+ ).rgb;
244
+ if (pbrEnvironmentFilter.sourceEncoding == 1) {
245
+ let lower = color / 12.92;
246
+ let upper = pow((color + 0.055) / 1.055, vec3f(2.4));
247
+ color = mix(lower, upper, step(vec3f(0.04045), color));
248
+ }
249
+ return color;
250
+ }
251
+
252
+ fn importanceSampleEnvironment(sequence: vec2f, normal: vec3f, roughness: f32) -> vec3f {
253
+ let alpha = max(roughness * roughness, 0.0001);
254
+ let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
255
+ let cosine = sqrt(
256
+ (1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)
257
+ );
258
+ let sine = sqrt(max(1.0 - cosine * cosine, 0.0));
259
+ let halfVector = vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine);
260
+ return normalize(getEnvironmentTangentBasis(normal) * halfVector);
261
+ }
262
+
263
+ fn getEnvironmentGeometry(normalDotDirection: f32, roughness: f32) -> f32 {
264
+ let alpha = roughness * roughness;
265
+ let factor = alpha * 0.5;
266
+ return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);
267
+ }
268
+
269
+ fn integrateEnvironmentBRDF(textureCoordinate: vec2f, sampleCount: u32) -> vec2f {
270
+ let normalDotView = max(textureCoordinate.x, 0.001);
271
+ let roughness = 1.0 - textureCoordinate.y;
272
+ let viewDirection = vec3f(
273
+ sqrt(max(1.0 - normalDotView * normalDotView, 0.0)),
274
+ 0.0,
275
+ normalDotView
276
+ );
277
+ var integration = vec2f(0.0);
278
+
279
+ for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {
280
+ let halfVector = importanceSampleEnvironment(
281
+ getEnvironmentHammersley(sampleIndex, sampleCount),
282
+ vec3f(0.0, 0.0, 1.0),
283
+ roughness
284
+ );
285
+ let lightDirection = normalize(
286
+ 2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection
287
+ );
288
+ let normalDotLight = max(lightDirection.z, 0.0);
289
+ let normalDotHalf = max(halfVector.z, 0.0);
290
+ let viewDotHalf = max(dot(viewDirection, halfVector), 0.0);
291
+ if (normalDotLight > 0.0) {
292
+ let visibility = getEnvironmentGeometry(normalDotView, roughness) *
293
+ getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /
294
+ max(normalDotHalf * normalDotView, 0.0001);
295
+ let fresnel = pow(1.0 - viewDotHalf, 5.0);
296
+ integration += vec2f(1.0 - fresnel, fresnel) * visibility;
297
+ }
298
+ }
299
+ return integration / f32(sampleCount);
300
+ }
301
+
302
+ fn integrateEnvironmentDirection(normal: vec3f, sampleCount: u32) -> vec3f {
303
+ var accumulatedColor = vec3f(0.0);
304
+ var accumulatedWeight = 0.0;
305
+
306
+ for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {
307
+ let sequence = getEnvironmentHammersley(sampleIndex, sampleCount);
308
+ var direction: vec3f;
309
+ var sampleWeight: f32;
310
+
311
+ if (pbrEnvironmentFilter.mode == 1) {
312
+ let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
313
+ let cosine = sqrt(1.0 - sequence.y);
314
+ let sine = sqrt(sequence.y);
315
+ direction = normalize(
316
+ getEnvironmentTangentBasis(normal) *
317
+ vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine)
318
+ );
319
+ sampleWeight = 1.0;
320
+ } else {
321
+ let halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);
322
+ direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);
323
+ sampleWeight = max(dot(normal, direction), 0.0);
324
+ }
325
+
326
+ accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;
327
+ accumulatedWeight += sampleWeight;
328
+ }
329
+ return accumulatedColor / max(accumulatedWeight, 0.0001);
330
+ }
331
+
332
+ @fragment
333
+ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
334
+ // ClipSpace UVs increase upward; WebGPU texture rows increase downward.
335
+ let textureCoordinate = vec2f(inputs.uv.x, 1.0 - inputs.uv.y);
336
+ let sampleCount = u32(max(pbrEnvironmentFilter.sampleCount, 1));
337
+ if (pbrEnvironmentFilter.mode == 2) {
338
+ return vec4f(integrateEnvironmentBRDF(textureCoordinate, sampleCount), 0.0, 1.0);
339
+ }
340
+
341
+ let direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, textureCoordinate);
342
+ return vec4f(integrateEnvironmentDirection(direction, sampleCount), 1.0);
343
+ }
344
+ `;
345
+ //# sourceMappingURL=prefiltered-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefiltered-environment.js","sourceRoot":"","sources":["../../../../src/modules/lighting/prefiltered-environment/prefiltered-environment.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,4DAA4D;AAmB5D,MAAM,aAAa,GAAG,UAAU,CAAC;;;;;;;;;;CAUhC,CAAC;AAEF,MAAM,aAAa,GAAG,UAAU,CAAC;;;;;;;;;;;;CAYhC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,sBAAsB;IAC5B,aAAa,EAAE;QACb,EAAC,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAC;QACxC,EAAC,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAC;KACzC;IACD,EAAE,EAAE,aAAa;IACjB,MAAM,EAAE,aAAa;IACrB,WAAW,EAAE,CAAC,UAA8C,EAAE,EAAE,CAAC,UAAU;IAC3E,YAAY,EAAE;QACZ,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,KAAK;KACtB;IACD,eAAe,EAAE;QACf,IAAI,EAAE,CAAC;QACP,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,CAAC;QACP,WAAW,EAAE,EAAE;QACf,cAAc,EAAE,CAAC;KAClB;CAKF,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJvD,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0IvD,CAAC"}
@@ -0,0 +1,228 @@
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 shadow_glsl_exports = {};
19
+ __export(shadow_glsl_exports, {
20
+ SHADOW_GLSL: () => SHADOW_GLSL
21
+ });
22
+ module.exports = __toCommonJS(shadow_glsl_exports);
23
+ const SHADOW_GLSL = (
24
+ /* glsl */
25
+ `
26
+ precision highp sampler2DArray;
27
+ struct DirectionalShadowLightUniform {
28
+ vec3 direction;
29
+ float strength;
30
+ float normalBias;
31
+ float sourceAngularRadius;
32
+ float cascadeBlendFraction;
33
+ float farFadeFraction;
34
+ float shadowDistance;
35
+ };
36
+ struct SpotShadowLightUniform {
37
+ vec3 position;
38
+ float range;
39
+ vec3 direction;
40
+ float outerConeCos;
41
+ float sourceRadius;
42
+ float normalBias;
43
+ float strength;
44
+ float nearPlane;
45
+ };
46
+ struct PointShadowLightUniform {
47
+ vec3 position;
48
+ float range;
49
+ float sourceRadius;
50
+ float normalBias;
51
+ float strength;
52
+ float nearPlane;
53
+ };
54
+ layout(std140) uniform shadowUniforms {
55
+ int directionalLightCount;
56
+ int spotLightCount;
57
+ int pointLightCount;
58
+ int cascadeCount;
59
+ int blockerSampleCount;
60
+ int filterSampleCount;
61
+ vec4 cascadeSplits;
62
+ mat4 directionalViewProjectionMatrices[4];
63
+ mat4 spotViewProjectionMatrices[4];
64
+ mat4 pointViewProjectionMatrices[24];
65
+ DirectionalShadowLightUniform directionalLights[1];
66
+ SpotShadowLightUniform spotLights[4];
67
+ PointShadowLightUniform pointLights[4];
68
+ } shadow;
69
+ uniform sampler2DArray directionalShadowTexture;
70
+ uniform sampler2DArray spotShadowTexture;
71
+ uniform sampler2DArray pointShadowTexture;
72
+ const float SHADOW_PI = 3.141592653589793;
73
+ float shadow_hash(vec3 position) {
74
+ return fract(sin(dot(position, vec3(12.9898, 78.233, 37.719))) * 43758.5453);
75
+ }
76
+ vec2 shadow_diskSample(int index, int count, float rotation) {
77
+ float fraction = (float(index) + 0.5) / max(float(count), 1.0);
78
+ float angle = float(index) * 2.39996323 + rotation;
79
+ return sqrt(fraction) * vec2(cos(angle), sin(angle));
80
+ }
81
+ vec3 shadow_project(mat4 matrix, vec3 worldPosition) {
82
+ vec4 clip = matrix * vec4(worldPosition, 1.0);
83
+ vec3 projected = clip.xyz / max(abs(clip.w), 0.00001);
84
+ // Shared matrices retain [0,1] depth; WebGL texture rows start at the bottom.
85
+ return vec3(projected.xy * 0.5 + 0.5, projected.z);
86
+ }
87
+ bool shadow_validProjection(vec3 projected) {
88
+ return all(greaterThanEqual(projected, vec3(0.0))) && all(lessThanEqual(projected, vec3(1.0)));
89
+ }
90
+ // Bilinear interpolation of four depth comparisons matches a hardware 2x2 PCF lookup.
91
+ float shadow_compare(sampler2DArray shadowMap, vec2 coordinate, int layer, float reference) {
92
+ ivec2 dimensions = textureSize(shadowMap, 0).xy;
93
+ vec2 position = coordinate * vec2(dimensions) - 0.5;
94
+ ivec2 base = ivec2(floor(position));
95
+ vec2 fraction = fract(position);
96
+ ivec2 maximum = dimensions - 1;
97
+ float lowerLeft = step(reference, texelFetch(shadowMap, ivec3(clamp(base, ivec2(0), maximum), layer), 0).r);
98
+ float lowerRight = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(1,0), ivec2(0), maximum), layer), 0).r);
99
+ float upperLeft = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(0,1), ivec2(0), maximum), layer), 0).r);
100
+ float upperRight = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(1,1), ivec2(0), maximum), layer), 0).r);
101
+ return mix(mix(lowerLeft, lowerRight, fraction.x), mix(upperLeft, upperRight, fraction.x), fraction.y);
102
+ }
103
+ float shadow_arrayPCSS(sampler2DArray shadowMap, int layer, vec3 projected, float searchRadius, float rotation, float penumbraScale) {
104
+ if (!shadow_validProjection(projected)) return 1.0;
105
+ float texel = 1.0 / float(textureSize(shadowMap, 0).x);
106
+ searchRadius = max(texel, searchRadius);
107
+ float blockerDepth = 0.0;
108
+ float blockerCount = 0.0;
109
+ for (int index = 0; index < 24; index++) {
110
+ if (index >= shadow.blockerSampleCount) break;
111
+ vec2 coordinate = clamp(projected.xy + shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius, vec2(0.0), vec2(1.0));
112
+ float depth = textureLod(shadowMap, vec3(coordinate, float(layer)), 0.0).r;
113
+ if (depth < projected.z) { blockerDepth += depth; blockerCount += 1.0; }
114
+ }
115
+ if (blockerCount == 0.0) return 1.0;
116
+ float averageBlocker = blockerDepth / blockerCount;
117
+ float penumbra = clamp((projected.z - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);
118
+ float radius = max(texel, searchRadius * (1.0 + penumbra * penumbraScale));
119
+ float visibility = 0.0;
120
+ for (int index = 0; index < 48; index++) {
121
+ if (index >= shadow.filterSampleCount) break;
122
+ vec2 coordinate = clamp(projected.xy + shadow_diskSample(index, shadow.filterSampleCount, rotation) * radius, vec2(0.0), vec2(1.0));
123
+ visibility += shadow_compare(shadowMap, coordinate, layer, projected.z);
124
+ }
125
+ return visibility / max(float(shadow.filterSampleCount), 1.0);
126
+ }
127
+ int shadow_directionalCascadeIndex(float viewDepth) {
128
+ int cascadeIndex = 0;
129
+ for (int index = 0; index < 4; index++) {
130
+ if (index >= shadow.cascadeCount) break;
131
+ cascadeIndex = index;
132
+ if (viewDepth <= shadow.cascadeSplits[index]) break;
133
+ }
134
+ return cascadeIndex;
135
+ }
136
+ int shadow_getDirectionalCascadeIndex(float viewDepth) {
137
+ return shadow.directionalLightCount == 0 ? -1 : shadow_directionalCascadeIndex(viewDepth);
138
+ }
139
+ float shadow_directionalPCSS(int cascadeIndex, vec3 worldPosition, float viewDepth) {
140
+ DirectionalShadowLightUniform light = shadow.directionalLights[0];
141
+ return shadow_arrayPCSS(directionalShadowTexture, cascadeIndex,
142
+ shadow_project(shadow.directionalViewProjectionMatrices[cascadeIndex], worldPosition),
143
+ light.sourceAngularRadius * viewDepth / max(light.shadowDistance, 0.001),
144
+ shadow_hash(worldPosition) * 2.0 * SHADOW_PI, 18.0);
145
+ }
146
+ float shadow_getDirectionalFactor(vec3 worldPosition, vec3 worldNormal, float viewDepth) {
147
+ if (shadow.directionalLightCount == 0 || viewDepth <= 0.0) return 1.0;
148
+ DirectionalShadowLightUniform light = shadow.directionalLights[0];
149
+ if (viewDepth >= light.shadowDistance) return 1.0;
150
+ vec3 position = worldPosition + normalize(worldNormal) * light.normalBias;
151
+ int cascadeIndex = shadow_directionalCascadeIndex(viewDepth);
152
+ float visibility = shadow_directionalPCSS(cascadeIndex, position, viewDepth);
153
+ if (cascadeIndex + 1 < shadow.cascadeCount) {
154
+ float cascadeStart = cascadeIndex > 0 ? shadow.cascadeSplits[cascadeIndex - 1] : 0.0;
155
+ float cascadeEnd = shadow.cascadeSplits[cascadeIndex];
156
+ float blendWidth = max((cascadeEnd - cascadeStart) * light.cascadeBlendFraction, 0.0001);
157
+ float blend = smoothstep(cascadeEnd - blendWidth, cascadeEnd, viewDepth);
158
+ if (blend > 0.0) visibility = mix(visibility, shadow_directionalPCSS(cascadeIndex + 1, position, viewDepth), blend);
159
+ }
160
+ float fadeWidth = max(light.shadowDistance * light.farFadeFraction, 0.0001);
161
+ visibility = mix(visibility, 1.0, smoothstep(light.shadowDistance - fadeWidth, light.shadowDistance, viewDepth));
162
+ return mix(1.0, visibility, light.strength);
163
+ }
164
+ float shadow_getSpotFactor(int lightIndex, vec3 worldPosition, vec3 worldNormal) {
165
+ if (lightIndex < 0 || lightIndex >= shadow.spotLightCount) return 1.0;
166
+ SpotShadowLightUniform light = shadow.spotLights[lightIndex];
167
+ vec3 fromLight = worldPosition - light.position;
168
+ float distanceToLight = length(fromLight);
169
+ if (distanceToLight >= light.range || dot(normalize(fromLight), normalize(light.direction)) < light.outerConeCos) return 1.0;
170
+ vec3 position = worldPosition + normalize(worldNormal) * light.normalBias;
171
+ float visibility = shadow_arrayPCSS(spotShadowTexture, lightIndex,
172
+ shadow_project(shadow.spotViewProjectionMatrices[lightIndex], position),
173
+ light.sourceRadius / max(distanceToLight, 0.001) * 0.5,
174
+ shadow_hash(worldPosition) * 2.0 * SHADOW_PI, 16.0);
175
+ return mix(1.0, visibility, light.strength);
176
+ }
177
+ float shadow_pointReferenceDepth(float majorDistance, float nearPlane, float farPlane) {
178
+ return farPlane / (farPlane - nearPlane) - (farPlane * nearPlane) / ((farPlane - nearPlane) * majorDistance);
179
+ }
180
+ vec3 shadow_pointCoordinate(int lightIndex, vec3 direction) {
181
+ vec3 magnitude = abs(direction);
182
+ int face = magnitude.x >= magnitude.y && magnitude.x >= magnitude.z ? (direction.x >= 0.0 ? 0 : 1)
183
+ : magnitude.y >= magnitude.z ? (direction.y >= 0.0 ? 2 : 3) : (direction.z >= 0.0 ? 4 : 5);
184
+ PointShadowLightUniform light = shadow.pointLights[lightIndex];
185
+ vec3 projected = shadow_project(shadow.pointViewProjectionMatrices[lightIndex * 6 + face], light.position + direction * light.range * 0.5);
186
+ return vec3(projected.xy, float(lightIndex * 6 + face));
187
+ }
188
+ float shadow_getPointFactor(int lightIndex, vec3 worldPosition, vec3 worldNormal) {
189
+ if (lightIndex < 0 || lightIndex >= shadow.pointLightCount) return 1.0;
190
+ PointShadowLightUniform light = shadow.pointLights[lightIndex];
191
+ vec3 fromLight = worldPosition + normalize(worldNormal) * light.normalBias - light.position;
192
+ float distanceToLight = length(fromLight);
193
+ if (distanceToLight >= light.range || distanceToLight <= light.nearPlane) return 1.0;
194
+ vec3 direction = normalize(fromLight);
195
+ float referenceDepth = shadow_pointReferenceDepth(max(max(abs(fromLight.x), abs(fromLight.y)), abs(fromLight.z)), light.nearPlane, light.range);
196
+ vec3 reference = abs(direction.y) > 0.99 ? vec3(0,0,1) : vec3(0,1,0);
197
+ vec3 tangent = normalize(cross(direction, reference));
198
+ vec3 bitangent = normalize(cross(direction, tangent));
199
+ float searchRadius = light.sourceRadius / max(distanceToLight, 0.001);
200
+ float rotation = shadow_hash(worldPosition) * 2.0 * SHADOW_PI;
201
+ float blockerDepth = 0.0;
202
+ float blockerCount = 0.0;
203
+ for (int index = 0; index < 24; index++) {
204
+ if (index >= shadow.blockerSampleCount) break;
205
+ vec2 disk = shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius;
206
+ vec3 coordinate = shadow_pointCoordinate(lightIndex, normalize(direction + tangent * disk.x + bitangent * disk.y));
207
+ float depth = textureLod(pointShadowTexture, coordinate, 0.0).r;
208
+ if (depth < referenceDepth) { blockerDepth += depth; blockerCount += 1.0; }
209
+ }
210
+ if (blockerCount == 0.0) return 1.0;
211
+ float averageBlocker = blockerDepth / blockerCount;
212
+ float penumbra = clamp((referenceDepth - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);
213
+ float radius = searchRadius * (1.0 + penumbra * 12.0);
214
+ float visibility = 0.0;
215
+ for (int index = 0; index < 48; index++) {
216
+ if (index >= shadow.filterSampleCount) break;
217
+ vec2 disk = shadow_diskSample(index, shadow.filterSampleCount, rotation) * radius;
218
+ vec3 coordinate = shadow_pointCoordinate(lightIndex, normalize(direction + tangent * disk.x + bitangent * disk.y));
219
+ visibility += shadow_compare(pointShadowTexture, coordinate.xy, int(coordinate.z), referenceDepth);
220
+ }
221
+ return mix(1.0, visibility / max(float(shadow.filterSampleCount), 1.0), light.strength);
222
+ }
223
+ `
224
+ );
225
+ // Annotate the CommonJS export names for ESM import in node:
226
+ 0 && (module.exports = {
227
+ SHADOW_GLSL
228
+ });
@@ -0,0 +1,3 @@
1
+ /** WebGL2 sampling uses raw depth arrays and explicit comparisons; cube arrays are face arrays. */
2
+ export declare const SHADOW_GLSL = "\nprecision highp sampler2DArray;\nstruct DirectionalShadowLightUniform {\n vec3 direction;\n float strength;\n float normalBias;\n float sourceAngularRadius;\n float cascadeBlendFraction;\n float farFadeFraction;\n float shadowDistance;\n};\nstruct SpotShadowLightUniform {\n vec3 position;\n float range;\n vec3 direction;\n float outerConeCos;\n float sourceRadius;\n float normalBias;\n float strength;\n float nearPlane;\n};\nstruct PointShadowLightUniform {\n vec3 position;\n float range;\n float sourceRadius;\n float normalBias;\n float strength;\n float nearPlane;\n};\nlayout(std140) uniform shadowUniforms {\n int directionalLightCount;\n int spotLightCount;\n int pointLightCount;\n int cascadeCount;\n int blockerSampleCount;\n int filterSampleCount;\n vec4 cascadeSplits;\n mat4 directionalViewProjectionMatrices[4];\n mat4 spotViewProjectionMatrices[4];\n mat4 pointViewProjectionMatrices[24];\n DirectionalShadowLightUniform directionalLights[1];\n SpotShadowLightUniform spotLights[4];\n PointShadowLightUniform pointLights[4];\n} shadow;\nuniform sampler2DArray directionalShadowTexture;\nuniform sampler2DArray spotShadowTexture;\nuniform sampler2DArray pointShadowTexture;\nconst float SHADOW_PI = 3.141592653589793;\nfloat shadow_hash(vec3 position) {\n return fract(sin(dot(position, vec3(12.9898, 78.233, 37.719))) * 43758.5453);\n}\nvec2 shadow_diskSample(int index, int count, float rotation) {\n float fraction = (float(index) + 0.5) / max(float(count), 1.0);\n float angle = float(index) * 2.39996323 + rotation;\n return sqrt(fraction) * vec2(cos(angle), sin(angle));\n}\nvec3 shadow_project(mat4 matrix, vec3 worldPosition) {\n vec4 clip = matrix * vec4(worldPosition, 1.0);\n vec3 projected = clip.xyz / max(abs(clip.w), 0.00001);\n // Shared matrices retain [0,1] depth; WebGL texture rows start at the bottom.\n return vec3(projected.xy * 0.5 + 0.5, projected.z);\n}\nbool shadow_validProjection(vec3 projected) {\n return all(greaterThanEqual(projected, vec3(0.0))) && all(lessThanEqual(projected, vec3(1.0)));\n}\n// Bilinear interpolation of four depth comparisons matches a hardware 2x2 PCF lookup.\nfloat shadow_compare(sampler2DArray shadowMap, vec2 coordinate, int layer, float reference) {\n ivec2 dimensions = textureSize(shadowMap, 0).xy;\n vec2 position = coordinate * vec2(dimensions) - 0.5;\n ivec2 base = ivec2(floor(position));\n vec2 fraction = fract(position);\n ivec2 maximum = dimensions - 1;\n float lowerLeft = step(reference, texelFetch(shadowMap, ivec3(clamp(base, ivec2(0), maximum), layer), 0).r);\n float lowerRight = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(1,0), ivec2(0), maximum), layer), 0).r);\n float upperLeft = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(0,1), ivec2(0), maximum), layer), 0).r);\n float upperRight = step(reference, texelFetch(shadowMap, ivec3(clamp(base + ivec2(1,1), ivec2(0), maximum), layer), 0).r);\n return mix(mix(lowerLeft, lowerRight, fraction.x), mix(upperLeft, upperRight, fraction.x), fraction.y);\n}\nfloat shadow_arrayPCSS(sampler2DArray shadowMap, int layer, vec3 projected, float searchRadius, float rotation, float penumbraScale) {\n if (!shadow_validProjection(projected)) return 1.0;\n float texel = 1.0 / float(textureSize(shadowMap, 0).x);\n searchRadius = max(texel, searchRadius);\n float blockerDepth = 0.0;\n float blockerCount = 0.0;\n for (int index = 0; index < 24; index++) {\n if (index >= shadow.blockerSampleCount) break;\n vec2 coordinate = clamp(projected.xy + shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius, vec2(0.0), vec2(1.0));\n float depth = textureLod(shadowMap, vec3(coordinate, float(layer)), 0.0).r;\n if (depth < projected.z) { blockerDepth += depth; blockerCount += 1.0; }\n }\n if (blockerCount == 0.0) return 1.0;\n float averageBlocker = blockerDepth / blockerCount;\n float penumbra = clamp((projected.z - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);\n float radius = max(texel, searchRadius * (1.0 + penumbra * penumbraScale));\n float visibility = 0.0;\n for (int index = 0; index < 48; index++) {\n if (index >= shadow.filterSampleCount) break;\n vec2 coordinate = clamp(projected.xy + shadow_diskSample(index, shadow.filterSampleCount, rotation) * radius, vec2(0.0), vec2(1.0));\n visibility += shadow_compare(shadowMap, coordinate, layer, projected.z);\n }\n return visibility / max(float(shadow.filterSampleCount), 1.0);\n}\nint shadow_directionalCascadeIndex(float viewDepth) {\n int cascadeIndex = 0;\n for (int index = 0; index < 4; index++) {\n if (index >= shadow.cascadeCount) break;\n cascadeIndex = index;\n if (viewDepth <= shadow.cascadeSplits[index]) break;\n }\n return cascadeIndex;\n}\nint shadow_getDirectionalCascadeIndex(float viewDepth) {\n return shadow.directionalLightCount == 0 ? -1 : shadow_directionalCascadeIndex(viewDepth);\n}\nfloat shadow_directionalPCSS(int cascadeIndex, vec3 worldPosition, float viewDepth) {\n DirectionalShadowLightUniform light = shadow.directionalLights[0];\n return shadow_arrayPCSS(directionalShadowTexture, cascadeIndex,\n shadow_project(shadow.directionalViewProjectionMatrices[cascadeIndex], worldPosition),\n light.sourceAngularRadius * viewDepth / max(light.shadowDistance, 0.001),\n shadow_hash(worldPosition) * 2.0 * SHADOW_PI, 18.0);\n}\nfloat shadow_getDirectionalFactor(vec3 worldPosition, vec3 worldNormal, float viewDepth) {\n if (shadow.directionalLightCount == 0 || viewDepth <= 0.0) return 1.0;\n DirectionalShadowLightUniform light = shadow.directionalLights[0];\n if (viewDepth >= light.shadowDistance) return 1.0;\n vec3 position = worldPosition + normalize(worldNormal) * light.normalBias;\n int cascadeIndex = shadow_directionalCascadeIndex(viewDepth);\n float visibility = shadow_directionalPCSS(cascadeIndex, position, viewDepth);\n if (cascadeIndex + 1 < shadow.cascadeCount) {\n float cascadeStart = cascadeIndex > 0 ? shadow.cascadeSplits[cascadeIndex - 1] : 0.0;\n float cascadeEnd = shadow.cascadeSplits[cascadeIndex];\n float blendWidth = max((cascadeEnd - cascadeStart) * light.cascadeBlendFraction, 0.0001);\n float blend = smoothstep(cascadeEnd - blendWidth, cascadeEnd, viewDepth);\n if (blend > 0.0) visibility = mix(visibility, shadow_directionalPCSS(cascadeIndex + 1, position, viewDepth), blend);\n }\n float fadeWidth = max(light.shadowDistance * light.farFadeFraction, 0.0001);\n visibility = mix(visibility, 1.0, smoothstep(light.shadowDistance - fadeWidth, light.shadowDistance, viewDepth));\n return mix(1.0, visibility, light.strength);\n}\nfloat shadow_getSpotFactor(int lightIndex, vec3 worldPosition, vec3 worldNormal) {\n if (lightIndex < 0 || lightIndex >= shadow.spotLightCount) return 1.0;\n SpotShadowLightUniform light = shadow.spotLights[lightIndex];\n vec3 fromLight = worldPosition - light.position;\n float distanceToLight = length(fromLight);\n if (distanceToLight >= light.range || dot(normalize(fromLight), normalize(light.direction)) < light.outerConeCos) return 1.0;\n vec3 position = worldPosition + normalize(worldNormal) * light.normalBias;\n float visibility = shadow_arrayPCSS(spotShadowTexture, lightIndex,\n shadow_project(shadow.spotViewProjectionMatrices[lightIndex], position),\n light.sourceRadius / max(distanceToLight, 0.001) * 0.5,\n shadow_hash(worldPosition) * 2.0 * SHADOW_PI, 16.0);\n return mix(1.0, visibility, light.strength);\n}\nfloat shadow_pointReferenceDepth(float majorDistance, float nearPlane, float farPlane) {\n return farPlane / (farPlane - nearPlane) - (farPlane * nearPlane) / ((farPlane - nearPlane) * majorDistance);\n}\nvec3 shadow_pointCoordinate(int lightIndex, vec3 direction) {\n vec3 magnitude = abs(direction);\n int face = magnitude.x >= magnitude.y && magnitude.x >= magnitude.z ? (direction.x >= 0.0 ? 0 : 1)\n : magnitude.y >= magnitude.z ? (direction.y >= 0.0 ? 2 : 3) : (direction.z >= 0.0 ? 4 : 5);\n PointShadowLightUniform light = shadow.pointLights[lightIndex];\n vec3 projected = shadow_project(shadow.pointViewProjectionMatrices[lightIndex * 6 + face], light.position + direction * light.range * 0.5);\n return vec3(projected.xy, float(lightIndex * 6 + face));\n}\nfloat shadow_getPointFactor(int lightIndex, vec3 worldPosition, vec3 worldNormal) {\n if (lightIndex < 0 || lightIndex >= shadow.pointLightCount) return 1.0;\n PointShadowLightUniform light = shadow.pointLights[lightIndex];\n vec3 fromLight = worldPosition + normalize(worldNormal) * light.normalBias - light.position;\n float distanceToLight = length(fromLight);\n if (distanceToLight >= light.range || distanceToLight <= light.nearPlane) return 1.0;\n vec3 direction = normalize(fromLight);\n float referenceDepth = shadow_pointReferenceDepth(max(max(abs(fromLight.x), abs(fromLight.y)), abs(fromLight.z)), light.nearPlane, light.range);\n vec3 reference = abs(direction.y) > 0.99 ? vec3(0,0,1) : vec3(0,1,0);\n vec3 tangent = normalize(cross(direction, reference));\n vec3 bitangent = normalize(cross(direction, tangent));\n float searchRadius = light.sourceRadius / max(distanceToLight, 0.001);\n float rotation = shadow_hash(worldPosition) * 2.0 * SHADOW_PI;\n float blockerDepth = 0.0;\n float blockerCount = 0.0;\n for (int index = 0; index < 24; index++) {\n if (index >= shadow.blockerSampleCount) break;\n vec2 disk = shadow_diskSample(index, shadow.blockerSampleCount, rotation) * searchRadius;\n vec3 coordinate = shadow_pointCoordinate(lightIndex, normalize(direction + tangent * disk.x + bitangent * disk.y));\n float depth = textureLod(pointShadowTexture, coordinate, 0.0).r;\n if (depth < referenceDepth) { blockerDepth += depth; blockerCount += 1.0; }\n }\n if (blockerCount == 0.0) return 1.0;\n float averageBlocker = blockerDepth / blockerCount;\n float penumbra = clamp((referenceDepth - averageBlocker) / max(abs(averageBlocker), 0.001), 0.0, 1.0);\n float radius = searchRadius * (1.0 + penumbra * 12.0);\n float visibility = 0.0;\n for (int index = 0; index < 48; index++) {\n if (index >= shadow.filterSampleCount) break;\n vec2 disk = shadow_diskSample(index, shadow.filterSampleCount, rotation) * radius;\n vec3 coordinate = shadow_pointCoordinate(lightIndex, normalize(direction + tangent * disk.x + bitangent * disk.y));\n visibility += shadow_compare(pointShadowTexture, coordinate.xy, int(coordinate.z), referenceDepth);\n }\n return mix(1.0, visibility / max(float(shadow.filterSampleCount), 1.0), light.strength);\n}\n";
3
+ //# sourceMappingURL=shadow-glsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadow-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/shadow/shadow-glsl.ts"],"names":[],"mappings":"AAIA,mGAAmG;AACnG,eAAO,MAAM,WAAW,24UAsMvB,CAAC"}