From a7878c109a748ef08cb5369b3b87ab4f75dc02bb Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Mon, 15 Jul 2024 19:49:35 +0200 Subject: [PATCH] Models render. TODO: Add transforms and complete the UV1 etc. --- samples/03_model_render/model_loader.cpp | 15 +---- samples/03_model_render/model_loader.h | 4 +- samples/03_model_render/model_render.cpp | 5 +- samples/03_model_render/pipeline_utils.cpp | 2 +- .../render_resource_manager.cpp | 7 ++- .../03_model_render/shader/model.frag.glsl | 31 ++++++++-- .../03_model_render/shader/model.vert.glsl | 57 +++++++++++++------ 7 files changed, 79 insertions(+), 42 deletions(-) diff --git a/samples/03_model_render/model_loader.cpp b/samples/03_model_render/model_loader.cpp index 56a3e74..f54f236 100644 --- a/samples/03_model_render/model_loader.cpp +++ b/samples/03_model_render/model_loader.cpp @@ -19,8 +19,6 @@ #include "render_resource_manager.h" #include -#include -#include vec4 VectorToVec4(const std::vector &vec) @@ -48,7 +46,7 @@ VectorToVec3(const std::vector &vec) TextureHandle ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, StagingBuffer *stagingBuffer, - tinygltf::Image *image) + tinygltf::Image *image) const { assert(image->component == 4); @@ -58,14 +56,6 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, Stagin stagingBuffer->Init(m_ResourceManager->m_Device, byteSize); stagingBuffer->Write(m_ResourceManager->m_Device, 0, byteSize, image->image.data()); - // .srcAccessMask = , - // .dstAccessMask = , - // .oldLayout = , - // .newLayout = , - // .srcQueueFamilyIndex = , - // .dstQueueFamilyIndex = , - // .image = , - // .subresourceRange = vk::ImageMemoryBarrier imageStartBarrier = { .srcAccessMask = vk::AccessFlagBits::eNone, .dstAccessMask = vk::AccessFlagBits::eTransferWrite, @@ -409,7 +399,8 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched) texCoord0Count = Cast(uvAccessor->count); texCoord0.reserve(vertexPositions.size()); - assert(uvAccessor->type == TINYGLTF_TYPE_VEC2); + assert(uvAccessor->type == TINYGLTF_TYPE_VEC2 && + uvAccessor->componentType == TINYGLTF_COMPONENT_TYPE_FLOAT); { vec2 *data = Recast(uvBuffer->data.data() + byteOffset); texCoord0.insert(texCoord0.end(), data, data + vertexCount); diff --git a/samples/03_model_render/model_loader.h b/samples/03_model_render/model_loader.h index b956dc0..bfaea3c 100644 --- a/samples/03_model_render/model_loader.h +++ b/samples/03_model_render/model_loader.h @@ -91,8 +91,8 @@ struct ModelLoader u32 graphicsQueueIndex); ~ModelLoader(); - TextureHandle - LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, StagingBuffer *stagingBuffer, tinygltf::Image *image); + TextureHandle LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, StagingBuffer *stagingBuffer, + tinygltf::Image *image) const; Model LoadModel(cstr path, cstr name = nullptr, bool batched = false); constexpr static auto ANormal = "NORMAL"; diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index a7cb3f3..c61f51b 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -217,11 +217,13 @@ main(int, char **) struct ModelData { BufferHandle m_VertexBuffer; + BufferHandle m_UvBuffer; BufferHandle m_Materials; }; ModelData modelData = { .m_VertexBuffer = model.m_VertexPositionHandle, + .m_UvBuffer = model.m_TexCoord0Handle, .m_Materials = model.m_MaterialsHandle, }; @@ -293,8 +295,7 @@ main(int, char **) for (auto &prim : model.m_MeshPrimitives) { - cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, sizeof modelData, - sizeof prim.m_MaterialIdx, &prim.m_MaterialIdx); + cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, sizeof modelData, sizeof prim, &prim); cmd.drawIndexed(prim.m_IndexCount, 1, prim.m_FirstIndex, Cast(prim.m_VertexOffset), 0); } diff --git a/samples/03_model_render/pipeline_utils.cpp b/samples/03_model_render/pipeline_utils.cpp index 84e5a9b..b19700b 100644 --- a/samples/03_model_render/pipeline_utils.cpp +++ b/samples/03_model_render/pipeline_utils.cpp @@ -58,7 +58,7 @@ CreatePipeline(const Device *device, const Swapchain *swapchain, const RenderRes vk::PushConstantRange pushConstantRange = { .stageFlags = vk::ShaderStageFlagBits::eAll, .offset = 0, - .size = 32, + .size = 36, }; vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = { diff --git a/samples/03_model_render/render_resource_manager.cpp b/samples/03_model_render/render_resource_manager.cpp index 16bf216..7053d35 100644 --- a/samples/03_model_render/render_resource_manager.cpp +++ b/samples/03_model_render/render_resource_manager.cpp @@ -144,13 +144,14 @@ RenderResourceManager::RenderResourceManager(const Device *device, u16 maxSize) u32 buffersCount = eastl::min(properties.limits.maxPerStageDescriptorStorageBuffers - 1024, Cast(maxSize)); u32 texturesCount = eastl::min(properties.limits.maxPerStageDescriptorSampledImages - 1024, Cast(maxSize)); + // TODO: Switch to bindless samplers / multiple sampler configurations vk::SamplerCreateInfo samplerCreateInfo = { .magFilter = vk::Filter::eLinear, .minFilter = vk::Filter::eLinear, .mipmapMode = vk::SamplerMipmapMode::eLinear, - .addressModeU = vk::SamplerAddressMode::eClampToBorder, - .addressModeV = vk::SamplerAddressMode::eClampToBorder, - .addressModeW = vk::SamplerAddressMode::eClampToBorder, + .addressModeU = vk::SamplerAddressMode::eRepeat, + .addressModeV = vk::SamplerAddressMode::eRepeat, + .addressModeW = vk::SamplerAddressMode::eRepeat, .mipLodBias = 0.0f, .anisotropyEnable = true, .maxAnisotropy = properties.limits.maxSamplerAnisotropy, diff --git a/samples/03_model_render/shader/model.frag.glsl b/samples/03_model_render/shader/model.frag.glsl index 8ea9d89..2b1cacd 100644 --- a/samples/03_model_render/shader/model.frag.glsl +++ b/samples/03_model_render/shader/model.frag.glsl @@ -2,12 +2,11 @@ #pragma shader_stage(fragment) #extension GL_EXT_nonuniform_qualifier : enable -//layout (location = 0) in vec2 inUV; +layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; struct VertexData { float position[4]; -// float uv[2]; }; struct MaterialData { @@ -22,6 +21,8 @@ struct MaterialData { uint m_EmissionTex; }; +#define INVALID_HANDLE 0xFFFFFFFF + layout(set = 0, binding = 1) uniform sampler2D textures[]; layout(std430, set = 0, binding = 0) readonly buffer Vertices { VertexData data[]; @@ -33,14 +34,34 @@ layout(std430, set = 0, binding = 0) readonly buffer Materials { layout(push_constant) uniform Block { uint vertexBufferHandle; + uint uvBufferHandle; uint materialBufferHandle; - uint materialIdx; -}; + uint m_VertexOffset; + int m_NormalOffset; // <0 for invalid + int m_TexCoord0Offset; // <0 for invalid + uint m_FirstIndex; + uint m_IndexCount; + int m_MaterialIdx; // <0 for invalid +} pcb; vec4 ToVec4(float array[4]) { return vec4(array[0], array[1], array[2], array[3]); } +vec4 GetAlbedo(uint materialBufferId, int materialId, vec2 uv0) { + if (materialId < 0) { + return vec4(1.0f, 0.0f, 1.0f, 1.0f); + } else { + vec4 albedoFactor = ToVec4(materialsBuffer[materialBufferId].data[materialId].m_AlbedoFactor); + uint albedoTexId = materialsBuffer[materialBufferId].data[materialId].m_AlbedoTex; + if (albedoTexId == INVALID_HANDLE) { + return albedoFactor; + } else { + return texture(textures[albedoTexId], uv0); + } + } +} + void main() { - outColor = ToVec4(materialsBuffer[materialBufferHandle].data[materialIdx].m_AlbedoFactor);// vec4(texture(textures[textureHandle], inUV).rgb, 1.0f); + outColor = GetAlbedo(pcb.materialBufferHandle, pcb.m_MaterialIdx, inUV);// texture(textures[materialsBuffer[pcb.materialBufferHandle].data[pcb.m_MaterialIdx].m_AlbedoTex], inUV);// ToVec4(materialsBuffer[pcb.materialBufferHandle].data[pcb.m_MaterialIdx].m_AlbedoFactor);// vec4(texture(textures[textureHandle], inUV).rgb, 1.0f); } \ No newline at end of file diff --git a/samples/03_model_render/shader/model.vert.glsl b/samples/03_model_render/shader/model.vert.glsl index 8051212..ff38ca0 100644 --- a/samples/03_model_render/shader/model.vert.glsl +++ b/samples/03_model_render/shader/model.vert.glsl @@ -2,11 +2,16 @@ #pragma shader_stage(vertex) #extension GL_EXT_nonuniform_qualifier : enable -//layout(location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; -struct VertexData { +struct Position { float position[4]; -// float uv[2]; +}; +struct Normal { + float normal[4]; +}; +struct UV { + float uv[2]; }; struct MaterialData { @@ -21,27 +26,39 @@ struct MaterialData { uint m_EmissionTex; }; +#define INVALID_HANDLE 0xFFFFFFFF + layout(std430, set = 0, binding = 0) readonly buffer Vertices { - VertexData data[]; + Position data[]; } vertexBuffer[]; +layout(std430, set = 0, binding = 0) readonly buffer Normals { + Normal data[]; +} normalBuffer[]; +layout(std430, set = 0, binding = 0) readonly buffer TexCoord0 { + UV data[]; +} uvBuffer[]; layout(std430, set = 0, binding = 0) readonly buffer Materials { MaterialData data[]; } materialsBuffer[]; vec3 GetPosition(uint bufferId, uint vertexIdx) { return vec3( - vertexBuffer[bufferId].data[vertexIdx].position[0], - vertexBuffer[bufferId].data[vertexIdx].position[1], - vertexBuffer[bufferId].data[vertexIdx].position[2] + vertexBuffer[bufferId].data[vertexIdx].position[0], + vertexBuffer[bufferId].data[vertexIdx].position[1], + vertexBuffer[bufferId].data[vertexIdx].position[2] ); } -//vec2 GetUV(uint bufferId, uint vertexIdx) { -// return vec2( -// vertexBuffer[bufferId].data[vertexIdx].uv[0], -// vertexBuffer[bufferId].data[vertexIdx].uv[1] -// ); -//} +vec2 GetUV(uint bufferId, uint vertexIdx) { + if (bufferId == INVALID_HANDLE) { + return vec2(0.0f, 0.0f); + } else { + return vec2( + uvBuffer[bufferId].data[vertexIdx].uv[0], + uvBuffer[bufferId].data[vertexIdx].uv[1] + ); + } +} layout(set = 1, binding = 0) uniform Camera { mat4 model; @@ -51,11 +68,17 @@ layout(set = 1, binding = 0) uniform Camera { layout(push_constant) uniform Block { uint vertexBufferHandle; + uint uvBufferHandle; uint materialBufferHandle; - uint materialIdx; -}; + uint m_VertexOffset; + int m_NormalOffset; // <0 for invalid + int m_TexCoord0Offset; // <0 for invalid + uint m_FirstIndex; + uint m_IndexCount; + int m_MaterialIdx; // <0 for invalid +} pcb; void main() { - // outUV = GetUV(vertexBufferHandle, gl_VertexIndex); - gl_Position = ubo.proj * ubo.view * ubo.model * vec4(GetPosition(vertexBufferHandle, gl_VertexIndex), 1.0f); + outUV = GetUV(pcb.uvBufferHandle, gl_VertexIndex); + gl_Position = ubo.proj * ubo.view * ubo.model * vec4(GetPosition(pcb.vertexBufferHandle, gl_VertexIndex), 1.0f); } \ No newline at end of file