diff options
author | Gone2Daly <71726742+Gone2Daly@users.noreply.github.com> | 2023-07-22 21:05:42 +0200 |
---|---|---|
committer | Gone2Daly <71726742+Gone2Daly@users.noreply.github.com> | 2023-07-22 21:05:42 +0200 |
commit | 71b3cd829f80de4c2cd3972d8bfd5ee470a5d180 (patch) | |
tree | b4280fde6eef2ae6987648bc7bf8e00e9011bb7f /game/addons/zylann.hterrain/tools/brush/shaders | |
parent | ce9022d0df74d6c33db3686622be2050d873ab0b (diff) |
init_testtest3d
Diffstat (limited to 'game/addons/zylann.hterrain/tools/brush/shaders')
10 files changed, 507 insertions, 0 deletions
diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/alpha.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/alpha.gdshader new file mode 100644 index 0000000..f8a05c5 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/alpha.gdshader @@ -0,0 +1,19 @@ +shader_type canvas_item; +render_mode blend_disabled; + +uniform sampler2D u_src_texture; +uniform vec4 u_src_rect; +uniform float u_opacity = 1.0; +uniform float u_value = 1.0; + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +void fragment() { + float brush_value = u_opacity * texture(TEXTURE, UV).r; + + vec4 src = texture(u_src_texture, get_src_uv(SCREEN_UV)); + COLOR = vec4(src.rgb, mix(src.a, u_value, brush_value)); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/color.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/color.gdshader new file mode 100644 index 0000000..eec65f5 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/color.gdshader @@ -0,0 +1,68 @@ +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_color = vec4(1.0); +uniform sampler2D u_heightmap; +uniform float u_normal_min_y = 0.0; +uniform float u_normal_max_y = 1.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 = texture(u_src_texture, src_uv); + + // Despite hints, albedo textures render darker. + // Trying to undo sRGB does not work because of 8-bit precision loss + // that would occur either in texture, or on the source image. + // So it's not possible to use viewports to paint albedo... + //src.rgb = pow(src.rgb, vec3(0.4545)); + + vec4 col = vec4(mix(src.rgb, u_color.rgb, brush_value), src.a); + COLOR = col; +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/erode.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/erode.gdshader new file mode 100644 index 0000000..669f4d7 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/erode.gdshader @@ -0,0 +1,64 @@ +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_color = vec4(1.0); + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +// float get_noise(vec2 pos) { +// return fract(sin(dot(pos.xy ,vec2(12.9898,78.233))) * 43758.5453); +// } + +float get_height(sampler2D heightmap, vec2 uv) { + return sample_heightmap(heightmap, uv); +} + +float erode(sampler2D heightmap, vec2 uv, vec2 pixel_size, float weight) { + float r = 3.0; + + // Divide so the shader stays neighbor dependent 1 pixel across. + // For this to work, filtering must be enabled. + vec2 eps = pixel_size / (0.99 * r); + + float h = get_height(heightmap, uv); + float eh = h; + //float dh = h; + + // Morphology with circular structuring element + for (float y = -r; y <= r; ++y) { + for (float x = -r; x <= r; ++x) { + + vec2 p = vec2(x, y); + float nh = get_height(heightmap, uv + p * eps); + + float s = max(length(p) - r, 0); + eh = min(eh, nh + s); + + //s = min(r - length(p), 0); + //dh = max(dh, nh + s); + } + } + + eh = mix(h, eh, weight); + //dh = mix(h, dh, u_weight); + + float ph = eh;//mix(eh, dh, u_dilation); + + return ph; +} + +void fragment() { + float brush_value = u_opacity * texture(TEXTURE, UV).r; + vec2 src_pixel_size = 1.0 / vec2(textureSize(u_src_texture, 0)); + float ph = erode(u_src_texture, get_src_uv(SCREEN_UV), src_pixel_size, brush_value); + //ph += brush_value * 0.35; + COLOR = encode_height_to_viewport(ph); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/flatten.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/flatten.gdshader new file mode 100644 index 0000000..c51f03a --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/flatten.gdshader @@ -0,0 +1,22 @@ +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 float u_flatten_value; + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +void fragment() { + float brush_value = u_opacity * texture(TEXTURE, UV).r; + + float src_h = sample_heightmap(u_src_texture, get_src_uv(SCREEN_UV)); + float h = mix(src_h, u_flatten_value, brush_value); + COLOR = encode_height_to_viewport(h); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/level.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/level.gdshader new file mode 100644 index 0000000..4721b43 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/level.gdshader @@ -0,0 +1,45 @@ +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 float u_factor = 1.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); +} + +// TODO Could actually level to whatever height the brush was at the beginning of the stroke? + +void fragment() { + float brush_value = u_factor * u_opacity * texture(TEXTURE, UV).r; + + // The heightmap does not have mipmaps, + // so we need to use an approximation of average. + // This is not a very good one though... + float dst_h = 0.0; + vec2 uv_min = vec2(u_src_rect.xy); + vec2 uv_max = vec2(u_src_rect.xy + u_src_rect.zw); + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + float x = mix(uv_min.x, uv_max.x, float(i) / 4.0); + float y = mix(uv_min.y, uv_max.y, float(j) / 4.0); + float h = get_height(u_src_texture, vec2(x, y)); + dst_h += h; + } + } + dst_h /= (5.0 * 5.0); + + // TODO I have no idea if this will check out + float src_h = get_height(u_src_texture, get_src_uv(SCREEN_UV)); + float h = mix(src_h, dst_h, brush_value); + COLOR = encode_height_to_viewport(h); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/raise.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/raise.gdshader new file mode 100644 index 0000000..10ee982 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/raise.gdshader @@ -0,0 +1,22 @@ +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 float u_factor = 1.0; + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +void fragment() { + float brush_value = u_factor * u_opacity * texture(TEXTURE, UV).r; + + float src_h = sample_heightmap(u_src_texture, get_src_uv(SCREEN_UV)); + float h = src_h + brush_value; + COLOR = encode_height_to_viewport(h); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/smooth.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/smooth.gdshader new file mode 100644 index 0000000..27123e4 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/smooth.gdshader @@ -0,0 +1,34 @@ +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 float u_factor = 1.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); +} + +void fragment() { + float brush_value = u_factor * u_opacity * texture(TEXTURE, UV).r; + + vec2 src_pixel_size = 1.0 / vec2(textureSize(u_src_texture, 0)); + vec2 src_uv = get_src_uv(SCREEN_UV); + vec2 offset = src_pixel_size; + float src_nx = get_height(u_src_texture, src_uv - vec2(offset.x, 0.0)); + float src_px = get_height(u_src_texture, src_uv + vec2(offset.x, 0.0)); + float src_ny = get_height(u_src_texture, src_uv - vec2(0.0, offset.y)); + float src_py = get_height(u_src_texture, src_uv + vec2(0.0, offset.y)); + float src_h = get_height(u_src_texture, src_uv); + float dst_h = (src_h + src_nx + src_px + src_ny + src_py) * 0.2; + float h = mix(src_h, dst_h, brush_value); + COLOR = encode_height_to_viewport(h); +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/splat16.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/splat16.gdshader new file mode 100644 index 0000000..68ebaa8 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/splat16.gdshader @@ -0,0 +1,81 @@ +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_other_splatmap_1; +uniform sampler2D u_other_splatmap_2; +uniform sampler2D u_other_splatmap_3; +uniform sampler2D u_heightmap; +uniform float u_normal_min_y = 0.0; +uniform float u_normal_max_y = 1.0; + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +float sum(vec4 v) { + return v.x + v.y + v.z + v.w; +} + +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); + + // It is assumed 3 other renders are done the same with the other 3 + vec4 src0 = texture(u_src_texture, src_uv); + vec4 src1 = texture(u_other_splatmap_1, src_uv); + vec4 src2 = texture(u_other_splatmap_2, src_uv); + vec4 src3 = texture(u_other_splatmap_3, src_uv); + float t = brush_value; + vec4 s0 = mix(src0, u_splat, t); + vec4 s1 = mix(src1, vec4(0.0), t); + vec4 s2 = mix(src2, vec4(0.0), t); + vec4 s3 = mix(src3, vec4(0.0), t); + float sum = sum(s0) + sum(s1) + sum(s2) + sum(s3); + s0 /= sum; + s1 /= sum; + s2 /= sum; + s3 /= sum; + COLOR = s0; +} 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; +} diff --git a/game/addons/zylann.hterrain/tools/brush/shaders/splat_indexed.gdshader b/game/addons/zylann.hterrain/tools/brush/shaders/splat_indexed.gdshader new file mode 100644 index 0000000..9828068 --- /dev/null +++ b/game/addons/zylann.hterrain/tools/brush/shaders/splat_indexed.gdshader @@ -0,0 +1,89 @@ +shader_type canvas_item; +render_mode blend_disabled; + +uniform sampler2D u_src_texture; +uniform vec4 u_src_rect; +uniform float u_opacity = 1.0; +uniform int u_texture_index; +uniform int u_mode; // 0: output index, 1: output weight +uniform sampler2D u_index_map; +uniform sampler2D u_weight_map; + +vec2 get_src_uv(vec2 screen_uv) { + vec2 uv = u_src_rect.xy + screen_uv * u_src_rect.zw; + return uv; +} + +void fragment() { + float brush_value = u_opacity * texture(TEXTURE, UV).r; + + vec2 src_uv = get_src_uv(SCREEN_UV); + vec4 iv = texture(u_index_map, src_uv); + vec4 wv = texture(u_weight_map, src_uv); + + float i[3] = {iv.r, iv.g, iv.b}; + float w[3] = {wv.r, wv.g, wv.b}; + + if (brush_value > 0.0) { + float texture_index_f = float(u_texture_index) / 255.0; + int ci = u_texture_index % 3; + + float cm[3] = {-1.0, -1.0, -1.0}; + cm[ci] = 1.0; + + // Decompress third weight to make computations easier + w[2] = 1.0 - w[0] - w[1]; + + if (abs(i[ci] - texture_index_f) > 0.001) { + // Pixel does not have our texture index, + // transfer its weight to other components first + if (w[ci] > brush_value) { + w[0] -= cm[0] * brush_value; + w[1] -= cm[1] * brush_value; + w[2] -= cm[2] * brush_value; + + } else if (w[ci] >= 0.f) { + w[ci] = 0.f; + i[ci] = texture_index_f; + } + + } else { + // Pixel has our texture index, increase its weight + if (w[ci] + brush_value < 1.f) { + w[0] += cm[0] * brush_value; + w[1] += cm[1] * brush_value; + w[2] += cm[2] * brush_value; + + } else { + // Pixel weight is full, we can set all components to the same index. + // Need to nullify other weights because they would otherwise never reach + // zero due to normalization + w[0] = 0.0; + w[1] = 0.0; + w[2] = 0.0; + + w[ci] = 1.0; + + i[0] = texture_index_f; + i[1] = texture_index_f; + i[2] = texture_index_f; + } + } + + w[0] = clamp(w[0], 0.0, 1.0); + w[1] = clamp(w[1], 0.0, 1.0); + w[2] = clamp(w[2], 0.0, 1.0); + + // Renormalize + float sum = w[0] + w[1] + w[2]; + w[0] /= sum; + w[1] /= sum; + w[2] /= sum; + } + + if (u_mode == 0) { + COLOR = vec4(i[0], i[1], i[2], 1.0); + } else { + COLOR = vec4(w[0], w[1], w[2], 1.0); + } +} |