NatureGL Grassv1.1.0

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.

js
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 async

Bakes 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.

OptionTypeDefault
rendererTHREE.WebGLRenderer—Required. Runs the blade and trample passes
sceneTHREE.Object3D—Required. Parent of the grass meshes
cameraTHREE.Camera—Required. Tiles follow and are culled against it
terrainTerrainDescription or TerrainField—Required. See Terrain
quality'low', 'medium', 'high', 'ultra''high'See Quality levels
presetstring or GrassPreset'meadow'See Presets
windWindFielda new fieldShare an existing wind
lightingGrassLighting—Passed to setLighting()
trampleSizenumber160Metres covered by the trample buffer

#Frame loop

#grass.update(dt): voidmethod

Call 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(): voidmethod

A no-op: the grass holds no screen-sized buffers. It exists so the API matches the other NatureGL libraries.

#grass.dispose(): voidmethod

Removes the grass from the scene and frees all GPU resources, including the trample buffer and the baked terrain.

#Parameters and presets

#grass.loadPreset(nameOrObject): voidmethod

Applies 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? }): voidmethod

Partial update. Fields you leave out keep their value. See Grass parameters.

#grass.getParams(): GrassPresetmethod

The current state as a preset object. It round-trips through loadPreset().

#grass.setQualityLevel(level): voidmethod

Rebuilds 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): voidmethod

Re-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?): voidmethod

Follows 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): voidmethod

Sets lighting by hand. Omitted fields keep their value.

FieldType
sunDirectionVector3Towards the light. Normalised for you
sunColorColor, Vector3 or [r, g, b]Colour × intensity, in three.js light units
ambientsameSky ambient (hemisphere sky colour × intensity)
groundAmbientsameGround bounce. Defaults to ambient × 0.3 when ambient is set alone
shadowLightDirectionalLight | nullThe light whose PCF shadow map the grass receives
cloudShadow{ texture, matrix } | nullSame as setCloudShadow()
#grass.setCloudShadow(cloudShadow | null): voidmethod

matrix 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): () => voidmethod

Flattens 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): voidmethod

Stops an object from trampling. Calling the function that addTrampler() returned does the same.

#Materials

#grass.patchTerrainMaterial(material, { amount = 1 }?): Materialmethod

Paints 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: TerrainFieldThe baked terrain. terrain.heightAt(x, z) is a fast CPU height query
wind: WindFieldThe wind field
trample: TrampleFieldThe trample buffer
object: THREE.GroupHolds 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()
bladeCountSame as stats.blades
enabledfalse hides the grass and skips culling. Wind and trampling keep running
qualityThe current tier name (getter)
maxDistanceOuter radius of the last ring in metres
colors{ base, tip, dry, leaf }: the current season palette as linear THREE.Colors
paramsThe current grass section (read-only, use setParams)
uniformsThe shared uniform objects (advanced)

#TerrainField

#new TerrainField(description)class

Bakes 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, maxHeightFrom the last bake
uniforms{ uTerrainTex, uTerrainTint, uTerrainRect, uTerrainRes } for TERRAIN_GLSL
versionIncrements on every bake
dispose()Frees the textures
#normalizeBounds(bounds): { minX, minZ, maxX, maxZ }function

Accepts { 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 }?)class

A gust field shared by reference between every material that uses it. See Wind field.

Member
speed, gust, directionGetters and setters. direction is in degrees, the way the wind blows towards
setDirection(deg)Same as setting direction
timeSeconds of wind time elapsed
update(dt)Advances wind time. grass.update() calls it
getUniforms(){ uWindTime, uWindSpeed, uWindGust, uWindDir } for a ShaderMaterial
WindField.glslStatic. 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 }?): Materialmethod

Makes 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: TrampleFieldproperty

Created 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
recoverSpring-back rate in 1/s, default 0.16
enabledPause or resume trampling
reset()Clear all flattening
setResolution(n)Texels per side. setQualityLevel() sets it
size, resolutionMetres 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 async

Pass 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?): voidmethod

Streams 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 }?): ScatterLayermethod

Adds layer.material, layer.stemColor and layer.setAmount(a).

#scatter.addRocks({ density = 0.004, positions?, scale = [0.35, 1.45], color = 0x8a867e, viewDistance = 160, …layerOptions }?): ScatterLayermethod

Adds layer.material.

#scatter.addTrees({ density = 0.0006, positions?, scale = [0.9, 1.35], leafColor = 0x6a9a3a, viewDistance = 320, …layerOptions }?): ScatterLayermethod

Adds layer.barkMaterial and layer.leafMaterial.

#scatter.addBushes({ density = 0.004, positions?, scale = [0.7, 1.4], color = 0x5a8a32, viewDistance = 120, …layerOptions }?): ScatterLayermethod

Adds 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): ScatterLayermethod

A 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
countInstances 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
visibleShow or hide the layer
countInstances alive
objectThe layer's THREE.Group
options, name
#patchLeafTranslucency(material): voidfunction

Adds 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 async

Additive 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
intensity0 hides them
setCount(n)
objectThe 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()
SEASONSThe four palette keys { s, base, tip, dry, leaf }
seasonColors(s)The interpolated { base, tip, dry, leaf } as linear THREE.Colors

#Low-level exports

Export
GeometrycreateFlowerGeometry(), createRockGeometry(seed), createTreeGeometry(seed) → { bark, leaves, height }, createBushGeometry(seed)
TexturescreateBarkTexture(), createLeafTexture(), createRockTexture(): DataTextures, no DOM needed
GLSLNOISE_GLSL (gpHash12, gpHash22, gpNoise), WIND_GLSL (windAt, gpGustAt), TERRAIN_GLSL (terrainSample, terrainHeight, terrainTint), TRAMPLE_GLSL (trampleAt). Pair them with the matching uniforms objects