The surface
Twelve public symbols. That is the whole API.
MCWIND standardises the wind and the
plant responses to it: grass and canopy. Everything else in the file is
mcw_-prefixed and free to use, and none of it is normative except the
six things that carry a wire format: MCW_MAG_REF,
MCW_LEAF_RANGE, MCW_WAKE_SIZE and the three texture encodings.
| Signature | Meaning |
|---|---|
| vec2 mcw_windDir(vec3 blockCentre) | Unit vector, downwind. |
| float mcw_windMag(vec3 blockCentre) | 0..1 normalised. Never m/s. |
| float mcw_windGain() | Provider strength multiplier; 1.0 with no provider. |
| float mcw_windPhase | Seconds, wraps at 9600. Advances per frame, not per tick. |
| float mcw_windProvider | 0.0 analytic, 1.0 a live mod is driving the field. |
| float mcw_grassHeight(...) | The height weight: exactly 0.0 at a planted base, 1.0 at a one-block tip. |
| vec2 mcw_grassPush(...) | World-space horizontal displacement, in blocks. Terrain shelter is folded in here as of v3. |
| vec3 mcw_honami(...) | Optional. Tilts the shading normal with the lean, so a gust front reads as a travelling band of light. |
| float mcw_leafWeld(...) | v2. How free a leaf is to move: 0.0 welded to the wood, 1.0 fully free. Returns 1.0 with no provider. |
| vec3 mcw_leafSway(...) | v4. The canopy motion: held lean, breathing, gust spring-back, calm idle. Needs no provider at all. |
| vec2 mcw_gustWake(...) | v5. Blown debris drafts the grass it skims past. Takes the camera position, because the header cannot have one. Returns vec2(0.0) with no provider. |
| vec3 mcw_fireLean(...) | v6. Wind shears a flame downwind. The lean saturates rather than growing without limit, because a flame is buoyant and tears instead of lying flat. Needs no provider at all. |
The provider seam
Same pack code. Two data sources.
A provider publishes three uniforms and three texture channels. You
do not declare or handle any of them; mcwind.glsl does. Supporting a provider
costs you nothing: no second code path, no mod detection, no fallback to write, and nothing
added to shaders.properties. New channels arrive by swapping the file.
two version numbers, and they are not the same one
Header version is
which symbols mcwind.glsl defines, what this page publishes, currently v6.
mcw_providerVersion is what the installed mod supplies at
runtime, currently up to 4.0. They move independently, and conflating them is the easiest
way to misread the table.
| Header | Adds | Needs a provider? |
|---|---|---|
| v1 | analytic field + grass response | no |
| v2 | mcw_leafWeld: canopy anchoring | yes · mcw_leafAnchor |
| v3 | terrain shelter & steering, folded into mcw_grassPush | yes · mcw_windFlow |
| v4 | mcw_leafSway: canopy motion | no |
| v5 | mcw_gustWake: debris drafts the grass it skims | yes · mcw_gustWake_tex |
| v6 | mcw_fireLean: wind shears a flame downwind | no |
Canopy
motion needs no mod at all. It is the analytic field plus geometry, so it works at
mcw_providerVersion 0.0 and on OptiFine. Only anchoring, terrain shelter and the
gust wake need a provider. And terrain shelter is deliberately not a symbol: as of v3 it lives
inside mcw_grassPush, so a v1-era integration gained it by swapping the file and
changing nothing. The gust wake is the counterpoint, and it is a symbol for one
concrete reason: it needs the camera position to fade out before its tile wraps, and the
header cannot have one, because declaring a uniform the pack already owns is a hard compile
error. So the pack passes it in, on one extra line.
Honest limits
What the header does not do.
- The field is not continuous across the 9600-second wrap: one visible seam every 2h40m, in exchange for float precision holding everywhere else. Known and specified.
- No terrain awareness on its own. Lee wakes, crest speed-up and valley funnelling need a provider's solver. The header cannot see the world.
- The canopy anchor has no vertical structure.
mcw_leafAnchoris a column field (distance to the nearest wood in XZ), so the very crown of a tall tree is held stiffer than it should be. Known, and unchanged by v5. It is the first thing a future version should fix. mcw_windMagis 0..1 normalised. Never m/s.- It is not a layer on top of your own wave. Run both and the motion doubles and the base un-plants.
- Budget grass and canopy separately. Grass is ~23 value-noise taps per
vertex;
mcw_leafSwayis ~59, andMCW_EDDY = 0.0does not gate its three extra curls. That still leaves ~47.
A worked example
What it actually takes, in someone else's pack.
Rather than describe the integration, here it is: MCWIND wired into Eclipse, a large, actively maintained Chocapic13-lineage pack. Grass and canopy, both passes, with every decision documented and a revert path.
Eclipse + MCWIND
3 files · +108 −3shaders/lib/mcwind.glsl, the vendored CC0 headerat_midBlock declarationVines, fire and water keep Eclipse's own wave, so both responses sit side by side in one scene and can be compared directly. It also fixed a pre-existing bug in passing: Eclipse called two different overloads of its own leaf function in the two passes, so its leaf geometry and leaf shadow had never been computing the same displacement.
Stated plainly: that is a fork, offered upstream, not a shipped adoption. It is a demonstration that the integration is small and legible in a pack nobody wrote for this standard, and it has not been reviewed by Eclipse's author. Eclipse is an edit of Bliss, which is an edit of Chocapic13's shaders; the fork carries their credits and Chocapic13's terms.
Nobody owns MCWIND.
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. A standard
that one project controls is not a standard, and the namespace is mcw_,
deliberately named after no pack and no mod.