aboutsummaryrefslogtreecommitdiff
path: root/game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader
diff options
context:
space:
mode:
Diffstat (limited to 'game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader')
-rw-r--r--game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader63
1 files changed, 63 insertions, 0 deletions
diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader
new file mode 100644
index 0000000..1291dbd
--- /dev/null
+++ b/game/addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader
@@ -0,0 +1,63 @@
+shader_type canvas_item;
+render_mode blend_disabled;
+
+#include "res://addons/zylann.hterrain/shaders/include/heightmap.gdshaderinc"
+
+uniform sampler2D u_src_texture;
+uniform vec4 u_src_rect;
+uniform float u_opacity = 1.0;
+uniform vec4 u_splat = vec4(1.0, 0.0, 0.0, 0.0);
+uniform sampler2D u_heightmap;
+uniform float u_normal_min_y = 0.0;
+uniform float u_normal_max_y = 1.0;
+//uniform float u_normal_falloff = 0.0;
+
+vec2 get_src_uv(vec2 screen_uv) {
+ vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw;
+ return uv;
+}
+
+float get_height(sampler2D heightmap, vec2 uv) {
+ return sample_heightmap(heightmap, uv);
+}
+
+vec3 get_normal(sampler2D heightmap, vec2 pos) {
+ vec2 ps = vec2(1.0) / vec2(textureSize(heightmap, 0));
+ float hnx = get_height(heightmap, pos + vec2(-ps.x, 0.0));
+ float hpx = get_height(heightmap, pos + vec2(ps.x, 0.0));
+ float hny = get_height(heightmap, pos + vec2(0.0, -ps.y));
+ float hpy = get_height(heightmap, pos + vec2(0.0, ps.y));
+ return normalize(vec3(hnx - hpx, 2.0, hpy - hny));
+}
+
+// Limits painting based on the slope, with a bit of falloff
+float apply_slope_limit(float brush_value, vec3 normal, float normal_min_y, float normal_max_y) {
+ float normal_falloff = 0.2;
+
+ // If an edge is at min/max, make sure it won't be affected by falloff
+ normal_min_y = normal_min_y <= 0.0 ? -2.0 : normal_min_y;
+ normal_max_y = normal_max_y >= 1.0 ? 2.0 : normal_max_y;
+
+ brush_value *= 1.0 - smoothstep(
+ normal_max_y - normal_falloff,
+ normal_max_y + normal_falloff, normal.y);
+
+ brush_value *= smoothstep(
+ normal_min_y - normal_falloff,
+ normal_min_y + normal_falloff, normal.y);
+
+ return brush_value;
+}
+
+void fragment() {
+ float brush_value = u_opacity * texture(TEXTURE, UV).r;
+
+ vec2 src_uv = get_src_uv(SCREEN_UV);
+ vec3 normal = get_normal(u_heightmap, src_uv);
+ brush_value = apply_slope_limit(brush_value, normal, u_normal_min_y, u_normal_max_y);
+
+ vec4 src_splat = texture(u_src_texture, src_uv);
+ vec4 s = mix(src_splat, u_splat, brush_value);
+ s = s / (s.r + s.g + s.b + s.a);
+ COLOR = s;
+}