One wind that Minecraft shaderpacks and wind mods can agree on.
Right now every shaderpack invents its own wind, and every wind mod invents its own. They disagree, so a player running both watches grass lean one way while blown leaves go another. MCWIND is a shared definition of which way the wind is blowing here, right now, and how hard, plus the grass and canopy responses that answer it.
It is one file, mcwind.glsl, and it is public domain.
#include "/lib/mcwind.glsl"
vec3 blockCentre = worldPos + clamp(at_midBlock.xyz / 64.0, -2.0, 2.0);
// grass
float h = mcw_grassHeight(worldPos, blockCentre, isUpperHalf);
vec2 push = mcw_grassPush(blockCentre, h);
position.xz += push;
// leaves
float weld = mcw_leafWeld(worldPos, blockCentre);
position.xyz += mcw_leafSway(worldPos, blockCentre, weld);Do the same in your shadow pass. That's the integration.
The analytic field is not a stub. A prevailing heading that veers and backs over minutes,
curl-noise eddies, travelling gust fronts with a Kolmogorov-ish octave cascade, a diurnal cycle
(breezy afternoons, still evenings), and rain response. No textures, no extra passes, no
shaders.properties entry, deterministic everywhere.
The same code silently picks up the mod's live weather, its wind presets, its frame-smooth clock, and (from v3) terrain shelter: wakes behind walls and hills, speed-ups over exposed crests, valley funnelling, forest-floor becalming.
You write nothing for any of it. No preset handling, no mod detection, no fallback path. Detection is
a uniform, and the GL spec guarantees an unset uniform reads exactly 0.0, so "no provider" is
unambiguous rather than a guess.
| Version | Adds | What a pack does to get it |
|---|---|---|
| v1 | the analytic field + grass response | integrate |
| v2 | mcw_leafWeld: canopy anchoring |
call it, if you want it |
| v3 | terrain shelter + steering | nothing: folded inside mcw_grassPush |
| v4 | mcw_leafSway: canopy motion |
call it, if you want it. No provider needed |
| v5 | mcw_gustWake: blown debris drafts the grass it skims |
one line in your grass branch. Needs a provider |
| v6 | mcw_fireLean: wind shears a flame downwind |
call it on a flame's top vertices. No provider needed |
A pack integrated against v1 picks up v3 shelter by swapping this file and changing nothing else. An older pack is never broken by a newer provider; a newer pack against an older provider drops silently to the analytic path.
Header version and provider version are different numbers. The table above is this file's feature
level. mcw_providerVersion is what the installed mod supplies at runtime. v4 and v6 need no provider
at all. Both are analytic field plus geometry, so the canopy moves and fire leans with no mod installed
and on OptiFine. Only v2 (mcw_leafAnchor), v3 (mcw_windFlow) and v5 (mcw_gustWake_tex) require a
provider channel to do anything.
Vendored this file before 2026-07-26? Replace it. Two normative constants changed: the
at_midBlockclamp is now±2.0(was±1.0) and the phase wrap is now9600.0(was3600.0). Neither fails loudly: the first shears foliage for no visible reason on bushy-leaf resource packs, the second desynchronises from a provider's own particles after an hour of play. Nothing else in your integration changes. See the changelog for why.
MCWIND standardises the wind and the plant responses to it: grass (mcw_grassPush) and canopy
(mcw_leafWeld for anchoring, mcw_leafSway for motion).
Earlier drafts said "trees stay yours" and deliberately withheld a canopy motion response. That is reversed as of v4. A canopy is the part most packs get wrong and the part least worth solving twice, so it belongs in the standard. Every wind-driven response lives here now.
If you want the shared field but your own feel, mcw_windField is public: take the raw heading,
speed and gust and write your own curve. Agree on the wind, not on the look.
This is not a drop-in. Integration is a small, well-scoped patch (a reference integration into a large third-party pack came to about a dozen lines across two files), but it does require knowing where your pack decides "this vertex is grass". No header can know that for you.
Everything after the first integration is a file swap.
Read IMPLEMENTING.md before you start, and
INTEGRATING-CANOPY.md when you get to leaves. It documents the prerequisites, the
invariants that will bite you, and a troubleshooting table built from real integration failures,
including the three that cost the most time: camera-relative worldPos in Chocapic-lineage packs,
the shadow pass being a separate program, and a geometry-stage grass option silently generating
blades downstream of your edit.
Providers (mods that publish the live field):
- WindLink: the reference provider, publishing
4.0(supplies the v2 leaf anchor, the v3 terrain flow and the v5 gust wake).
Consumers (packs that vendor the header): none published yet. If you ship one, open a PR and add it here.
MCWIND is new, and this list is short on purpose rather than by omission. The header does not need any of it: with no provider installed you still get the full analytic field, which is the whole reason the standard is safe to adopt early.
mcwind.glsl is dedicated to the public domain under CC0 1.0. No attribution required,
no warranty. Vendor it, ship it, fork it, sell it. Nobody owns MCWIND. That is the point. A
standard that one project controls is not a standard.
The namespace is mcw_, deliberately neutral and named after no pack or mod, for the same reason
labPBR is not named after the person who wrote it.