1
1
#version 430 core
2
+ #extension GL_EXT_shader_16bit_storage : require
2
3
3
4
#include "rasterizationCommon.h"
4
5
layout(local_size_x = WORKGROUP_SIZE) in;
5
6
6
- #include <nbl/builtin/glsl/utils/indirect_commands.glsl>
7
-
8
7
layout(set=0, binding=0, std430, row_major) restrict readonly buffer PerInstanceCull
9
8
{
10
9
CullData_t cullData[];
11
10
};
12
- layout(set=0, binding=1, std430) restrict coherent buffer IndirectDraws
13
- {
14
- nbl_glsl_DrawElementsIndirectCommand_t draws[];
15
- } commandBuff;
16
- layout(set=0, binding=2, std430) restrict coherent buffer MVPs
11
+ layout(set=0, binding=1, std430) restrict buffer MVPs
17
12
{
18
13
mat4 mvps[];
19
14
} mvpBuff;
20
15
21
-
16
+ layout(set=0, binding=2, std430, column_major) restrict buffer CubeMVPs
17
+ {
18
+ mat4 cubeMVPs[];
19
+ } cubeMvpBuff;
20
+
21
+ #define CUBE_COMMAND_BUFF_SET 0
22
+ #define CUBE_COMMAND_BUFF_BINDING 3
23
+ #define FRUSTUM_CULLED_COMMAND_BUFF_SET 0
24
+ #define FRUSTUM_CULLED_COMMAND_BUFF_BINDING 4
25
+ #define OCCLUSION_CULLED_COMMAND_BUFF_SET 0
26
+ #define OCCLUSION_CULLED_COMMAND_BUFF_BINDING 5
27
+ #define CUBE_DRAW_GUID_BUFF_SET 0
28
+ #define CUBE_DRAW_GUID_BUFF_BINDING 6
29
+ #define OCCLUSION_DISPATCH_INDIRECT_BUFF_SET 0
30
+ #define OCCLUSION_DISPATCH_INDIRECT_BUFF_BINDING 7
31
+ #define VISIBLE_BUFF_SET 0
32
+ #define VISIBLE_BUFF_BINDING 8
33
+ #include "occlusionCullingShaderCommon.glsl"
22
34
23
35
layout(push_constant, row_major) uniform PushConstants
24
36
{
25
37
CullShaderData_t data;
26
38
} pc;
27
39
28
-
29
-
30
40
#include <nbl/builtin/glsl/utils/culling.glsl>
31
41
#include <nbl/builtin/glsl/utils/transform.glsl>
32
42
43
+ bool unpackFreezeCullFlag(in uint packedVal)
44
+ {
45
+ return bool(packedVal >> 16u);
46
+ }
47
+
48
+ uint unpackMaxBatchCount(in uint packedVal)
49
+ {
50
+ return packedVal & 0x0000FFFFu;
51
+ }
33
52
34
53
void main()
35
54
{
36
- if (gl_GlobalInvocationID.x >= pc.data.maxBatchCount )
55
+ if (gl_GlobalInvocationID.x >= unpackMaxBatchCount( pc.data.freezeCullingAndMaxBatchCountPacked) )
37
56
return;
57
+
58
+ mvpBuff.mvps[gl_GlobalInvocationID.x] = pc.data.viewProjMatrix; // no model matrices
38
59
39
- mvpBuff.mvps[gl_GlobalInvocationID.x] = pc.data.viewProjMatrix;
60
+ const CullData_t batchCullData = cullData[gl_GlobalInvocationID.x];
61
+ const uint drawCommandGUID = batchCullData.drawCommandGUID;
62
+ occlusionCommandBuff.draws[drawCommandGUID].instanceCount = 0;
40
63
41
- if (bool (pc.data.freezeCulling ))
64
+ if (unpackFreezeCullFlag (pc.data.freezeCullingAndMaxBatchCountPacked ))
42
65
return;
43
66
44
- const CullData_t batchCullData = cullData[gl_GlobalInvocationID.x];
45
67
46
68
const mat2x3 bbox = mat2x3(batchCullData.aabbMinEdge,batchCullData.aabbMaxEdge);
47
69
bool couldBeVisible = nbl_glsl_couldBeVisible(pc.data.viewProjMatrix,bbox);
48
-
49
- commandBuff.draws[batchCullData.drawCommandGUID].instanceCount = couldBeVisible == true ? 1 : 0;
70
+
71
+ if (couldBeVisible)
72
+ {
73
+ const vec3 localCameraPos = pc.data.worldCamPos; // true in this case
74
+ const bool cameraInsideAABB = all(greaterThanEqual(localCameraPos, batchCullData.aabbMinEdge)) && all(lessThanEqual(localCameraPos, batchCullData.aabbMaxEdge));
75
+ const bool assumedVisible = uint(visibleBuff.visible[gl_GlobalInvocationID.x]) == 1u || cameraInsideAABB;
76
+ frustumCommandBuff.draws[drawCommandGUID].instanceCount = assumedVisible ? 1u : 0u;
77
+ // if not frustum culled and batch was not visible in the last frame, and it makes sense to test
78
+ if(!assumedVisible)
79
+ {
80
+ const uint currCubeIdx = atomicAdd(cubeIndirectDraw.draw.instanceCount, 1);
81
+
82
+ if(currCubeIdx % WORKGROUP_SIZE == 0)
83
+ atomicAdd(occlusionDispatchIndirect.di.num_groups_x, 1);
84
+
85
+ // only works for a source geometry box which is [0,1]^2, the geometry creator box is [-0.5,0.5]^2, so either make your own box, or work out the math for this
86
+ vec3 aabbExtent = batchCullData.aabbMaxEdge - batchCullData.aabbMinEdge;
87
+ cubeMvpBuff.cubeMVPs[currCubeIdx] = mat4(
88
+ pc.data.viewProjMatrix[0]*aabbExtent.x,
89
+ pc.data.viewProjMatrix[1]*aabbExtent.y,
90
+ pc.data.viewProjMatrix[2]*aabbExtent.z,
91
+ pc.data.viewProjMatrix*vec4(batchCullData.aabbMinEdge,1)
92
+ );
93
+
94
+ cubeDrawGUIDBuffer.drawGUID[currCubeIdx] = drawCommandGUID;
95
+ }
96
+ }
97
+ else
98
+ frustumCommandBuff.draws[drawCommandGUID].instanceCount = 0;
99
+
100
+ // does `freezeCulling` affect this negatively?
101
+ visibleBuff.visible[gl_GlobalInvocationID.x] = uint16_t(0u);
50
102
}
0 commit comments