Reference
API reference
Everything exported from src/index.js and build/index.js. The types are in build/*.d.ts, which tsc generates from the JSDoc.
import {
GrassSystem, WindField, TerrainField, normalizeBounds, TrampleField,
ScatterSystem, ScatterLayer, patchLeafTranslucency, Fireflies,
QUALITY_LEVELS, PRESETS, getPresetParams, SEASONS, seasonColors,
createFlowerGeometry, createRockGeometry, createTreeGeometry, createBushGeometry,
createBarkTexture, createLeafTexture, createRockTexture,
NOISE_GLSL, WIND_GLSL, TERRAIN_GLSL, TRAMPLE_GLSL,
} from 'naturegl-grass';#GrassSystem
GrassSystem.create(options): Promise<GrassSystem>static asyncBakes the terrain, builds the LOD rings for the quality tier, loads the preset and adds grass.object to options.scene. new GrassSystem(options) does the same synchronously.
| Option | Type | Default | |
|---|---|---|---|
renderer | THREE.WebGLRenderer | — | Required. Runs the blade and trample passes |
scene | THREE.Object3D | — | Required. Parent of the grass meshes |
camera | THREE.Camera | — | Required. Tiles follow and are culled against it |
terrain | TerrainDescription or TerrainField | — | Required. See Terrain |
quality | 'low', 'medium', 'high', 'ultra' | 'high' | See Quality levels |
preset | string or GrassPreset | 'meadow' | See Presets |
wind | WindField | a new field | Share an existing wind |
lighting | GrassLighting | — | Passed to setLighting() |
trampleSize | number | 160 | Metres covered by the trample buffer |
#Frame loop
grass.update(dt): voidmethodCall once per frame, before renderer.render. It advances the wind and the trample buffer, syncs bound lights, culls and sorts the chunks, and runs the blade pass. dt is in seconds. The examples clamp it to 0.05.
grass.resize(): voidmethodA no-op: the grass holds no screen-sized buffers. It exists so the API matches the other NatureGL libraries.
grass.dispose(): voidmethodRemoves the grass from the scene and frees all GPU resources, including the trample buffer and the baked terrain.
#Parameters and presets
grass.loadPreset(nameOrObject): voidmethodApplies the preset's grass and wind sections, and keeps its scatter and environment sections for getParams(). Throws on an unknown name.
grass.setParams({ grass?, wind? }): voidmethodPartial update. Fields you leave out keep their value. See Grass parameters.
grass.getParams(): GrassPresetmethodThe current state as a preset object. It round-trips through loadPreset().
grass.setQualityLevel(level): voidmethodRebuilds the LOD rings and resizes the trample buffer. It is cheap and can run at runtime. Throws on an unknown level. Read the tier back from grass.quality.
#Terrain
grass.setTerrain(terrain): voidmethodRe-bakes the terrain description into the existing TerrainField and clears the chunk cache. A ScatterSystem or Fireflies that shares this terrain picks up the change.
#Lighting
grass.bindLights(directional, hemisphere?): voidmethodFollows a DirectionalLight and an optional HemisphereLight on every update(): the light direction, colour × intensity, the hemisphere's sky and ground colours × intensity, and the directional light's shadow map. bindLights(null) unbinds.
grass.setLighting(lighting): voidmethodSets lighting by hand. Omitted fields keep their value.
| Field | Type | |
|---|---|---|
sunDirection | Vector3 | Towards the light. Normalised for you |
sunColor | Color, Vector3 or [r, g, b] | Colour × intensity, in three.js light units |
ambient | same | Sky ambient (hemisphere sky colour × intensity) |
groundAmbient | same | Ground bounce. Defaults to ambient × 0.3 when ambient is set alone |
shadowLight | DirectionalLight | null | The light whose PCF shadow map the grass receives |
cloudShadow | { texture, matrix } | null | Same as setCloudShadow() |
grass.setCloudShadow(cloudShadow | null): voidmethodmatrix maps a world position to texture UV (xy / w). The texture's red channel is the sun transmittance, 1 = lit. It darkens only the sun term. Pass null to turn it off.
#Interaction
grass.addTrampler(object3D, radius = 0.8, strength = 1): () => voidmethodFlattens the grass around the object's world position and pushes it along the object's motion. The effect fades out as the object rises above the ground. Returns a function that removes the trampler. See Trampling.
grass.removeTrampler(object3D): voidmethodStops an object from trampling. Calling the function that addTrampler() returned does the same.
#Materials
grass.patchTerrainMaterial(material, { amount = 1 }?): MaterialmethodPaints the grass turf colour onto your ground material under the mask, with the same palette, dry patches and gust sheen as the blades. Supports MeshStandardMaterial, MeshPhysicalMaterial, MeshLambertMaterial and MeshPhongMaterial, and chains with other onBeforeCompile patches. amount (0..1) is kept in material.userData.grassTurf.uTurfAmount.
#Properties
| Property | |
|---|---|
terrain: TerrainField | The baked terrain. terrain.heightAt(x, z) is a fast CPU height query |
wind: WindField | The wind field |
trample: TrampleField | The trample buffer |
object: THREE.Group | Holds the ring meshes (renderOrder −10 and up, so the grass draws before the ground) |
stats | { chunks, blades, drawCalls, lods: [{ chunks, blades }] } for the last update() |
bladeCount | Same as stats.blades |
enabled | false hides the grass and skips culling. Wind and trampling keep running |
quality | The current tier name (getter) |
maxDistance | Outer radius of the last ring in metres |
colors | { base, tip, dry, leaf }: the current season palette as linear THREE.Colors |
params | The current grass section (read-only, use setParams) |
uniforms | The shared uniform objects (advanced) |
#TerrainField
new TerrainField(description)classBakes a terrain description into an RG32F texture (height and mask) and an RGBA8 tint texture, and keeps a CPU copy for chunk bounds and height queries.
| Member | |
|---|---|
set(description) | Re-bake. version increments |
heightAt(x, z) | Bilinear height from the bake |
maskAt(x, z) | Bilinear mask, 0 outside bounds |
sample(x, z, channel) | Channel 0 = height, 1 = mask |
rectStats(x0, z0, x1, z1) | { minY, maxY, maxMask } inside a rectangle |
bounds, resolution, minHeight, maxHeight | From the last bake |
uniforms | { uTerrainTex, uTerrainTint, uTerrainRect, uTerrainRes } for TERRAIN_GLSL |
version | Increments on every bake |
dispose() | Frees the textures |
normalizeBounds(bounds): { minX, minZ, maxX, maxZ }functionAccepts { minX, minZ, maxX, maxZ }, a THREE.Box2 (its y is world Z) or [minX, minZ, maxX, maxZ]. Throws on anything else.
#WindField
new WindField({ speed = 0.5, gust = 0.6, direction = 40 }?)classA gust field shared by reference between every material that uses it. See Wind field.
| Member | |
|---|---|
speed, gust, direction | Getters and setters. direction is in degrees, the way the wind blows towards |
setDirection(deg) | Same as setting direction |
time | Seconds of wind time elapsed |
update(dt) | Advances wind time. grass.update() calls it |
getUniforms() | { uWindTime, uWindSpeed, uWindGust, uWindDir } for a ShaderMaterial |
WindField.glsl | Static. GLSL for windAt(vec2 xz, float t), gpGustAt() and the noise helpers |
sample(x, z, target?) | CPU approximation of windAt. Returns a Vector2 |
wind.patchMaterial(material, { height = 1, strength = 1, flutter = 0, trample = null }?): MaterialmethodMakes a built-in material sway with this wind, on Mesh and InstancedMesh, and on MeshDepthMaterial for matching shadows. Displacement grows with (y / height)² in object space. Pass trample: grass.trample to flatten the object under tramplers too. Chains with other onBeforeCompile hooks.
#TrampleField
grass.trample: TrampleFieldpropertyCreated by the grass. A ping-pong half-float buffer (R flatten amount, GB push direction) that re-centres on the camera in texel steps.
| Member | |
|---|---|
addTrampler(obj, radius = 0.8, strength = 1) → remove() | Same as grass.addTrampler |
removeTrampler(obj) | |
stamp(x, z, radius, strength = 1, dirX = 0, dirZ = 0) | One-frame stamp |
recover | Spring-back rate in 1/s, default 0.16 |
enabled | Pause or resume trampling |
reset() | Clear all flattening |
setResolution(n) | Texels per side. setQualityLevel() sets it |
size, resolution | Metres covered, texels per side |
uniforms | { uTrampleTex, uTrampleArea, uTrampleOn } for TRAMPLE_GLSL |
update(dt, focus), dispose() | Called by the grass |
Up to 16 stamps per frame, tramplers and one-shot stamps combined.
#ScatterSystem
ScatterSystem.create({ scene, camera, grass?, terrain?, wind?, trample?, seed = 1, buildBudget = 6 }): Promise<ScatterSystem>static asyncPass grass to reuse its terrain, wind and trample field, or pass terrain (and optionally wind and trample) yourself. See Trees, flowers and rocks.
scatter.update(dt?): voidmethodStreams chunks around the camera, at most buildBudget new chunks per call. Rebuilds every layer when the shared terrain was re-baked.
scatter.addFlowers({ amount = 0.35, height = 1, palette?, viewDistance = 42, stemColor = 0x2a4a10, …layerOptions }?): ScatterLayermethodAdds layer.material, layer.stemColor and layer.setAmount(a).
scatter.addRocks({ density = 0.004, positions?, scale = [0.35, 1.45], color = 0x8a867e, viewDistance = 160, …layerOptions }?): ScatterLayermethodAdds layer.material.
scatter.addTrees({ density = 0.0006, positions?, scale = [0.9, 1.35], leafColor = 0x6a9a3a, viewDistance = 320, …layerOptions }?): ScatterLayermethodAdds layer.barkMaterial and layer.leafMaterial.
scatter.addBushes({ density = 0.004, positions?, scale = [0.7, 1.4], color = 0x5a8a32, viewDistance = 120, …layerOptions }?): ScatterLayermethodAdds layer.material. Since 1.1.0 all four ready-made layers forward filter, maskPower, maxSlope, cluster, seed, sink, chunkSize, fade and name to addLayer().
scatter.addLayer(options): ScatterLayermethodA custom layer of instanced parts. The options are listed on Trees, flowers and rocks.
| Member | |
|---|---|
removeLayer(layer) | Dispose and remove one layer |
refresh() | Rebuild every layer |
setTerrain(description?) | Re-bake an owned terrain and rebuild |
count | Instances alive across all layers |
layers, object, terrain, wind, trample, buildBudget | |
dispose() |
#ScatterLayer
| Member | |
|---|---|
set(partialOptions) | Update options and rebuild |
rebuild() | Drop all chunks; they regenerate on the next update |
visible | Show or hide the layer |
count | Instances alive |
object | The layer's THREE.Group |
options, name |
patchLeafTranslucency(material): voidfunctionAdds a back-lit glow from the scene's first DirectionalLight to any lit material.
#Fireflies
Fireflies.create({ scene, grass?, terrain?, count = 700, radius = 28, size = 0.14, color = 0xbfff4d, intensity = 1, heightRange = [0.35, 1.75] }): Promise<Fireflies>static asyncAdditive points that hover over the terrain around a focus point. See Fireflies.
| Member | |
|---|---|
update(dt, focus, camera?, renderer?) | Advance and re-centre. Pass the camera and renderer to keep the point size right |
intensity | 0 hides them |
setCount(n) | |
object | The THREE.Points |
dispose() |
#Presets, quality and seasons
| Export | |
|---|---|
PRESETS | { meadow, golden, windy, wildflowers, autumn, savanna, night } |
getPresetParams(name) | A deep clone. Throws on an unknown name |
QUALITY_LEVELS | { low, medium, high, ultra }, each { label, lods: [{ chunk, blades, segs, width, radius }], trampleResolution, clumpSearch }. Editable before create() |
SEASONS | The four palette keys { s, base, tip, dry, leaf } |
seasonColors(s) | The interpolated { base, tip, dry, leaf } as linear THREE.Colors |
#Low-level exports
| Export | |
|---|---|
| Geometry | createFlowerGeometry(), createRockGeometry(seed), createTreeGeometry(seed) → { bark, leaves, height }, createBushGeometry(seed) |
| Textures | createBarkTexture(), createLeafTexture(), createRockTexture(): DataTextures, no DOM needed |
| GLSL | NOISE_GLSL (gpHash12, gpHash22, gpNoise), WIND_GLSL (windAt, gpGustAt), TERRAIN_GLSL (terrainSample, terrainHeight, terrainTint), TRAMPLE_GLSL (trampleAt). Pair them with the matching uniforms objects |