diff --git a/projects/mesh_shader/resources/shaders/common.inc b/projects/mesh_shader/resources/shaders/common.inc new file mode 100644 index 0000000000000000000000000000000000000000..280ffee215a8b8342b78d1f5558d63a05e16859b --- /dev/null +++ b/projects/mesh_shader/resources/shaders/common.inc @@ -0,0 +1,4 @@ +struct ObjectMatrices{ + mat4 model; + mat4 mvp; +}; \ No newline at end of file diff --git a/projects/mesh_shader/resources/shaders/shader.frag b/projects/mesh_shader/resources/shaders/shader.frag index f4f6982f2089e6c8e102027f3b8763bb38f8e59c..17bf8f960bb6996f039c4e73e547db802f1ceab4 100644 --- a/projects/mesh_shader/resources/shaders/shader.frag +++ b/projects/mesh_shader/resources/shaders/shader.frag @@ -28,5 +28,5 @@ vec3 colorFromIndex(uint i){ void main() { outColor = normalize(passNormal) * 0.5 + 0.5; - outColor = colorFromIndex(passTaskIndex); + //outColor = colorFromIndex(passTaskIndex); } \ No newline at end of file diff --git a/projects/mesh_shader/resources/shaders/shader.task b/projects/mesh_shader/resources/shaders/shader.task index 3f666fbbe6e4031ff2063171992c375301e45c7e..f00e749f911b080450cb4912fbf0c6354b378f43 100644 --- a/projects/mesh_shader/resources/shaders/shader.task +++ b/projects/mesh_shader/resources/shaders/shader.task @@ -4,6 +4,7 @@ #extension GL_GOOGLE_include_directive : enable #include "meshlet.inc" +#include "common.inc" layout(local_size_x=32) in; @@ -13,31 +14,27 @@ taskNV out Task { } OUT; layout( push_constant ) uniform constants{ - uint meshletCount; uint matrixIndex; + uint meshletCount; }; -layout(std430, binding = 2) readonly buffer meshletBuffer +// TODO: reuse mesh stage binding at location 2 after required fix in framework +layout(std430, binding = 5) readonly buffer meshletBuffer { Meshlet meshlets[]; }; struct Plane{ - vec3 pointOnPlane; - float padding0; - vec3 normal; - float padding1; + vec3 pointOnPlane; + float padding0; + vec3 normal; + float padding1; }; layout(set=0, binding=3, std140) uniform cameraPlaneBuffer{ Plane cameraPlanes[6]; }; -struct ObjectMatrices{ - mat4 model; - mat4 mvp; -}; - layout(std430, binding = 4) readonly buffer matrixBuffer { ObjectMatrices objectMatrices[]; @@ -49,7 +46,8 @@ bool isSphereInsideFrustum(vec3 spherePos, float sphereRadius, Plane cameraPlane bool isInside = true; for(int i = 0; i < 6; i++){ Plane p = cameraPlanes[i]; - isInside = isInside && dot(p.normal, spherePos - p.pointOnPlane) + sphereRadius < 0; + isInside = isInside && dot(p.normal, spherePos - p.pointOnPlane) - sphereRadius < 0; + //break; } return isInside; } @@ -67,7 +65,9 @@ void main() { taskCount = 0; } - if(isSphereInsideFrustum(meshlet.meanPosition, meshlet.boundingSphereRadius, cameraPlanes)){ + // TODO: scaling support + vec3 meshletPositionWorld = (vec4(meshlet.meanPosition, 1) * objectMatrices[matrixIndex].model).xyz; + if(isSphereInsideFrustum(meshletPositionWorld, meshlet.boundingSphereRadius, cameraPlanes)){ uint outIndex = atomicAdd(taskCount, 1); OUT.meshletIndices[outIndex] = gl_GlobalInvocationID.x; } diff --git a/projects/mesh_shader/resources/shaders/shader.vert b/projects/mesh_shader/resources/shaders/shader.vert index 636545262a70a490a6aabfd5809a61f226c84a30..fca5057976f995183c040195bdbd592c63f1074e 100644 --- a/projects/mesh_shader/resources/shaders/shader.vert +++ b/projects/mesh_shader/resources/shaders/shader.vert @@ -1,5 +1,8 @@ #version 450 -#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable + +#include "common.inc" layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inNormal; @@ -7,13 +10,19 @@ layout(location = 1) in vec3 inNormal; layout(location = 0) out vec3 passNormal; layout(location = 1) out uint dummyOutput; +layout(std430, binding = 0) readonly buffer matrixBuffer +{ + ObjectMatrices objectMatrices[]; +}; + layout( push_constant ) uniform constants{ - mat4 mvp; + uint matrixIndex; uint padding; // pad to same size as mesh shader constants }; + void main() { - gl_Position = mvp * vec4(inPosition, 1.0); + gl_Position = objectMatrices[matrixIndex].mvp * vec4(inPosition, 1.0); passNormal = inNormal; dummyOutput = padding * 0; // padding must be used, else compiler shrinks constant size diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index d08564f3f85eb34b08945fd2039ab308dbfc7f0e..d7441d0dd9f0a875e70fd01e4182454977d981a8 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -30,7 +30,7 @@ CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) { float far; camera.getNearFar(near, far); - glm::vec3 up = glm::dot(forward, glm::vec3(0, -1, 0)) < 0.99 ? glm::vec3(0, -1, 0) : glm::vec3(1, 0, 0); + glm::vec3 up = glm::vec3(0, -1, 0); glm::vec3 right = glm::normalize(glm::cross(forward, up)); up = glm::cross(forward, right); @@ -51,25 +51,25 @@ CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) { CameraPlanes cameraPlanes; // near - cameraPlanes.planes[0].pointOnPlane = nearCenter; - cameraPlanes.planes[0].normal = -forward; + cameraPlanes.planes[0].pointOnPlane = nearCenter; + cameraPlanes.planes[0].normal = -forward; // far - cameraPlanes.planes[1].pointOnPlane = farCenter; - cameraPlanes.planes[1].normal = forward; + cameraPlanes.planes[1].pointOnPlane = farCenter; + cameraPlanes.planes[1].normal = forward; // top - cameraPlanes.planes[2].pointOnPlane = nearUpCenter; - cameraPlanes.planes[2].normal = glm::normalize(glm::cross(farUpCenter - nearUpCenter, right)); + cameraPlanes.planes[2].pointOnPlane = nearUpCenter; + cameraPlanes.planes[2].normal = glm::normalize(glm::cross(farUpCenter - nearUpCenter, right)); // bot - cameraPlanes.planes[3].pointOnPlane = nearDownCenter; - cameraPlanes.planes[3].normal = glm::normalize(glm::cross(right, farDownCenter - nearDownCenter)); + cameraPlanes.planes[3].pointOnPlane = nearDownCenter; + cameraPlanes.planes[3].normal = glm::normalize(glm::cross(right, farDownCenter - nearDownCenter)); // right - cameraPlanes.planes[4].pointOnPlane = nearRightCenter; - cameraPlanes.planes[4].normal = glm::normalize(glm::cross(up, farRightCenter - nearRightCenter)); + cameraPlanes.planes[4].pointOnPlane = nearRightCenter; + cameraPlanes.planes[4].normal = glm::normalize(glm::cross(up, farRightCenter - nearRightCenter)); // left - cameraPlanes.planes[5].pointOnPlane = nearLeftCenter; - cameraPlanes.planes[5].normal = glm::normalize(glm::cross(farLeftCenter - nearLeftCenter, up)); + cameraPlanes.planes[5].pointOnPlane = nearLeftCenter; + cameraPlanes.planes[5].normal = glm::normalize(glm::cross(farLeftCenter - nearLeftCenter, up)); return cameraPlanes; } @@ -201,16 +201,29 @@ int main(int argc, const char** argv) { } const vkcv::VertexLayout bunnyLayout (bindings); + vkcv::DescriptorSetHandle vertexShaderDescriptorSet = core.createDescriptorSet(bunnyShaderProgram.getReflectedDescriptors()[0]); + const vkcv::PipelineConfig bunnyPipelineDefinition { - bunnyShaderProgram, - (uint32_t)windowWidth, - (uint32_t)windowHeight, - renderPass, - { bunnyLayout }, - {}, - false + bunnyShaderProgram, + (uint32_t)windowWidth, + (uint32_t)windowHeight, + renderPass, + { bunnyLayout }, + { core.getDescriptorSet(vertexShaderDescriptorSet).layout }, + false }; + struct ObjectMatrices { + glm::mat4 model; + glm::mat4 mvp; + }; + const size_t objectCount = 1; + vkcv::Buffer<ObjectMatrices> matrixBuffer = core.createBuffer<ObjectMatrices>(vkcv::BufferType::STORAGE, objectCount); + + vkcv::DescriptorWrites vertexShaderDescriptorWrites; + vertexShaderDescriptorWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, matrixBuffer.getHandle()) }; + core.writeDescriptorSet(vertexShaderDescriptorSet, vertexShaderDescriptorWrites); + vkcv::PipelineHandle bunnyPipeline = core.createGraphicsPipeline(bunnyPipelineDefinition); if (!bunnyPipeline) @@ -236,9 +249,9 @@ int main(int argc, const char** argv) { meshShaderProgram.addShader(shaderStage, path); }); - uint32_t setID = 0; - vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet( meshShaderProgram.getReflectedDescriptors()[setID]); - const vkcv::VertexLayout meshShaderLayout(bindings); + uint32_t setID = 0; + vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet( meshShaderProgram.getReflectedDescriptors()[setID]); + const vkcv::VertexLayout meshShaderLayout(bindings); const vkcv::PipelineConfig meshShaderPipelineDefinition{ meshShaderProgram, @@ -260,19 +273,13 @@ int main(int argc, const char** argv) { vkcv::Buffer<CameraPlanes> cameraPlaneBuffer = core.createBuffer<CameraPlanes>(vkcv::BufferType::UNIFORM, 1); - struct ObjectMatrices { - glm::mat4 model; - glm::mat4 mvp; - }; - const size_t objectCount = 1; - vkcv::Buffer<ObjectMatrices> matrixBuffer = core.createBuffer<ObjectMatrices>(vkcv::BufferType::STORAGE, objectCount); - - vkcv::DescriptorWrites meshShaderWrites; + vkcv::DescriptorWrites meshShaderWrites; meshShaderWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, meshShaderVertexBuffer.getHandle()), vkcv::StorageBufferDescriptorWrite(1, meshShaderIndexBuffer.getHandle()), vkcv::StorageBufferDescriptorWrite(2, meshletBuffer.getHandle()), - vkcv::StorageBufferDescriptorWrite(4, matrixBuffer.getHandle()) + vkcv::StorageBufferDescriptorWrite(4, matrixBuffer.getHandle()), + vkcv::StorageBufferDescriptorWrite(5, meshletBuffer.getHandle()), }; meshShaderWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(3, cameraPlaneBuffer.getHandle()) @@ -295,6 +302,9 @@ int main(int argc, const char** argv) { cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -2)); + bool useMeshShader = true; + bool updateFrustumPlanes = true; + while (window.isWindowOpen()) { vkcv::Window::pollEvents(); @@ -319,19 +329,19 @@ int main(int argc, const char** argv) { matrixBuffer.fill({ objectMatrices }); struct PushConstants { - uint32_t meshletCount; uint32_t matrixIndex; + uint32_t meshletCount; }; - PushConstants pushConstants{ meshShaderModelData.meshlets.size(), 0 }; + PushConstants pushConstants{ 0, meshShaderModelData.meshlets.size() }; - const CameraPlanes cameraPlanes = computeCameraPlanes(camera); - cameraPlaneBuffer.fill({ cameraPlanes }); + if (updateFrustumPlanes) { + const CameraPlanes cameraPlanes = computeCameraPlanes(camera); + cameraPlaneBuffer.fill({ cameraPlanes }); + } const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - const bool useMeshShader = true; - vkcv::PushConstants pushConstantData(sizeof(pushConstants)); pushConstantData.appendDrawcall(pushConstants); @@ -350,26 +360,31 @@ int main(int argc, const char** argv) { } else { + vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(vertexShaderDescriptorSet).vulkanHandle); + core.recordDrawcallsToCmdStream( cmdStream, renderPass, bunnyPipeline, pushConstantData, - { vkcv::DrawcallInfo(renderMesh, {}) }, + { vkcv::DrawcallInfo(renderMesh, { descriptorUsage }) }, { renderTargets }); } core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); - // gui.beginGUI(); - // - // ImGui::Begin("Settings"); - // ImGui::End(); - // - // gui.endGUI(); - - core.endFrame(); + gui.beginGUI(); + + ImGui::Begin("Settings"); + ImGui::Checkbox("Use mesh shader", &useMeshShader); + ImGui::Checkbox("Upadte frustum culling", &updateFrustumPlanes); + + ImGui::End(); + + gui.endGUI(); + + core.endFrame(); } return 0; }