diff options
Diffstat (limited to 'shaders')
| -rw-r--r-- | shaders/combine.frag | 65 | ||||
| -rw-r--r-- | shaders/combine.vert | 11 | ||||
| -rw-r--r-- | shaders/shader.frag | 25 | ||||
| -rw-r--r-- | shaders/shader.vert | 5 | 
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;  } | 
