Files
Trinittu/proc-terrain/triplanar_slope.gdshader
2026-01-31 22:48:55 +01:00

49 lines
1.5 KiB
Plaintext

shader_type spatial;
render_mode cull_disabled;
group_uniforms textures;
uniform sampler2D texture_top : source_color, filter_linear_mipmap, repeat_enable;
uniform sampler2D texture_side : source_color, filter_linear_mipmap, repeat_enable;
group_uniforms blending;
uniform float blend_sharpness : hint_range(0.1, 20.0) = 5.0;
uniform float slope_threshold : hint_range(0.0, 1.0) = 0.7;
group_uniforms uv_scaling;
uniform vec3 uv_scale = vec3(0.1, 0.1, 0.1);
varying vec3 world_pos;
varying vec3 world_normal;
void vertex() {
world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
world_normal = normalize((MODEL_MATRIX * vec4(NORMAL, 0.0)).xyz);
}
void fragment() {
vec3 abs_normal = abs(world_normal);
vec2 uv_xz = world_pos.xz * uv_scale.x;
vec2 uv_xy = world_pos.xy * uv_scale.y;
vec2 uv_zy = world_pos.zy * uv_scale.z;
vec3 weights = pow(abs_normal, vec3(blend_sharpness));
weights /= (weights.x + weights.y + weights.z);
vec4 tex_xz = texture(texture_top, uv_xz);
vec4 tex_xy = texture(texture_side, uv_xy);
vec4 tex_zy = texture(texture_side, uv_zy);
vec4 triplanar_color = tex_xz * weights.y + tex_xy * weights.z + tex_zy * weights.x;
float up_factor = dot(world_normal, vec3(0.0, 1.0, 0.0));
float slope_blend = smoothstep(slope_threshold - 0.1, slope_threshold + 0.1, up_factor);
vec4 top_color = texture(texture_top, uv_xz);
vec4 side_color = (tex_xy * weights.z + tex_zy * weights.x) / max(weights.z + weights.x, 0.001);
vec4 final_color = mix(side_color, top_color, slope_blend);
ALBEDO = final_color.rgb;
}