Last active
December 15, 2024 10:27
-
-
Save Trass3r/4297b66a9cc3473f17077fe6060bf21c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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