blob: f3bd26c3935e6a670b8e1c0f68a55b2a0f36fad0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
struct Fragment
{
vec4 color;
float depth;
};
layout(binding=1, std430) buffer offsetBuffer {
uint offset[];
};
layout(binding=2, std430) buffer countBuffer {
uint count[];
};
layout(binding=3, std430) buffer fragmentBuffer {
Fragment fragment[];
};
out vec4 outColor;
uniform uint width;
uniform vec4 background;
vec4 blend(vec4 outColor, vec4 color)
{
return mix(outColor,color,color.a);
}
void main()
{
uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x);
uint size=count[headIndex];
if(size == 0u) {
#ifdef GPUINDEXING
offset[headIndex]=0u;
#endif
discard;
}
uint listIndex=offset[headIndex];
const uint maxSize=16u;
// Sort the fragments with respect to descending depth
if(size < maxSize) {
Fragment sortedList[maxSize];
sortedList[0]=fragment[listIndex];
for(uint i=1u; i < size; i++) {
Fragment temp=fragment[listIndex+i];
float depth=temp.depth;
uint j=i;
Fragment f;
while(f=sortedList[j-1u], j > 0u && depth > f.depth) {
sortedList[j]=f;
j--;
}
sortedList[j]=temp;
}
outColor=background;
for(uint i=0u; i < size; i++)
outColor=blend(outColor,sortedList[i].color);
} else {
for(uint i=1u; i < size; i++) {
Fragment temp=fragment[listIndex+i];
float depth=temp.depth;
uint j=i;
Fragment f;
while(f=fragment[listIndex+j-1u], j > 0u && depth > f.depth) {
fragment[listIndex+j]=f;
j--;
}
fragment[listIndex+j]=temp;
}
outColor=background;
uint stop=listIndex+size;
for(uint i=listIndex; i < stop; i++)
outColor=blend(outColor,fragment[i].color);
}
count[headIndex]=0u;
#ifdef GPUINDEXING
offset[headIndex]=0u;
#endif
}
|