diff --git a/computeparticles/computeparticles.vcxproj b/computeparticles/computeparticles.vcxproj index 8650396c..9d4b51d3 100644 --- a/computeparticles/computeparticles.vcxproj +++ b/computeparticles/computeparticles.vcxproj @@ -89,6 +89,11 @@ + + + + + diff --git a/computeparticles/computeparticles.vcxproj.filters b/computeparticles/computeparticles.vcxproj.filters index 1247208e..80246e85 100644 --- a/computeparticles/computeparticles.vcxproj.filters +++ b/computeparticles/computeparticles.vcxproj.filters @@ -13,6 +13,9 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + {e28680da-cc95-413d-b6f0-0e1f9967ee88} + @@ -39,4 +42,15 @@ Header Files + + + Shaders + + + Shaders + + + Shaders + + \ No newline at end of file diff --git a/computeshader/computeshader.vcxproj.filters b/computeshader/computeshader.vcxproj.filters index b36bf08e..2107681a 100644 --- a/computeshader/computeshader.vcxproj.filters +++ b/computeshader/computeshader.vcxproj.filters @@ -13,6 +13,9 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + {232f5393-2624-4cd4-84ed-9fdda34ff64c} + diff --git a/data/shaders/raytracing/raytracing.comp b/data/shaders/raytracing/raytracing.comp index 1940349c..92c881a2 100644 --- a/data/shaders/raytracing/raytracing.comp +++ b/data/shaders/raytracing/raytracing.comp @@ -10,16 +10,16 @@ layout (binding = 0, rgba8) uniform writeonly image2D resultImage; #define EPSILON 0.0001 #define MAXLEN 1000.0 -#define PLANEID 1 -#define SPHERECOUNT 3 #define SHADOW 0.5 -#define RAYBOUNCES 1 +#define RAYBOUNCES 2 #define REFLECTIONSTRENGTH 0.4 +#define REFLECTIONFALLOFF 0.5 -struct Camera { - vec3 pos; - vec3 lookat; - float fov; +struct Camera +{ + vec3 pos; + vec3 lookat; + float fov; }; layout (binding = 1) uniform UBO @@ -31,50 +31,60 @@ layout (binding = 1) uniform UBO mat4 rotMat; } ubo; +struct Sphere +{ + vec3 pos; + float radius; + vec3 diffuse; + float specular; + int id; +}; + +struct Plane +{ + vec3 normal; + float distance; + vec3 diffuse; + float specular; + int id; +}; + +layout (std140, binding = 2) buffer Spheres +{ + Sphere spheres[ ]; +}; + +layout (std140, binding = 3) buffer Planes +{ + Plane planes[ ]; +}; + void reflectRay(inout vec3 rayD, in vec3 mormal) { - rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal; + rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal; } -// Lighting calculations +// Lighting ========================================================= float lightDiffuse(vec3 normal, vec3 lightDir) { - return clamp(dot(normal, lightDir), 0.0, 1.0); + return clamp(dot(normal, lightDir), 0.25, 1.0); } -float lightSpecular(vec3 normal, vec3 lightDir) +float lightSpecular(vec3 normal, vec3 lightDir, float specularFactor) { - vec3 viewVec = normalize(ubo.camera.pos); - vec3 halfVec = normalize(lightDir + viewVec); - return pow(clamp(dot(normal, halfVec), 0.0, 1.0), 32.0); + vec3 viewVec = normalize(ubo.camera.pos); + vec3 halfVec = normalize(lightDir + viewVec); + return pow(clamp(dot(normal, halfVec), 0.0, 1.0), specularFactor); } -// Primitives - -// Basic material description -struct Material -{ - vec3 diffuse; - vec3 specular; -}; - -// Sphere -struct Sphere -{ - int id; - vec3 pos; - float r; - Material material; -} sphere; - -Sphere spheres[SPHERECOUNT]; +// Sphere =========================================================== float sphereIntersect(in vec3 rayO, in vec3 rayD, in Sphere sphere) { vec3 oc = rayO - sphere.pos; float b = 2.0 * dot(oc, rayD); - float c = dot(oc, oc) - sphere.r*sphere.r; + float c = dot(oc, oc) - sphere.radius*sphere.radius; float h = b*b - 4.0*c; if (h < 0.0) { @@ -86,51 +96,58 @@ float sphereIntersect(in vec3 rayO, in vec3 rayD, in Sphere sphere) vec3 sphereNormal(in vec3 pos, in Sphere sphere) { - return (pos - sphere.pos) / sphere.r; + return (pos - sphere.pos) / sphere.radius; } -// Plane +// Plane =========================================================== -float planeIntersect(vec3 rayO, vec3 rayD) +float planeIntersect(vec3 rayO, vec3 rayD, Plane plane) { - return -rayO.y/rayD.y; + float d = dot(rayD, plane.normal); + + if (d == 0.0) + return 0.0; + + float t = -(plane.distance + dot(rayO, plane.normal)) / d; + + if (t < 0.0) + return 0.0; + + return t; } -vec3 planeNormal(in vec3 pos) -{ - return vec3(0.0, 1.0, 0.0); -} -int intersect(in vec3 rayO, in vec3 rayD, out float resT) +int intersect(in vec3 rayO, in vec3 rayD, inout float resT) { int id = -1; - resT = MAXLEN; - for (int i = 0; i < SPHERECOUNT; i++) + for (int i = 0; i < spheres.length(); i++) { float tSphere = sphereIntersect(rayO, rayD, spheres[i]); - if (tSphere > EPSILON) + if ((tSphere > EPSILON) && (tSphere < resT)) { id = spheres[i].id; resT = tSphere; - return id; - break; } } - - float tplane = planeIntersect(rayO, rayD); - if ((tplane > EPSILON) && (tplane < resT)) + + for (int i = 0; i < planes.length(); i++) { - id = PLANEID; - resT = tplane; - } + float tplane = planeIntersect(rayO, rayD, planes[i]); + if ((tplane > EPSILON) && (tplane < resT)) + { + id = planes[i].id; + resT = tplane; + } + } return id; } float calcShadow(in vec3 rayO, in vec3 rayD, in int id) { - for (int i = 0; i < SPHERECOUNT; i++) + //todo: avoid backprojection + for (int i = 0; i < spheres.length(); i++) { float tSphere = sphereIntersect(rayO, rayD, spheres[i]); if (tSphere > EPSILON) @@ -143,13 +160,13 @@ float calcShadow(in vec3 rayO, in vec3 rayD, in int id) vec3 fog(in float t, in vec3 color) { - return mix(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0)); + return mix(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0)); } vec3 renderScene(inout vec3 rayO, inout vec3 rayD, inout int id) { vec3 color = vec3(0.0); - float t = 0.0; + float t = MAXLEN; // Get intersected object ID int objectID = intersect(rayO, rayD, t); @@ -162,64 +179,53 @@ vec3 renderScene(inout vec3 rayO, inout vec3 rayD, inout int id) vec3 pos = rayO + t * rayD; vec3 lightVec = normalize(ubo.lightPos - pos); vec3 normal; - - if (objectID == PLANEID) + + // Planes + + // Spheres + + for (int i = 0; i < planes.length(); i++) { - normal = planeNormal(pos); - float diffuse = clamp(dot(normal, lightVec), 0.0, 1.0); - color = vec3(1.0, 1.0, 1.0) * diffuse; - } - else - { - for (int i = 0; i < SPHERECOUNT; i++) + if (objectID == planes[i].id) { - if (objectID == spheres[i].id) - { - normal = sphereNormal(pos, spheres[i]); - float diffuse = lightDiffuse(normal, lightVec); - float specular = lightSpecular(normal, lightVec); - color = diffuse * spheres[i].material.diffuse + specular * spheres[i].material.specular; - } + normal = planes[i].normal; + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec, planes[i].specular); + color = diffuse * planes[i].diffuse + specular; } } + for (int i = 0; i < spheres.length(); i++) + { + if (objectID == spheres[i].id) + { + normal = sphereNormal(pos, spheres[i]); + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec, spheres[i].specular); + color = diffuse * spheres[i].diffuse.rgb + specular; + } + } + + if (id == -1) + return color; + id = objectID; // Shadows - color *= calcShadow(pos, lightVec, objectID); + color *= calcShadow(pos, lightVec, objectID); // Fog color = fog(t, color); // Reflect ray for next render pass reflectRay(rayD, normal); - rayO = pos; + rayO = pos; return color; } void main() { - // Scene setup - // todo : from ubo - spheres[0].id = 2; - spheres[0].pos = vec3(-2.25, 1.0, 0.0); - spheres[0].r = 1.0; - spheres[0].material.diffuse = vec3(1.0, 0.0, 0.0); - spheres[0].material.specular = vec3(2.0); - - spheres[1].id = 3; - spheres[1].pos = vec3(0.0, 2.5, 0.0); - spheres[1].r = 1.0; - spheres[1].material.diffuse = vec3(0.0, 0.0, 1.0); - spheres[1].material.specular = vec3(2.0); - - spheres[2].id = 4; - spheres[2].pos = vec3(2.25, 1.0, 0.0); - spheres[2].r = 1.0; - spheres[2].material.diffuse = vec3(0.0, 1.0, 0.0); - spheres[2].material.specular = vec3(2.0); - ivec2 dim = imageSize(resultImage); vec2 uv = vec2(gl_GlobalInvocationID.xy) / dim; @@ -230,14 +236,16 @@ void main() int id = 0; vec3 finalColor = renderScene(rayO, rayD, id); - bool reflections = true; + const bool reflections = true; // Reflection if (reflections) { + float reflectionStrength = REFLECTIONSTRENGTH; for (int i = 0; i < RAYBOUNCES; i++) { vec3 reflectionColor = renderScene(rayO, rayD, id); - finalColor = (1.0 - REFLECTIONSTRENGTH) * finalColor + REFLECTIONSTRENGTH * mix(reflectionColor, finalColor, 1.0 - REFLECTIONSTRENGTH); + finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * mix(reflectionColor, finalColor, 1.0 - reflectionStrength); + reflectionStrength *= REFLECTIONFALLOFF; } } diff --git a/data/shaders/raytracing/raytracing.comp.spv b/data/shaders/raytracing/raytracing.comp.spv index 45f33ffb..fb3eabc9 100644 Binary files a/data/shaders/raytracing/raytracing.comp.spv and b/data/shaders/raytracing/raytracing.comp.spv differ diff --git a/raytracing/raytracing.cpp b/raytracing/raytracing.cpp index 3661b41f..ec71658f 100644 --- a/raytracing/raytracing.cpp +++ b/raytracing/raytracing.cpp @@ -45,6 +45,11 @@ public: // Resources for the compute part of the example struct { + struct { + vk::Buffer spheres; // (Shader) storage buffer object with scene spheres + vk::Buffer planes; // (Shader) storage buffer object with scene planes + } storageBuffers; + vk::Buffer uniformBuffer; // Uniform buffer object containing scene data VkQueue queue; // Separate queue for compute commands (queue family may differ from the one used for graphics) VkCommandPool commandPool; // Use a separate command pool (queue family may differ from the one used for graphics) VkCommandBuffer commandBuffer; // Command buffer storing the dispatch commands and barriers @@ -53,26 +58,43 @@ public: VkDescriptorSet descriptorSet; // Compute shader bindings VkPipelineLayout pipelineLayout; // Layout of the compute pipeline VkPipeline pipeline; // Compute raytracing pipeline + struct UBOCompute { // Compute shader uniform block object + glm::vec3 lightPos; + float aspectRatio; // Aspect ratio of the viewport + glm::vec4 fogColor = glm::vec4(0.0f); + struct { + glm::vec3 pos = glm::vec3(0.0f, 0.0f, 4.0f); + glm::vec3 lookat = glm::vec3(0.0f, 0.5f, 0.0f); + float fov = 10.0f; + } camera; + } ubo; } compute; - vk::Buffer uniformDataCompute; + // SSBO sphere declaration + struct Sphere { // Shader uses std140 layout (so we only use vec4 instead of vec3) + glm::vec3 pos; + float radius; + glm::vec3 diffuse; + float specular; + uint32_t id; // Id used to identify sphere for raytracing + glm::ivec3 _pad; + }; - struct { - glm::vec3 lightPos; - float aspectRatio; // Aspect ratio of the viewport - glm::vec4 fogColor = glm::vec4(0.0f); - struct { - glm::vec3 pos = glm::vec3(0.0f, 1.5f, 4.0f); - glm::vec3 lookat = glm::vec3(0.0f, 0.5f, 0.0f); - float fov = 10.0f; - } camera; - } uboCompute; + // SSBO plane declaration + struct Plane { + glm::vec3 normal; + float distance; + glm::vec3 diffuse; + float specular; + uint32_t id; + glm::ivec3 _pad; + }; VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) { title = "Vulkan Example - Compute shader ray tracing"; enableTextOverlay = true; - uboCompute.aspectRatio = (float)width / (float)height; + compute.ubo.aspectRatio = (float)width / (float)height; paused = true; timerSpeed *= 0.5f; } @@ -90,7 +112,9 @@ public: vkDestroyDescriptorSetLayout(device, compute.descriptorSetLayout, nullptr); vkDestroyFence(device, compute.fence, nullptr); vkDestroyCommandPool(device, compute.commandPool, nullptr); - uniformDataCompute.destroy(); + compute.uniformBuffer.destroy(); + compute.storageBuffers.spheres.destroy(); + compute.storageBuffers.planes.destroy(); textureLoader->destroyTexture(textureComputeTarget); } @@ -259,15 +283,113 @@ public: vkEndCommandBuffer(compute.commandBuffer); } + uint32_t currentId = 0; // Id used to identify objects by the ray tracing shader + + Sphere newSphere(glm::vec3 pos, float radius, glm::vec3 diffuse, float specular) + { + Sphere sphere; + sphere.id = currentId++; + sphere.pos = pos; + sphere.radius = radius; + sphere.diffuse = diffuse; + sphere.specular = specular; + return sphere; + } + + Plane newPlane(glm::vec3 normal, float distance, glm::vec3 diffuse, float specular) + { + Plane plane; + plane.id = currentId++; + plane.normal = normal; + plane.distance = distance; + plane.diffuse = diffuse; + plane.specular = specular; + return plane; + } + + // Setup and fill the compute shader storage buffers containing primitives for the raytraced scene + void prepareStorageBuffers() + { + // Spheres + std::vector spheres; + spheres.push_back(newSphere(glm::vec3(1.75f, -0.5f, 0.0f), 1.0f, glm::vec3(0.0f, 1.0f, 0.0f), 32.0f)); + spheres.push_back(newSphere(glm::vec3(0.0f, 1.0f, -0.5f), 1.0f, glm::vec3(0.65f, 0.77f, 0.97f), 32.0f)); + spheres.push_back(newSphere(glm::vec3(-1.75f, -0.75f, -0.5f), 1.25f, glm::vec3(0.9f, 0.76f, 0.46f), 32.0f)); +// spheres.push_back(newSphere(glm::vec3(-2.25f, -1.0f, 0.5f), 1.0f, glm::vec3(1.0f, 0.32f, 0.36f), 32.0f)); + //spheres.push_back(newSphere(glm::vec3(-2.25f, 1.0f, 0.0f), 1.0f, glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(2.0f))); + //spheres.push_back(newSphere(glm::vec3(0.f, 2.5f, 0.0f), 1.0f, glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(2.0f))); + //spheres.push_back(newSphere(glm::vec3(2.25f, 1.0f, 0.0f), 1.0f, glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(2.0f))); + VkDeviceSize storageBufferSize = spheres.size() * sizeof(Sphere); + + // Stage + vk::Buffer stagingBuffer; + + vulkanDevice->createBuffer( + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &stagingBuffer, + storageBufferSize, + spheres.data()); + + vulkanDevice->createBuffer( + // The SSBO will be used as a storage buffer for the compute pipeline and as a vertex buffer in the graphics pipeline + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &compute.storageBuffers.spheres, + storageBufferSize); + + // Copy to staging buffer + VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + VkBufferCopy copyRegion = {}; + copyRegion.size = storageBufferSize; + vkCmdCopyBuffer(copyCmd, stagingBuffer.buffer, compute.storageBuffers.spheres.buffer, 1, ©Region); + VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); + + stagingBuffer.destroy(); + + // Planes + std::vector planes; + const float roomDim = 4.0f; + planes.push_back(newPlane(glm::vec3(0.0f, 1.0f, 0.0f), roomDim, glm::vec3(1.0f), 32.0f)); + planes.push_back(newPlane(glm::vec3(0.0f, -1.0f, 0.0f), roomDim, glm::vec3(1.0f), 32.0f)); + planes.push_back(newPlane(glm::vec3(0.0f, 0.0f, 1.0f), roomDim, glm::vec3(1.0f), 32.0f)); + planes.push_back(newPlane(glm::vec3(0.0f, 0.0f, -1.0f), roomDim, glm::vec3(0.0f), 32.0f)); + planes.push_back(newPlane(glm::vec3(-1.0f, 0.0f, 0.0f), roomDim, glm::vec3(1.0f, 0.0f, 0.0f), 32.0f)); + planes.push_back(newPlane(glm::vec3(1.0f, 0.0f, 0.0f), roomDim, glm::vec3(0.0f, 1.0f, 0.0f), 32.0f)); + storageBufferSize = planes.size() * sizeof(Plane); + + // Stage + vulkanDevice->createBuffer( + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &stagingBuffer, + storageBufferSize, + planes.data()); + + vulkanDevice->createBuffer( + // The SSBO will be used as a storage buffer for the compute pipeline and as a vertex buffer in the graphics pipeline + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &compute.storageBuffers.planes, + storageBufferSize); + + // Copy to staging buffer + copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + copyRegion.size = storageBufferSize; + vkCmdCopyBuffer(copyCmd, stagingBuffer.buffer, compute.storageBuffers.planes.buffer, 1, ©Region); + VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); + + stagingBuffer.destroy(); + } + void setupDescriptorPool() { std::vector poolSizes = { - vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), - // Graphics pipeline uses image samplers for display - vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4), - // Compute pipeline uses storage images image loads and stores - vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1), + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), // Compute UBO + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4), // Graphics image samplers + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1), // Storage image for ray traced image output + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2), // Storage buffer for the scene primitives }; VkDescriptorPoolCreateInfo descriptorPoolInfo = @@ -426,16 +548,26 @@ public: vkGetDeviceQueue(device, vulkanDevice->queueFamilyIndices.compute, 0, &compute.queue); std::vector setLayoutBindings = { - // Binding 0 : Sampled image (write) + // Binding 0: Storage image (raytraced output) vkTools::initializers::descriptorSetLayoutBinding( VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT, 0), - // Binding 1 : Uniform buffer block + // Binding 1: Uniform buffer block vkTools::initializers::descriptorSetLayoutBinding( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, - 1) + 1), + // Binding 1: Shader storage buffer for the spheres + vkTools::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_SHADER_STAGE_COMPUTE_BIT, + 2), + // Binding 1: Shader storage buffer for the planes + vkTools::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_SHADER_STAGE_COMPUTE_BIT, + 3) }; VkDescriptorSetLayoutCreateInfo descriptorLayout = @@ -462,18 +594,30 @@ public: std::vector computeWriteDescriptorSets = { - // Binding 0 : Output storage image + // Binding 0: Output storage image vkTools::initializers::writeDescriptorSet( compute.descriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0, &textureComputeTarget.descriptor), - // Binding 1 : Uniform buffer block + // Binding 1: Uniform buffer block vkTools::initializers::writeDescriptorSet( compute.descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, - &uniformDataCompute.descriptor) + &compute.uniformBuffer.descriptor), + // Binding 2: Shader storage buffer for the spheres + vkTools::initializers::writeDescriptorSet( + compute.descriptorSet, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 2, + &compute.storageBuffers.spheres.descriptor), + // Binding 2: Shader storage buffer for the planes + vkTools::initializers::writeDescriptorSet( + compute.descriptorSet, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 3, + &compute.storageBuffers.planes.descriptor) }; vkUpdateDescriptorSets(device, computeWriteDescriptorSets.size(), computeWriteDescriptorSets.data(), 0, NULL); @@ -517,22 +661,24 @@ public: // Compute shader parameter uniform buffer block vulkanDevice->createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformDataCompute, - sizeof(uboCompute)); + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &compute.uniformBuffer, + sizeof(compute.ubo)); updateUniformBuffers(); } void updateUniformBuffers() { - uboCompute.lightPos.x = 0.0f + sin(glm::radians(timer * 360.0f)) * 2.0f; - uboCompute.lightPos.y = 5.0f; - uboCompute.lightPos.z = 1.0f; - uboCompute.lightPos.z = 0.0f + cos(glm::radians(timer * 360.0f)) * 2.0f; - VK_CHECK_RESULT(uniformDataCompute.map()); - memcpy(uniformDataCompute.mapped, &uboCompute, sizeof(uboCompute)); - uniformDataCompute.unmap(); + compute.ubo.lightPos.x = 0.0f + sin(glm::radians(timer * 360.0f)) * cos(glm::radians(timer * 360.0f)) * 2.0f; + compute.ubo.lightPos.y = 0.0f + sin(glm::radians(timer * 360.0f)) * 2.0f; + compute.ubo.lightPos.z = 0.0f + cos(glm::radians(timer * 360.0f)) * 2.0f; + + compute.ubo.lightPos.y = 2.0f; + + VK_CHECK_RESULT(compute.uniformBuffer.map()); + memcpy(compute.uniformBuffer.mapped, &compute.ubo, sizeof(compute.ubo)); + compute.uniformBuffer.unmap(); } void draw() @@ -547,7 +693,7 @@ public: VulkanExampleBase::submitFrame(); // Submit compute commands - // Use a fence to ensure that compute command buffer has finished executin before using it again + // Use a fence to ensure that compute command buffer has finished executing before using it again vkWaitForFences(device, 1, &compute.fence, VK_TRUE, UINT64_MAX); vkResetFences(device, 1, &compute.fence); @@ -561,6 +707,7 @@ public: void prepare() { VulkanExampleBase::prepare(); + prepareStorageBuffers(); prepareUniformBuffers(); prepareTextureTarget(&textureComputeTarget, TEX_DIM, TEX_DIM, VK_FORMAT_R8G8B8A8_UNORM); setupDescriptorSetLayout(); @@ -585,7 +732,7 @@ public: virtual void viewChanged() { - uboCompute.aspectRatio = (float)width / (float)height; + compute.ubo.aspectRatio = (float)width / (float)height; updateUniformBuffers(); } };