View Frustum culling for mesh shading

This commit is contained in:
Dynamitos
2023-12-15 11:57:13 +01:00
parent 462999858f
commit b24635e848
17 changed files with 71 additions and 40 deletions
+7 -4
View File
@@ -39,15 +39,18 @@
<Item Name="[value]">value</Item> <Item Name="[value]">value</Item>
</Expand> </Expand>
</Type> </Type>
<Type Name="Seele::Map&lt;*,*&gt;"> <Type Name="Seele::Map&lt;*&gt;">
<DisplayString>{{ size={_size} }</DisplayString> <DisplayString>{{ size={_size} }</DisplayString>
<Expand> <Expand>
<Item Name="[size]">_size</Item> <Item Name="[size]">_size</Item>
<Item Name="[comp]">comp</Item> <Item Name="[comp]">comp</Item>
<ArrayItems> <TreeItems>
<Size>_size</Size> <Size>_size</Size>
<ValuePointer>nodeContainer._data</ValuePointer> <HeadPointer>root</HeadPointer>
</ArrayItems> <LeftPointer>left</LeftPointer>
<RightPointer>right</RightPointer>
<ValueNode Condition="!((bool)_Isnil)">pair</ValueNode>
</TreeItems>
</Expand> </Expand>
</Type> </Type>
<Type Name="Seele::Map&lt;*&gt;::Node"> <Type Name="Seele::Map&lt;*&gt;::Node">
+1 -1
+3 -3
View File
@@ -18,8 +18,8 @@ ParameterBlock<LightCullingData> pLightCullingData;
float4 fragmentMain(in FragmentParameter params) : SV_Target float4 fragmentMain(in FragmentParameter params) : SV_Target
{ {
LightingParameter lightingParams = params.getLightingParameter(); LightingParameter lightingParams = params.getLightingParameter();
MaterialParameter materialParams = params.getMaterialParameter();
let brdf = pMaterial.prepare(params.getMaterialParameter()); let brdf = pMaterial.prepare(materialParams);
float3 result = float3(0, 0, 0); float3 result = float3(0, 0, 0);
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i) for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
{ {
@@ -29,5 +29,5 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
{ {
result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf); result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
} }
return float4(result, 1.0f); return float4(materialParams.vertexColor, 1.0f);
} }
+10 -8
View File
@@ -29,19 +29,19 @@ void taskMain(
localToClip = mul(pViewParams.projectionMatrix, mul(pViewParams.viewMatrix, instance.transformMatrix)); localToClip = mul(pViewParams.projectionMatrix, mul(pViewParams.viewMatrix, instance.transformMatrix));
// Left // Left
viewFrustum.sides[0].n = float3(1, 0, 0); viewFrustum.sides[0].n = float3(1, 0, 0);
viewFrustum.sides[0].d = -0.8; viewFrustum.sides[0].d = 0.7;
// Right // Right
viewFrustum.sides[1].n = float3(-1, 0, 0); viewFrustum.sides[1].n = float3(-1, 0, 0);
viewFrustum.sides[1].d = 0.8; viewFrustum.sides[1].d = 0.7;
// Top // Top
viewFrustum.sides[2].n = float3(0, -1, 0); viewFrustum.sides[2].n = float3(0, -1, 0);
viewFrustum.sides[2].d = 0.8; viewFrustum.sides[2].d = 0.7;
// Bottom // Bottom
viewFrustum.sides[1].n = float3(0, 1, 0); viewFrustum.sides[3].n = float3(0, 1, 0);
viewFrustum.sides[1].d = -0.8; viewFrustum.sides[3].d = 0.7;
// Base // Base
viewFrustum.basePlane.n = float3(0, 0, 1); viewFrustum.basePlane.n = float3(0, 0, 1);
viewFrustum.basePlane.d = 0; viewFrustum.basePlane.d = 0.2;
} }
GroupMemoryBarrierWithGroupSync(); GroupMemoryBarrierWithGroupSync();
MeshData mesh = pScene.meshData[groupID]; MeshData mesh = pScene.meshData[groupID];
@@ -51,7 +51,7 @@ void taskMain(
{ {
uint m = mesh.meshletOffset + i; uint m = mesh.meshletOffset + i;
MeshletDescription meshlet = pScene.meshletInfos[m]; MeshletDescription meshlet = pScene.meshletInfos[m];
//if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum))
{ {
uint index; uint index;
InterlockedAdd(head, 1, index); InterlockedAdd(head, 1, index);
@@ -119,7 +119,9 @@ void meshMain(
uint v = min(i, m.vertexCount - 1); uint v = min(i, m.vertexCount - 1);
{ {
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
vertices[v] = pVertexData.getAttributes(md.indicesOffset + vertexIndex).getParameter(inst.transformMatrix); VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex);
attr.vertexColor = m.color;
vertices[v] = attr.getParameter(inst.transformMatrix);
} }
} }
} }
+10 -10
View File
@@ -8,18 +8,18 @@ struct AABB
float pad1; float pad1;
bool insideFrustum(float4x4 transform, Frustum frustum) bool insideFrustum(float4x4 transform, Frustum frustum)
{ {
float3 corners[8]; float4 corners[8];
corners[0] = mul(transform, float4(min.x, min.y, min.z, 1.0f)).xyz; corners[0] = mul(transform, float4(min.x, min.y, min.z, 1.0f));
corners[1] = mul(transform, float4(min.x, min.y, max.z, 1.0f)).xyz; corners[1] = mul(transform, float4(min.x, min.y, max.z, 1.0f));
corners[2] = mul(transform, float4(min.x, max.y, min.z, 1.0f)).xyz; corners[2] = mul(transform, float4(min.x, max.y, min.z, 1.0f));
corners[3] = mul(transform, float4(min.x, max.y, max.z, 1.0f)).xyz; corners[3] = mul(transform, float4(min.x, max.y, max.z, 1.0f));
corners[4] = mul(transform, float4(max.x, min.y, min.z, 1.0f)).xyz; corners[4] = mul(transform, float4(max.x, min.y, min.z, 1.0f));
corners[5] = mul(transform, float4(max.x, min.y, max.z, 1.0f)).xyz; corners[5] = mul(transform, float4(max.x, min.y, max.z, 1.0f));
corners[6] = mul(transform, float4(max.x, max.y, min.z, 1.0f)).xyz; corners[6] = mul(transform, float4(max.x, max.y, min.z, 1.0f));
corners[7] = mul(transform, float4(max.x, max.y, max.z, 1.0f)).xyz; corners[7] = mul(transform, float4(max.x, max.y, max.z, 1.0f));
for(int i = 0; i < 8; ++i) for(int i = 0; i < 8; ++i)
{ {
if(frustum.pointInside(corners[i])) if(frustum.pointInside(corners[i].xyz / corners[i].w))
{ {
return true; return true;
} }
+2 -4
View File
@@ -35,15 +35,13 @@ struct Frustum
Plane basePlane; Plane basePlane;
bool pointInside(float3 point) bool pointInside(float3 point)
{ {
float result = dot(basePlane.n, point) + basePlane.d; if (dot(basePlane.n, point) + basePlane.d < 0.0f)
if (0.0f > result)
{ {
return false; return false;
} }
for(int p = 0; p < 4; ++p) for(int p = 0; p < 4; ++p)
{ {
result = dot(sides[p].n, point) + sides[p].d; if(dot(sides[p].n, point) + sides[p].d < 0.0f)
if(0.0f > result)
{ {
return false; return false;
} }
+3
View File
@@ -7,10 +7,13 @@ struct MeshletDescription
uint32_t primitiveCount; uint32_t primitiveCount;
uint32_t vertexOffset; uint32_t vertexOffset;
uint32_t primitiveOffset; uint32_t primitiveOffset;
float3 color;
float pad;
}; };
struct MeshData struct MeshData
{ {
AABB boundingBox;
uint32_t numMeshlets; uint32_t numMeshlets;
uint32_t meshletOffset; uint32_t meshletOffset;
uint32_t firstIndex; uint32_t firstIndex;
+1
View File
@@ -329,6 +329,7 @@ void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset)
meshAsset->setStatus(Asset::Status::Loading); meshAsset->setStatus(Asset::Status::Loading);
Assimp::Importer importer; Assimp::Importer importer;
importer.ReadFile(args.filePath.string().c_str(), (uint32)( importer.ReadFile(args.filePath.string().c_str(), (uint32)(
aiProcess_ImproveCacheLocality |
aiProcess_FlipUVs | aiProcess_FlipUVs |
aiProcess_Triangulate | aiProcess_Triangulate |
aiProcess_SortByPType | aiProcess_SortByPType |
+1 -1
View File
@@ -12,7 +12,7 @@ Camera::Camera()
, bNeedsViewBuild(false) , bNeedsViewBuild(false)
, cameraPos(Vector()) , cameraPos(Vector())
{ {
yaw = 3.1415f/2; yaw = -3.1415f/2;
pitch = 0; pitch = 0;
} }
+1 -1
View File
@@ -165,7 +165,7 @@ typedef uint32 KeyModifierFlags;
namespace Gfx namespace Gfx
{ {
static constexpr bool useAsyncCompute = true; static constexpr bool useAsyncCompute = true;
static constexpr bool waitIdleOnSubmit = true; static constexpr bool waitIdleOnSubmit = false;
static constexpr bool useMeshShading = true; static constexpr bool useMeshShading = true;
static constexpr uint32 numFramesBuffered = 3; static constexpr uint32 numFramesBuffered = 3;
+3 -1
View File
@@ -38,7 +38,7 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
.instance = InstanceData { .instance = InstanceData {
.transformMatrix = transform.toMatrix(), .transformMatrix = transform.toMatrix(),
}, },
.data = data .data = data,
}); });
} }
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle(); matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
@@ -109,10 +109,12 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
meshlets.add(MeshletDescription{ meshlets.add(MeshletDescription{
.boundingBox = m.boundingBox,
.vertexCount = m.numVertices, .vertexCount = m.numVertices,
.primitiveCount = m.numPrimitives, .primitiveCount = m.numPrimitives,
.vertexOffset = vertexOffset, .vertexOffset = vertexOffset,
.primitiveOffset = primitiveOffset, .primitiveOffset = primitiveOffset,
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
}); });
} }
meshData[id].add(MeshData{ meshData[id].add(MeshData{
+2
View File
@@ -98,6 +98,8 @@ protected:
uint32_t primitiveCount; uint32_t primitiveCount;
uint32_t vertexOffset; uint32_t vertexOffset;
uint32_t primitiveOffset; uint32_t primitiveOffset;
Vector color;
float pad0;
}; };
Map<std::string, MaterialData> materialData; Map<std::string, MaterialData> materialData;
Map<MeshId, Array<MeshData>> meshData; Map<MeshId, Array<MeshData>> meshData;
+17 -5
View File
@@ -216,23 +216,35 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
} }
void Allocator::free(PAllocation allocation) void Allocator::free()
{ {
//std::cout << "Freeing allocation" << std::endl;
for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex)
{ {
for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
{ {
if (heaps[heapIndex].allocations[alloc] == allocation) if (heaps[heapIndex].allocations[alloc]->bytesUsed == 0)
{ {
heaps[heapIndex].inUse -= allocation->bytesAllocated; heaps[heapIndex].inUse -= heaps[heapIndex].allocations[alloc]->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl; std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.removeAt(alloc, false); heaps[heapIndex].allocations.removeAt(alloc, false);
return; alloc--;
} }
} }
} }
} }
void Allocator::print()
{
for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex)
{
std::cout << "Heap " << heapIndex << std::endl;
for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
{
std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed / heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
}
}
}
uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties) uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties)
{ {
for (uint32 i = 0; i < memProperties.memoryTypeCount; i++) for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
+2 -1
View File
@@ -122,7 +122,8 @@ public:
return allocate(requirements, props, &allocInfo); return allocate(requirements, props, &allocInfo);
} }
void free(PAllocation allocation); void free();
void print();
private: private:
static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB
struct HeapInfo struct HeapInfo
+1 -1
View File
@@ -448,7 +448,7 @@ void Graphics::pickPhysicalDevice()
{ {
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0)
{ {
//meshShadingEnabled = true; meshShadingEnabled = true;
break; break;
} }
} }
+1
View File
@@ -170,4 +170,5 @@ void DestructionManager::notifyCmdComplete(PCommand cmd)
sems[cmd].clear(); sems[cmd].clear();
renderPasses[cmd].clear(); renderPasses[cmd].clear();
allocs[cmd].clear(); allocs[cmd].clear();
//graphics->getAllocator()->free();
} }
+6
View File
@@ -7,6 +7,8 @@
#include "System/LightGather.h" #include "System/LightGather.h"
#include "System/MeshUpdater.h" #include "System/MeshUpdater.h"
#include "System/CameraUpdater.h" #include "System/CameraUpdater.h"
#include "Graphics/Vulkan/Graphics.h"
#include "Graphics/Vulkan/Allocator.h"
using namespace Seele; using namespace Seele;
@@ -96,6 +98,10 @@ void GameView::reloadGame()
void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier)
{ {
if (code == KeyCode::KEY_P && action == InputAction::PRESS)
{
((Vulkan::Graphics*)graphics.getHandle())->getAllocator()->print();
}
keyboardSystem->keyCallback(code, action, modifier); keyboardSystem->keyCallback(code, action, modifier);
} }