91 lines
4.4 KiB
Plaintext
91 lines
4.4 KiB
Plaintext
shader_type spatial;
|
|
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
|
|
|
|
#include "foliage_trail.gdshaderinc"
|
|
|
|
uniform vec2 wind_direction = vec2(0.94, 0.34);
|
|
uniform float wind_strength : hint_range(0.0, 0.2) = 0.07;
|
|
uniform float wind_speed : hint_range(0.0, 2.0) = 0.55;
|
|
uniform float gust_speed : hint_range(0.0, 1.0) = 0.12;
|
|
uniform float gust_strength : hint_range(0.0, 0.8) = 0.35;
|
|
uniform float flutter_strength : hint_range(0.0, 0.05) = 0.012;
|
|
uniform float wind_phase : hint_range(0.0, 6.2832) = 0.0;
|
|
uniform float wind_base_height = -1.2;
|
|
uniform float wind_full_height = 1.2;
|
|
uniform vec3 albedo : source_color = vec3(0.19, 0.38, 0.17);
|
|
uniform float roughness : hint_range(0.0, 1.0) = 0.9;
|
|
uniform float painted_vertex_weight : hint_range(0.0, 1.0) = 0.0;
|
|
uniform vec3 contact_root = vec3(0.0);
|
|
uniform float contact_strength = 0.0;
|
|
uniform int interactor_count = 0;
|
|
uniform vec3 interactor_positions[8];
|
|
varying vec3 paint_position;
|
|
|
|
void vertex() {
|
|
paint_position = VERTEX;
|
|
float height_factor = clamp((VERTEX.y - wind_base_height) / max(wind_full_height - wind_base_height, 0.01), 0.0, 1.0);
|
|
height_factor = height_factor * height_factor;
|
|
|
|
vec2 direction = normalize(wind_direction);
|
|
vec2 crosswind = vec2(-direction.y, direction.x);
|
|
float world_phase = wind_phase + dot(MODEL_MATRIX[3].xz, vec2(0.07, 0.05));
|
|
float gust_wave = 0.5 + 0.5 * sin(TIME * gust_speed + world_phase * 0.7);
|
|
float gust = mix(1.0 - gust_strength, 1.0, gust_wave);
|
|
float bend = sin(TIME * wind_speed + world_phase) * wind_strength * gust;
|
|
float flutter = sin(TIME * 1.7 + world_phase * 1.9 + VERTEX.y * 2.0) * flutter_strength;
|
|
|
|
// Crown orientation varies, but all foliage follows the same world breeze.
|
|
vec3 world_bend = vec3(direction.x, 0.0, direction.y) * bend;
|
|
world_bend += vec3(crosswind.x, 0.0, crosswind.y) * flutter;
|
|
VERTEX += (inverse(MODEL_MATRIX) * vec4(world_bend, 0.0)).xyz * height_factor;
|
|
if (foliage_trails_enabled && contact_strength > 0.0) {
|
|
// One bend for the whole bush, including fruit; its base remains planted.
|
|
vec3 contact = sample_foliage_trail(contact_root);
|
|
vec3 edge_contact = sample_foliage_trail(contact_root + vec3(0.45, 0.0, 0.0));
|
|
if (edge_contact.z > contact.z) { contact = edge_contact; }
|
|
edge_contact = sample_foliage_trail(contact_root - vec3(0.45, 0.0, 0.0));
|
|
if (edge_contact.z > contact.z) { contact = edge_contact; }
|
|
edge_contact = sample_foliage_trail(contact_root + vec3(0.0, 0.0, 0.45));
|
|
if (edge_contact.z > contact.z) { contact = edge_contact; }
|
|
edge_contact = sample_foliage_trail(contact_root - vec3(0.0, 0.0, 0.45));
|
|
if (edge_contact.z > contact.z) { contact = edge_contact; }
|
|
vec3 world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
|
float rooted = smoothstep(0.0, 1.25, world_position.y - contact_root.y);
|
|
// Bushes spring back faster than the flattened meadow trail.
|
|
float spring = pow(contact.z, 5.0);
|
|
vec2 bend_direction = contact.xy / max(length(contact.xy), 0.001);
|
|
for (int index = 0; index < 8; index++) {
|
|
if (index >= interactor_count) { break; }
|
|
vec2 offset = contact_root.xz - interactor_positions[index].xz;
|
|
float distance_to_actor = length(offset);
|
|
float influence = 1.0 - smoothstep(0.25, 1.8, distance_to_actor);
|
|
influence *= 1.0 - smoothstep(0.55, 1.35, abs(contact_root.y - interactor_positions[index].y));
|
|
if (influence > spring) {
|
|
spring = influence;
|
|
bend_direction = offset / max(distance_to_actor, 0.001);
|
|
}
|
|
}
|
|
vec3 displacement = vec3(bend_direction.x, -0.18, bend_direction.y) * spring * contact_strength * rooted;
|
|
VERTEX += (inverse(MODEL_MATRIX) * vec4(displacement, 0.0)).xyz;
|
|
}
|
|
}
|
|
|
|
void fragment() {
|
|
float patches = sin(paint_position.x * 6.0 + sin(paint_position.z * 7.0)) * sin(paint_position.y * 5.0);
|
|
float top = smoothstep(-0.65, 0.8, paint_position.y);
|
|
vec3 pigment = mix(vec3(1.0), COLOR.rgb, painted_vertex_weight);
|
|
vec3 shade_tint = mix(vec3(0.77, 0.95, 1.01), vec3(1.10, 1.06, 0.87), top);
|
|
ALBEDO = albedo * pigment * shade_tint * mix(0.91, 1.13, top);
|
|
ALBEDO *= 1.0 + smoothstep(0.18, 0.65, patches) * 0.07;
|
|
ROUGHNESS = roughness;
|
|
SPECULAR = 0.0;
|
|
}
|
|
|
|
void light() {
|
|
float band = smoothstep(0.08, 0.18, dot(NORMAL, LIGHT));
|
|
float highlight = smoothstep(0.62, 0.74, dot(NORMAL, LIGHT));
|
|
vec3 tone = mix(vec3(0.32, 0.48, 0.39), vec3(0.87, 0.92, 0.72), band);
|
|
tone = mix(tone, vec3(1.12, 1.08, 0.82), highlight);
|
|
DIFFUSE_LIGHT += tone * ATTENUATION * LIGHT_COLOR / PI;
|
|
}
|