-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathclustering.comp
88 lines (62 loc) · 2.38 KB
/
clustering.comp
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
85
86
87
88
#version 430
#extension GL_ARB_shading_language_include : require
#include </data/shaders/common/reprojection.glsl>
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
layout (r32ui, binding = 0) restrict writeonly uniform uimage1D compactUsedIDs;
layout (r16ui, binding = 1) restrict uniform writeonly uimage3D lightListIds;
uniform sampler2D depthSampler;
layout (std140, binding = 0) buffer atomicBuffer_
{
uint atomicCounter;
};
uniform mat4 projectionMatrix;
uniform float zFar;
const int numDepthSlices = 16;
const int numSlicesIntoFirstSlice = 3;
float scaleFactor = (numDepthSlices + numSlicesIntoFirstSlice) / log2(zFar);
shared bool[numDepthSlices] usedDepthSlices;
shared int counter;
shared uint startIndex;
void main()
{
uvec2 clusterCoord = uvec2(gl_WorkGroupID.xy);
// initialization
if (gl_LocalInvocationID.x == 0)
counter = 0;
if (gl_LocalInvocationID.x < 16)
usedDepthSlices[gl_LocalInvocationID.x] = false;
barrier();
memoryBarrierShared();
// mark used depth slices
for(int i = 0; i < 128; i++) {
ivec2 fragCoord = ivec2(clusterCoord * 128) + ivec2(gl_LocalInvocationID.x, i);
float depth = linearDepth(depthSampler, fragCoord, projectionMatrix);
int depthSlice = int(max(log2(-depth) * scaleFactor - numSlicesIntoFirstSlice, 0));
bool inImageBounds = all(lessThan(fragCoord, textureSize(depthSampler, 0).xy));
if (inImageBounds)
usedDepthSlices[depthSlice] = true;
}
barrier();
memoryBarrierShared();
// from here on, each invocation processes one depth slice
if (gl_LocalInvocationID.x >= 16)
return;
uint depthSlice = gl_LocalInvocationID.x;
// count used depth slices
uint localCounter = 0;
if(usedDepthSlices[depthSlice])
localCounter = atomicAdd(counter, 1);
barrier();
memoryBarrierShared();
// allocate space for used cluster IDs
if (depthSlice == 0)
startIndex = atomicAdd(atomicCounter, counter);
barrier();
memoryBarrierShared();
// store cluster ID
if(usedDepthSlices[depthSlice]) {
uint clusterID = clusterCoord.x | clusterCoord.y << 8 | depthSlice << 16;
imageStore(compactUsedIDs, int(startIndex+localCounter), uvec4(clusterID, 0, 0, 0));
imageStore(lightListIds, ivec3(clusterCoord, depthSlice), uvec4(startIndex+localCounter, 0, 0, 0));
}
}