Grass shader
Animated grass shader with many parameters
How to set up :
Make a scene with multimesh instance and a two mesh instance, the in the first mesh instance drop an obj file with one blade grass blade (for example: this, copy the text and save as .obj ) , then add a quad mesh to the second mesh instance and scale it as you wish. Finaly click on the multimesh and on the top should be a button multimesh and select populate surface, then select the quad as the surface and the grass blade as the source, max out the random rotation, set the amount and click populate. (Although i would recomand making your own multimesh script tutorial)
alternatively you can download the demo project and folow the instructions there
Shader code
shader_type spatial;
render_mode cull_disabled;
uniform float sway = 1.14;
uniform float sway_ = 0.34;
uniform float sway_pow = 1.3;
uniform float grass_roughness = 0.3;
uniform float sway_noise_sampeling_scale = 0.12;
uniform float sway_time_scale = 0.2;
uniform vec3 sway_dir = vec3(1.0,0.0,1.0);
uniform sampler2D sway_noise; //noise with with and height 1000
uniform float color_scale = 0.3;
uniform float color_grad_height = -0.5;
uniform vec4 top_color : hint_color;
uniform vec4 bot_color : hint_color;
uniform vec3 grass_scale = vec3(1.0,1.0,1.0);
varying vec3 vert;
varying float curent_wind;
float sclamp(float f,float sc){
return clamp(((f-0.5)*sc)+0.5,0.0,1.0);
}
void fragment()
{
ALBEDO = mix(bot_color,top_color,(vert.y+color_grad_height)*color_scale).xyz;
NORMAL *= FRONT_FACING ? 1.0 : -1.0;
SPECULAR = 0.5;
ROUGHNESS = clamp(1.0-(sclamp(curent_wind,0.8)*grass_roughness),0.2,1);
}
void vertex()
{
VERTEX *= grass_scale;
vert = VERTEX;
NORMAL = vec3(0.0,1.0,0.0);
vec4 sway_dir_local = vec4(sway_dir,0.0) * WORLD_MATRIX;
vec3 world_vertex = (WORLD_MATRIX * vec4(VERTEX,1.0)).xyz;
curent_wind = texture(sway_noise,normalize(sway_dir.xz) * (-TIME*sway_time_scale) + world_vertex.xz*vec2(sway_noise_sampeling_scale)).x;
VERTEX += normalize(sway_dir_local.xyz) * sway * (VERTEX.y) * sclamp(curent_wind,1.5);
VERTEX.y -= sway_*abs(pow(VERTEX.x,sway_pow));
}