2
3
4
5
9#include "Render/Vulkan/VulkanRenderBackend.h"
10#include "Resources/Loader/MeshLoader.h"
18 positions .CreateBuffer(name +
"PositionsBuffer", VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR);
19 normals .CreateBuffer(name +
"NormalsBuffer" );
20 colors .CreateBuffer(name +
"ColorsBuffer" );
21 texCoords .CreateBuffer(name +
"TexCoordsBuffer" );
22 vertices .CreateBuffer(name +
"VerticesBuffer" );
23 primitivePoints .CreateBuffer(name +
"PrimitivePointsBuffer", VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR);
24 primitiveVertices .CreateBuffer(name +
"PrimitiveVerticesBuffer" );
25 primitiveLocations .CreateBuffer(name +
"PrimitiveLocationsBuffer" );
26 meshlets .CreateBuffer(name +
"MeshletsBuffer" );
39 primitivePointsAddress = 0;
40 primitiveVerticesAddress = 0;
41 primitiveLocationsAddress = 0;
42 materialParameterAddress = 0;
47 m_Buffer = std::make_shared<VulkanBuffer>(
48 VulkanRenderBackend::GetState() ,
50 sizeof(SpicesShader::MeshDesc) ,
51 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
52 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
53 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
54 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
55 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
58 m_Buffer->WriteToBuffer(
this);
66 desc.m_Buffer->CopyBuffer(m_Buffer->Get(), desc.m_Buffer->Get(),
sizeof(SpicesShader::MeshDesc));
75 return m_Buffer->GetAddress();
90 const VkBuffer buffers[] = { m_MeshResource.positions.buffer->Get() };
91 constexpr VkDeviceSize offsets[] = { 0 };
92 vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
93 vkCmdBindIndexBuffer(commandBuffer, m_MeshResource.primitivePoints.buffer->Get(), 0, VK_INDEX_TYPE_UINT32);
101 const auto ptr = m_Material->GetConstantParams().find_value(
"lod");
104 lodLevel = std::any_cast<
int>(ptr->value.paramValue);
105 lodLevel = std::max(lodLevel, 0);
106 lodLevel = std::min(lodLevel, (
int)m_MeshResource.lods.attributes->size() - 1);
108 const Lod& lod0 = (*m_MeshResource.lods.attributes)[lodLevel];
109 vkCmdDrawIndexed(commandBuffer, lod0.nPrimitives * 3, 1, lod0.primVertexOffset * 3, 0, 0);
116 VulkanRenderBackend::GetState().m_VkFunc.vkCmdDrawMeshTasksEXT(commandBuffer, m_NTasks, 1, 1);
123 if (m_Instanced || !ResourcePool<MeshPack>::Has(m_MeshPackName))
return false;
125 auto ptr = ResourcePool<MeshPack>::Access(m_MeshPackName);
128
129
130 m_Desc = ptr->m_Desc.Copy();
131 m_MeshResource = ptr->m_MeshResource;
132 m_NTasks = ptr->m_NTasks;
133 m_MeshTaskIndirectDrawCommand = ptr->m_MeshTaskIndirectDrawCommand;
134 m_Accel = ptr->m_Accel;
135 m_IsRequiredAccel = ptr->m_IsRequiredAccel.load();
139 m_Desc.UpdatematerialParameterAddress(m_Material->GetMaterialParamsAddress());
149 m_Material = ResourcePool<Material>::Load<Material>(materialPath, materialPath);
150 m_Material->BuildMaterial();
152 m_Desc.UpdatematerialParameterAddress(m_Material->GetMaterialParamsAddress());
159 m_Material = material;
160 m_Material->BuildMaterial();
162 m_Desc.UpdatematerialParameterAddress(material->GetMaterialParamsAddress());
169 if(!m_HitShaderHandle.has_value())
171 std::stringstream ss;
172 ss <<
"MeshPack do not has a valid material handle.";
174 SPICES_CORE_ERROR(ss.str())
177 return m_HitShaderHandle.value().load();
184 if (!m_ShaderGroupHandle.has_value())
186 std::stringstream ss;
187 ss <<
"MeshPack do not has a valid material handle.";
189 SPICES_CORE_ERROR(ss.str())
192 return m_ShaderGroupHandle.value().load();
200
201
202 const VkDeviceAddress vertexAddress = m_MeshResource.positions.buffer->GetAddress();
203 const VkDeviceAddress indicesAddress = m_MeshResource.primitivePoints.buffer->GetAddress();
205 const Lod& lod0 = (*m_MeshResource.lods.attributes)[0];
209
210
211
212 VkAccelerationStructureGeometryTrianglesDataKHR triangles {};
213 triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
214 triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
215 triangles.vertexData.deviceAddress = vertexAddress;
216 triangles.vertexStride =
sizeof(glm::vec3);
217 triangles.indexType = VK_INDEX_TYPE_UINT32;
218 triangles.indexData.deviceAddress = indicesAddress;
220 triangles.maxVertex =
static_cast<uint32_t>(m_MeshResource.primitivePoints.buffer->GetSize() /
sizeof(glm::uvec3) * 3 - 1);
223
224
225 VkAccelerationStructureGeometryKHR asGeom {};
226 asGeom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
227 asGeom.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
228 asGeom.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
229 asGeom.geometry.triangles = triangles;
232
233
234 VkAccelerationStructureBuildRangeInfoKHR offset {};
235 offset.firstVertex = 0;
236 offset.primitiveCount = maxPrimitiveCount;
237 offset.primitiveOffset = lod0.primVertexOffset;
238 offset.transformOffset = 0;
241
242
243 VulkanRayTracing::BlasInput input;
244 input.asGeometry.emplace_back(asGeom);
245 input.asBuildOffsetInfo.emplace_back(offset);
246 input.accel = &m_Accel;
255 if(m_IsRequiredAccel)
return true;
257 m_IsRequiredAccel =
true;
265 if(!m_IsRequiredAccel)
267 SPICES_CORE_ERROR(
"Can not access accel before require it.")
272 SPICES_CORE_ERROR(
"Can not access accel before build it.")
282 m_NTasks = m_MeshResource.meshlets.attributes->size() / SpicesShader::SUBGROUP_SIZE + 1;
283 m_MeshTaskIndirectDrawCommand.firstTask = 0;
284 m_MeshTaskIndirectDrawCommand.taskCount = m_NTasks;
286 m_MeshResource.CreateBuffer(m_MeshPackName);
288 m_Desc.UpdatepositionsAddress (m_MeshResource.positions.buffer );
289 m_Desc.UpdatenormalsAddress (m_MeshResource.normals.buffer );
290 m_Desc.UpdatecolorsAddress (m_MeshResource.colors.buffer );
291 m_Desc.UpdatetexCoordsAddress (m_MeshResource.texCoords.buffer );
292 m_Desc.UpdateverticesAddress (m_MeshResource.vertices.buffer );
293 m_Desc.UpdateprimitivePointsAddress (m_MeshResource.primitivePoints.buffer );
294 m_Desc.UpdateprimitiveVerticesAddress (m_MeshResource.primitiveVertices.buffer );
295 m_Desc.UpdateprimitiveLocationsAddress (m_MeshResource.primitiveLocations.buffer );
296 m_Desc.UpdatemeshletsAddress (m_MeshResource.meshlets.buffer );
297 m_Desc.UpdatenMeshlets (m_MeshResource.meshlets.attributes ->size());
301 m_MeshResource.positions.attributes =
nullptr;
302 m_MeshResource.normals.attributes =
nullptr;
303 m_MeshResource.colors.attributes =
nullptr;
304 m_MeshResource.texCoords.attributes =
nullptr;
305 m_MeshResource.vertices.attributes =
nullptr;
306 m_MeshResource.primitivePoints.attributes =
nullptr;
307 m_MeshResource.primitiveVertices.attributes =
nullptr;
308 m_MeshResource.primitiveLocations.attributes =
nullptr;
309 m_MeshResource.meshlets.attributes =
nullptr;
321 for (uint32_t i = 0; i <
m_Rows; i++)
323 float rowRamp = i /
static_cast<
float>(
m_Rows - 1) - 0.5f;
327 const uint32_t vtIndex = i *
m_Columns + j;
328 float colRamp = j /
static_cast<
float>(
m_Columns - 1) - 0.5f;
330 m_MeshResource.positions.attributes->push_back({ colRamp, rowRamp, 0.0f });
331 m_MeshResource.normals .attributes->push_back({ 0.0f, 0.0f, -1.0f });
332 m_MeshResource.colors .attributes->push_back({ 1.0f, 1.0f, 1.0f });
333 m_MeshResource.texCoords.attributes->push_back({ colRamp + 0.5, 0.5 - rowRamp });
335 m_MeshResource.vertices .attributes->push_back(glm::uvec4(vtIndex));
339 for (uint32_t i = 0; i <
m_Rows - 1; i++)
341 for (uint32_t j = 0; j <
m_Columns - 1; j++)
343 const uint32_t vtIndex = i *
m_Columns + j;
345 m_MeshResource.primitiveVertices.attributes->push_back({ vtIndex, vtIndex + 1, vtIndex + m_Columns + 1 });
346 m_MeshResource.primitiveVertices.attributes->push_back({ vtIndex + m_Columns + 1, vtIndex + m_Columns, vtIndex });
365 auto ApplyMatrixInPositions = [&](
auto& positions,
const glm::mat4& matrix) {
367 for (uint64_t i = 0; i < positions.size(); i++)
369 glm::vec4 p = matrix * glm::vec4(positions[i], 1.0f);
370 positions[i] = { p.x, p.y, p.z };
374 auto ApplyMatrixInNormals = [&](
auto& normals,
const glm::mat4& matrix) {
376 for (uint64_t i = 0; i < normals.size(); i++)
378 glm::vec4 n = matrix * glm::vec4(normals[i], 1.0f);
379 normals[i] = { n.x, n.y, n.z };
383 auto CopyToVertices = [&](
auto& resources) {
385 uint64_t nPositions = m_MeshResource.positions.attributes->size();
386 m_MeshResource.positions.attributes->insert(
387 m_MeshResource.positions.attributes->end(),
388 resources.positions.attributes->begin(),
389 resources.positions.attributes->end()
392 uint64_t nNormals = m_MeshResource.normals.attributes->size();
393 m_MeshResource.normals.attributes->insert(
394 m_MeshResource.normals.attributes->end(),
395 resources.normals.attributes->begin(),
396 resources.normals.attributes->end()
399 uint64_t nColors = m_MeshResource.colors.attributes->size();
400 m_MeshResource.colors.attributes->insert(
401 m_MeshResource.colors.attributes->end(),
402 resources.colors.attributes->begin(),
403 resources.colors.attributes->end()
406 uint64_t nTexCoords = m_MeshResource.texCoords.attributes->size();
407 m_MeshResource.texCoords.attributes->insert(
408 m_MeshResource.texCoords.attributes->end(),
409 resources.texCoords.attributes->begin(),
410 resources.texCoords.attributes->end()
413 uint64_t nVertices = m_MeshResource.vertices.attributes->size();
414 for (
auto& vertex : *resources.vertices.attributes)
416 m_MeshResource.vertices.attributes->push_back({
417 vertex.x + nPositions ,
418 vertex.y + nNormals ,
420 vertex.w + nTexCoords
424 uint64_t nPrimVertices = m_MeshResource.primitiveVertices.attributes->size();
425 for (
auto& primitiveVertex : *resources.primitiveVertices.attributes)
427 m_MeshResource.primitiveVertices.attributes->push_back({
428 primitiveVertex.x + nVertices,
429 primitiveVertex.y + nVertices,
430 primitiveVertex.z + nVertices
439 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -0.5f));
443 const auto positions = resources.positions.attributes;
444 ApplyMatrixInPositions(*positions, tran);
446 const auto normals = resources.normals.attributes;
447 ApplyMatrixInNormals(*normals, tran);
449 CopyToVertices(resources);
456 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.5f));
457 const glm::mat4 rot = glm::toMat4(glm::quat({0.0f, glm::radians(180.0f), 0.0f}));
461 const auto positions = resources.positions.attributes;
462 ApplyMatrixInPositions(*positions, tran * rot);
464 const auto normals = resources.normals.attributes;
465 ApplyMatrixInNormals(*normals, tran * rot);
467 CopyToVertices(resources);
474 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.0f, 0.0f));
475 const glm::mat4 rot = glm::toMat4(glm::quat({ 0.0f, glm::radians(-90.0f), 0.0f }));
479 const auto positions = resources.positions.attributes;
480 ApplyMatrixInPositions(*positions, tran * rot);
482 const auto normals = resources.normals.attributes;
483 ApplyMatrixInNormals(*normals, tran * rot);
485 CopyToVertices(resources);
492 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.0f, 0.0f));
493 const glm::mat4 rot = glm::toMat4(glm::quat({ 0.0f, glm::radians(90.0f), 0.0f }));
497 const auto positions = resources.positions.attributes;
498 ApplyMatrixInPositions(*positions, tran * rot);
500 const auto normals = resources.normals.attributes;
501 ApplyMatrixInNormals(*normals, tran * rot);
503 CopyToVertices(resources);
510 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -0.5f, 0.0f));
511 const glm::mat4 rot = glm::toMat4(glm::quat({ glm::radians(-90.0f), 0.0f, 0.0f }));
515 const auto positions = resources.positions.attributes;
516 ApplyMatrixInPositions(*positions, tran * rot);
518 const auto normals = resources.normals.attributes;
519 ApplyMatrixInNormals(*normals, tran * rot);
521 CopyToVertices(resources);
528 const glm::mat4 tran = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.5f, 0.0f));
529 const glm::mat4 rot = glm::toMat4(glm::quat({ glm::radians(90.0f), 0.0f, 0.0f }));
533 const auto positions = resources.positions.attributes;
534 ApplyMatrixInPositions(*positions, tran * rot);
536 const auto normals = resources.normals.attributes;
537 ApplyMatrixInNormals(*normals, tran * rot);
539 CopyToVertices(resources);
569 for (uint32_t i = 0; i <
m_Rows; i++)
571 const float rowRamp = i /
static_cast<
float>(
m_Rows - 1) * 180.0f;
575 const uint32_t vtIndex = i *
m_Columns + j;
576 const float colRamp = j * 360.0f /
static_cast<
float>(
m_Columns - 1);
578 glm::vec3 position{ glm::sin(glm::radians(rowRamp)) * glm::sin(glm::radians(colRamp)), glm::cos(glm::radians(rowRamp)), glm::sin(glm::radians(rowRamp)) * glm::cos(glm::radians(colRamp)) };
580 m_MeshResource.positions.attributes->push_back(position);
581 m_MeshResource.normals .attributes->push_back(glm::normalize(position));
582 m_MeshResource.colors .attributes->push_back({ 1.0f, 1.0f, 1.0f });
583 m_MeshResource.texCoords.attributes->push_back({ j /
static_cast<
float>(m_Columns - 1), i /
static_cast<
float>(m_Rows - 1) });
585 m_MeshResource.vertices .attributes->push_back(glm::uvec4(vtIndex));
589 for (uint32_t i = 0; i <
m_Rows - 1; i++)
591 for (uint32_t j = 0; j <
m_Columns - 1; j++)
593 const uint32_t vtIndex = i *
m_Columns + j;
595 m_MeshResource.primitiveVertices.attributes->push_back({ vtIndex, vtIndex + 1, vtIndex + m_Columns + 1 });
596 m_MeshResource.primitiveVertices.attributes->push_back({ vtIndex + m_Columns + 1, vtIndex + m_Columns, vtIndex });
#define SPICES_PROFILE_ZONE
virtual bool OnCreatePack(bool isCreateBuffer=true) override
This interface is used for build specific mesh pack data.
uint32_t m_Columns
How much cols number we use.
uint32_t m_Rows
How much rows number we use.
CubePack Class. This class defines box type mesh pack.
virtual bool OnCreatePack(bool isCreateBuffer=true) override
This interface is used for build specific mesh pack data.
std::string m_Path
The mesh file path in disk.
FilePack Class. This class defines file type mesh pack.
Material Class. This class contains a branch of parameter and shader, also descriptor.
static bool Load(const std::string &fileName, MeshPack *outMeshPack)
Public called API, it is entrance.
MeshLoader Class. This class only defines static function for load data from mesh file.
std::string m_MeshPackName
MeshPack Name.
void OnDraw(const VkCommandBuffer &commandBuffer) const
Draw indexed.
virtual bool OnCreatePack(bool isCreateBuffer=true)
This interface is used for build specific mesh pack data.
uint32_t GetShaderGroupHandle() const
Get ShaderGroup Handle, which accessed by gdc buffer.
void OnDrawMeshTasks(const VkCommandBuffer &commandBuffer) const
Draw Mesh Tasks.
uint32_t GetHitShaderHandle() const
Get Hit Shader Handle, which accessed by ray gen shader.
MeshPack(const std::string &name, bool instanced)
Constructor Function.
bool HasBlasAccel()
Is this meshPack has a valid blas.
void CreateBuffer()
Create Vertices buffer anf Indices buffer.
VulkanRayTracing::BlasInput MeshPackToVkGeometryKHR()
Convert MeshPack into the ray tracing geometry used to build the BLAS.
void OnBind(const VkCommandBuffer &commandBuffer) const
Bind VBO and EBO.
void SetMaterial(std::shared_ptr< Material > material)
Set specific material for this class.
const MeshResource & GetResource() const
Get Resource.
void SetMaterial(const std::string &materialPath)
Set specific material for this class.
uint32_t m_NTasks
Task Shader Work Group Size.
UUID m_UUID
UUID for mesh pack.
bool m_Instanced
If this mesh pack needs instanced.
AccelKHR & GetAccel()
Get this accel.
MeshPack Class. This class defines some basic behaves and variables. This class need to be inherited ...
static void GenerateMeshLodClusterHierarchy(MeshPack *meshPack)
Generate Mesh Lod Resources.
Class for provide functions of process Meshpack.
uint32_t m_Columns
How much cols number we use.
uint32_t m_Rows
How much rows number we use.
virtual bool OnCreatePack(bool isCreateBuffer=true) override
This interface is used for build specific mesh pack data.
PlanePack(uint32_t rows=2, uint32_t columns=2, bool instanced=true)
Constructor Function. Init member variables.
PlanePack Class. This class defines plane type mesh pack.
uint32_t m_Rows
How much rows number we use.
virtual bool OnCreatePack(bool isCreateBuffer=true) override
This interface is used for build specific mesh pack data.
uint32_t m_Columns
How much cols number we use.
SpherePack Class. This class defines sphere type mesh pack.
UUID()
Constructor Function.
This class helps to generate a uuid for one resource.
MeshDesc()
Constructor Function.
MeshDesc Copy() const
Copy a MeshDesc from this.
uint64_t GetBufferAddress() const
Get m_Buffer's Address.
Add Construction Functions to SpicesShader::MeshDesc.
void CreateBuffer(const std::string &name)
Create MeshResource Buffers.