Start here
Installation
NatureGL Grass ships as a folder with a runnable demo, the library source, and a prebuilt ES module with TypeScript declarations. Pick the integration path that suits your build.
#Requirements
| three.js | >= 0.180 as a peer dependency. Developed and tested on r186 |
| Renderer | THREE.WebGLRenderer with WebGL2 and float colour buffers (EXT_color_buffer_float, which three enables and all desktop GPUs support). No WebGPU needed |
| Shadows | Optional. The grass receives the default THREE.PCFShadowMap of one directional light |
| Node | 18 or newer, only for the demo and the build scripts |
#Run the demo first
#Unpack and install
cd naturegl-grass
npm install#Start the dev server
npm run devIt opens http://localhost:5185/demo/: the rolling-hills meadow with trees, rocks, flowers, fireflies and a ball that tramples the grass. The demo page lists every control.
#Build or test (optional)
npm run build # library -> build/ (+ .d.ts), static demo -> dist/
npm test # headless real-GPU smoke test: every preset -> test-results/*.png + fps
node scripts/check-examples.mjs # opens examples/basic and examples/cdn, fails on errors#What's in the folder
├── src/the library: no DOM UI, no scenery│ ├── GrassSystem.jsthe facade: create, update, presets, quality, lighting│ ├── TerrainField.jsbakes heightAt / mask / colorAt to textures│ ├── WindField.jsshared gust field + patchMaterial()│ ├── TrampleField.jscamera-following trample buffer│ ├── ScatterSystem.jsstreamed trees, bushes, rocks, flowers, custom layers│ ├── Fireflies.jsadditive firefly points│ ├── geometry/blade strip, procedural props and textures│ ├── shaders/GLSL as template strings│ └── config/QualityLevels.js, seasons.js, presets/├── build/prebuilt ESM bundle + .d.ts├── demo/the full demo app (terrain, sky, ball, UI)├── examples/basic/minimal Vite integration├── examples/cdn/plain JS + import map└── scripts/smoke.mjs, check-examples.mjs and dev tools
#Add it to your project
The library adds meshes to your scene and renders nothing on its own. three is a peer dependency and is not bundled.
Copy build/ into your project, for example as lib/naturegl-grass/, and import from it. three stays an external import, so your bundler or an import map resolves it.
import { GrassSystem } from './lib/naturegl-grass/index.js';build/index.d.ts gives editors full types, and a source map sits next to the bundle.
src/ is plain ES modules with JSDoc. The GLSL lives in .glsl.js template strings, so no bundler plugin is needed.
import { GrassSystem } from './lib/naturegl-grass/index.js';Choose this if you want to read or patch the shaders in place.
Point an alias at the source and keep the package next to your app. The demo uses this path itself (see vite.config.js).
import { resolve } from 'node:path';
export default {
resolve: {
alias: { 'naturegl-grass': resolve(__dirname, '../naturegl-grass/src/index.js') },
},
};import { GrassSystem } from 'naturegl-grass';#Without a bundler
An import map resolves three from a CDN. The library comes from build/.
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/"
} }
</script>
<script type="module">
import * as THREE from 'three';
import { GrassSystem } from '../../build/index.js';
</script>Serve the package root with any static server, such as npx http-server ., and open /examples/cdn/.