Breathe of the Wild Style grass in Three.js
Last year, I came across a great video on YouTube by Kristof Dedene showing a method of making Zelda style grass in Blender. Below is my attempt to recreate it in Three.js.
Geometry
To begin with, I needed to determine how to draw a blade of grass. I settled on using 5 vertices. The low number of vertices would improve performance and allow more grass to render.
To create each grass blade, I needed to find it's center position and a random rotation angle. Using this angle, I pushed out from the center to find the location of the bottom 2 vertices. I repeated this for the top 2 vertices but only going out half as far. Next, I set vertical height of each vertex to a pre determined number. I could tweak these numbers to change the appearance of the field.
To find the UV coordinates, I normalized the center position (relative to the size of the field) to be between 0 and 1. Each grass blade would appear as a single color that was sampled from the underlying texture. Looking across the field, it appeared as a changing gradient.
I used vertex colors to assign the bottom 2 vertices as black, middle as gray and the top one as white. This would be used for animating the grass in a vertex shader.
Once I had my field generated, I would need a shader for rendering it.
Shaders
There are 2 types of GLSL shaders. A vertex shader which controls the shape of the geometry and a fragment shader that controls how it renders.
I passed a time value as a variable into the vertex shader, and used this with the Sin function to offset blade vertices. Using the vertex colors I set above, I was able to determine which point on the grass blade it was. The bottom vertices were kept static, the middle were offset a little and the single point at the top had the greatest movement. This gave the appearence of grass swaying in the wind.
In addition to the time value, I also added the UV position of the vertex in the Sin function. This results in the blades moving at different times similiar to gusts of wind.
Finally, In the fragment shader I passed in 2 textures. The first was a splattered green texture for the grass blades to sample from. The second was a black and white cloud noise texture which looked like clouds were casting shadows on the field.