Files
armorpaint/paint/shaders/dilate_pass.kong
T
luboslenco 3dbdf2b3ed Cleanup
2025-08-07 14:58:38 +02:00

119 lines
2.8 KiB
Plaintext

#[set(everything)]
const constants: {
dilate_radius: float;
tex_size: float2;
};
#[set(everything)]
const sampler_linear: sampler;
#[set(everything)]
const tex: tex2d;
#[set(everything)]
const texdilate: tex2d;
// const offsets: float2[8] = {
// float2(-1.0, 0.0), float2( 1.0, 0.0), float2( 0.0, 1.0), float2( 0.0, -1.0),
// float2(-1.0, 1.0), float2( 1.0, 1.0), float2( 1.0, -1.0), float2(-1.0, -1.0)
// };
struct vert_in {
pos: float2;
}
struct vert_out {
pos: float4;
tex: float2;
}
fun get_offset(i: int): float2 {
if (i == 0) {
return float2(-1.0, 0.0);
}
if (i == 1) {
return float2( 1.0, 0.0);
}
if (i == 2) {
return float2( 0.0, 1.0);
}
if (i == 3) {
return float2( 0.0, -1.0);
}
if (i == 4) {
return float2(-1.0, 1.0);
}
if (i == 5) {
return float2( 1.0, 1.0);
}
if (i == 6) {
return float2( 1.0, -1.0);
}
return float2(-1.0, -1.0);
}
fun dilate_pass_vert(input: vert_in): vert_out {
var output: vert_out;
output.tex = input.pos.xy * 0.5 + 0.5;
output.tex.y = 1.0 - output.tex.y;
output.pos = float4(input.pos.xy, 0.0, 1.0);
return output;
}
fun dilate_pass_frag(input: vert_out): float4 {
// Based on https://shaderbits.com/blog/uv-dilation by Ryan Brucks
var texel_size: float2 = float2(1.0, 1.0) / constants.tex_size;
var min_dist: float = 10000000.0;
//var coord: uint2 = uint2(input.tex * constants.tex_size);
var coordf: float2 = float2(input.tex.x * constants.tex_size.x, input.tex.y * constants.tex_size.y);
var coord: uint2 = uint2(uint(coordf.x), uint(coordf.y));
//var mask: float = texdilate[coord].r;
var mask4: float4 = texdilate[coord];
var mask: float = mask4.r;
if (mask > 0.0) {
discard;
}
var color: float4 = tex[coord];
var i: int = 0;
while (i < int(constants.dilate_radius)) {
i += 1;
var j: int = 0;
while (j < 8) {
var cur_uv: float2 = input.tex + get_offset(j) * texel_size * float2(float(i), float(i));
coordf = cur_uv * constants.tex_size;
coord = uint2(uint(coordf.x), uint(coordf.y));
var offset_mask4: float4 = texdilate[coord];
var offset_mask: float = offset_mask4.r;
var offset_col: float4 = tex[coord];
if (offset_mask != 0.0) {
var cur_dist: float = length(input.tex - cur_uv);
if (cur_dist < min_dist) {
var project_uv: float2 = cur_uv + get_offset(j) * texel_size * float2(float(i), float(i)) * float2(0.25, 0.25);
var direction: float4 = sample_lod(tex, sampler_linear, project_uv, 0.0);
min_dist = cur_dist;
if (direction.x != 0.0 || direction.y != 0.0 || direction.z != 0.0) {
var delta: float4 = offset_col - direction;
color = offset_col + delta * float4(4.0, 4.0, 4.0, 4.0);
}
else {
color = offset_col;
}
}
}
j += 1;
}
}
return color;
}
#[pipe]
struct pipe {
vertex = dilate_pass_vert;
fragment = dilate_pass_frag;
}