51 lines
1.7 KiB
Plaintext
51 lines
1.7 KiB
Plaintext
shader_type spatial;
|
|
render_mode cull_back;
|
|
|
|
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);
|
|
uniform vec2 texture_top_tiling = vec2(1.0, 1.0);
|
|
uniform vec2 texture_side_tiling = vec2(1.0, 1.0);
|
|
|
|
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 * texture_top_tiling;
|
|
vec2 uv_xy = world_pos.xy * uv_scale.y * texture_side_tiling;
|
|
vec2 uv_zy = world_pos.zy * uv_scale.z * texture_side_tiling;
|
|
|
|
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;
|
|
}
|