-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlight_lists.comp
126 lines (100 loc) · 4.04 KB
/
light_lists.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#version 430
#extension GL_ARB_shading_language_include : require
#include </data/shaders/common/floatpacking.glsl>
#include </data/shaders/common/reprojection.glsl>
// gl_WorkGroupID.x determines cluster, gl_WorkGroupID.y the sub-list in that cluster.
// gl_LocalInvocationID.x determines which light in that sub-list is processed.
layout (local_size_x = 64, local_size_y = 1, local_size_x = 1) in;
layout (r32ui, binding = 0) restrict readonly uniform uimage1D compactUsedClusterIDs;
layout (r16ui, binding = 1) restrict writeonly uniform uimage2D lightLists;
layout (rgba32f, binding = 2) restrict writeonly uniform image2D clusterCorners;
const int totalVplCount = 1024;
layout (std140, binding = 0) uniform packedVplBuffer_
{
vec4 vplPositionNormalBuffer[totalVplCount];
};
layout (std140, binding = 0) buffer atomicBuffer_
{
uint numUsedClusters;
};
uniform ivec2 viewport;
uniform mat4 projectionMatrix;
uniform mat4 viewProjectionInverseMatrix;
uniform float zFar;
uniform int vplStartIndex = 0;
uniform int vplEndIndex = totalVplCount;
const uint pixelsPerCluster = 128;
const uint maxNumLights = 1024;
const float nearPlane = 0.05;
const int numDepthSlices = 16;
const int numSlicesIntoFirstSlice = 3;
float scaleFactor = (numDepthSlices + numSlicesIntoFirstSlice) / log2(zFar);
float sliceToZ(uint slice)
{
if (slice == 0)
return nearPlane;
return -pow(2, (slice + numSlicesIntoFirstSlice) / scaleFactor);
}
shared uint sharedCounter;
void main()
{
uint id = gl_WorkGroupID.x;
if (id >= numUsedClusters)
return;
uint clusterID = imageLoad(compactUsedClusterIDs, int(id)).x;
uint clusterX = clusterID & 0xFFu;
uint clusterY = clusterID >> 8 & 0xFFu;
uint clusterZ = clusterID >> 16 & 0xFFu;
uvec3 clusterCoord = uvec3(clusterX, clusterY, clusterZ);
float viewSpaceZFront = sliceToZ(clusterZ);
float viewSpaceZBack = sliceToZ(clusterZ + 1);
float ndcL = float(clusterCoord.x) * pixelsPerCluster / viewport.x;
float ndcR = float(clusterCoord.x + 1) * pixelsPerCluster / viewport.x;
float ndcB = float(clusterCoord.y) * pixelsPerCluster / viewport.y;
float ndcT = float(clusterCoord.y + 1) * pixelsPerCluster / viewport.y;
float ndcFront = logDepth(viewSpaceZFront, projectionMatrix);
float ndcBack = logDepth(viewSpaceZBack, projectionMatrix);
vec3 corners[8];
corners[0] = vec3(ndcL, ndcB, ndcFront);
corners[1] = vec3(ndcL, ndcB, ndcBack);
corners[2] = vec3(ndcR, ndcB, ndcFront);
corners[3] = vec3(ndcR, ndcB, ndcBack);
corners[4] = vec3(ndcL, ndcT, ndcFront);
corners[5] = vec3(ndcL, ndcT, ndcBack);
corners[6] = vec3(ndcL, ndcT, ndcFront);
corners[7] = vec3(ndcL, ndcT, ndcBack);
for (int i = 0; i < 8; i++) {
vec4 v = vec4(corners[i], 1.0);
v = v * 2.0 - 1.0;
v = viewProjectionInverseMatrix * v;
corners[i] = v.xyz / v.w;
}
// debug data buffer
// for (int i = 0; i < 8; i++) {
// imageStore(clusterCorners, ivec2(id, i), vec4(corners[i], 0.0));
// }
// imageStore(clusterCorners, ivec2(id, 0), vec4(clusterCoord, 0.0));
// imageStore(clusterCorners, ivec2(id, 1), vec4(viewSpaceZFront, viewSpaceZBack, 0.0, 0.0));
sharedCounter = 1;
barrier();
memoryBarrierShared();
uint subListStartIndex = gl_WorkGroupID.y * 64u;
uint vplID = subListStartIndex + gl_LocalInvocationID.x;
vec4 vplPositionNormal = vplPositionNormalBuffer[vplID];
bool found = false;
for (int j = 0; j < 8; j++) {
vec3 corner = corners[j];
vec3 vplToCorner = corner - vplPositionNormal.xyz;
vec3 vplNormal = unpack3SNFromFloat(vplPositionNormal.w);
found = found || (dot(vplToCorner, vplNormal) >= 0);
}
// found = true;
if (found) {
uint counter = atomicAdd(sharedCounter, 1);
imageStore(lightLists, ivec2(id, subListStartIndex + counter), uvec4(vplID, 0, 0, 0));
}
barrier();
memoryBarrierShared();
if(gl_LocalInvocationID.x == 0)
imageStore(lightLists, ivec2(id, subListStartIndex), uvec4(sharedCounter, 0, 0, 0));
}