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);
 | 
						|
} |