Added support for Bone Weights and Bone Indices vertex attributes for meshes

This commit is contained in:
Kah Wei 2022-11-20 01:33:55 +08:00
parent 6fa14aff85
commit 841948b82c
8 changed files with 505 additions and 343 deletions

View File

@ -0,0 +1,65 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
//#include "ShaderDescriptorDefinitions.glsl"
layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aTangent;
layout(location = 4) in mat4 worldTransform;
layout(location = 5) in ivec4 aBoneIndices;
layout(location = 6) in vec4 aBoneWeights;
layout(location = 8) in uvec2 integerData;
layout(location = 0) out struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} Out;
// material stuff
layout(location = 3) out struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} Out2;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
Out2.materialIndex = gl_InstanceIndex;
Out2.eid = integerData[0];
Out2.lightLayerIndex = integerData[1];
// for transforming gBuffer position and normal data
mat4 modelViewMat = cameraData.viewMat * worldTransform;
// gBuffer position will be in view space
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
// uvs for texturing in fragment shader
Out.uv = aUV;
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
// normals are also in view space
Out.normal.rgb = transposeInv * aNormal.rgb;
Out.normal.rgb = normalize (Out.normal.rgb);
// clip space for rendering
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
}

View File

@ -54,7 +54,7 @@ namespace SHADE
std::vector<SHVec3> VertexNormals; std::vector<SHVec3> VertexNormals;
std::vector<SHVec2> VertexTexCoords; std::vector<SHVec2> VertexTexCoords;
std::vector<uint32_t> Indices; std::vector<uint32_t> Indices;
std::vector<MeshBoneInfo> BonesInfo; std::vector<int> VertexBoneIndices;
std::vector<MeshBone> Bones; std::vector<SHVec4> VertexBoneWeights;
}; };
} }

View File

@ -176,6 +176,20 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
static constexpr uint32_t INTEGER_DATA = 5; static constexpr uint32_t INTEGER_DATA = 5;
/***************************************************************************/
/*!
\brief
Vertex buffer bindings for the bone indices buffer.
*/
/***************************************************************************/
static constexpr uint32_t BONE_INDICES = 6;
/***************************************************************************/
/*!
\brief
Vertex buffer bindings for the bone weights buffer.
*/
/***************************************************************************/
static constexpr uint32_t BONE_WEIGHTS = 7;
}; };

View File

@ -432,6 +432,8 @@ namespace SHADE
std::make_pair(meshLibrary.GetVertexTexCoordsBuffer(), SHGraphicsConstants::VertexBufferBindings::TEX_COORD), std::make_pair(meshLibrary.GetVertexTexCoordsBuffer(), SHGraphicsConstants::VertexBufferBindings::TEX_COORD),
std::make_pair(meshLibrary.GetVertexNormalsBuffer(), SHGraphicsConstants::VertexBufferBindings::NORMAL), std::make_pair(meshLibrary.GetVertexNormalsBuffer(), SHGraphicsConstants::VertexBufferBindings::NORMAL),
std::make_pair(meshLibrary.GetVertexTangentsBuffer(), SHGraphicsConstants::VertexBufferBindings::TANGENT), std::make_pair(meshLibrary.GetVertexTangentsBuffer(), SHGraphicsConstants::VertexBufferBindings::TANGENT),
std::make_pair(meshLibrary.GetVertexBoneIndicesBuffer(), SHGraphicsConstants::VertexBufferBindings::BONE_INDICES),
std::make_pair(meshLibrary.GetVertexBoneWeightsBuffer(), SHGraphicsConstants::VertexBufferBindings::BONE_WEIGHTS),
std::make_pair(meshLibrary.GetIndexBuffer(), 0), std::make_pair(meshLibrary.GetIndexBuffer(), 0),
}; };
@ -483,6 +485,11 @@ namespace SHADE
// Bind all the buffers required for meshes // Bind all the buffers required for meshes
for (auto& [buffer, bindingPoint] : MESH_DATA) for (auto& [buffer, bindingPoint] : MESH_DATA)
{ {
// Ignore invalid buffers
if (!buffer)
continue;
// Assign based on type
if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer)
currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer)
@ -721,9 +728,9 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Mesh Registration Functions */ /* Mesh Registration Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices) SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices, const SHMesh::VertexBoneIndices* const boneIndices, const SHMesh::VertexWeights* const boneWeights)
{ {
return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices); return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, boneIndices, boneWeights, indexCount, indices);
} }
void SHGraphicsSystem::RemoveMesh(Handle<SHMesh> mesh) void SHGraphicsSystem::RemoveMesh(Handle<SHMesh> mesh)

View File

@ -204,7 +204,7 @@ namespace SHADE
*/ */
/*******************************************************************************/ /*******************************************************************************/
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices); Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices, const SHMesh::VertexBoneIndices* const boneIndices = nullptr, const SHMesh::VertexWeights* const boneWeights = nullptr);
/*******************************************************************************/ /*******************************************************************************/
/*! /*!

View File

@ -20,18 +20,28 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
SHADE::Handle<SHADE::SHMesh> SHMeshLibrary::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices) SHADE::Handle<SHADE::SHMesh> SHMeshLibrary::AddMesh
(
uint32_t vertexCount, const SHMesh::VertexPosition* const positions,
const SHMesh::VertexTexCoord* const texCoords,
const SHMesh::VertexTangent* const tangents,
const SHMesh::VertexNormal* const normals,
const SHMesh::VertexBoneIndices* const boneIndices,
const SHMesh::VertexWeights* const boneWeights,
uint32_t indexCount, const SHMesh::Index* const indices)
{ {
isDirty = true; isDirty = true;
auto handle = meshes.Create(); auto handle = meshes.Create();
meshAddJobs.emplace_back( MeshAddJob meshAddJobs.emplace_back(MeshAddJob
{ {
vertexCount, vertexCount,
positions, positions,
texCoords, texCoords,
tangents, tangents,
normals, normals,
boneIndices,
boneWeights,
indexCount, indexCount,
indices, indices,
handle handle
@ -83,6 +93,8 @@ namespace SHADE
vertTexCoordStorage.erase(vertTexCoordStorage.begin() + nextVertInsertPoint, vertTexCoordStorage.begin() + mesh->FirstVertex); vertTexCoordStorage.erase(vertTexCoordStorage.begin() + nextVertInsertPoint, vertTexCoordStorage.begin() + mesh->FirstVertex);
vertTangentStorage.erase(vertTangentStorage.begin() + nextVertInsertPoint, vertTangentStorage.begin() + mesh->FirstVertex); vertTangentStorage.erase(vertTangentStorage.begin() + nextVertInsertPoint, vertTangentStorage.begin() + mesh->FirstVertex);
vertNormalStorage.erase(vertNormalStorage.begin() + nextVertInsertPoint, vertNormalStorage.begin() + mesh->FirstVertex); vertNormalStorage.erase(vertNormalStorage.begin() + nextVertInsertPoint, vertNormalStorage.begin() + mesh->FirstVertex);
vertBoneIdxStorage.erase(vertBoneIdxStorage.begin() + nextVertInsertPoint, vertBoneIdxStorage.begin() + mesh->FirstVertex);
vertBoneWeightStorage.erase(vertBoneWeightStorage.begin() + nextVertInsertPoint, vertBoneWeightStorage.begin() + mesh->FirstVertex);
// - Update mesh data // - Update mesh data
mesh->FirstVertex = nextVertInsertPoint; mesh->FirstVertex = nextVertInsertPoint;
@ -110,11 +122,13 @@ namespace SHADE
newIdxElems += addJob.IndexCount; newIdxElems += addJob.IndexCount;
} }
// - Reserve new memory // - Reserve new memory
vertPosStorage .reserve(newVertElems); vertPosStorage.reserve(newVertElems);
vertTexCoordStorage.reserve(newVertElems); vertTexCoordStorage.reserve(newVertElems);
vertTangentStorage .reserve(newVertElems); vertTangentStorage.reserve(newVertElems);
vertNormalStorage .reserve(newVertElems); vertNormalStorage.reserve(newVertElems);
indexStorage .reserve(newIdxElems); vertBoneIdxStorage.reserve(newVertElems);
vertBoneWeightStorage.reserve(newVertElems);
indexStorage.reserve(newIdxElems);
// - Append new data // - Append new data
for (auto& addJob : meshAddJobs) for (auto& addJob : meshAddJobs)
{ {
@ -149,6 +163,22 @@ namespace SHADE
vertNormalStorage.end(), vertNormalStorage.end(),
addJob.VertexNormals, addJob.VertexNormals + addJob.VertexCount addJob.VertexNormals, addJob.VertexNormals + addJob.VertexCount
); );
if (addJob.VertexBoneIndices)
{
vertBoneIdxStorage.insert
(
vertBoneIdxStorage.end(),
addJob.VertexBoneIndices, addJob.VertexBoneIndices + addJob.VertexCount * SHMesh::BONE_INDICES_PER_VERTEX
);
}
if (addJob.VertexBoneWeights)
{
vertBoneWeightStorage.insert
(
vertBoneWeightStorage.end(),
addJob.VertexBoneWeights, addJob.VertexBoneWeights + addJob.VertexCount
);
}
indexStorage.insert indexStorage.insert
( (
indexStorage.end(), indexStorage.end(),
@ -192,6 +222,28 @@ namespace SHADE
BuffUsage::eVertexBuffer, BuffUsage::eVertexBuffer,
"Mesh Library Vertex Normals" "Mesh Library Vertex Normals"
); );
if (!vertBoneIdxStorage.empty())
{
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertBoneIdxBuffer,
vertBoneIdxStorage.data(),
static_cast<uint32_t>(vertBoneIdxStorage.size()) * sizeof(SHMesh::VertexBoneIndices),
BuffUsage::eVertexBuffer,
"Mesh Library Vertex Bone Indices"
);
}
if (!vertBoneWeightStorage.empty())
{
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertBoneWeightBuffer,
vertBoneWeightStorage.data(),
static_cast<uint32_t>(vertBoneWeightStorage.size()) * sizeof(SHMesh::VertexWeights),
BuffUsage::eVertexBuffer,
"Mesh Library Vertex Bone Weights"
);
}
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, indexBuffer, device, cmdBuffer, indexBuffer,

View File

@ -19,6 +19,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Resource/SHResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE namespace SHADE
{ {
@ -49,6 +50,13 @@ namespace SHADE
using VertexTexCoord = SHVec2; using VertexTexCoord = SHVec2;
using VertexTangent = SHVec3; using VertexTangent = SHVec3;
using VertexNormal = SHVec3; using VertexNormal = SHVec3;
using VertexBoneIndices = int;
using VertexWeights = SHVec4;
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
static constexpr size_t BONE_INDICES_PER_VERTEX = 4;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -105,7 +113,13 @@ namespace SHADE
*/ */
/*******************************************************************************/ /*******************************************************************************/
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices); Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions,
const SHMesh::VertexTexCoord* const texCoords,
const SHMesh::VertexTangent* const tangents,
const SHMesh::VertexNormal* const normals,
const SHMesh::VertexBoneIndices* const boneIndices,
const SHMesh::VertexWeights* const boneWeights,
uint32_t indexCount, const SHMesh::Index* const indices);
/*******************************************************************************/ /*******************************************************************************/
/*! /*!
@ -144,7 +158,9 @@ namespace SHADE
Handle<SHVkBuffer> GetVertexTexCoordsBuffer() const noexcept { return vertTexCoordBuffer; } Handle<SHVkBuffer> GetVertexTexCoordsBuffer() const noexcept { return vertTexCoordBuffer; }
Handle<SHVkBuffer> GetVertexTangentsBuffer() const noexcept { return vertTangentBuffer; } Handle<SHVkBuffer> GetVertexTangentsBuffer() const noexcept { return vertTangentBuffer; }
Handle<SHVkBuffer> GetVertexNormalsBuffer() const noexcept { return vertNormalBuffer; } Handle<SHVkBuffer> GetVertexNormalsBuffer() const noexcept { return vertNormalBuffer; }
Handle<SHVkBuffer> GetIndexBuffer() const { return indexBuffer; } Handle<SHVkBuffer> GetVertexBoneIndicesBuffer() const noexcept { return vertBoneIdxBuffer; }
Handle<SHVkBuffer> GetVertexBoneWeightsBuffer() const noexcept { return vertBoneWeightBuffer; }
Handle<SHVkBuffer> GetIndexBuffer() const noexcept { return indexBuffer; }
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -155,10 +171,12 @@ namespace SHADE
uint32_t VertexCount = 0; uint32_t VertexCount = 0;
const SHMesh::VertexPosition* VertexPositions = nullptr; const SHMesh::VertexPosition* VertexPositions = nullptr;
const SHMesh::VertexTexCoord* VertexTexCoords = nullptr; const SHMesh::VertexTexCoord* VertexTexCoords = nullptr;
const SHMesh::VertexTangent * VertexTangents = nullptr; const SHMesh::VertexTangent* VertexTangents = nullptr;
const SHMesh::VertexNormal * VertexNormals = nullptr; const SHMesh::VertexNormal* VertexNormals = nullptr;
const SHMesh::VertexBoneIndices* VertexBoneIndices = nullptr;
const SHMesh::VertexWeights* VertexBoneWeights = nullptr;
uint32_t IndexCount = 0; uint32_t IndexCount = 0;
const SHMesh::Index * Indices = nullptr; const SHMesh::Index* Indices = nullptr;
Handle<SHMesh> Handle; Handle<SHMesh> Handle;
}; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -168,20 +186,24 @@ namespace SHADE
std::vector<MeshAddJob> meshAddJobs; std::vector<MeshAddJob> meshAddJobs;
std::vector<Handle<SHMesh>> meshRemoveJobs; std::vector<Handle<SHMesh>> meshRemoveJobs;
// Tracking // Tracking
SHResourceLibrary<SHMesh> meshes{}; SHResourceLibrary<SHMesh> meshes;
std::vector<Handle<SHMesh>> meshOrder; std::vector<Handle<SHMesh>> meshOrder;
// CPU Storage // CPU Storage
std::vector<SHMesh::VertexPosition> vertPosStorage; std::vector<SHMesh::VertexPosition> vertPosStorage;
std::vector<SHMesh::VertexTexCoord> vertTexCoordStorage; std::vector<SHMesh::VertexTexCoord> vertTexCoordStorage;
std::vector<SHMesh::VertexTangent> vertTangentStorage; std::vector<SHMesh::VertexTangent> vertTangentStorage;
std::vector<SHMesh::VertexNormal> vertNormalStorage; std::vector<SHMesh::VertexNormal> vertNormalStorage;
std::vector<SHMesh::VertexBoneIndices> vertBoneIdxStorage; // Must be in multiples of 4
std::vector<SHMesh::VertexWeights> vertBoneWeightStorage;
std::vector<SHMesh::Index> indexStorage; std::vector<SHMesh::Index> indexStorage;
// GPU Storage // GPU Storage
Handle<SHVkBuffer> vertPosBuffer{}; Handle<SHVkBuffer> vertPosBuffer{};
Handle<SHVkBuffer> vertTexCoordBuffer{}; Handle<SHVkBuffer> vertTexCoordBuffer{};
Handle<SHVkBuffer> vertTangentBuffer{}; Handle<SHVkBuffer> vertTangentBuffer{};
Handle<SHVkBuffer> vertNormalBuffer{}; Handle<SHVkBuffer> vertNormalBuffer{};
Handle<SHVkBuffer> indexBuffer {}; Handle<SHVkBuffer> vertBoneIdxBuffer{};
Handle<SHVkBuffer> vertBoneWeightBuffer{};
Handle<SHVkBuffer> indexBuffer{};
// Flags // Flags
bool isDirty = true; bool isDirty = true;
}; };

View File

@ -293,6 +293,8 @@ namespace SHADE
meshData.VertexTexCoords.data(), meshData.VertexTexCoords.data(),
meshData.VertexTangents.data(), meshData.VertexTangents.data(),
meshData.VertexNormals.data(), meshData.VertexNormals.data(),
nullptr,
nullptr,
static_cast<uint32_t>(meshData.Indices.size()), static_cast<uint32_t>(meshData.Indices.size()),
meshData.Indices.data() meshData.Indices.data()
); );