Added frustum culling, use low-poly mesh to move limitation towards cpu
This commit is contained in:
parent
7768992bda
commit
a41ff27bb9
7 changed files with 1599 additions and 18 deletions
|
|
@ -8,7 +8,7 @@ if %ERRORLEVEL% EQU 0 (
|
|||
xcopy "..\..\data\shaders\multithreading\*.spv" "assets\shaders\multithreading" /Y
|
||||
|
||||
mkdir "assets\models"
|
||||
xcopy "..\..\data\models\retroufo_red.dae" "assets\models" /Y
|
||||
xcopy "..\..\data\models\retroufo_red_lowpoly.dae" "assets\models" /Y
|
||||
xcopy "..\..\data\models\sphere.obj" "assets\models" /Y
|
||||
|
||||
mkdir "res\drawable"
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace vkMeshLoader
|
|||
MeshBufferInfo vertices;
|
||||
MeshBufferInfo indices;
|
||||
uint32_t indexCount;
|
||||
glm::vec3 dim;
|
||||
};
|
||||
|
||||
// Get vertex size from vertex layout
|
||||
|
|
@ -449,6 +450,10 @@ public:
|
|||
}
|
||||
meshBuffer->vertices.size = vertexBuffer.size() * sizeof(float);
|
||||
|
||||
dim.min *= scale;
|
||||
dim.max *= scale;
|
||||
dim.size *= scale;
|
||||
|
||||
std::vector<uint32_t> indexBuffer;
|
||||
for (uint32_t m = 0; m < m_Entries.size(); m++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -309,6 +309,8 @@ void VulkanExampleBase::loadMesh(
|
|||
vertexLayout,
|
||||
scale);
|
||||
|
||||
meshBuffer->dim = mesh->dim.size;
|
||||
|
||||
delete(mesh);
|
||||
}
|
||||
|
||||
|
|
|
|||
1549
data/models/retroufo_red_lowpoly.dae
Normal file
1549
data/models/retroufo_red_lowpoly.dae
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -22,6 +22,7 @@
|
|||
#include "vulkanexamplebase.h"
|
||||
|
||||
#include "threadpool.hpp"
|
||||
#include "frustum.hpp"
|
||||
|
||||
#define VERTEX_BUFFER_BIND_ID 0
|
||||
#define ENABLE_VALIDATION false
|
||||
|
|
@ -88,6 +89,8 @@ public:
|
|||
float rotationSpeed;
|
||||
float scale;
|
||||
float deltaT;
|
||||
float stateT = 0;
|
||||
bool visible = true;
|
||||
};
|
||||
|
||||
struct ThreadData {
|
||||
|
|
@ -104,17 +107,21 @@ public:
|
|||
|
||||
vkTools::ThreadPool threadPool;
|
||||
|
||||
// Max. dimension of the ufo mesh for use as the sphere
|
||||
// radius for frustum culling
|
||||
float objectSphereDim;
|
||||
|
||||
// View frustum for culling invisible objects
|
||||
vkTools::Frustum frustum;
|
||||
|
||||
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
||||
{
|
||||
width = 1280;
|
||||
height = 720;
|
||||
zoom = -16.0f;
|
||||
zoom = -32.5f;
|
||||
zoomSpeed = 2.5f;
|
||||
rotationSpeed = 0.5f;
|
||||
rotation = { -30.0f, -35.0f, 0.0f };
|
||||
rotation = { 0.0f, 37.5f, 0.0f };
|
||||
title = "Vulkan Example - Multi threaded rendering";
|
||||
// Get number of max. concurrrent threads
|
||||
// todo : May not work on all compilers (e.g. old GCC versions?)
|
||||
numThreads = std::thread::hardware_concurrency();
|
||||
assert(numThreads > 0);
|
||||
#if defined(__ANDROID__)
|
||||
|
|
@ -126,7 +133,7 @@ public:
|
|||
|
||||
threadPool.setThreadCount(numThreads);
|
||||
|
||||
numObjectsPerThread = 128 / numThreads;
|
||||
numObjectsPerThread = 256 / numThreads;
|
||||
}
|
||||
|
||||
~VulkanExample()
|
||||
|
|
@ -262,7 +269,7 @@ public:
|
|||
thread->objectData[j].rotation = glm::vec3(0.0f, rnd(360.0f), 0.0f);
|
||||
thread->objectData[j].deltaT = rnd(1.0f);
|
||||
thread->objectData[j].rotationDir = (rnd(100.0f) < 50.0f) ? 1.0f : -1.0f;
|
||||
thread->objectData[j].rotationSpeed = (2.0f + rnd(4.0f)) * thread->objectData[i].rotationDir;
|
||||
thread->objectData[j].rotationSpeed = (2.0f + rnd(4.0f)) * thread->objectData[j].rotationDir;
|
||||
thread->objectData[j].scale = 0.75f + rnd(0.5f);
|
||||
|
||||
thread->pushConstBlock[j].color = glm::vec3(rnd(1.0f), rnd(1.0f), rnd(1.0f));
|
||||
|
|
@ -277,11 +284,21 @@ public:
|
|||
// Builds the secondary command buffer for each thread
|
||||
void threadRenderCode(uint32_t threadIndex, uint32_t cmdBufferIndex, VkCommandBufferInheritanceInfo inheritanceInfo)
|
||||
{
|
||||
ThreadData *thread = &threadData[threadIndex];
|
||||
ObjectData *objectData = &thread->objectData[cmdBufferIndex];
|
||||
|
||||
// Check visibility against view frustum
|
||||
objectData->visible = frustum.checkSphere(objectData->pos, objectSphereDim * 0.5f);
|
||||
|
||||
if (!objectData->visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VkCommandBufferBeginInfo commandBufferBeginInfo = vkTools::initializers::commandBufferBeginInfo();
|
||||
commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||
commandBufferBeginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||
|
||||
ThreadData *thread = &threadData[threadIndex];
|
||||
VkCommandBuffer cmdBuffer = thread->commandBuffer[cmdBufferIndex];
|
||||
|
||||
vkTools::checkResult(vkBeginCommandBuffer(cmdBuffer, &commandBufferBeginInfo));
|
||||
|
|
@ -295,17 +312,15 @@ public:
|
|||
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.phong);
|
||||
|
||||
// Update
|
||||
// todo : timebased
|
||||
ObjectData *objectData = &thread->objectData[cmdBufferIndex];
|
||||
objectData->rotation.y += 0.15f * objectData->rotationSpeed;
|
||||
objectData->rotation.y += 2.5f * objectData->rotationSpeed * frameTimer;
|
||||
if (objectData->rotation.y > 360.0f)
|
||||
{
|
||||
objectData->rotation.y -= 360.0f;
|
||||
}
|
||||
objectData->deltaT += 0.0015f;
|
||||
objectData->deltaT += 0.15f * frameTimer;
|
||||
if (objectData->deltaT > 1.0f)
|
||||
objectData->deltaT -= 1.0f;
|
||||
objectData->pos.y = sin(glm::radians(objectData->deltaT * 360.0f)) * 1.5f;
|
||||
objectData->pos.y = sin(glm::radians(objectData->deltaT * 360.0f)) * 2.5f;
|
||||
|
||||
objectData->model = glm::translate(glm::mat4(), objectData->pos);
|
||||
objectData->model = glm::rotate(objectData->model, -sinf(glm::radians(objectData->deltaT * 360.0f)) * 0.25f, glm::vec3(objectData->rotationDir, 0.0f, 0.0f));
|
||||
|
|
@ -423,9 +438,13 @@ public:
|
|||
for (uint32_t i = 0; i < numObjectsPerThread; i++)
|
||||
{
|
||||
threadPool.threads[t]->addJob([=] { threadRenderCode(t, i, inheritanceInfo); });
|
||||
// Only submit if object is within the current view frustum
|
||||
if (threadData[t].objectData[i].visible)
|
||||
{
|
||||
commandBuffers.push_back(threadData[t].commandBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threadPool.wait();
|
||||
|
||||
|
|
@ -461,7 +480,6 @@ public:
|
|||
VkResult fenceRes;
|
||||
do
|
||||
{
|
||||
// todo : timeout as define
|
||||
fenceRes = vkWaitForFences(device, 1, &renderFence, VK_TRUE, 100000000);
|
||||
} while (fenceRes == VK_TIMEOUT);
|
||||
vkTools::checkResult(fenceRes);
|
||||
|
|
@ -477,8 +495,9 @@ public:
|
|||
|
||||
void loadMeshes()
|
||||
{
|
||||
loadMesh(getAssetPath() + "models/retroufo_red.dae", &meshes.ufo, vertexLayout, 0.12f);
|
||||
loadMesh(getAssetPath() + "models/retroufo_red_lowpoly.dae", &meshes.ufo, vertexLayout, 0.12f);
|
||||
loadMesh(getAssetPath() + "models/sphere.obj", &meshes.skysphere, vertexLayout, 1.0f);
|
||||
objectSphereDim = std::max(std::max(meshes.ufo.dim.x, meshes.ufo.dim.y), meshes.ufo.dim.z);
|
||||
}
|
||||
|
||||
void setupVertexDescriptions()
|
||||
|
|
@ -632,6 +651,8 @@ public:
|
|||
matrices.view = glm::rotate(matrices.view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
matrices.view = glm::rotate(matrices.view, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
matrices.view = glm::rotate(matrices.view, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
frustum.update(matrices.projection * matrices.view);
|
||||
}
|
||||
|
||||
void prepare()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<ClCompile Include="multithreading.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\base\frustum.hpp" />
|
||||
<ClInclude Include="..\base\threadpool.hpp" />
|
||||
<ClInclude Include="..\base\vulkandebug.h" />
|
||||
<ClInclude Include="..\base\vulkanexamplebase.h" />
|
||||
|
|
|
|||
|
|
@ -41,5 +41,8 @@
|
|||
<ClInclude Include="..\base\threadpool.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\frustum.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue