first commit
This commit is contained in:
19
addons/zylann.hterrain/tools/brush/shaders/alpha.gdshader
Executable file
19
addons/zylann.hterrain/tools/brush/shaders/alpha.gdshader
Executable file
@@ -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));
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://ctyfdcpwn7u1h
|
||||
68
addons/zylann.hterrain/tools/brush/shaders/color.gdshader
Executable file
68
addons/zylann.hterrain/tools/brush/shaders/color.gdshader
Executable file
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://cm5sx634mgyfw
|
||||
64
addons/zylann.hterrain/tools/brush/shaders/erode.gdshader
Executable file
64
addons/zylann.hterrain/tools/brush/shaders/erode.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://c42imxjqfdrbc
|
||||
22
addons/zylann.hterrain/tools/brush/shaders/flatten.gdshader
Executable file
22
addons/zylann.hterrain/tools/brush/shaders/flatten.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bjv4wyrnk5ve6
|
||||
45
addons/zylann.hterrain/tools/brush/shaders/level.gdshader
Executable file
45
addons/zylann.hterrain/tools/brush/shaders/level.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://coke71n64caxu
|
||||
22
addons/zylann.hterrain/tools/brush/shaders/raise.gdshader
Executable file
22
addons/zylann.hterrain/tools/brush/shaders/raise.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://ckob4h0qetlwr
|
||||
34
addons/zylann.hterrain/tools/brush/shaders/smooth.gdshader
Executable file
34
addons/zylann.hterrain/tools/brush/shaders/smooth.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://soc6v0vp5q57
|
||||
81
addons/zylann.hterrain/tools/brush/shaders/splat16.gdshader
Executable file
81
addons/zylann.hterrain/tools/brush/shaders/splat16.gdshader
Executable file
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://b28x6nh72ksgb
|
||||
63
addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader
Executable file
63
addons/zylann.hterrain/tools/brush/shaders/splat4.gdshader
Executable file
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://imbkuc1meusn
|
||||
89
addons/zylann.hterrain/tools/brush/shaders/splat_indexed.gdshader
Executable file
89
addons/zylann.hterrain/tools/brush/shaders/splat_indexed.gdshader
Executable file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://ccj38q8toifpu
|
||||
Reference in New Issue
Block a user