Files
project-thor/addons/terrain_3d/extras/particle_example/grass.gdshader
Nikolai Fesenko 85d50d3bd4 new terrain plugin
2025-08-13 21:08:35 +02:00

70 lines
2.4 KiB
Plaintext

// Copyright © 2025 Cory Petkovsek, Roope Palmroos, and Contributors.
shader_type spatial;
render_mode skip_vertex_transform, cull_disabled, blend_mix;
uniform vec2 wind_direction = vec2(1.0, 1.0);
varying vec4 data;
// A lot of hard coded things here atm.
void vertex() {
// Wind effect from model data, in this case no vertex colors,
// so just use vertex Y component, including mesh offset
data[2] = (VERTEX.y + 0.55);
data[2] *= data[2]; // make non-linear
// Ribbon used as a grass mesh.. so pinch the top.
VERTEX.xz *= (1.0 - data[2]);
// Brighten tips
COLOR = mix(COLOR, vec4(1.0), smoothstep(0.9, 1.0, data[2]));
// Darken base, skip is scale is less than threshold, as this means "grow in" is occuring.
COLOR *= INSTANCE_CUSTOM[3] < 0.35 ? 1. : mix(1.0, 0.75, smoothstep(0.35, 0.0, data[2]));
// Save red/green shift for fragment
data.rg = INSTANCE_CUSTOM.rg;
// World space vertex
vec3 w_vertex = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
// Get wind force and scale from process()
float scale = pow(INSTANCE_CUSTOM[3] * INSTANCE_CUSTOM[3], 0.707);
float force = INSTANCE_CUSTOM[2] * data[2] * scale;
// Add some cheap jitter at high wind values
force -= fract(force * 256.0) * force * 0.05;
// Curve the result
force = pow(force, 0.707);
// These 2 combined result in a decent bend without resorting to matrices or pivot data.
// Lateral move and wobble
float lateral_wobble = sin(TIME * 2.0 * (1.0 + data.r + data.g)) * 0.25 * (1.0 - INSTANCE_CUSTOM[2]);
vec2 direction = normalize(wind_direction);
w_vertex.xz -= (vec2(-direction.y, direction.x) * lateral_wobble + direction) * force;
// Flatten
w_vertex.y -= INSTANCE_CUSTOM[2] * force * data[2];
// Save final wind force value for fragment.
data[3] = force;
VERTEX = (VIEW_MATRIX * vec4(w_vertex, 1.0)).xyz;
NORMAL = MODELVIEW_NORMAL_MATRIX * NORMAL;
BINORMAL = MODELVIEW_NORMAL_MATRIX * BINORMAL;
TANGENT = MODELVIEW_NORMAL_MATRIX * TANGENT;
}
void fragment() {
// Hard coded color.
ALBEDO = vec3(0.20, 0.22, 0.05) * (data[2] * 0.5 + 0.5);
ALBEDO.rg *= (data.rg * 0.3 + 0.9);
ALBEDO *= pow(COLOR.rgb, vec3(2.2));
// Modify roughness / specular based on wind force for added detail
float spec_rough = clamp(max(data[2], data[3]), 0., 1.);
ROUGHNESS = 1. - spec_rough;
SPECULAR = clamp(spec_rough * 0.25, 0., .15);
BACKLIGHT = vec3(0.33);
#if CURRENT_RENDERER == RENDERER_COMPATIBILITY
ALBEDO = pow(ALBEDO, vec3(0.4));
#endif
}