#version 430 #define TILE_SIZE 16 uniform mat4 P; uniform vec2 ScreenDimensions; struct Plane { vec3 Normal; float d; }; struct Frustum { Plane Planes[4]; }; layout (std430, binding = 0) buffer FrustumBuffer { Frustum Data[]; } Frustums; vec4 ConvertToView(vec4 ScreenCoords) { vec2 normalizedScreenCoords = ScreenCoords.xy / ScreenDimensions; vec4 clipSpace = vec4( vec2(normalizedScreenCoords.x, normalizedScreenCoords.y) * 2.0 - 1.0, ScreenCoords.z, ScreenCoords.w); vec4 view = inverse(P) * clipSpace; view = view / view.w; return view; } Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 ) { Plane plane; vec3 v0 = p1 - p0; vec3 v2 = p2 - p0; plane.Normal = normalize( cross( v0, v2 ) ); plane.d = dot( vec3(plane.Normal), p0 ); // Always 0 probably return plane; } layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; void main () { //Top-Left = 0 | Top-Right = 1 //Bottom-Left = 2 | Bottom-Right = 3 vec4 ScreenCoords[4]; ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0); ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0); ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); vec3 ViewVectors[4]; for(int i = 0; i < 4; i++) { ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i])); } vec3 EyePos = vec3(0.0, 0.0 ,0.0); Frustum f; f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]); // left plane f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]); // right plane f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]); // top plane f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]); // bottom plane if ( gl_GlobalInvocationID.x < ScreenDimensions.x / TILE_SIZE && gl_GlobalInvocationID.y < ScreenDimensions.y / TILE_SIZE ) { // inside the screen Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*int(ScreenDimensions.x/TILE_SIZE)] = f; } }