Files
Vulkan-Samples/shaders/multi_draw_indirect/cull.comp
T
2025-09-04 10:54:47 +08:00

102 lines
2.3 KiB
Plaintext

#version 460
/* Copyright (c) 2021 Holochip Corporation
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
layout(local_size_x = 64) in;
struct ModelInformation
{
float x;
float y;
float z;
float r;
uint texture_index;
uint firstIndex;
uint indexCount;
uint _pad;
};
struct VkDrawIndexedIndirectCommand
{
uint indexCount;
uint instanceCount;
uint firstIndex;
int vertexOffset;
uint firstInstance;
};
layout(std430, set = 0, binding = 0) buffer readonly ModelInformationBuffer
{
ModelInformation arr[];
}
model_buffer;
layout(set = 0, binding = 2) uniform GlobalUniform
{
mat4 view;
mat4 proj;
mat4 proj_view;
uint model_count;
}
global_uniform;
layout(std430, set = 0, binding = 3) buffer writeonly CommandBuffer
{
VkDrawIndexedIndirectCommand commands[];
}
command_buffer;
// See "VisibilityTester" in the C++ code for explanation
bool check_is_visible(mat4 mat, vec3 origin, float radius)
{
uint plane_index = 0;
for (uint i = 0; i < 3; ++i)
{
for (uint j = 0; j < 2; ++j, ++plane_index)
{
if (plane_index == 2 || plane_index == 3)
{
continue;
}
const float sign = (j > 0) ? 1.f : -1.f;
vec4 plane = vec4(0, 0, 0, 0);
for (uint k = 0; k < 4; ++k)
{
plane[k] = mat[k][3] + sign * mat[k][i];
}
plane.xyzw /= sqrt(dot(plane.xyz, plane.xyz));
if (dot(origin, plane.xyz) + plane.w + radius < 0)
{
return false;
}
}
}
return true;
}
void main()
{
uint id = gl_GlobalInvocationID.x;
if (id >= global_uniform.model_count)
{
return;
}
ModelInformation model = model_buffer.arr[id];
bool is_visible = check_is_visible(global_uniform.proj_view, vec3(model.x, model.y, model.z), model.r);
command_buffer.commands[id].instanceCount = is_visible ? 1 : 0;
}