Blend Scatter Demo
App: apps/blend_scatter_demo/
Demonstrates Blender foliage import (engine PLM-252, Block BLD): the .blend loader
emits baked scatter as GPU-instanced draws. GrassField.blend carries a hidden grass-blade
prototype plus a Plume_Scatter Empty whose plume3d_scatter_xforms bakes 196 blade
transforms + colours, and
BlendResult.instantiateScatter(scene) turns each
baked prototype into one InstancedMesh — a single GPU-instanced
draw per prototype, coordinate-converted onto the ground plane, with per-instance frustum
culling and wind sway. The clean visual proof of the baked-scatter pipeline.
Run from root
Section titled “Run from root”% ./plume3d blend_scatter_demoA camera looks across the grass patch. The demo captures a screenshot at frame 60 — printing the number of instanced meshes created — and exits at frame 80.
What it does
Section titled “What it does”-
Loads a grass shader first so it is the active shader (the instanced draw path uses the active shader), plus a lit shader for the ground plane:
Graphics.loadShader("shaders/grass") // FIRST -> active shader for the instanced foliage_lit = Graphics.loadShader("shaders/lit") -
Loads the baked
.blendand emits the scatter as instanced draws in one call, which returns the number ofInstancedMeshes created (one per baked prototype):var blend = Resource.loadBlend("Models/GrassField.blend")_created = blend.instantiateScatter(_scene)System.print("instantiateScatter created %(_created) instanced mesh(es)") -
Sets a global wind (
Graphics.setWind) the grass shader reads to sway the blades, adds a flat ground plane (MeshGen.plane) for context, and draws the scene (_scene.draw()submits the instanced foliage with the active grass shader).
- Resource —
loadBlend. - BlendResult —
instantiateScatter(emit the blend’s baked foliage as one GPU-instanced mesh per prototype; returns the count created). - InstancedMesh — the single GPU-instanced draw each prototype becomes (per-instance colour + frustum culling + wind).
- Graphics —
loadShader,setWind; MeshGen —plane.
- The scatter is authored + baked in Blender, not in script. Where
Grass Field hand-places instances in Wren and
Scatter Demo places them procedurally with the
Scatterfactories, this demo loads a field baked into the.blend— the geometry-nodes / particles / collection-instances authoring workflow round-tripped through the loader. - One
InstancedMeshper prototype. Each baked prototype is a single GPU-instanced draw; per-instance colour comes from the baked table (theparams.xscale + wind conventions of enhanced instancing apply). Coordinates convert automatically (Blender Z-up → engine Y-up).
See BlendResult for the full blend surface and the
Foliage + Terrain Demo for baked scatter plus an
auto-collidered terrain — the latter loads its whole level in one call with
Scene.loadBlendScene, which composes instantiateScatter
with terrain and static props.