From 2250b1737d2709a62102c03ad41cb20b45c67326 Mon Sep 17 00:00:00 2001 From: JC Date: Tue, 18 Jun 2024 19:33:04 -0700 Subject: [PATCH] grass shader --- engine/platform/Vulkan/VKbuffer.cpp | 40 ++++++++++++++----- engine/platform/Vulkan/VKbuffer.h | 2 +- engine/platform/Vulkan/VKrenderer.cpp | 2 +- .../platform/Vulkan/VKresourceDescriptor.cpp | 2 +- engine/platform/Vulkan/shaders/grass.vert | 19 +++++---- engine/renderer/buffer.cpp | 4 +- engine/renderer/buffer.h | 6 ++- engine/renderer/builder/terrainBuilder.cpp | 9 +++-- 8 files changed, 54 insertions(+), 30 deletions(-) diff --git a/engine/platform/Vulkan/VKbuffer.cpp b/engine/platform/Vulkan/VKbuffer.cpp index 81208ad6..3d754a19 100644 --- a/engine/platform/Vulkan/VKbuffer.cpp +++ b/engine/platform/Vulkan/VKbuffer.cpp @@ -59,18 +59,40 @@ namespace GfxRenderEngine VK_Buffer::VK_Buffer(uint size, Buffer::BufferUsage bufferUsage) : m_Device(VK_Core::m_Device.get()) { - if (bufferUsage == Buffer::BufferUsage::SMALL_SHADER_DATA_BUFFER_VISIBLE_TO_CPU) + switch (bufferUsage) { - m_InstanceSize = size; - m_InstanceCount = 1; - m_UsageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - m_MemoryPropertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + case Buffer::BufferUsage::UNIFORM_BUFFER_VISIBLE_TO_CPU: + { + m_InstanceSize = size; + m_InstanceCount = 1; + m_UsageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + m_MemoryPropertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - VkDeviceSize minOffsetAlignment = m_Device->m_Properties.limits.minUniformBufferOffsetAlignment; + VkDeviceSize minOffsetAlignment = m_Device->m_Properties.limits.minUniformBufferOffsetAlignment; - m_AlignmentSize = GetAlignment(m_InstanceSize, minOffsetAlignment); - m_BufferSize = m_AlignmentSize * m_InstanceCount; - m_Device->CreateBuffer(m_BufferSize, m_UsageFlags, m_MemoryPropertyFlags, m_Buffer, m_Memory); + m_AlignmentSize = GetAlignment(m_InstanceSize, minOffsetAlignment); + m_BufferSize = m_AlignmentSize * m_InstanceCount; + m_Device->CreateBuffer(m_BufferSize, m_UsageFlags, m_MemoryPropertyFlags, m_Buffer, m_Memory); + break; + } + case Buffer::BufferUsage::STORAGE_BUFFER_VISIBLE_TO_CPU: + { + m_InstanceSize = size; + m_InstanceCount = 1; + m_UsageFlags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + m_MemoryPropertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + + VkDeviceSize minOffsetAlignment = m_Device->m_Properties.limits.minUniformBufferOffsetAlignment; + + m_AlignmentSize = GetAlignment(m_InstanceSize, minOffsetAlignment); + m_BufferSize = m_AlignmentSize * m_InstanceCount; + m_Device->CreateBuffer(m_BufferSize, m_UsageFlags, m_MemoryPropertyFlags, m_Buffer, m_Memory); + break; + } + default: + { + LOG_CORE_CRITICAL("unrecognized buffer usage"); + } } } diff --git a/engine/platform/Vulkan/VKbuffer.h b/engine/platform/Vulkan/VKbuffer.h index d7e91059..0fe8be8d 100644 --- a/engine/platform/Vulkan/VKbuffer.h +++ b/engine/platform/Vulkan/VKbuffer.h @@ -43,7 +43,7 @@ namespace GfxRenderEngine VK_Buffer(VkDeviceSize instanceSize, uint instanceCount, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize minOffsetAlignment = 1); - VK_Buffer(uint size, Buffer::BufferUsage bufferUsage = Buffer::BufferUsage::SMALL_SHADER_DATA_BUFFER_VISIBLE_TO_CPU); + VK_Buffer(uint size, Buffer::BufferUsage bufferUsage = Buffer::BufferUsage::UNIFORM_BUFFER_VISIBLE_TO_CPU); virtual ~VK_Buffer(); diff --git a/engine/platform/Vulkan/VKrenderer.cpp b/engine/platform/Vulkan/VKrenderer.cpp index 637358e9..eea76e9d 100644 --- a/engine/platform/Vulkan/VKrenderer.cpp +++ b/engine/platform/Vulkan/VKrenderer.cpp @@ -153,7 +153,7 @@ namespace GfxRenderEngine VK_DescriptorSetLayout::Builder() .AddBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) // shader data for instances .AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) // dummy - .AddBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) // shader data for height map + .AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) // shader data for height map .Build(); std::unique_ptr instanceDescriptorSetLayout = diff --git a/engine/platform/Vulkan/VKresourceDescriptor.cpp b/engine/platform/Vulkan/VKresourceDescriptor.cpp index 3fcb6fe5..b73ab830 100644 --- a/engine/platform/Vulkan/VKresourceDescriptor.cpp +++ b/engine/platform/Vulkan/VKresourceDescriptor.cpp @@ -63,7 +63,7 @@ namespace GfxRenderEngine } if (hBuffer) { - builder.AddBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT); + builder.AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT); } std::unique_ptr localDescriptorSetLayout = builder.Build(); diff --git a/engine/platform/Vulkan/shaders/grass.vert b/engine/platform/Vulkan/shaders/grass.vert index 8c085ad9..561f551a 100644 --- a/engine/platform/Vulkan/shaders/grass.vert +++ b/engine/platform/Vulkan/shaders/grass.vert @@ -69,9 +69,9 @@ layout(set = 2, binding = 0) uniform InstanceUniformBuffer #define WIDTH 1024 // row #define HEIGHT 750 // col #define NUM_HEIGHT_VALUES WIDTH*HEIGHT // 768000 -#define INSTANCE_COUNT 16384 // max buffer size 65536 bytes +#define INSTANCE_COUNT NUM_HEIGHT_VALUES -layout(set = 2, binding = 2) uniform HeightMap +layout(set = 2, binding = 2) readonly buffer HeightMap { int m_HeightMapData[INSTANCE_COUNT]; } heightMap; @@ -86,19 +86,18 @@ void main() { mat4 baseModelMatrix = baseTransform.m_InstanceData.m_ModelMatrix; mat4 normalMatrix = baseTransform.m_InstanceData.m_NormalMatrix; - - - int index = int(floor(46.875 * gl_InstanceIndex)); + + int index = gl_InstanceIndex; int hgt = heightMap.m_HeightMapData[index]; float row = floor(index / WIDTH); float col = floor((index - WIDTH * row)); - + mat4 localTranslation = mat4 ( - vec4(1.0, 0.0, 0.0, 0.0), // first column - vec4(0.0, 1.0, 0.0, 0.0), // second column - vec4(0.0, 0.0, 1.0, 0.0), // third column - vec4(col, hgt, row, 1.0) // fourth column + vec4(4.0, 0.0, 0.0, 0.0), // first column + vec4(0.0, 4.0, 0.0, 0.0), // second column + vec4(0.0, 0.0, 4.0, 0.0), // third column + vec4(col, row, -hgt, 1.0) // fourth column ); // projection * view * model * position diff --git a/engine/renderer/buffer.cpp b/engine/renderer/buffer.cpp index 905497b0..fac69c80 100644 --- a/engine/renderer/buffer.cpp +++ b/engine/renderer/buffer.cpp @@ -29,14 +29,14 @@ namespace GfxRenderEngine { - std::shared_ptr Buffer::Create(uint size) + std::shared_ptr Buffer::Create(uint size, BufferUsage bufferUsage) { std::shared_ptr buffer; switch (RendererAPI::GetAPI()) { case RendererAPI::VULKAN: - buffer = std::make_shared(size); + buffer = std::make_shared(size, bufferUsage); break; default: buffer = nullptr; diff --git a/engine/renderer/buffer.h b/engine/renderer/buffer.h index 090c5663..ea426b97 100644 --- a/engine/renderer/buffer.h +++ b/engine/renderer/buffer.h @@ -35,7 +35,8 @@ namespace GfxRenderEngine public: enum class BufferUsage { - SMALL_SHADER_DATA_BUFFER_VISIBLE_TO_CPU + UNIFORM_BUFFER_VISIBLE_TO_CPU, + STORAGE_BUFFER_VISIBLE_TO_CPU }; public: @@ -43,6 +44,7 @@ namespace GfxRenderEngine virtual void MapBuffer() = 0; virtual void WriteToBuffer(const void* data) = 0; virtual bool Flush() = 0; - static std::shared_ptr Create(uint size /*in bytes*/); + static std::shared_ptr Create(uint size /*in bytes*/, + BufferUsage bufferUsage = BufferUsage::UNIFORM_BUFFER_VISIBLE_TO_CPU); }; } // namespace GfxRenderEngine diff --git a/engine/renderer/builder/terrainBuilder.cpp b/engine/renderer/builder/terrainBuilder.cpp index 8babcabc..40c6f0ab 100644 --- a/engine/renderer/builder/terrainBuilder.cpp +++ b/engine/renderer/builder/terrainBuilder.cpp @@ -289,7 +289,7 @@ namespace GfxRenderEngine if (fileExists) { Image& heightMap = *terrainComponent.m_HeightMap.get(); - uint heightMapSize = std::min(16384, heightMap.Size()); + uint heightMapSize = heightMap.Size(); Resources::ResourceBuffers resourceBuffers; { // unforunately, need to copy one buffer into another (glsl does not support uint8_t by default) @@ -300,7 +300,7 @@ namespace GfxRenderEngine } int bufferSize = heightMapSize * sizeof(int); // in bytes auto& ubo = resourceBuffers[Resources::HEIGHTMAP]; - ubo = Buffer::Create(bufferSize); + ubo = Buffer::Create(bufferSize, Buffer::BufferUsage::STORAGE_BUFFER_VISIBLE_TO_CPU); resourceBuffers[Resources::HEIGHTMAP]->MapBuffer(); // update ubo ubo->WriteToBuffer(bufferData.data()); @@ -319,8 +319,9 @@ namespace GfxRenderEngine registry.emplace(grassNode.GetGameObject(), grassTag); auto& transform = registry.get(grassEntityRoot); - transform.SetTranslation({-11.0f, 8.4f, -1.4f}); - transform.SetScale({0.235f, 0.235f, 0.235f}); + transform.SetRotation({3.14159f, 0.767164f, 3.14159f}); + transform.SetTranslation({4.37885f, -1.14346f, 59.3405f}); + transform.SetScale({0.0649992f, 0.0376f, 0.0649992f}); } } }