mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 10:59:20 +02:00
58 lines
2.2 KiB
Plaintext
58 lines
2.2 KiB
Plaintext
// bounding boxes of the light clusters in view space, see gl/cluster_grid.h
|
|
// one invocation per cluster, run when the projection or the depth range of the pass changes
|
|
|
|
#include <common>
|
|
|
|
layout(local_size_x = CLUSTER_BUILD_GROUP_SIZE) in;
|
|
|
|
// clip space w at the lower boundary of slice k: the inverse of the slice formula used when shading
|
|
float slice_depth(uint k)
|
|
{
|
|
return exp((float(k) - cluster_slice_bias) / cluster_slice_scale);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
uint index = gl_GlobalInvocationID.x;
|
|
if (index >= uint(CLUSTER_COUNT))
|
|
return;
|
|
|
|
uvec3 cell = uvec3(
|
|
index % uint(CLUSTER_GRID_X),
|
|
(index / uint(CLUSTER_GRID_X)) % uint(CLUSTER_GRID_Y),
|
|
index / uint(CLUSTER_GRID_X * CLUSTER_GRID_Y));
|
|
|
|
// clip x, y and w are affine functions of the view space position, while clip z is constant (reverse z with
|
|
// the far plane at infinity), which makes the projection matrix singular. the position is recovered from
|
|
// those three alone, so off-axis and rotated screens of custom viewports and vr eyes work too
|
|
mat3 linear = mat3(
|
|
vec3(cluster_projection[0][0], cluster_projection[0][1], cluster_projection[0][3]),
|
|
vec3(cluster_projection[1][0], cluster_projection[1][1], cluster_projection[1][3]),
|
|
vec3(cluster_projection[2][0], cluster_projection[2][1], cluster_projection[2][3]));
|
|
vec3 translation = vec3(cluster_projection[3][0], cluster_projection[3][1], cluster_projection[3][3]);
|
|
mat3 unproject = inverse(linear);
|
|
|
|
// the tile in clip space xy, the slice in clip space w
|
|
vec2 tiles = vec2(CLUSTER_GRID_X, CLUSTER_GRID_Y);
|
|
vec2 ndc_min = vec2(cell.xy) / tiles * 2.0 - 1.0;
|
|
vec2 ndc_max = vec2(cell.xy + 1U) / tiles * 2.0 - 1.0;
|
|
float w_near = slice_depth(cell.z);
|
|
float w_far = slice_depth(cell.z + 1U);
|
|
|
|
vec3 lower = vec3(3.402823e38);
|
|
vec3 upper = vec3(-3.402823e38);
|
|
for (int corner = 0; corner < 8; ++corner)
|
|
{
|
|
vec2 ndc = vec2(
|
|
(corner & 1) != 0 ? ndc_max.x : ndc_min.x,
|
|
(corner & 2) != 0 ? ndc_max.y : ndc_min.y);
|
|
float w = (corner & 4) != 0 ? w_far : w_near;
|
|
vec3 position = unproject * (vec3(ndc * w, w) - translation);
|
|
lower = min(lower, position);
|
|
upper = max(upper, position);
|
|
}
|
|
|
|
cluster_aabbs[index].lower = vec4(lower, 0.0);
|
|
cluster_aabbs[index].upper = vec4(upper, 0.0);
|
|
}
|