# fx_noise
Procedural noise for effect shaders, as WGSL other shaders include with `#include "fx_noise"`:
integer hashes, value and gradient noise in 2D and 3D, fBm and ridged fBm over them, curl noise, and
worley (cellular) noise that returns the distance to the nearest feature point and that cell's id.
The functions are pure math over their arguments, so a material's fragment shader and a compute
shader can both include it and read the same field. Every generator takes an explicit `seed`, so one
shader draws several uncorrelated fields from the same coordinates. The hashes mix integers, so a
value is the same bit pattern wherever it runs; the float entry points hash a float's bit pattern,
with `0.0` and `-0.0` folded together.
```wgsl
#include "fx_noise"
```
| Function | Returns |
|---|---|
| `fx_hash11(x)`, `fx_hash21(p)`, `fx_hash31(p)` | a stable value in [0, 1) for a number or point |
| `fx_value_noise2(p, seed)`, `fx_value_noise3(p, seed)` | smooth value noise in [0, 1) |
| `fx_gradient_noise2(p, seed)`, `fx_gradient_noise3(p, seed)` | gradient (Perlin-style) noise in [-1, 1], exactly 0 at every integer point |
| `fx_fbm2(p, octaves, lacunarity, gain, seed)`, `fx_fbm3(...)` | fractal sum of gradient noise in [-1, 1]: clouds, smoke, rock |
| `fx_ridged_fbm3(p, octaves, lacunarity, gain, seed)` | ridged fractal noise in [0, 1]: cracks, crags, veins |
| `fx_curl_noise3(p, seed)` | a divergence-free flow vector: swirling smoke and dust |
| `fx_worley2(p, seed)`, `fx_worley3(p, seed)` | `{ dist, cell, id }` of the nearest feature point: foam cells, stone, sparkle |
| `fx_worley_fbm2(p, octaves, lacunarity, gain, seed)` | fractal cellular noise in [0, 1] |
## Arguments
- `p` is an `f32`, `vec2f` or `vec3f` coordinate, matching the function's dimension.
- `seed` is a `u32`.
- `octaves` is a `u32`, clamped to 1 through `FX_FBM_MAX_OCTAVES` (12). Each octave multiplies the
frequency by `lacunarity` and the amplitude by `abs(gain)`, and the fBm functions divide by the
summed amplitudes, which keeps the stated range for any gain. Octave `i` uses seed `seed + i *
1013`.
## Building blocks
The module also exports the pieces the generators are built from:
| Function or item | What it is |
|---|---|
| `fx_hash_u32(x)`, `fx_hash_u2(x, y)`, `fx_hash_u3(x, y, z)` | Integer avalanche hashes of one, two or three `u32` words, returning a `u32`. |
| `fx_unorm(h)`, `fx_snorm(h)` | A hashed `u32` as an `f32` in [0, 1) or [-1, 1), from its top 24 bits. |
| `fx_bits(x)` | The `u32` bits of an `f32`, with negative zero folded onto positive zero. |
| `fx_hash22(p)`, `fx_hash33(p)` | Two or three decorrelated values in [0, 1) for a 2D or 3D point. |
| `fx_lattice_u2(cell, seed)`, `fx_lattice_u3(cell, seed)` | The hashed `u32` a seeded integer lattice corner (`vec2i` or `vec3i`) carries. |
| `fx_lattice21(cell, seed)`, `fx_lattice31(cell, seed)` | That corner's value in [0, 1); `fx_value_noise2` at an integer point equals `fx_lattice21` of that point. |
| `fx_fade(t)` | The quintic fade `t^3 * (t * (6t - 15) + 10)` used to interpolate across a cell. |
| `fx_gradient2(cell, seed)`, `fx_gradient3(cell, seed)` | The unit gradient a seeded lattice corner carries; the 3D one is spread evenly over the sphere. |
| `fx_curl_potential3(p, seed)` | The three-component potential `fx_curl_noise3` takes the curl of, by central differences over `FX_CURL_EPSILON` (0.05). |
| `fx_cell_point2(cell, seed)`, `fx_cell_point3(cell, seed)` | Where a cell's feature point sits inside the cell, in [0, 1) per axis. |
| `fx_cell_id2(cell, seed)`, `fx_cell_id3(cell, seed)` | The id in [0, 1) a cell is tinted by. |
| `FxWorley2`, `FxWorley3` | The worley result: `dist` (`f32`), `cell` (`vec2i` or `vec3i`) and `id` (`f32`). |
| `FX_TAU` | 2 pi. |
`fx_worley2` searches the 3 by 3 cells around the sample and `fx_worley3` the 3 by 3 by 3 cells.
`fx_worley_fbm2` sums `1 - dist`, clamped to [0, 1], over its octaves, so feature points read as
peaks.
## Used by
The waterfall (`wf_particle`, `wf_pool`, `wf_rock`, `wf_sheet`) and wall blast (`blast_puff`,
`blast_shock`, `blast_stone`) shaders in this package draw their foam, mist, rock, dust and debris
from it, and so does the Procgen Effects Showcase world's `blast_ground`.
# effectShowcase
The procedural effects of the Procgen Effects Showcase world. Each one is a `.procGraph` that plays
through a `Generator`, and every shader, material and module a graph draws with sits beside it in
this package, so the package carries everything its graphs need. Each graph's README says what it
makes, how to place it and what each of its inputs changes.
## Contents
| Folder | Graphs | What they make |
|---|---|---|
| `combat/` | `impact`, `muzzleFlash`, `tracer` | A round striking a hard surface, the bloom at a barrel as a weapon fires, and the glowing streak of a round in flight. They draw with `fxFlash`, `fxSmoke` and `fxSpark` in `combat/shaders/`. |
| `blast/` | `wall_blast` | A charge blowing a breach through a stone block wall, on a 9.6 s loop. |
| `storm/` | `storm`, `tower` | A thunderstorm around a lone tower: wind-driven rain, lightning striking on the schedule `schedule.module` keeps, and sparks and smoke where strikes land. `tower` is the stone keep it stands around. |
| `rift/` | `arcane_rift` | A rift tearing open in the ground, its motes and rubble moved by the compute shaders in `rift/compute/`. |
| `dragon/` | `dragon_breath` | A dragon's fire breath sweeping a courtyard: a flame jet, rolling smoke and drifting embers. |
| `launch/` | `launch` | A heavy-lift rocket liftoff on one looping timeline, with the heat-haze material `rk_haze_mat`. |
| `waterfall/` | `wf_env`, `wf_water`, `wf_spray`, `wf_foam`, `wf_mist` | A waterfall built in parts: the cliff, basin and boulders, the falling and still water, the droplets, the foam where the falls land, and the mist with its rainbow. Its water materials are in `waterfall/materials/`. |
| `shaders/` | | `fx_noise`, the noise functions the waterfall and wall blast shaders include. |
## Playing one
A graph plays on a `Generator` component bound to it:
```lua
-- `graph` is the graph's reference: the AssetRef `asset.resolve` or a search returns for it.
local e = entity.spawn("impact", { position = { 0, 1, 0 } })
e.component.add("Generator", { graph = graph, playOn = "load" })
```
Set a graph's inputs with the Generator's `params`, e.g. `params = { size = 3 }`.