Grass Geometry Shader with Interactivity (Part 1, the shader)

Hi all, 

Here is finally the interactive grass geometry shader. This part is the shader itself, it will work on meshes like planes, next part will be an editor script to paint the grass where you want it.

When you turn off shadowcasting on the mesh it looks pretty close to the grass in Genshin Impact :)

The shader applied to a 40x40 Probuilder plane (with shadows)

I'm gonna go over the basics of how to works, but please check out the Roystan tutorial at the bottom for a good explanation on the geometry part of the grassblades.

Geometry Setup

Instead of a normal Vertex/Fragment shader, for a geometry shader we add a third part, in between them. 

So we start with Vertex, then go to Geometry (v2g), then from Geometry to Fragment (g2f)


Interactivity is done by taking the player position and calculating a sphere around it with _Radius property, using this to displace the grassblades.

To make it work, add This Script to your player character

Building the Grassblades

Every vertex will add the number of grassblades defined under the CGINCLUDE, which will consist of the number of segments also defined under CGINCLUDE

(There is a limit to how many you can have in an instance)

By looping through the grassblades, a new blade is added by looping through the number of segments.
The bottom edges will be i = 0, meaning the grassblade rotation is excluded, the width is smaller for a nicer shape, and there will be no displacement from the interactivity.

The finishing segment is just one triangle, adding the top vertex in the middle.

Adding Colors

For the basic color we just lerp two color properties over the UV's . Then add in the light color data using _LightColor0, and multiply with the shadows, and vertex colors (added via painter script) for small color variations. 

To make sure its not completely black when there are no lights, add in a little bit of the base color (you maybe want this removed depending on your game). Finally a bit of the ambient lighting is added.

UV's are created for the grass segment when we add a new triangle, the value underlined here

Adding additional (Point/Spot) Light Support via ForwardAdd

Point light pass using UNITY_LIGHT_ATTENUATION , multiplied by the built-in _LightColor0 to get the spotlight colors.

Adding shadows via shadowcaster pass

Basic shadowcaster pass that takes the g2f result so all blades show up with correct shadows for the movement.

Link to shader code with comments(Updated):

(I added camera based distance fade for grass amount)


Grass Shader by
Point Cloud Grass - Lets Make a Grass Renderer 

Thanks for reading!

Become a patron to

Unlock 143 exclusive posts
Be part of the community
Connect via private message