summaryrefslogtreecommitdiff
path: root/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'shaders')
-rw-r--r--shaders/combine.frag65
-rw-r--r--shaders/combine.vert11
-rw-r--r--shaders/shader.frag25
-rw-r--r--shaders/shader.vert5
4 files changed, 101 insertions, 5 deletions
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;
}