119 lines
2.8 KiB
Plaintext
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;
|
|
}
|