@woosh/meep-engine 3.61.1 → 3.61.2
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/package.json +1 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -0
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +4 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -1
- package/src/generation/foliage/material/foliage_atlas_cutout.js +21 -5
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -0
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_cluster_representatives.js +178 -78
- package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_mesh_build_bark.js +178 -97
- package/src/generation/foliage/skeleton/ShootLightField.d.ts +1 -0
- package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootLightField.js +88 -17
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +5 -2
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootWoodHash.js +191 -25
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +4 -0
- package/src/shade/playground/probe_clipmap_box/README.md +55 -0
- package/src/shade/playground/probe_clipmap_box/index.html +185 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts +8 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/main.js +323 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +93 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/scene.js +256 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +6 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.js +49 -24
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.js +50 -19
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.js +6 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +5 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +7 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +10 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +14 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -22
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +53 -65
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +9 -20
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +14 -19
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.js +13 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +4 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +4 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +4 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +14 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +3 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +7 -15
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +5 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +26 -8
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +170 -142
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +5 -8
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +15 -4
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +33 -7
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts +40 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.js +75 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js +3 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.js +41 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.js +24 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +3 -2
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +4 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +2 -5
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +3 -20
- package/src/shade/renderer/water/chunk_water_gi.d.ts +1 -1
- package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_gi.js +6 -8
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +76 -32
- package/src/core/math/hash/squirrel3.d.ts +0 -17
- package/src/core/math/hash/squirrel3.d.ts.map +0 -1
- package/src/core/math/hash/squirrel3.js +0 -30
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts +0 -12
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.js +0 -30
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_hash_lk } from "../random/chunk_hash_lk.js";
|
|
3
|
+
import { chunk_hash_to_float01 } from "../random/chunk_hash_to_float01.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Evaluates a 2D shuffled, Owen-scrambled Sobol (0, 2)-sequence point in [0, 1)^2
|
|
8
|
+
* entirely in registers with zero lookup tables.
|
|
9
|
+
*
|
|
10
|
+
* Every power-of-two prefix of 2^m samples forms a fully stratified (0, m, 2)-net
|
|
11
|
+
* across all elementary dyadic rectangles of area 2^-m, while per-pixel seeding
|
|
12
|
+
* decorrelates sample sets across pixels and bounce dimensions:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Index shuffling (MSB-to-LSB):** `sample_idx` is Owen-scrambled top-down via
|
|
15
|
+
* `reverseBits(hash_lk(reverseBits(sample_idx), ...))`. This maps every aligned
|
|
16
|
+
* block of 2^m contiguous indices `[k * 2^m, (k + 1) * 2^m)` bijectively onto
|
|
17
|
+
* another aligned 2^m block, randomizing traversal order per pixel while keeping
|
|
18
|
+
* bits `i_31..i_m` constant across the block so prefix stratification holds.
|
|
19
|
+
* 2. **Dimension 0 (Van der Corput):** Prior to radical inversion, the base-2
|
|
20
|
+
* Van der Corput sequence is the identity on `i`. Because bit 0 of `i` (`i_0`)
|
|
21
|
+
* already represents the geometric MSB (2^-1), `hash_lk` is applied directly
|
|
22
|
+
* followed by a single `reverseBits`.
|
|
23
|
+
* 3. **Dimension 1 (Sobol D1):** Computed without direction-number tables by
|
|
24
|
+
* multiplying `i` by the 32x32 upper-triangular Pascal matrix over GF(2)
|
|
25
|
+
* (`P_{k,j} = C(j, k) mod 2`, the 5-fold Kronecker power of `[1 1; 0 1]`) using
|
|
26
|
+
* 5 logarithmic butterfly shift-XOR stages before coordinate scrambling.
|
|
27
|
+
*
|
|
28
|
+
* For multi-bounce path tracing, pass a combined hash of `(pixel_coord, bounce_dim_pair)`
|
|
29
|
+
* as `pixel_seed` to construct padded 2D (0, 2)-sequences without high-dimensional
|
|
30
|
+
* direction tables.
|
|
31
|
+
*
|
|
32
|
+
* @see Brent Burley, "Practical Hash-based Owen Scrambling", Journal of Computer
|
|
33
|
+
* Graphics Techniques (JCGT), vol. 9, no. 4, pp. 1-20, 2020.
|
|
34
|
+
* http://jcgt.org/published/0009/04/01/
|
|
35
|
+
* @see Nathan Vegdahl, "Building a Better LK Hash", 2021.
|
|
36
|
+
* https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
|
37
|
+
* @see Ilya M. Sobol', "On the distribution of points in a cube and the approximate
|
|
38
|
+
* evaluation of integrals", USSR Computational Mathematics and Mathematical
|
|
39
|
+
* Physics, vol. 7, no. 4, pp. 86-112, 1967.
|
|
40
|
+
*
|
|
41
|
+
* @type {CodeChunk}
|
|
42
|
+
*/
|
|
43
|
+
export const chunk_sobol_sample_vec2 = CodeChunk.from(
|
|
44
|
+
//language=WGSL
|
|
45
|
+
`
|
|
46
|
+
fn sample_sobol_2d(sample_idx: u32, pixel_seed: u32) -> vec2<f32> {
|
|
47
|
+
// 1. Shuffle index (MSB -> LSB):
|
|
48
|
+
// Reverse sample_idx so s_31 is at bit 0, run LSB->MSB hash,
|
|
49
|
+
// then reverse back so i_0 is at bit 0 for Sobol generation.
|
|
50
|
+
let idx_seed = pixel_seed ^ 0x79c68e4au;
|
|
51
|
+
let i = reverseBits(hash_lk(reverseBits(sample_idx), idx_seed));
|
|
52
|
+
|
|
53
|
+
// 2. Dimension 0 (Van der Corput):
|
|
54
|
+
// i_0 (geometric MSB) is already at bit 0. Hash LSB->MSB, then
|
|
55
|
+
// reverse once so the geometric MSB sits at bit 31.
|
|
56
|
+
let u0 = reverseBits(hash_lk(i, pixel_seed ^ 0x9e3779b9u));
|
|
57
|
+
|
|
58
|
+
// 3. Dimension 1 (Sobol D1 via upper-triangular Pascal matrix):
|
|
59
|
+
// Requires i_0 at bit 0 so high bits (i_31..i_m, which are constant
|
|
60
|
+
// across 2^m-aligned blocks) shift down into low bits.
|
|
61
|
+
var b = i;
|
|
62
|
+
b ^= b >> 16u;
|
|
63
|
+
b ^= (b & 0xff00ff00u) >> 8u;
|
|
64
|
+
b ^= (b & 0xf0f0f0f0u) >> 4u;
|
|
65
|
+
b ^= (b & 0xccccccccu) >> 2u;
|
|
66
|
+
b ^= (b & 0xaaaaaaaau) >> 1u;
|
|
67
|
+
let u1 = reverseBits(hash_lk(b, pixel_seed ^ 0xbb67ae85u));
|
|
68
|
+
|
|
69
|
+
return vec2<f32>(hash_to_float01(u0), hash_to_float01(u1));
|
|
70
|
+
}
|
|
71
|
+
`,[
|
|
72
|
+
chunk_hash_lk,
|
|
73
|
+
chunk_hash_to_float01
|
|
74
|
+
]
|
|
75
|
+
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_vdc_radical_inverse.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_vdc_radical_inverse.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wCAFU,SAAS,CAalB;0BApByB,6BAA6B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_hash_to_float01 } from "../random/chunk_hash_to_float01.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
*
|
|
@@ -12,8 +13,9 @@ export const chunk_vdc_radical_inverse = CodeChunk.from(
|
|
|
12
13
|
fn vdc_radical_inverse(bits:u32) -> f32{
|
|
13
14
|
let b = reverseBits(bits);
|
|
14
15
|
|
|
15
|
-
return
|
|
16
|
+
return hash_to_float01(b);
|
|
16
17
|
}
|
|
17
18
|
`, [
|
|
19
|
+
chunk_hash_to_float01
|
|
18
20
|
]
|
|
19
21
|
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies Brent Burley's improved seeded Laine-Karras permutation hash for fast
|
|
3
|
+
* hash-based Owen scrambling of low-discrepancy sequences.
|
|
4
|
+
*
|
|
5
|
+
* Every operation in the sequence — integer addition, multiplication by an odd
|
|
6
|
+
* integer, and XOR-multiplication by an even constant — is a bijection modulo 2^k
|
|
7
|
+
* for all k in [1, 32]. Consequently, bit `i` of the output depends exclusively
|
|
8
|
+
* on bits `0..=i` of `x_in`, propagating entropy strictly from least-significant
|
|
9
|
+
* bit (LSB) to most-significant bit (MSB) while preserving prefix stratification.
|
|
10
|
+
*
|
|
11
|
+
* True Owen scrambling randomizes binary radical inverses from MSB to LSB. Unless
|
|
12
|
+
* your input sequence is already evaluated in bit-reversed order, wrap the call
|
|
13
|
+
* with `reverseBits`: `reverseBits(hash_lk(reverseBits(x), seed))`.
|
|
14
|
+
*
|
|
15
|
+
* @see Nathan Vegdahl, "Building a Better LK Hash", 2021.
|
|
16
|
+
* https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
|
17
|
+
* @see Brent Burley, "Practical Hash-based Owen Scrambling", Journal of Computer
|
|
18
|
+
* Graphics Techniques (JCGT), vol. 9, no. 4, pp. 1-20, 2020.
|
|
19
|
+
* http://jcgt.org/published/0009/04/01/
|
|
20
|
+
* @see Samuli Laine and Tero Karras, "Stratified Sampling for Stochastic
|
|
21
|
+
* Transparency", Computer Graphics Forum (Proceedings of EGSR), vol. 30,
|
|
22
|
+
* no. 4, pp. 1197-1204, 2011. https://doi.org/10.1111/j.1467-8659.2011.01978.x
|
|
23
|
+
*
|
|
24
|
+
* @type {CodeChunk}
|
|
25
|
+
*/
|
|
26
|
+
export const chunk_hash_lk: CodeChunk;
|
|
27
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
28
|
+
//# sourceMappingURL=chunk_hash_lk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_hash_lk.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/random/chunk_hash_lk.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,4BAFU,SAAS,CAejB;0BAxCwB,6BAA6B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Applies Brent Burley's improved seeded Laine-Karras permutation hash for fast
|
|
5
|
+
* hash-based Owen scrambling of low-discrepancy sequences.
|
|
6
|
+
*
|
|
7
|
+
* Every operation in the sequence — integer addition, multiplication by an odd
|
|
8
|
+
* integer, and XOR-multiplication by an even constant — is a bijection modulo 2^k
|
|
9
|
+
* for all k in [1, 32]. Consequently, bit `i` of the output depends exclusively
|
|
10
|
+
* on bits `0..=i` of `x_in`, propagating entropy strictly from least-significant
|
|
11
|
+
* bit (LSB) to most-significant bit (MSB) while preserving prefix stratification.
|
|
12
|
+
*
|
|
13
|
+
* True Owen scrambling randomizes binary radical inverses from MSB to LSB. Unless
|
|
14
|
+
* your input sequence is already evaluated in bit-reversed order, wrap the call
|
|
15
|
+
* with `reverseBits`: `reverseBits(hash_lk(reverseBits(x), seed))`.
|
|
16
|
+
*
|
|
17
|
+
* @see Nathan Vegdahl, "Building a Better LK Hash", 2021.
|
|
18
|
+
* https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
|
19
|
+
* @see Brent Burley, "Practical Hash-based Owen Scrambling", Journal of Computer
|
|
20
|
+
* Graphics Techniques (JCGT), vol. 9, no. 4, pp. 1-20, 2020.
|
|
21
|
+
* http://jcgt.org/published/0009/04/01/
|
|
22
|
+
* @see Samuli Laine and Tero Karras, "Stratified Sampling for Stochastic
|
|
23
|
+
* Transparency", Computer Graphics Forum (Proceedings of EGSR), vol. 30,
|
|
24
|
+
* no. 4, pp. 1197-1204, 2011. https://doi.org/10.1111/j.1467-8659.2011.01978.x
|
|
25
|
+
*
|
|
26
|
+
* @type {CodeChunk}
|
|
27
|
+
*/
|
|
28
|
+
export const chunk_hash_lk = CodeChunk.from(
|
|
29
|
+
//language=WGSL
|
|
30
|
+
`
|
|
31
|
+
fn hash_lk(x_in: u32, seed: u32) -> u32 {
|
|
32
|
+
var x = x_in;
|
|
33
|
+
x ^= x * 0x3d20adeau;
|
|
34
|
+
x += seed;
|
|
35
|
+
x *= (seed >> 16u) | 1u;
|
|
36
|
+
x ^= x * 0x05526c56u;
|
|
37
|
+
x ^= x * 0x53a22864u;
|
|
38
|
+
return x;
|
|
39
|
+
}
|
|
40
|
+
`
|
|
41
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `a + b × scale`, coefficient by coefficient: a weighted SH added to a sum.
|
|
3
|
+
*
|
|
4
|
+
* ```wgsl
|
|
5
|
+
* fn sh3_color_add_scaled(a: array<vec3<f32>, 9>, b: array<vec3<f32>, 9>, scale: f32) -> array<vec3<f32>, 9>
|
|
6
|
+
* ```
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_sh3_color_add_scaled: CodeChunk;
|
|
11
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
12
|
+
//# sourceMappingURL=chunk_sh3_color_add_scaled.d.ts.map
|
package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_sh3_color_add_scaled.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,yCAFU,SAAS,CAchB;0BAvBuB,6BAA6B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `a + b × scale`, coefficient by coefficient: a weighted SH added to a sum.
|
|
5
|
+
*
|
|
6
|
+
* ```wgsl
|
|
7
|
+
* fn sh3_color_add_scaled(a: array<vec3<f32>, 9>, b: array<vec3<f32>, 9>, scale: f32) -> array<vec3<f32>, 9>
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* @type {CodeChunk}
|
|
11
|
+
*/
|
|
12
|
+
export const chunk_sh3_color_add_scaled = CodeChunk.from(
|
|
13
|
+
//language=WGSL
|
|
14
|
+
`
|
|
15
|
+
fn sh3_color_add_scaled(a: array<vec3<f32>, 9>, b: array<vec3<f32>, 9>, scale: f32) -> array<vec3<f32>, 9> {
|
|
16
|
+
var out: array<vec3<f32>, 9>;
|
|
17
|
+
|
|
18
|
+
for (var i = 0; i < 9; i++) {
|
|
19
|
+
out[i] = a[i] + b[i] * scale;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
`);
|
|
@@ -34,11 +34,11 @@ export class GPUIrradianceClipmap {
|
|
|
34
34
|
/**
|
|
35
35
|
* @returns {GPUTextureContext}
|
|
36
36
|
*/
|
|
37
|
-
get texture_y(): GPUTextureContext;
|
|
37
|
+
get texture_y(): import("../../texture/GPUTextureContext.js").GPUTextureContext;
|
|
38
38
|
/**
|
|
39
39
|
* @returns {GPUTextureContext}
|
|
40
40
|
*/
|
|
41
|
-
get texture_cocg(): GPUTextureContext;
|
|
41
|
+
get texture_cocg(): import("../../texture/GPUTextureContext.js").GPUTextureContext;
|
|
42
42
|
/**
|
|
43
43
|
* @returns {GPUBuffer}
|
|
44
44
|
*/
|
|
@@ -112,6 +112,7 @@ export class GPUIrradianceClipmap {
|
|
|
112
112
|
destroy(): void;
|
|
113
113
|
#private;
|
|
114
114
|
}
|
|
115
|
+
export type GPUTextureContext = import("../../texture/GPUTextureContext.js").GPUTextureContext;
|
|
115
116
|
import { GPUTileAtlas3D } from "../../texture/atlas/GPUTileAtlas3D.js";
|
|
116
117
|
import { IrradianceCascadePlacement } from "./IrradianceCascadePlacement.js";
|
|
117
118
|
import { ShaderSwitchSet } from "../../shader/compiler/ShaderSwitchSet.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUIrradianceClipmap.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUIrradianceClipmap.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js"],"names":[],"mappings":"AAiDA;;;;;;;;;;;;;GAaG;AACH;IA2CI;;;;;;;OAOG;IACH;QAL4B,aAAa,GAA9B,MAAM;QAC6B,UAAU,GAA7C,MAAM,GAAC,UAAU,MAAM,CAAC;QACP,SAAS,GAA1B,MAAM;QACW,WAAW,GAA5B,MAAM;OA+DhB;IAED;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,gFAEC;IAED;;OAEG;IACH,mFAEC;IAED;;OAEG;IACH,yBAEC;IAED;;OAEG;IACH,4BAEC;IAED;;;OAGG;IACH,0BAEC;IAED;;OAEG;IACH,4CAEC;IAED;;OAEG;IACH,uBAEC;IAED;;;;;;;;OAQG;IACH,oBALW,MAAM,KACN,MAAM,KACN,MAAM,oBACN,eAAe,QAgFzB;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH;QAZsG,KAAK,EAAhG,OAAO,8DAA8D,EAAE,UAAU;QACZ,MAAM,EAA3E,OAAO,kCAAkC,EAAE,gBAAgB;QACO,SAAS,EAA3E,OAAO,gCAAgC,EAAE,eAAe;QACxC,eAAe,EAA/B,MAAM;QACoB,eAAe,GAAzC,eAAe;QACuE,MAAM,GAA5F,OAAO,oDAAoD,EAAE,cAAc;QACkB,GAAG,GAAhG,OAAO,sDAAsD,EAAE,mBAAmB;QACgB,MAAM,EAAxG,OAAO,8DAA8D,EAAE,iBAAiB;QAErE,YAAY;QAC7B;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAkJtD;IAED;;OAEG;IACH,gBAQC;;CACJ;gCAxeY,OAAO,oCAAoC,EAAE,iBAAiB;+BAJ5C,uCAAuC;2CAmB3B,iCAAiC;gCAxB5C,0CAA0C"}
|
|
@@ -10,6 +10,10 @@ import { encoder_prepare_shader_bindings_defaults } from "../../shader/resource/
|
|
|
10
10
|
import { SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR } from "../../shadow/map/SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR.js";
|
|
11
11
|
import { GPUTileAtlas3D } from "../../texture/atlas/GPUTileAtlas3D.js";
|
|
12
12
|
import { DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR } from "../../texture/DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {import("../../texture/GPUTextureContext.js").GPUTextureContext} GPUTextureContext
|
|
16
|
+
*/
|
|
13
17
|
import {
|
|
14
18
|
IRRADIANCE_CLIPMAP_CASCADE_LIMIT,
|
|
15
19
|
IRRADIANCE_CLIPMAP_DEFAULT_BLEND_SKIRT,
|
package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts
CHANGED
|
@@ -20,11 +20,8 @@ export const chunk_irradiance_clipmap_gi_sample_lpv: CodeChunk;
|
|
|
20
20
|
* voxel is no surface, so there is no normal to bias the point by or to weigh back faces with, nor a view.
|
|
21
21
|
* Where no probe weighs anything, the environment SH, as under IBL.
|
|
22
22
|
*
|
|
23
|
-
* The probes' SH is
|
|
24
|
-
* `
|
|
25
|
-
* `volumetrics_irradiance_sh_add_radiance` turns back into it: 2π × the luma, band 1 in the basis order
|
|
26
|
-
* (y, z, x), and the chroma, which only the constant band has, over band 0's basis constant. Reads the probes'
|
|
27
|
-
* group, `view` and `environment_sh`.
|
|
23
|
+
* The probes' SH is radiance SH3, as Brick4's: its bands 0 and 1 are the radiance SH2. Reads the probes' group,
|
|
24
|
+
* `view` and `environment_sh`.
|
|
28
25
|
* @type {CodeChunk}
|
|
29
26
|
*/
|
|
30
27
|
export const chunk_irradiance_clipmap_gi_sample_probe_clipmap: CodeChunk;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_irradiance_clipmap_gi_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_irradiance_clipmap_gi_sample.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js"],"names":[],"mappings":"AAYA;;;GAGG;AACH,qDAFU,SAAS,CAcjB;AAIF;;;;GAIG;AACH,wDAFU,SAAS,CAYjB;AAEF;;;GAGG;AACH,qDAFU,SAAS,CAqBjB;AAEF;;;;;;;;;GASG;AACH,+DAFU,SAAS,CAwBjB;AAIF;;;;;GAKG;AACH,iDAFU,eAAe,CAEiE;0BA3GhE,oCAAoC;gCAC9B,0CAA0C"}
|
package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { chunk_brick4_sample_sh } from "../../global_illumination/brick4/gpu/draw/chunk_brick4_sample_sh.js";
|
|
2
2
|
import { chunk_probe_clipmap_pick } from "../../global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js";
|
|
3
3
|
import { INDIRECT_LIGHTING } from "../../INDIRECT_LIGHTING.js";
|
|
4
|
-
import { chunk_YCoCg_to_rgb } from "../../shader/chunk/color/YCoCg/chunk_YCoCg_to_rgb.js";
|
|
5
4
|
import { chunk_jitter_from_vectors } from "../../shader/chunk/random/chunk_jitter_from_vectors.js";
|
|
6
5
|
import { ENVIRONMENT_SH_RESOURCE } from "../../light/environment/ENVIRONMENT_SH_RESOURCE.js";
|
|
7
6
|
import { ShadeIndirectLightingMode } from "../../ShadeIndirectLightingMode.js";
|
|
@@ -79,11 +78,8 @@ fn irradiance_clipmap_gi_sample(position_ws: vec3<f32>) -> array<vec3<f32>, 4> {
|
|
|
79
78
|
* voxel is no surface, so there is no normal to bias the point by or to weigh back faces with, nor a view.
|
|
80
79
|
* Where no probe weighs anything, the environment SH, as under IBL.
|
|
81
80
|
*
|
|
82
|
-
* The probes' SH is
|
|
83
|
-
* `
|
|
84
|
-
* `volumetrics_irradiance_sh_add_radiance` turns back into it: 2π × the luma, band 1 in the basis order
|
|
85
|
-
* (y, z, x), and the chroma, which only the constant band has, over band 0's basis constant. Reads the probes'
|
|
86
|
-
* group, `view` and `environment_sh`.
|
|
81
|
+
* The probes' SH is radiance SH3, as Brick4's: its bands 0 and 1 are the radiance SH2. Reads the probes' group,
|
|
82
|
+
* `view` and `environment_sh`.
|
|
87
83
|
* @type {CodeChunk}
|
|
88
84
|
*/
|
|
89
85
|
export const chunk_irradiance_clipmap_gi_sample_probe_clipmap = CodeChunk.from(
|
|
@@ -102,24 +98,11 @@ fn irradiance_clipmap_gi_sample(position_ws: vec3<f32>) -> array<vec3<f32>, 4> {
|
|
|
102
98
|
);
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
|
|
106
|
-
const TWO_PI: f32 = 6.283185307179586;
|
|
107
|
-
const BAND_0_BASIS: f32 = 0.28209479177387814;
|
|
108
|
-
|
|
109
|
-
let Y = probes.sh.Y * TWO_PI;
|
|
110
|
-
|
|
111
|
-
// the Metro layout is (x, y, z, constant); the basis order is (constant, y, z, x)
|
|
112
|
-
return array<vec3<f32>, 4>(
|
|
113
|
-
YCoCg_to_rgb(vec3<f32>(Y.w, probes.sh.CoCg * (BAND_0_BASIS * TWO_PI))),
|
|
114
|
-
vec3<f32>(Y.y),
|
|
115
|
-
vec3<f32>(Y.z),
|
|
116
|
-
vec3<f32>(Y.x),
|
|
117
|
-
);
|
|
101
|
+
return array<vec3<f32>, 4>(probes.sh[0], probes.sh[1], probes.sh[2], probes.sh[3]);
|
|
118
102
|
}
|
|
119
103
|
`, [
|
|
120
104
|
chunk_probe_clipmap_pick,
|
|
121
105
|
chunk_jitter_from_vectors,
|
|
122
|
-
chunk_YCoCg_to_rgb,
|
|
123
106
|
]
|
|
124
107
|
);
|
|
125
108
|
|
|
@@ -12,7 +12,7 @@ export const chunk_water_gi_ibl: CodeChunk;
|
|
|
12
12
|
export const chunk_water_gi_brick4: CodeChunk;
|
|
13
13
|
/**
|
|
14
14
|
* The probe clipmap (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §9.5): each call one pick at the point, jittered by a
|
|
15
|
-
* hash of the point and the normal, as Brick4's is. The irradiance is
|
|
15
|
+
* hash of the point and the normal, as Brick4's is. The irradiance is the picked SH resolved at the normal,
|
|
16
16
|
* the normal standing in for the view, which the irradiance call has none of. The specular is the probes'
|
|
17
17
|
* radiance picked by the normal and the view (§9.3). Where no probe weighs anything, each is the environment's.
|
|
18
18
|
* Reads the probes' group, `view` and `tEnvironment`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_water_gi.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/chunk_water_gi.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_water_gi.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/water/chunk_water_gi.js"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,iCAFU,SAAS,CAUoC;AAEvD;;;;GAIG;AACH,oCAFU,SAAS,CAgBwB;AAE3C;;;;;;;GAOG;AACH,2CAFU,SAAS,CAuB+D;AAElF;;;;;;GAMG;AACH,6BAFU,eAAe,CAE6C;0BA3F5C,iCAAiC;gCAC3B,uCAAuC"}
|
|
@@ -9,11 +9,10 @@ import {
|
|
|
9
9
|
} from "../global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js";
|
|
10
10
|
import { INDIRECT_LIGHTING } from "../INDIRECT_LIGHTING.js";
|
|
11
11
|
import { ShadeIndirectLightingMode } from "../ShadeIndirectLightingMode.js";
|
|
12
|
-
import { PI_DECLARATION } from "../shader/chunk/math/PI_DECLARATION.js";
|
|
13
12
|
import { chunk_jitter_from_vectors } from "../shader/chunk/random/chunk_jitter_from_vectors.js";
|
|
14
13
|
import {
|
|
15
|
-
|
|
16
|
-
} from "../shader/chunk/spherical_harmonics/
|
|
14
|
+
chunk_sh3_color_get_irradiance_at
|
|
15
|
+
} from "../shader/chunk/spherical_harmonics/chunk_sh3_color_get_irradiance_at.js";
|
|
17
16
|
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
18
17
|
import { CodeChunkChoice } from "../shader/compiler/CodeChunkChoice.js";
|
|
19
18
|
|
|
@@ -69,7 +68,7 @@ fn water_gi_specular(position: vec3<f32>, normal: vec3<f32>, view_direction: vec
|
|
|
69
68
|
|
|
70
69
|
/**
|
|
71
70
|
* The probe clipmap (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §9.5): each call one pick at the point, jittered by a
|
|
72
|
-
* hash of the point and the normal, as Brick4's is. The irradiance is
|
|
71
|
+
* hash of the point and the normal, as Brick4's is. The irradiance is the picked SH resolved at the normal,
|
|
73
72
|
* the normal standing in for the view, which the irradiance call has none of. The specular is the probes'
|
|
74
73
|
* radiance picked by the normal and the view (§9.3). Where no probe weighs anything, each is the environment's.
|
|
75
74
|
* Reads the probes' group, `view` and `tEnvironment`.
|
|
@@ -80,8 +79,7 @@ fn water_gi_irradiance(position: vec3<f32>, normal: vec3<f32>) -> vec3<f32> {
|
|
|
80
79
|
let probes = probe_clipmap_sample_sh(position, normal, normal, jitter_from_vectors(position, normal));
|
|
81
80
|
|
|
82
81
|
if (probes.found) {
|
|
83
|
-
|
|
84
|
-
return PI * resolve_irradiance_sh_to_diffuse(probes.sh.Y, probes.sh.CoCg, normal);
|
|
82
|
+
return sh3_color_get_irradiance_at(normal, probes.sh);
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
return get_ibl_irradiance(normal);
|
|
@@ -96,8 +94,8 @@ fn water_gi_specular(position: vec3<f32>, normal: vec3<f32>, view_direction: vec
|
|
|
96
94
|
|
|
97
95
|
return get_ibl_radiance(view_direction, normal, roughness);
|
|
98
96
|
}
|
|
99
|
-
`, [chunk_probe_clipmap_pick, chunk_probe_clipmap_sample_radiance,
|
|
100
|
-
chunk_jitter_from_vectors,
|
|
97
|
+
`, [chunk_probe_clipmap_pick, chunk_probe_clipmap_sample_radiance, chunk_sh3_color_get_irradiance_at,
|
|
98
|
+
chunk_jitter_from_vectors, chunk_get_ibl_irradiance, chunk_get_ibl_radiance]);
|
|
101
99
|
|
|
102
100
|
/**
|
|
103
101
|
* The water's indirect lighting by the renderer's mode ({@link INDIRECT_LIGHTING}): IBL and LPV
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WGSLLanguageCore.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/WGSLLanguageCore.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"WGSLLanguageCore.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/WGSLLanguageCore.js"],"names":[],"mappings":";IAk6DA;;;;;;;;;;;;;OAaG;IACH,+DAyFC"}
|
|
@@ -99,11 +99,26 @@ const BITCAST_F16 = new Float16Array(BITCAST_BUFFER);
|
|
|
99
99
|
* @returns {*}
|
|
100
100
|
*/
|
|
101
101
|
function makeVec(TypedArrayCtor, size, args) {
|
|
102
|
-
|
|
102
|
+
const n = args.length;
|
|
103
|
+
if (n === 0) {
|
|
103
104
|
return new TypedArrayCtor(size);
|
|
104
105
|
}
|
|
106
|
+
if (n === size && typeof args[0] === 'number') {
|
|
107
|
+
let all_num = true;
|
|
108
|
+
for (let k = 1; k < n; k++) {
|
|
109
|
+
if (typeof args[k] !== 'number') {
|
|
110
|
+
all_num = false;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (all_num) {
|
|
115
|
+
const out = new TypedArrayCtor(size);
|
|
116
|
+
for (let k = 0; k < size; k++) out[k] = args[k];
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
105
120
|
// Single scalar → broadcast.
|
|
106
|
-
if (
|
|
121
|
+
if (n === 1 && typeof args[0] === 'number') {
|
|
107
122
|
const v = args[0];
|
|
108
123
|
const out = new TypedArrayCtor(size);
|
|
109
124
|
for (let i = 0; i < size; i++) out[i] = v;
|
|
@@ -112,7 +127,8 @@ function makeVec(TypedArrayCtor, size, args) {
|
|
|
112
127
|
// Otherwise flatten.
|
|
113
128
|
const out = new TypedArrayCtor(size);
|
|
114
129
|
let i = 0;
|
|
115
|
-
for (
|
|
130
|
+
for (let k = 0; k < n; k++) {
|
|
131
|
+
const a = args[k];
|
|
116
132
|
if (typeof a === 'number' || typeof a === 'boolean') {
|
|
117
133
|
out[i++] = +a;
|
|
118
134
|
} else if (a != null && typeof a.length === 'number') {
|
|
@@ -213,7 +229,31 @@ function is_vec(v) {
|
|
|
213
229
|
* @param {function(number, number): number} op
|
|
214
230
|
* @returns {*}
|
|
215
231
|
*/
|
|
232
|
+
const op_add = (x, y) => x + y;
|
|
233
|
+
const op_sub = (x, y) => x - y;
|
|
234
|
+
const op_mul = (x, y) => x * y;
|
|
235
|
+
const op_div = (x, y) => x / y;
|
|
236
|
+
const op_add_f32 = (x, y) => Math.fround(x + y);
|
|
237
|
+
const op_sub_f32 = (x, y) => Math.fround(x - y);
|
|
238
|
+
const op_mul_f32 = (x, y) => Math.fround(x * y);
|
|
239
|
+
const op_div_f32 = (x, y) => Math.fround(x / y);
|
|
240
|
+
const op_add_f16 = (x, y) => round_f16(x + y);
|
|
241
|
+
const op_sub_f16 = (x, y) => round_f16(x - y);
|
|
242
|
+
const op_mul_f16 = (x, y) => round_f16(x * y);
|
|
243
|
+
const op_div_f16 = (x, y) => round_f16(x / y);
|
|
244
|
+
const op_rem = (x, y) => x % y;
|
|
245
|
+
const op_idiv = (x, y) => Math.trunc(x / y);
|
|
246
|
+
const op_add_u32 = (x, y) => (x + y) >>> 0;
|
|
247
|
+
const op_sub_u32 = (x, y) => (x - y) >>> 0;
|
|
248
|
+
const op_mul_u32 = (x, y) => Math.imul(x, y) >>> 0;
|
|
249
|
+
const op_add_i32 = (x, y) => (x + y) | 0;
|
|
250
|
+
const op_sub_i32 = (x, y) => (x - y) | 0;
|
|
251
|
+
const op_mul_i32 = (x, y) => Math.imul(x, y) | 0;
|
|
252
|
+
|
|
216
253
|
function binop(a, b, op) {
|
|
254
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
255
|
+
return op(a, b);
|
|
256
|
+
}
|
|
217
257
|
const a_vec = is_vec(a);
|
|
218
258
|
const b_vec = is_vec(b);
|
|
219
259
|
|
|
@@ -302,7 +342,7 @@ function round_ties_to_even(x) {
|
|
|
302
342
|
}
|
|
303
343
|
|
|
304
344
|
function unop(a, op) {
|
|
305
|
-
if (!is_vec(a)) {
|
|
345
|
+
if (typeof a === "number" || !is_vec(a)) {
|
|
306
346
|
return op(a);
|
|
307
347
|
}
|
|
308
348
|
const out = new a.constructor(a.length);
|
|
@@ -321,15 +361,15 @@ function unop(a, op) {
|
|
|
321
361
|
* @returns {*}
|
|
322
362
|
*/
|
|
323
363
|
function ternop(a, b, c, op) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
364
|
+
const a_vec = is_vec(a);
|
|
365
|
+
const b_vec = is_vec(b);
|
|
366
|
+
const c_vec = is_vec(c);
|
|
367
|
+
if (a_vec || b_vec || c_vec) {
|
|
368
|
+
const ref = a_vec ? a : (b_vec ? b : c);
|
|
369
|
+
const length = ref.length;
|
|
370
|
+
const out = new ref.constructor(length);
|
|
328
371
|
for (let i = 0; i < length; i++) {
|
|
329
|
-
|
|
330
|
-
const bi = is_vec(b) ? b[i] : b;
|
|
331
|
-
const ci = is_vec(c) ? c[i] : c;
|
|
332
|
-
out[i] = op(ai, bi, ci);
|
|
372
|
+
out[i] = op(a_vec ? a[i] : a, b_vec ? b[i] : b, c_vec ? c[i] : c);
|
|
333
373
|
}
|
|
334
374
|
return out;
|
|
335
375
|
}
|
|
@@ -358,6 +398,10 @@ function ternop(a, b, c, op) {
|
|
|
358
398
|
* @returns {*}
|
|
359
399
|
*/
|
|
360
400
|
function copy_value(value) {
|
|
401
|
+
if (typeof value !== "object" || value === null) {
|
|
402
|
+
return value;
|
|
403
|
+
}
|
|
404
|
+
|
|
361
405
|
if (ArrayBuffer.isView(value)) {
|
|
362
406
|
return value.slice();
|
|
363
407
|
}
|
|
@@ -606,10 +650,10 @@ export const WGSLLanguageCore = {
|
|
|
606
650
|
// Arithmetic helpers (work on scalars and vectors element-wise)
|
|
607
651
|
// ---------------------------------------------------------------------
|
|
608
652
|
|
|
609
|
-
add: (a, b) =>
|
|
610
|
-
sub: (a, b) =>
|
|
611
|
-
mul: (a, b) =>
|
|
612
|
-
div: (a, b) =>
|
|
653
|
+
add: (a, b) => typeof a === "number" && typeof b === "number" ? a + b : binop(a, b, op_add),
|
|
654
|
+
sub: (a, b) => typeof a === "number" && typeof b === "number" ? a - b : binop(a, b, op_sub),
|
|
655
|
+
mul: (a, b) => typeof a === "number" && typeof b === "number" ? a * b : binop(a, b, op_mul),
|
|
656
|
+
div: (a, b) => typeof a === "number" && typeof b === "number" ? a / b : binop(a, b, op_div),
|
|
613
657
|
|
|
614
658
|
/*
|
|
615
659
|
The same four at f32, for a SCALAR whose type the compiler knows is f32.
|
|
@@ -632,23 +676,23 @@ export const WGSLLanguageCore = {
|
|
|
632
676
|
runtime. `Math.fround` of a vector is NaN, and binop is already idempotent here: a vec lane is
|
|
633
677
|
rounded and then stored into the Float32Array that would have rounded it anyway.
|
|
634
678
|
*/
|
|
635
|
-
add_f32: (a, b) =>
|
|
636
|
-
sub_f32: (a, b) =>
|
|
637
|
-
mul_f32: (a, b) =>
|
|
638
|
-
div_f32: (a, b) =>
|
|
679
|
+
add_f32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.fround(a + b) : binop(a, b, op_add_f32),
|
|
680
|
+
sub_f32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.fround(a - b) : binop(a, b, op_sub_f32),
|
|
681
|
+
mul_f32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.fround(a * b) : binop(a, b, op_mul_f32),
|
|
682
|
+
div_f32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.fround(a / b) : binop(a, b, op_div_f32),
|
|
639
683
|
|
|
640
684
|
// The same four at f16, for a SCALAR whose type the compiler knows is f16. Without these,
|
|
641
685
|
// scalar f16 arithmetic ran in f64 (`16000.0h * 8.0h` evaluated to 128000 instead of +Infinity,
|
|
642
686
|
// and `1e-3h * 1e-3h` evaluated to 1e-6 instead of underflowing in binary16).
|
|
643
|
-
add_f16: (a, b) =>
|
|
644
|
-
sub_f16: (a, b) =>
|
|
645
|
-
mul_f16: (a, b) =>
|
|
646
|
-
div_f16: (a, b) =>
|
|
647
|
-
rem: (a, b) =>
|
|
687
|
+
add_f16: (a, b) => typeof a === "number" && typeof b === "number" ? round_f16(a + b) : binop(a, b, op_add_f16),
|
|
688
|
+
sub_f16: (a, b) => typeof a === "number" && typeof b === "number" ? round_f16(a - b) : binop(a, b, op_sub_f16),
|
|
689
|
+
mul_f16: (a, b) => typeof a === "number" && typeof b === "number" ? round_f16(a * b) : binop(a, b, op_mul_f16),
|
|
690
|
+
div_f16: (a, b) => typeof a === "number" && typeof b === "number" ? round_f16(a / b) : binop(a, b, op_div_f16),
|
|
691
|
+
rem: (a, b) => typeof a === "number" && typeof b === "number" ? a % b : binop(a, b, op_rem),
|
|
648
692
|
|
|
649
693
|
// Integer division — truncates toward zero, matching WGSL `/` semantics on integer types.
|
|
650
694
|
// The compiler routes `/` through `idiv` when both operands' tracked types are integer.
|
|
651
|
-
idiv: (a, b) =>
|
|
695
|
+
idiv: (a, b) => typeof a === "number" && typeof b === "number" ? Math.trunc(a / b) : binop(a, b, op_idiv),
|
|
652
696
|
|
|
653
697
|
// WGSL integer arithmetic wraps at 32 bits; JS numbers grow instead. Without wrapping, any
|
|
654
698
|
// hash or PRNG that multiplies by a large odd constant leaves the u32 range within a step or
|
|
@@ -658,13 +702,13 @@ export const WGSLLanguageCore = {
|
|
|
658
702
|
//
|
|
659
703
|
// The compiler routes `+` / `-` / `*` here only when the result type is known to be an integer,
|
|
660
704
|
// so float math never reaches these.
|
|
661
|
-
add_u32: (a, b) =>
|
|
662
|
-
sub_u32: (a, b) =>
|
|
663
|
-
mul_u32: (a, b) =>
|
|
705
|
+
add_u32: (a, b) => typeof a === "number" && typeof b === "number" ? (a + b) >>> 0 : binop(a, b, op_add_u32),
|
|
706
|
+
sub_u32: (a, b) => typeof a === "number" && typeof b === "number" ? (a - b) >>> 0 : binop(a, b, op_sub_u32),
|
|
707
|
+
mul_u32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.imul(a, b) >>> 0 : binop(a, b, op_mul_u32),
|
|
664
708
|
|
|
665
|
-
add_i32: (a, b) =>
|
|
666
|
-
sub_i32: (a, b) =>
|
|
667
|
-
mul_i32: (a, b) =>
|
|
709
|
+
add_i32: (a, b) => typeof a === "number" && typeof b === "number" ? (a + b) | 0 : binop(a, b, op_add_i32),
|
|
710
|
+
sub_i32: (a, b) => typeof a === "number" && typeof b === "number" ? (a - b) | 0 : binop(a, b, op_sub_i32),
|
|
711
|
+
mul_i32: (a, b) => typeof a === "number" && typeof b === "number" ? Math.imul(a, b) | 0 : binop(a, b, op_mul_i32),
|
|
668
712
|
|
|
669
713
|
// Element-wise bitwise / shift helpers. JS's raw `&` / `|` / `^` / `<<` / `>>` work on
|
|
670
714
|
// scalars but not typed arrays (they coerce the array to a number → NaN), so the compiler
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Based on Squirrel3 hash function by Squirrel Eiserloh
|
|
3
|
-
*
|
|
4
|
-
* NOTE: every step is wrapping u32 arithmetic, matching the WGSL twin `chunk_hash_squirrel3` bit
|
|
5
|
-
* for bit. This used to multiply with plain `*`, which is a double multiply - `hash * 0x1B56C4E9`
|
|
6
|
-
* exceeds 2^53 for any int32-sized hash, so the low bits the following `hash ^= hash >> 8` mixes
|
|
7
|
-
* were rounded away before they were used. The result set bit 31 in exactly zero of 200,000
|
|
8
|
-
* outputs, half the codomain unreachable, and disagreed with the GPU on every value. An in-file
|
|
9
|
-
* comment used to blame the algorithm for the resulting low entropy; it was this port.
|
|
10
|
-
*
|
|
11
|
-
* @deprecated prefer {@link lowbias32}, as the WGSL chunk already says of its own twin
|
|
12
|
-
* @see GDC 2017 presentation on "Math for Game Programmers: Noise-Based RNG"
|
|
13
|
-
* @param {number} value expected to be an integer, if not - it will be truncated to such
|
|
14
|
-
* @returns {number} unsigned 32-bit integer
|
|
15
|
-
*/
|
|
16
|
-
export function squirrel3(value: number): number;
|
|
17
|
-
//# sourceMappingURL=squirrel3.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"squirrel3.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/hash/squirrel3.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,iCAHW,MAAM,GACJ,MAAM,CAYlB"}
|