You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
3.3 KiB
Plaintext
77 lines
3.3 KiB
Plaintext
shader_type spatial;
|
|
render_mode cull_disabled;
|
|
|
|
uniform float wind_speed = 0.2;
|
|
uniform float wind_strength = 2.0;
|
|
// How big, in world space, is the noise texture
|
|
// wind will tile every wind_texture_tile_size
|
|
uniform float wind_texture_tile_size = 20.0;
|
|
uniform float wind_vertical_strength = 0.3;
|
|
uniform vec2 wind_horizontal_direction = vec2(1.0, 0.5);
|
|
|
|
uniform sampler2D color_ramp : hint_default_black;
|
|
// we need a tiling noise here!
|
|
uniform sampler2D wind_noise : hint_default_black;
|
|
|
|
uniform vec3 character_position;
|
|
uniform float character_radius = 3.0;
|
|
uniform sampler2D character_distance_falloff_curve : hint_default_black;
|
|
uniform float character_push_strength = 1.0;
|
|
|
|
varying float debug_wind;
|
|
|
|
void vertex() {
|
|
vec3 world_vert = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
|
|
|
vec2 normalized_wind_direction = normalize(wind_horizontal_direction);
|
|
vec2 world_uv = world_vert.xz / wind_texture_tile_size + normalized_wind_direction * TIME * wind_speed;
|
|
// we displace only the top part of the mesh
|
|
// note that this means that the mesh needs to have UV in a way that the bottom of UV space
|
|
// is at the top of the mesh
|
|
float displacement_affect = (1.0 - UV.y);
|
|
float wind_noise_intensity = (textureLod(wind_noise, world_uv, 0.0).r - 0.5);
|
|
|
|
// We convert the direction of the wind into vertex space from world space
|
|
// if we used it directly in vertex space, rotated blades of grass wouldn't behave properly
|
|
vec2 vert_space_horizontal_dir =
|
|
(inverse(MODEL_MATRIX) * vec4(wind_horizontal_direction, 0.0, 0.0)).xy;
|
|
|
|
vert_space_horizontal_dir = normalize(vert_space_horizontal_dir);
|
|
|
|
vec3 bump_wind = vec3(
|
|
wind_noise_intensity * vert_space_horizontal_dir.x,
|
|
1.0 - wind_noise_intensity,
|
|
wind_noise_intensity * vert_space_horizontal_dir.y);
|
|
|
|
normalize(bump_wind);
|
|
|
|
bump_wind *= vec3(wind_strength, wind_vertical_strength, wind_strength);
|
|
|
|
VERTEX += bump_wind * displacement_affect;
|
|
|
|
// At the moment the blades are pushed away in a perfectly circular manner.
|
|
// We could distort the distance to the character based on a noise, to break a bit the
|
|
// circular shape. We could distort the falloff by sampling in a noise based on the xz coordinates.
|
|
// The task is left to the reader
|
|
|
|
vec3 dir_to_character = character_position - MODEL_MATRIX[3].xyz;
|
|
// uncomment the following line to have a horizontal only character push
|
|
//dir_to_character.y = 0.0;
|
|
float distance_to_character = length(dir_to_character);
|
|
float falloff = 1.0 - smoothstep(0.0, 1.0, distance_to_character/character_radius);
|
|
// Because we operate in vertex space, we need to convert the direction to the character
|
|
// in vertex space. Otherwise, it wouldn't work for rotated blades of grass.
|
|
// comment the next line to observe how the blades are not all facing away from the character.
|
|
dir_to_character = (inverse(MODEL_MATRIX) * vec4(dir_to_character, 0.0)).xyz;
|
|
dir_to_character = normalize(dir_to_character);
|
|
|
|
// sample the curve based on how far we are from the character, in normalized coordinates
|
|
float falloff_curve = texture(character_distance_falloff_curve, vec2(falloff)).x;
|
|
// direction to character is inverted because we want to point away from it
|
|
VERTEX += normalize(-dir_to_character) * falloff_curve * character_push_strength * displacement_affect;
|
|
|
|
}
|
|
|
|
void fragment() {
|
|
ALBEDO = texture(color_ramp, vec2(1.0 - UV.y, 0)).rgb ;
|
|
} |