feat(foliage): add recovering grass trails and bush contact

This commit is contained in:
Rijad Zuzo
2026-09-05 19:30:46 +02:00
parent da3bed67a0
commit 7899d36f03
21 changed files with 673 additions and 18 deletions
+16 -5
View File
@@ -2,6 +2,8 @@
shader_type spatial;
render_mode skip_vertex_transform, cull_disabled, specular_disabled;
#include "foliage_trail.gdshaderinc"
const int MAX_INTERACTORS = 8;
uniform vec2 wind_direction = vec2(1.0, 0.7);
uniform vec3 base_color : source_color = vec3(0.23, 0.40, 0.22);
@@ -9,7 +11,7 @@ uniform vec3 tip_color : source_color = vec3(0.53, 0.67, 0.35);
uniform float wind_amount : hint_range(0.0, 1.0) = 0.24;
uniform int interactor_count : hint_range(0, 8) = 0;
uniform vec3 interactor_positions[MAX_INTERACTORS];
uniform float interaction_radius : hint_range(0.25, 4.0) = 1.8;
uniform float interaction_radius : hint_range(0.25, 4.0) = 1.1;
uniform float interaction_strength : hint_range(0.0, 2.0) = 0.55;
uniform int clearing_count = 0;
uniform vec4 clearing_segments[4];
@@ -36,7 +38,10 @@ void vertex() {
vec3 world_vertex = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
float phase = dot(anchor.xz, vec2(0.38, 0.29));
float gust = sin(TIME * 1.15 + phase) * 0.65 + sin(TIME * 0.58 + phase * 0.42) * 0.35;
world_vertex.xz += normalize(wind_direction) * gust * wind_amount * tip_weight;
vec3 trail = sample_foliage_trail(anchor);
world_vertex.xz += normalize(wind_direction) * gust * wind_amount * tip_weight * (1.0 - trail.z * 0.75);
vec2 contact_bend = trail.xy * 0.72;
float pressure = trail.z;
shade_variation = sin(anchor.x * 0.30 + anchor.z * 0.21) * 0.5 + 0.5;
pressed_weight = 0.0;
for (int index = 0; index < MAX_INTERACTORS; index++) {
@@ -44,11 +49,17 @@ void vertex() {
vec2 offset = anchor.xz - interactor_positions[index].xz;
float distance_to_actor = length(offset);
float influence = 1.0 - smoothstep(0.25, interaction_radius, distance_to_actor);
influence *= 1.0 - smoothstep(0.55, 1.35, abs(anchor.y - interactor_positions[index].y));
vec2 away = offset / max(distance_to_actor, 0.08);
world_vertex.xz += away * influence * interaction_strength * tip_weight;
world_vertex.y -= influence * 0.18 * tip_weight;
pressed_weight = max(pressed_weight, influence);
if (influence > pressure) {
contact_bend = away * influence * interaction_strength;
pressure = influence;
}
}
world_vertex.xz += contact_bend * tip_weight;
// Lower relative to the blade's own root so short tufts stay above the ground.
world_vertex.y -= max(world_vertex.y - anchor.y, 0.0) * pressure * 0.78 * blade_height;
pressed_weight = pressure;
VERTEX = (VIEW_MATRIX * vec4(world_vertex, 1.0)).xyz;
NORMAL = normalize((VIEW_MATRIX * vec4(0.0, 1.0, 0.0, 0.0)).xyz);
}