Changing vertex data interfaces

This commit is contained in:
Dynamitos
2024-06-25 08:59:09 +02:00
parent bd63b14260
commit c352555b0b
11 changed files with 131 additions and 158 deletions
+2 -2
View File
@@ -20,7 +20,7 @@ ParameterBlock<DepthData> pDepthAttachment;
bool isBoxVisible(AABB bounding)
{
uint2 mipDimensions = uint2((uint(pViewParams.screenDimensions.x) + BLOCK_SIZE - 1) / BLOCK_SIZE, (uint(pViewParams.screenDimensions.y) + BLOCK_SIZE - 1) / BLOCK_SIZE);
uint2 mipDimensions = uint2(uint(pViewParams.screenDimensions.x), uint(pViewParams.screenDimensions.y));
// now we calculate what mip level we need to only sample up to 4 texels covering the entire meshlet
uint2 screenCornerMin = mipDimensions;
uint2 screenCornerMax = uint2(0, 0);
@@ -39,7 +39,7 @@ bool isBoxVisible(AABB bounding)
for(uint i = 0; i < 8; ++i)
{
float4 clipCorner = mul(modelViewProjection, corners[i]);
float4 screenCorner = clipToScreen(clipCorner) / BLOCK_SIZE;
float4 screenCorner = clipToScreen(clipCorner);
screenCornerMin = uint2(min(screenCornerMin.x, uint(screenCorner.x)), min(screenCornerMin.y, uint(screenCorner.y)));
screenCornerMax = uint2(max(screenCornerMax.x, uint(screenCorner.x)), max(screenCornerMax.y, uint(screenCorner.y)));
maxDepth = max(maxDepth, screenCorner.z);
+2 -18
View File
@@ -51,32 +51,16 @@ void reduceLevel(
setDstDepth(minCoords / 2, minDepth);
}
groupshared uint uMinDepth;
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
[shader("compute")]
void initialReduce(
uint3 threadID: SV_GroupThreadID,
uint3 groupID: SV_GroupID,
) {
uint reducedWidth = uint(pViewParams.screenDimensions.x) / BLOCK_SIZE;
uint width = uint(pViewParams.screenDimensions.x);
int2 groupOffset = groupID.xy * BLOCK_SIZE;
int2 texCoord = groupOffset + threadID.xy;
float fDepth = pDepthAttachment.texture.Load(int3(texCoord, 0)).r;
uint uDepth = asuint(fDepth);
if(groupID.x == 0 && groupID.y == 0)
{
uMinDepth = 0xffffffff;
}
GroupMemoryBarrierWithGroupSync();
InterlockedMin(uMinDepth, uDepth);
pDepthAttachment.buffer[texCoord.x + (texCoord.y * width)] = fDepth;
GroupMemoryBarrierWithGroupSync();
float fMinDepth = asfloat(uMinDepth);
if(threadID.x == 0 && threadID.y == 0)
{
pDepthAttachment.buffer[groupID.x + (groupID.y * reducedWidth)] = fMinDepth;
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ struct MeshData
static const uint32_t MAX_VERTICES = 256;
static const uint32_t MAX_PRIMITIVES = 256;
static const uint32_t TASK_GROUP_SIZE = 128;
static const uint32_t TASK_GROUP_SIZE = 32;
static const uint32_t MESH_GROUP_SIZE = 32;
static const uint32_t MAX_MESHLETS_PER_INSTANCE = 2048;
+69 -60
View File
@@ -6,6 +6,7 @@
#include "Graphics/Mesh.h"
#include "Graphics/Shader.h"
#include "Graphics/StaticMeshVertexData.h"
#include "ThreadPool.h"
#include <Asset/MaterialLoader.h>
#include <Asset/TextureLoader.h>
#include <assimp/Importer.hpp>
@@ -102,6 +103,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
std::string materialName = fmt::format("M{0}{1}{2}", baseName, material->GetName().C_Str(), m);
materialName.erase(std::remove(materialName.begin(), materialName.end(), '.'),
materialName.end()); // dots break adding the .asset extension later
materialName.erase(std::remove(materialName.begin(), materialName.end(), ':'),
materialName.end()); // dots break adding the .asset extension later
materialName.erase(std::remove(materialName.begin(), materialName.end(), '-'),
materialName.end()); // dots break adding the .asset extension later
materialName.erase(std::remove(materialName.begin(), materialName.end(), ' '),
@@ -401,81 +404,87 @@ void findMeshRoots(aiNode* node, List<aiNode*>& meshNodes) {
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
Component::Collider& collider) {
//List<std::function<void()>> work;
for (int32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) {
aiMesh* mesh = scene->mMeshes[meshIndex];
if (!(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
continue;
collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z));
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
// assume static mesh for now
Array<Vector4> positions(mesh->mNumVertices);
StaticArray<Array<Vector2>, MAX_TEXCOORDS> texCoords;
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
texCoords[i].resize(mesh->mNumVertices);
}
Array<Vector4> normals(mesh->mNumVertices);
Array<Vector4> tangents(mesh->mNumVertices);
Array<Vector4> biTangents(mesh->mNumVertices);
Array<Vector4> colors(mesh->mNumVertices);
globalMeshes.add(nullptr);
StaticMeshVertexData* vertexData = StaticMeshVertexData::getInstance();
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
positions[i] = Vector4(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z, 1.0f);
for (size_t j = 0; j < MAX_TEXCOORDS; ++j) {
if (mesh->HasTextureCoords(j)) {
texCoords[j][i] = Vector2(mesh->mTextureCoords[j][i].x, mesh->mTextureCoords[j][i].y);
MeshId id = vertexData->allocateVertexData(mesh->mNumVertices);
uint64 offset = vertexData->getMeshOffset(id);
collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z));
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
//work.add([&]() {
// assume static mesh for now
Array<Vector4> positions(mesh->mNumVertices);
StaticArray<Array<Vector2>, MAX_TEXCOORDS> texCoords;
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
texCoords[i].resize(mesh->mNumVertices);
}
Array<Vector4> normals(mesh->mNumVertices);
Array<Vector4> tangents(mesh->mNumVertices);
Array<Vector4> biTangents(mesh->mNumVertices);
Array<Vector4> colors(mesh->mNumVertices);
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
positions[i] = Vector4(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z, 1.0f);
for (size_t j = 0; j < MAX_TEXCOORDS; ++j) {
if (mesh->HasTextureCoords(j)) {
texCoords[j][i] = Vector2(mesh->mTextureCoords[j][i].x, mesh->mTextureCoords[j][i].y);
} else {
texCoords[j][i] = Vector2(0, 0);
}
}
normals[i] = Vector4(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z, 1.0f);
if (mesh->HasTangentsAndBitangents()) {
tangents[i] = Vector4(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z, 1.0f);
biTangents[i] = Vector4(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z, 1.0f);
} else {
texCoords[j][i] = Vector2(0, 0);
tangents[i] = Vector4(0, 0, 1, 1);
biTangents[i] = Vector4(1, 0, 0, 1);
}
if (mesh->HasVertexColors(0)) {
colors[i] = Vector4(mesh->mColors[0][i].r, mesh->mColors[0][i].g, mesh->mColors[0][i].b, 1.0f);
} else {
colors[i] = Vector4(1, 1, 1, 1);
}
}
normals[i] = Vector4(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z, 1.0f);
if (mesh->HasTangentsAndBitangents()) {
tangents[i] = Vector4(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z, 1.0f);
biTangents[i] = Vector4(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z, 1.0f);
} else {
tangents[i] = Vector4(0, 0, 1, 1);
biTangents[i] = Vector4(1, 0, 0, 1);
vertexData->loadPositions(offset, positions);
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
vertexData->loadTexCoords(offset, i, texCoords[i]);
}
if (mesh->HasVertexColors(0)) {
colors[i] = Vector4(mesh->mColors[0][i].r, mesh->mColors[0][i].g, mesh->mColors[0][i].b, 1.0f);
} else {
colors[i] = Vector4(1, 1, 1, 1);
vertexData->loadNormals(offset, normals);
vertexData->loadTangents(offset, tangents);
vertexData->loadBiTangents(offset, biTangents);
vertexData->loadColors(offset, colors);
Array<uint32> indices(mesh->mNumFaces * 3);
for (int32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) {
indices[faceIndex * 3 + 0] = mesh->mFaces[faceIndex].mIndices[0];
indices[faceIndex * 3 + 1] = mesh->mFaces[faceIndex].mIndices[1];
indices[faceIndex * 3 + 2] = mesh->mFaces[faceIndex].mIndices[2];
}
}
MeshId id = vertexData->allocateVertexData(mesh->mNumVertices);
vertexData->loadPositions(id, positions);
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
vertexData->loadTexCoords(id, i, texCoords[i]);
}
vertexData->loadNormals(id, normals);
vertexData->loadTangents(id, tangents);
vertexData->loadBiTangents(id, biTangents);
vertexData->loadColors(id, colors);
Array<Meshlet> meshlets;
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
Meshlet::build(positions, indices, meshlets);
vertexData->loadMesh(id, indices, meshlets);
Array<uint32> indices(mesh->mNumFaces * 3);
for (int32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) {
indices[faceIndex * 3 + 0] = mesh->mFaces[faceIndex].mIndices[0];
indices[faceIndex * 3 + 1] = mesh->mFaces[faceIndex].mIndices[1];
indices[faceIndex * 3 + 2] = mesh->mFaces[faceIndex].mIndices[2];
}
// collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
Array<Meshlet> meshlets;
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
Meshlet::build(positions, indices, meshlets);
vertexData->loadMesh(id, indices, meshlets);
// collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
globalMeshes[meshIndex] = new Mesh();
globalMeshes[meshIndex]->vertexData = vertexData;
globalMeshes[meshIndex]->id = id;
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
globalMeshes[meshIndex]->meshlets = std::move(meshlets);
globalMeshes[meshIndex]->indices = std::move(indices);
globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices;
globalMeshes[meshIndex] = new Mesh();
globalMeshes[meshIndex]->vertexData = vertexData;
globalMeshes[meshIndex]->id = id;
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
globalMeshes[meshIndex]->meshlets = std::move(meshlets);
globalMeshes[meshIndex]->indices = std::move(indices);
globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices;
//});
}
//getThreadPool().runAndWait(std::move(work));
}
Matrix4 convertMatrix(aiMatrix4x4 matrix) {
+22 -17
View File
@@ -63,25 +63,30 @@ int main() {
.filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg",
.type = TextureImportType::TEXTURE_CUBEMAP,
});
AssetImporter::importMesh(MeshImportArgs{.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx",
.importPath = "Whitechapel"});
//AssetImporter::importMesh(MeshImportArgs{
// .filePath = sourcePath / "import/models/city-suburbs/city-suburbs.gltf",
// .importPath = "suburbs",
//});
AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx",
.importPath = "Whitechapel",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
.importPath = "suburbs",
});
vd->commitMeshes();
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1920;
mainWindowInfo.height = 1080;
mainWindowInfo.preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB;
WindowCreateInfo mainWindowInfo = {
.width = 1920,
.height = 1080,
.title = "SeeleEngine",
.preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB,
};
auto window = windowManager->addWindow(graphics, mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.dimensions.size.x = 1920;
sceneViewInfo.dimensions.size.y = 1080;
sceneViewInfo.dimensions.offset.x = 0;
sceneViewInfo.dimensions.offset.y = 0;
sceneViewInfo.numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT;
ViewportCreateInfo sceneViewInfo = {
.dimensions =
{
.size = {1920, 1080},
.offset = {0, 0},
},
.numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT,
};
OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string());
sceneView->setFocused();
@@ -228,8 +228,8 @@ void DepthCullingPass::render() {
void DepthCullingPass::endFrame() {}
void DepthCullingPass::publishOutputs() {
uint32 width = (viewport->getOwner()->getFramebufferWidth() + BLOCK_SIZE - 1) / BLOCK_SIZE;
uint32 height = (viewport->getOwner()->getFramebufferHeight() + BLOCK_SIZE - 1) / BLOCK_SIZE;
uint32 width = viewport->getOwner()->getFramebufferWidth();
uint32 height = viewport->getOwner()->getFramebufferHeight();
uint32 bufferSize = 0;
while (width > 1 && height > 1) {
mipOffsets.add(bufferSize);
+18 -43
View File
@@ -16,67 +16,37 @@ StaticMeshVertexData* StaticMeshVertexData::getInstance() {
return &instance;
}
void StaticMeshVertexData::loadPositions(MeshId id, const Array<Vector4>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void StaticMeshVertexData::loadPositions(uint64 offset, const Array<Vector4>& data) {
assert(offset + data.size() <= head);
std::memcpy(positionData.data() + offset, data.data(), data.size() * sizeof(Vector4));
dirty = true;
}
void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void StaticMeshVertexData::loadTexCoords(uint64 offset, uint64 index, const Array<Vector2>& data) {
assert(offset + data.size() <= head);
std::memcpy(texCoordsData[index].data() + offset, data.data(), data.size() * sizeof(Vector2));
dirty = true;
}
void StaticMeshVertexData::loadNormals(MeshId id, const Array<Vector4>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void StaticMeshVertexData::loadNormals(uint64 offset, const Array<Vector4>& data) {
assert(offset + data.size() <= head);
std::memcpy(normalData.data() + offset, data.data(), data.size() * sizeof(Vector4));
dirty = true;
}
void StaticMeshVertexData::loadTangents(MeshId id, const Array<Vector4>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void StaticMeshVertexData::loadTangents(uint64 offset, const Array<Vector4>& data) {
assert(offset + data.size() <= head);
std::memcpy(tangentData.data() + offset, data.data(), data.size() * sizeof(Vector4));
dirty = true;
}
void StaticMeshVertexData::loadBiTangents(MeshId id, const Array<Vector4>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void StaticMeshVertexData::loadBiTangents(uint64 offset, const Array<Vector4>& data) {
assert(offset + data.size() <= head);
std::memcpy(biTangentData.data() + offset, data.data(), data.size() * sizeof(Vector4));
dirty = true;
}
void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector4>& data) {
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
void Seele::StaticMeshVertexData::loadColors(uint64 offset, const Array<Vector4>& data) {
assert(offset + data.size() <= head);
std::memcpy(colorData.data() + offset, data.data(), data.size() * sizeof(Vector4));
dirty = true;
@@ -85,7 +55,7 @@ void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector4>& da
void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) {
uint64 offset;
{
std::unique_lock l(mutex);
std::unique_lock l(vertexDataLock);
offset = meshOffsets[id];
}
Array<Vector4> pos(numVertices);
@@ -112,11 +82,16 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB
}
void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
uint64 offset;
{
std::unique_lock l(vertexDataLock);
offset = meshOffsets[id];
}
Array<Vector4> pos;
Array<Vector2> tex[MAX_TEXCOORDS];
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
Serialization::load(buffer, tex[i]);
loadTexCoords(id, i, tex[i]);
loadTexCoords(offset, i, tex[i]);
}
Array<Vector4> nor;
Array<Vector4> tan;
@@ -127,11 +102,11 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
Serialization::load(buffer, tan);
Serialization::load(buffer, bit);
Serialization::load(buffer, col);
loadPositions(id, pos);
loadNormals(id, nor);
loadTangents(id, tan);
loadBiTangents(id, bit);
loadColors(id, col);
loadPositions(offset, pos);
loadNormals(offset, nor);
loadTangents(offset, tan);
loadBiTangents(offset, bit);
loadColors(offset, col);
}
void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
+6 -7
View File
@@ -22,12 +22,12 @@ class StaticMeshVertexData : public VertexData {
StaticMeshVertexData();
virtual ~StaticMeshVertexData();
static StaticMeshVertexData* getInstance();
void loadPositions(MeshId id, const Array<Vector4>& data);
void loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data);
void loadNormals(MeshId id, const Array<Vector4>& data);
void loadTangents(MeshId id, const Array<Vector4>& data);
void loadBiTangents(MeshId id, const Array<Vector4>& data);
void loadColors(MeshId id, const Array<Vector4>& data);
void loadPositions(uint64 offset, const Array<Vector4>& data);
void loadTexCoords(uint64 offset, uint64 index, const Array<Vector2>& data);
void loadNormals(uint64 offset, const Array<Vector4>& data);
void loadTangents(uint64 offset, const Array<Vector4>& data);
void loadBiTangents(uint64 offset, const Array<Vector4>& data);
void loadColors(uint64 offset, const Array<Vector4>& data);
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
virtual void init(Gfx::PGraphics graphics) override;
@@ -44,7 +44,6 @@ class StaticMeshVertexData : public VertexData {
virtual void updateBuffers() override;
Array<StaticMatData> staticData;
std::mutex mutex;
Gfx::OShaderBuffer positions;
Array<Vector4> positionData;
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
+3 -2
View File
@@ -294,8 +294,9 @@ void VertexData::commitMeshes() {
MeshId VertexData::allocateVertexData(uint64 numVertices) {
std::unique_lock l(vertexDataLock);
MeshId res{idCounter++};
meshOffsets[res] = head;
meshVertexCounts[res] = numVertices;
meshOffsets.add(head);
meshVertexCounts.add(numVertices);
meshData.add({});
head += numVertices;
if (head > verticesAllocated) {
verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS);
+4 -3
View File
@@ -15,6 +15,7 @@ DECLARE_REF(MaterialInstance)
DECLARE_REF(Mesh)
struct MeshId {
uint64 id;
operator uint64() const { return id; }
std::strong_ordering operator<=>(const MeshId& other) const { return id <=> other.id; }
bool operator==(const MeshId& other) const { return id == other.id; }
};
@@ -102,9 +103,9 @@ class VertexData {
Array<TransparentDraw> transparentData;
std::mutex vertexDataLock;
Map<MeshId, MeshData> meshData;
Map<MeshId, uint64> meshOffsets;
Map<MeshId, uint64> meshVertexCounts;
Array<MeshData> meshData;
Array<uint64> meshOffsets;
Array<uint64> meshVertexCounts;
Array<MeshletDescription> meshlets;
Array<uint8> primitiveIndices;
+2 -3
View File
@@ -192,10 +192,9 @@ void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* buffer)
}
void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
if (size == 0)
return;
assert(dynamic);
if (buffers.size() > 0) {
size = std::max(getSize(), size);
}
for (uint32 i = 0; i < buffers.size(); ++i) {
if (buffers[i]->isCurrentlyBound()) {
continue;