BIRP - Grass Geometry Shader with Interactivity

Dec 8, 2020

(Check out the Compute Shader Version of this Grass System with more options over Here)

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.

The accompanying painting tool is over here:
Grass Geometry Shader Editor Tool

And the URP version is over here:
URP - Grass Geometry Shader with Interactivity

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

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.

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

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

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

(I added camera based distance fade for grass amount)