Skip to content

Instantly share code, notes, and snippets.

@Trass3r
Last active December 15, 2024 10:27
Show Gist options
  • Save Trass3r/4297b66a9cc3473f17077fe6060bf21c to your computer and use it in GitHub Desktop.
Save Trass3r/4297b66a9cc3473f17077fe6060bf21c to your computer and use it in GitHub Desktop.
#version 450
#extension GL_KHR_shader_subgroup_shuffle : require
#extension GL_EXT_samplerless_texture_functions : require
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
layout(set = 0, binding = 0, rgba8) writeonly uniform image2D uOutput;
layout(set = 0, binding = 1) uniform utexture2D uInput;
layout(push_constant) uniform Registers
{
ivec2 resolution;
} registers;
vec3 decode_endpoint_color(uint color)
{
ivec3 c = ivec3(color) >> ivec3(11, 5, 0);
c &= ivec3(31, 63, 31);
return vec3(c) / vec3(31.0, 63.0, 31.0);
}
bool decode_endpoints_color(uint payload, out vec3 ep0, out vec3 ep1)
{
uint color0 = payload & 0xffffu;
uint color1 = payload >> 16u;
bool opaque_mode = color0 > color1;
ep0 = decode_endpoint_color(color0);
ep1 = decode_endpoint_color(color1);
return opaque_mode;
}
vec4 interpolate_endpoint_color(vec3 ep0, vec3 ep1, int bits, bool opaque_mode)
{
vec4 res;
vec3 lerped;
if (opaque_mode)
{
if (bits < 2)
lerped = bits != 0 ? ep1 : ep0;
else
lerped = mix(ep0, ep1, (1.0 / 3.0) * float(bits - 1));
res = vec4(lerped, 1.0);
}
else
{
if (bits == 3)
{
res = vec4(0);
}
else
{
if (bits == 0)
lerped = ep0;
else if (bits == 1)
lerped = ep1;
else
lerped = 0.5 * (ep0 + ep1);
res = vec4(lerped, 1.0);
}
}
return res;
}
void main()
{
ivec2 tile_coord = ivec2(gl_WorkGroupID.xy) * 8;
tile_coord.x += 4 * (int(gl_LocalInvocationID.z) & 1);
tile_coord.y += 2 * (int(gl_LocalInvocationID.z) & 2);
ivec2 pixel_coord = ivec2(gl_LocalInvocationID.xy);
ivec2 coord = tile_coord + pixel_coord;
if (any(greaterThanEqual(coord, registers.resolution)))
return;
uvec4 payload;
if (gl_LocalInvocationID.xy == ivec2(0)) {
payload = texelFetch(uInput, tile_coord >> 2, 0);
}
payload = subgroupShuffle(payload, gl_SubgroupInvocationID & ~15);
uvec2 color_payload, alpha_payload;
color_payload = payload.xy;
float alpha;
vec3 ep0, ep1;
bool opaque_mode = decode_endpoints_color(color_payload.x, ep0, ep1);
int linear_pixel = 4 * pixel_coord.y + pixel_coord.x;
vec4 decoded = interpolate_endpoint_color(ep0, ep1, int((color_payload.y >> (2 * linear_pixel)) & 3), opaque_mode);
decoded.a = 1.0;
imageStore(uOutput, coord, decoded);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment