shader_type spatial; render_mode cull_disabled, diffuse_burley; // Grass clumps (MultiMesh). UV.y runs 0 at the root to 1 at the tip and drives // both wind bend and the root-to-tip colour gradient. Base colour uses the same // noise lookups as terrain.gdshader so the blades blend into the ground beneath. #include "res://shaders/common.gdshaderinc" uniform vec3 grass_lush : source_color = vec3(0.25, 0.40, 0.15); uniform vec3 grass_dry : source_color = vec3(0.48, 0.50, 0.22); uniform vec3 tip_tint : source_color = vec3(0.78, 0.88, 0.50); uniform float wind_strength = 0.2; uniform vec2 wind_dir = vec2(1.0, 0.35); varying vec3 inst_pos; varying float hfac; void vertex() { inst_pos = MODEL_MATRIX[3].xyz; hfac = UV.y; vec3 wp = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; vec2 wd = normalize(wind_dir); float gust = nz(wp.xz * 0.015 - TIME * 0.05 * wd); float sway = sin(TIME * 1.8 + wp.x * 0.35 + wp.z * 0.25) * 0.35 + gust * 1.3 - 0.4; float k = wind_strength * weather_wind * hfac * hfac; vec3 off = vec3(wd.x * sway * k, -abs(sway) * k * 0.3, wd.y * sway * k); VERTEX += (inverse(MODEL_MATRIX) * vec4(off, 0.0)).xyz; } void fragment() { float macro = nz(inst_pos.xz * 0.0035); float mid = nz(inst_pos.xz * 0.021 + 0.37); vec3 base = mix(grass_lush, grass_dry, smoothstep(0.48, 0.78, macro + (mid - 0.5) * 0.35)); base *= 0.82 + 0.36 * nz(inst_pos.xz * 0.17); vec3 col = base * mix(0.55, 1.0, hfac); // darker at the root col = mix(col, col * tip_tint * 1.3, smoothstep(0.6, 1.0, hfac) * 0.3); // Snow weighs down on the blades from the root up; rain darkens them. float snowy = clamp(weather_snow * 1.3 - hfac * 0.5 + (nz(inst_pos.xz * 0.17) - 0.5) * 0.4, 0.0, 0.85); col = mix(col, vec3(0.62, 0.65, 0.7), snowy); // greyer than ground snow: blades are lit as if flat col = wet_albedo(col, weather_wet * 0.6 * (1.0 - snowy)); ALBEDO = col; ROUGHNESS = 0.9; SPECULAR = 0.2; BACKLIGHT = vec3(0.35, 0.4, 0.15) * hfac; // Light blades as if they faced up (same as the ground), so a field reads as // one soft surface instead of thousands of flickering cards. NORMAL = normalize((VIEW_MATRIX * vec4(0.0, 1.0, 0.0, 0.0)).xyz); }