-
-
Notifications
You must be signed in to change notification settings - Fork 109
Add Foliage noEffectDoodad and predTex properties export, and Alpha along side Terrain textures #586
Description
Adding foliage support to wow.export
I've written this document based on what Claude Opus 8 helped me dig up. Even if I have checked its sayings, I'm not a WOW expert, so take it with caution.
Wow Export
What WoW needs to place foliage
Ground-effect doodads are driven by three things:
- Which doodad set : each terrain layer references a
GroundEffectTexturerow (viaeffectID) that lists the doodad models and their density/weights. - Where it can appear : the per-layer alpha weight inside each chunk (already exported as the
tex_<tile>_<chunk>.pngalpha texture, one layer per R/G/B/A channel). This is currently not exported if Terrain Textures are exported (can't export both, they have the same names). - Per-cell gating : within each chunk WoW further gates doodads on an ×ばつ8 "detail cell" grid using two MCNK header fields. This is the missing piece.
Already exported today
tex_<tile>_<chunk>.png: RGBA alpha weights, one terrain layer per channel (if "Alpha Textures" only, as "Terrain Textures" are combined/baked RGB textures without Alpha Texture's informations).tex_<tile>_<chunk>.json: per-layer descriptors (layer index,effectID,channelIndex, etc. Only exported if exporting "Alpha Textures", not "Terrain Textures").foliage/<effectID>.json: theGroundEffectTexturerow (density + weights).
Missing data (the gate)
Two per-cell MCNK header fields fully control whether doodads are emitted in a given detail cell. wow.export already parses both in ADTLoader.js but never writes them out:
noEffectDoodad:uint1_t[8][8]packed as a 64-bit bitmap (MCNK header0x050). A set bit means "no doodads in this cell".predominantTexture/lowQualityTextureMap:uint2_t[8][8](MCNK header0x040), eightint16rows. Each 2-bit value (0–3) is the index of the predominant terrain layer for that cell. WoW only spawns a layer's doodads where that layer is predominant, so this prevents every overlapping layer's foliage from stacking in the same cell.
What I've implemented in my tests
I've added a unpackDoodadGating(rootChunk) helper that returns two flat, 64-entry, row-major arrays (index = row * 8 + col):
noEffectDoodad[i]:0or1, from BigInt bitiof the packed field.predTex[i]:0–3, from(lowQualityTextureMap[row] >> (col * 2)) & 0x3.
And written both into each chunk's tex_<tile>_<chunk>.json (e.g. as noEffectDoodad and predTex properties). Applied in both export paths:
src/js/3D/exporters/ADTExporter.js(current split-alpha path).src/js/modules/legacy_tab_maps.js(legacy split path).
Orientation gotcha (document this for consumers)
The alpha PNG is written bottom-up (the exporter flips rows, v = 1 - row), but these gating arrays are written in raw header order (index 0 = MCAL row 0 = top). A consumer sampling the alpha texture and the gating grid with the same UV must vertically flip the cell row for the gating lookup (cell_row = 7 - floor(v * 8)). Columns are not flipped. Failing to do this mirrors the gate and blanks the wrong cells.
Optional: Alpha Textures export along side Terrain Textures
In my tests, I've added an opt-in "Foliage Alpha Textures" checkbox (gated on 1K to 16K Terrain Textures choice) that writes the per-chunk alpha weights as standalone tex_<tile>_<chunk>_alpha.png images. This is convenient for tools that want the alpha weights as plain image data rather than re-deriving them, but it is independent of the gating data above.
Blender Addon
Philosophy
The Blender Foliage addon I've vibe coded consumes the exported data :
- Read the exported terrain' alpha textures
tex_<tile>_<chunk>_alpha.pngandfoliage/<effectID>.jsonrows. - For each terrain layer, scatter that layer's doodads with Geometry Nodes, using the alpha weight as density and the per-cell gating (
noEffectDoodad+predTex) as an on/off mask.
Activity
Metadata
Metadata
Assignees
Labels
Projects
- Status📋 Backlog