A high-performance, noise-based procedural grass rendering system for Unity using GPU instancing and custom shaders. Inspired by Ghost of Tsushima's dynamic grass movement.
- 🌊 Dynamic Wind System - Noise-driven wind with traveling waves across the grass field
- ⚡ GPU Instancing - Efficiently renders 10,000+ grass blades using
Graphics.DrawMeshInstanced - 🎨 Organic Movement - Multi-layered noise (FBM) for natural, non-repetitive wind patterns
- 🧭 Dynamic Wind Direction - Wind direction calculated per-blade using 2D Perlin-like noise
- 🎛️ Fully Customizable - Complete control over density, size, wind strength, and appearance
- 🎮 Game-Ready - Optimized for real-time rendering with automatic batching
The main script that handles grass generation and rendering:
- Procedural mesh generation for individual grass blades
- Grid-based distribution with position randomization
- Automatic batch rendering for performance optimization
- Configurable density (default: 10,000 blades on 50x50 unit area)
Custom vertex/fragment shader with advanced wind simulation:
- Noise-based wind system with multiple layers
- Dynamic wind direction using 2D Perlin-like noise
- Height-based vertex displacement for realistic bending
- Gradient coloring from base to tip
- EaseIn curve shaping for smooth wind transitions
-
Import Files
- Add
GrassGenerator.csto your Unity project - Add
GrassShaderAdvanced.shaderto your project
- Add
-
Setup Scene
- Create an empty GameObject in your scene
- Attach the
GrassGeneratorcomponent
-
Create Material
- Create a new Material
- Select
Custom/GrassShaderAdvancedshader - Assign the material to the GrassGenerator script
-
Configure & Run
- Adjust parameters in the Inspector
- Enter Play mode to see the grass
| Parameter | Default | Description |
|---|---|---|
| Grass Blades | 10000 | Total number of grass blades |
| Num Grass X | 100 | Grid columns |
| Num Grass Z | 100 | Grid rows |
| Grass Patch Size | 50 | Area size in Unity units |
| Parameter | Default | Description |
|---|---|---|
| Wind Strength | 0.5 | Overall wind intensity |
| Wind Speed | 2.0 | Time multiplier for wind animation |
| Wind Direction Scale | 0.05 | Larger values = smaller wind patterns |
| Wind Strength Scale | 0.25 | Variation frequency |
| Wind Max Lean Angle | 1.25 | Maximum blade bending |
| Wind Ease Power | 2.0 | Wind curve smoothness |
| Parameter | Default | Description |
|---|---|---|
| Color | (0.2, 0.8, 0.2) | Base grass color |
| Tip Color | (0.4, 1.0, 0.4) | Grass tip color |
| Bend Amount | 0.3 | Static blade curvature |
Wind Strength: 0.4-0.6
Wind Speed: 1.5-2.5
Wind Direction Scale: 0.05
Wind Strength Scale: 0.25
Wind Max Lean Angle: 1.0-1.5
Wind Ease Power: 2.0-3.0
Wind Strength: 0.3
Wind Speed: 1.0
Wind Direction Scale: 0.02
Wind Strength Scale: 0.15
Wind Strength: 1.0
Wind Speed: 4.0
Wind Direction Scale: 0.1
Wind Strength Scale: 0.5
- Rendering Method: GPU Instancing via
Graphics.DrawMeshInstanced - Automatic Batching: Splits draws to respect Unity's 1023 instance limit
- Target Hardware: Medium to high-end hardware
- 10,000 blades: ~60 FPS on mid-range GPUs
- Optimization Tips:
- Reduce
grassBladescount for lower-end hardware - Adjust
grassBladeVertices(default: 15) for detail vs performance trade-off
- Reduce
The shader uses a sophisticated multi-layer noise system:
- Direction Noise: Samples 2D noise to determine wind direction (0-360°)
- Strength Noise: Secondary noise layer for wind intensity variation
- FBM Detail: Fractal Brownian Motion adds micro-detail
- Gust System: Pow-shaped noise creates sudden wind bursts
- Per-Blade Variation: Phase-shifted sine waves prevent synchronization
- Vertex Stage: Calculates wind displacement, rotation, and position
- Fragment Stage: Applies gradient coloring and noise-based shading
- Instancing: Uses
UNITY_VERTEX_INPUT_INSTANCE_IDfor unique per-blade randomness
- Unity 2020.3 or higher
- Shader Model 3.5+ (DX11/Metal/Vulkan)
- GPU with instancing support
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Share your improvements
For questions or feedback, please open an issue on GitHub.
- Inspired by the beautiful grass rendering in Ghost of Tsushima
- Built using Unity's GPU instancing system
- Noise functions adapted from classic Perlin noise algorithms
Made with ❤️ for the Unity community
