From 4ecdaa7cd08f4f3ee04cd49f8f2271636ac81e64 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sun, 11 Feb 2024 20:39:22 +0100 Subject: transparency Signed-off-by: Anna (navi) Figueiredo Gomes --- shaders/combine.frag | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ shaders/combine.vert | 11 +++++++++ shaders/shader.frag | 25 +++++++++++++++++--- shaders/shader.vert | 5 ++-- 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 shaders/combine.frag create mode 100644 shaders/combine.vert (limited to 'shaders') diff --git a/shaders/combine.frag b/shaders/combine.frag new file mode 100644 index 0000000..4240528 --- /dev/null +++ b/shaders/combine.frag @@ -0,0 +1,65 @@ +#version 450 + +#define LIST_END ~0x0 +#define SORT_MAX 32 + +layout (location = 0) out vec4 color; + +layout(binding = 0) uniform mvp { + mat4 model; + mat4 view; + mat4 proj; + uint count; +} ubo; + +layout(binding = 1) buffer fragment_buffer { + uvec3 fragments[]; +}; +layout(binding = 2, r32ui) uniform uimage2D head; +layout(binding = 3) buffer counter { + int data; +}; + +vec4 blend_colors(uint packed_color, vec4 dst_color) { + const vec4 src_color = unpackUnorm4x8(packed_color); + return vec4(mix(dst_color.rgb, src_color.rgb, src_color.a), dst_color.a * (1.0f - src_color.a)); +} + +void main() { + color = vec4(0, 0, 0, 1); + uint idx = imageLoad(head, ivec2(gl_FragCoord.xy)).r; + imageStore(head, ivec2(gl_FragCoord.xy), ivec4(LIST_END, 0, 0, 0)); + + uvec2 sorted[SORT_MAX]; + uint sorted_count = 0; + + // TODO: use a proper struct + while (idx != LIST_END) { + const uvec3 fragment = fragments[idx]; + idx = fragment.x; + + if (sorted_count < SORT_MAX) { + uint i = sorted_count; + for(; i > 0 && fragment.z > sorted[i - 1].y; i--) { + sorted[i] = sorted[i - 1]; + } + sorted[i] = fragment.yz; + sorted_count++; + } else if (fragment.z > sorted[0].y) { + color = blend_colors(sorted[0].x, color); + uint i = 0; + for (; i < SORT_MAX - 1 && fragment.z < sorted[i + 1].y; i++) { + sorted[i] = sorted[i + 1]; + } + sorted[i] = fragment.yz; + } else { + color = blend_colors(fragment.y, color); + } + } + + for (int i = 0; i < sorted_count; i++) { + color = blend_colors(sorted[i].x, color); + } + + color.a = 1.0f - color.a; +} diff --git a/shaders/combine.vert b/shaders/combine.vert new file mode 100644 index 0000000..b9b349e --- /dev/null +++ b/shaders/combine.vert @@ -0,0 +1,11 @@ +#version 450 + +const vec2 vertices[] = { + vec2(-1.0f, 3.0f), + vec2(-1.0f, -1.0f), + vec2(3.0f, -1.0f) +}; + +void main() { + gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0f, 1.0f); +} diff --git a/shaders/shader.frag b/shaders/shader.frag index a4ce603..eb255e3 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -1,8 +1,27 @@ #version 450 -layout(location = 0) in vec4 fragColor; -layout(location = 0) out vec4 outColor; +layout(location = 0) in vec4 color; + +layout(set = 0, binding = 0) uniform mvp { + mat4 model; + mat4 view; + mat4 proj; + uint count; +} ubo; + +layout(binding = 1) buffer fragment_buffer { + uvec3 fragments[]; +}; +layout(binding = 2, r32ui) uniform uimage2D head; +layout(binding = 3) buffer counter { + uint data; +}; void main() { - outColor = fragColor; + const uint idx = atomicAdd(data, 1); + if (idx >= ubo.count) { + discard; + } + const uint prev_idx = imageAtomicExchange(head, ivec2(gl_FragCoord.xy), idx); + fragments[idx] = uvec3(prev_idx, packUnorm4x8(color), floatBitsToUint(gl_FragCoord.z)); } diff --git a/shaders/shader.vert b/shaders/shader.vert index 48f67d6..181d1bd 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -10,6 +10,7 @@ layout(set = 0, binding = 0) uniform mvp { mat4 model; mat4 view; mat4 proj; + uint count; } ubo; layout(push_constant) uniform mesh_data { @@ -17,6 +18,6 @@ layout(push_constant) uniform mesh_data { } mesh; void main() { - gl_Position = ubo.proj * ubo.view * ubo.model * mesh.transform * ubo.model * vec4(in_position, 1.0); - frag_color = gl_Position; + gl_Position = ubo.proj * ubo.view * ubo.model * mesh.transform * vec4(in_position, 1.0); + frag_color = in_color; } -- cgit v1.2.3