Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
91 lines
2.3 KiB
Plaintext
91 lines
2.3 KiB
Plaintext
#version 450 core
|
|
|
|
/**
|
|
Maximum number of lights per cluster
|
|
*/
|
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
|
|
|
/**
|
|
The number of "threads" to run
|
|
*/
|
|
#define CULL_LOCAL_SIZE 128
|
|
|
|
/**
|
|
Bind points for different SSBOs
|
|
*/
|
|
#define CLUSTER_SSBO_BIND_POINT 1
|
|
#define POINT_LIGHT_SSBO_BIND_POINT 2
|
|
#define DIRECT_LIGHT_SSBO_BIND_POINT 3
|
|
|
|
|
|
layout(local_size_x = CULL_LOCAL_SIZE, local_size_y = 1, local_size_z = 1) in;
|
|
|
|
struct PointLight {
|
|
vec4 position;
|
|
vec4 color;
|
|
float constant;
|
|
float linear;
|
|
float quadratic;
|
|
float radius;
|
|
};
|
|
|
|
struct Cluster {
|
|
vec4 minPoint;
|
|
vec4 maxPoint;
|
|
uint count;
|
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
|
};
|
|
|
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterSSBO {
|
|
Cluster clusters[];
|
|
};
|
|
|
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer lightSSBO {
|
|
PointLight pointLight[];
|
|
};
|
|
|
|
uniform mat4 viewMatrix;
|
|
|
|
/**
|
|
* Number of lights in the scene
|
|
*/
|
|
uniform int lightCount;
|
|
|
|
bool testSphereAABB(uint i, Cluster c);
|
|
|
|
// each invocation of main() is a thread processing a cluster
|
|
void main() {
|
|
uint index = gl_WorkGroupID.x * CULL_LOCAL_SIZE + gl_LocalInvocationID.x;
|
|
Cluster cluster = clusters[index];
|
|
|
|
// we need to reset count because culling runs every frame.
|
|
// otherwise it would accumulate.
|
|
cluster.count = 0;
|
|
|
|
for (uint i = 0; i < lightCount; ++i){
|
|
if (testSphereAABB(i, cluster) && cluster.count < 100){
|
|
cluster.lightIndices[cluster.count] = i;
|
|
cluster.count++;
|
|
}
|
|
}
|
|
clusters[index] = cluster;
|
|
}
|
|
|
|
bool sphereAABBIntersection(vec3 center, float radius, vec3 aabbMin, vec3 aabbMax) {
|
|
// closest point on the AABB to the sphere center
|
|
vec3 closestPoint = clamp(center, aabbMin, aabbMax);
|
|
// squared distance between the sphere center and closest point
|
|
float distanceSquared = dot(closestPoint - center, closestPoint - center);
|
|
return distanceSquared <= radius * radius;
|
|
}
|
|
|
|
// this just unpacks data for sphereAABBIntersection
|
|
bool testSphereAABB(uint i, Cluster cluster) {
|
|
vec3 center = vec3(viewMatrix * pointLight[i].position);
|
|
float radius = pointLight[i].radius;
|
|
|
|
vec3 aabbMin = cluster.minPoint.xyz;
|
|
vec3 aabbMax = cluster.maxPoint.xyz;
|
|
|
|
return sphereAABBIntersection(center, radius, aabbMin, aabbMax);
|
|
} |