diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e28a3d23e7b0ada5040a5ee01fb8d13d855962..d8182d066de5ab2e2ebfa861cf69aca8aa3226f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ project(vkcv) # cmake options option(BUILD_MODULES "Enables building VkCV as shared libraries" ON) -option(BUILD_PROJECTS "Enables building the VkCV projects" ON) +option(BUILD_PROJECTS "Enables building the VkCV projects" OFF) option(BUILD_CLANG_FORMAT "Enables formatting the source code" OFF) option(BUILD_DOXYGEN_DOCS "Enables building the VkCV doxygen documentation" OFF) option(BUILD_SHARED "Enables building VkCV as shared libraries" OFF) @@ -97,7 +97,7 @@ add_compile_definitions(${vkcv_definitions}) # check if the framework is used from a parent scope get_directory_property(vkcv_parent_scope PARENT_DIRECTORY) -if (BUILD_MODULES) +if ((BUILD_MODULES) AND (EXISTS ${PROJECT_SOURCE_DIR}/modules)) message(STATUS "Modules: ON") # add modules as targets @@ -137,7 +137,7 @@ target_include_directories(vkcv BEFORE PUBLIC ${vkcv_include}) # link the framework using all required libraries target_link_libraries(vkcv ${vkcv_libraries}) -if (BUILD_PROJECTS) +if ((BUILD_PROJECTS) AND (EXISTS ${PROJECT_SOURCE_DIR}/projects)) message(STATUS "Projects: ON") # add sub-projects/examples as targets diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt deleted file mode 100644 index 1fffd2dab6cd34368d7140c857e7b885cea998cb..0000000000000000000000000000000000000000 --- a/projects/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ - -include(${vkcv_config_ext}/Project.cmake) - -# Add new projects/examples here: -add_subdirectory(bindless_textures) -add_subdirectory(fire_works) -add_subdirectory(first_triangle) -add_subdirectory(first_mesh) -add_subdirectory(first_scene) -add_subdirectory(head_demo) -add_subdirectory(indirect_dispatch) -add_subdirectory(indirect_draw) -add_subdirectory(mesh_shader) -add_subdirectory(particle_simulation) -add_subdirectory(path_tracer) -add_subdirectory(rtx_ambient_occlusion) -add_subdirectory(saf_r) -add_subdirectory(sph) -add_subdirectory(voxelization) -add_subdirectory(wobble_bobble) \ No newline at end of file diff --git a/projects/bindless_textures/.gitignore b/projects/bindless_textures/.gitignore deleted file mode 100644 index cd45650aee8ab49ad568556452dde2d9d51d5f13..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bindless_textures \ No newline at end of file diff --git a/projects/bindless_textures/CMakeLists.txt b/projects/bindless_textures/CMakeLists.txt deleted file mode 100644 index 86a93e04427d7ff103bda1dbd5a4602ff337d639..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(bindless_textures) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(bindless_textures src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(bindless_textures SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(bindless_textures vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg deleted file mode 100644 index 2217fb53744f9166232a40b78ee9518e04b0ded5..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f6c88f8f3facd9e91f8dd160bd8c4a602e433872ed18e08015a9fa9dfff889de -size 901465 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg deleted file mode 100644 index b8aa1533ae5a023a5fc8457f30ed60efe3bda32d..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:878b8fe4747d9ce693220edea1915de550e8f14d402d26a0915f162d40f84e91 -size 1763328 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg deleted file mode 100644 index 89789cba150eea7c7abbdc1851090f6021af978a..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e8300e1107bee7e681059d9da0a7e3ca422977e8b6f496e16452a4c94b3d385 -size 912347 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg deleted file mode 100644 index 3163d6391592ace10446cb71141a2192e63e9660..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:684426b49e841e267f12f06dc955b5b1d01b3ba3659bea0c5d73be889700929f -size 2336471 diff --git a/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg b/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg deleted file mode 100644 index 10e6ac33badf2a4795766a66546a62c67eb8b558..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d952ffb098faf9ac5eb25134eabac08f0c65d927a448b5e7b4f9c72510cfcbe0 -size 822659 diff --git a/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg b/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg deleted file mode 100644 index 2636039e272289c0fba3fa2d88a060b857501248..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 -size 1192476 diff --git a/projects/bindless_textures/resources/cube/cube.bin b/projects/bindless_textures/resources/cube/cube.bin deleted file mode 100644 index 3303cd8635848bee18e10ab8754d5e4e7218db92..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/cube.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 -size 840 diff --git a/projects/bindless_textures/resources/cube/cube.blend b/projects/bindless_textures/resources/cube/cube.blend deleted file mode 100644 index 62ccb2c742094bcfb5ed194ab905bffae86bfd65..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/cube.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 -size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.blend1 b/projects/bindless_textures/resources/cube/cube.blend1 deleted file mode 100644 index 13f21dcca218d7bc7a07a8a9682b5e1d9e607736..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/cube.blend1 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b -size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.glb b/projects/bindless_textures/resources/cube/cube.glb deleted file mode 100644 index 66a42c65e71dcf375e04cc378256024dd3c7834d..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/cube.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 -size 1194508 diff --git a/projects/bindless_textures/resources/cube/cube.gltf b/projects/bindless_textures/resources/cube/cube.gltf deleted file mode 100644 index 428176144843dd06c78fe1d11a6392a0ea02b22d..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/cube/cube.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac -size 2823 diff --git a/projects/bindless_textures/resources/shaders/shader.frag b/projects/bindless_textures/resources/shaders/shader.frag deleted file mode 100644 index c855eb407944c415dc4055716aa64a531c830ef3..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/shaders/shader.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_EXT_nonuniform_qualifier : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; -layout(location = 2) in flat int passTextureIndex; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform sampler textureSampler; -layout(set=0, binding=1) uniform texture2D materialTextures[]; - -void main() { - outColor = texture(sampler2D(materialTextures[nonuniformEXT(passTextureIndex)], textureSampler), passUV).rgb; -} \ No newline at end of file diff --git a/projects/bindless_textures/resources/shaders/shader.vert b/projects/bindless_textures/resources/shaders/shader.vert deleted file mode 100644 index 6bc918c6a186dcfb965719cd1e08cb448a49b44e..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/resources/shaders/shader.vert +++ /dev/null @@ -1,43 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; -layout(location = 2) out flat int passTextureIndex; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() -{ - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = inNormal; - passUV = inUV; - - passTextureIndex = (gl_VertexIndex / 4); - - /* - if(inNormal.x > 0.9) - passTextureIndex = 0; - - if(inNormal.x < -0.9) - passTextureIndex = 1; - - if(inNormal.y > 0.9) - passTextureIndex = 2; - - if(inNormal.y < -0.9) - passTextureIndex = 3; - - if(inNormal.z > 0.9) - passTextureIndex = 4; - - if(inNormal.z < -0.9) - passTextureIndex = 5; - */ -} \ No newline at end of file diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp deleted file mode 100644 index 42af6910cd0102f01df29d470269882ebd1cb0d0..0000000000000000000000000000000000000000 --- a/projects/bindless_textures/src/main.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "Bindless Textures"; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures &features) { - features.setShaderInputAttachmentArrayDynamicIndexing(true); - features.setShaderUniformTexelBufferArrayDynamicIndexing(true); - features.setShaderStorageTexelBufferArrayDynamicIndexing(true); - features.setShaderUniformBufferArrayNonUniformIndexing(true); - features.setShaderSampledImageArrayNonUniformIndexing(true); - features.setShaderStorageBufferArrayNonUniformIndexing(true); - features.setShaderStorageImageArrayNonUniformIndexing(true); - features.setShaderInputAttachmentArrayNonUniformIndexing(true); - features.setShaderUniformTexelBufferArrayNonUniformIndexing(true); - features.setShaderStorageTexelBufferArrayNonUniformIndexing(true); - - features.setDescriptorBindingUniformBufferUpdateAfterBind(true); - features.setDescriptorBindingSampledImageUpdateAfterBind(true); - features.setDescriptorBindingStorageImageUpdateAfterBind(true); - features.setDescriptorBindingStorageBufferUpdateAfterBind(true); - features.setDescriptorBindingUniformTexelBufferUpdateAfterBind(true); - features.setDescriptorBindingStorageTexelBufferUpdateAfterBind(true); - - features.setDescriptorBindingUpdateUnusedWhilePending(true); - features.setDescriptorBindingPartiallyBound(true); - features.setDescriptorBindingVariableDescriptorCount(true); - features.setRuntimeDescriptorArray(true); - } - ); - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, - features - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); - vkcv::Window& window = core.getWindow(windowHandle); - - vkcv::asset::Scene mesh; - - // TEST DATA - std::vector<vkcv::Image> texturesArray; - const std::string grassPaths[5] = { "resources/cube/Grass001_1K_AmbientOcclusion.jpg", - "resources/cube/Grass001_1K_Color.jpg", - "resources/cube/Grass001_1K_Displacement.jpg", - "resources/cube/Grass001_1K_Normal.jpg", - "resources/cube/Grass001_1K_Roughness.jpg" }; - - for (const auto &path : grassPaths) { - std::filesystem::path grassPath(path); - vkcv::asset::Texture grassTexture = vkcv::asset::loadTexture(grassPath); - - vkcv::Image texture = vkcv::image( - core, - vk::Format::eR8G8B8A8Srgb, - grassTexture.width, - grassTexture.height - ); - - texture.fill(grassTexture.data.data()); - texturesArray.push_back(texture); - } - - const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; - int result = vkcv::asset::loadScene(path, mesh); - - if (result == 1) { - std::cout << "Mesh loading successful!" << std::endl; - } else { - std::cerr << "Mesh loading failed: " << result << std::endl; - return 1; - } - - assert(!mesh.vertexGroups.empty()); - auto vertexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::VERTEX, - mesh.vertexGroups[0].vertexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - - vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); - - auto indexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::INDEX, - mesh.vertexGroups[0].indexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - - indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); - - vkcv::PassHandle firstMeshPass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - if (!firstMeshPass) { - std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ShaderProgram firstMeshProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compileProgram(firstMeshProgram, { - { vkcv::ShaderStage::VERTEX, "resources/shaders/shader.vert" }, - { vkcv::ShaderStage::FRAGMENT, "resources/shaders/shader.frag" } - }, nullptr); - - const auto vertexBufferBindings = vkcv::asset::loadVertexBufferBindings( - mesh.vertexGroups[0].vertexBuffer.attributes, - vertexBuffer.getHandle(), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL, - vkcv::asset::PrimitiveType::TEXCOORD_0 - } - ); - - std::vector<vkcv::VertexBinding> bindings = vkcv::createVertexBindings( - firstMeshProgram.getVertexAttachments() - ); - - const vkcv::VertexLayout firstMeshLayout { bindings }; - const std::unordered_map<uint32_t, vkcv::DescriptorBinding> &descriptorBindings = firstMeshProgram.getReflectedDescriptors().at(0); - - std::unordered_map<uint32_t, vkcv::DescriptorBinding> adjustedBindings = descriptorBindings; - adjustedBindings[1].descriptorCount = 6; - - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(adjustedBindings); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); - - vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - firstMeshProgram, - firstMeshPass, - { firstMeshLayout }, - { descriptorSetLayout } - ) - ); - - if (!firstMeshPipeline) { - std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - if (mesh.textures.empty()) { - std::cerr << "Error. No textures found. Exiting." << std::endl; - return EXIT_FAILURE; - } - - { - vkcv::asset::Texture &tex = mesh.textures[0]; - vkcv::Image texture = vkcv::image(core, vk::Format::eR8G8B8A8Srgb, tex.w, tex.h); - texture.fill(tex.data.data()); - texturesArray.push_back(texture); - } - - auto downsampleStream = core.createCommandStream(vkcv::QueueType::Graphics); - - for (auto& texture : texturesArray) { - texture.recordMipChainGeneration(downsampleStream, core.getDownsampler()); - } - - core.submitCommandStream(downsampleStream, false); - - vkcv::SamplerHandle sampler = vkcv::samplerLinear(core); - vkcv::DescriptorWrites setWrites; - - for(uint32_t i = 0; i < 6; i++) - { - - setWrites.writeSampledImage( - 1, - texturesArray[i].getHandle(), - 0, - false, - i - ); - } - - setWrites.writeSampler(0, sampler); - - core.writeDescriptorSet(descriptorSet, setWrites); - - vkcv::ImageHandle depthBuffer; - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::VertexData vertexData (vertexBufferBindings); - vertexData.setIndexBuffer(indexBuffer.getHandle()); - vertexData.setCount(mesh.vertexGroups[0].numIndices); - - vkcv::InstanceDrawcall drawcall (vertexData); - drawcall.useDescriptorSet(0, descriptorSet); - - vkcv::camera::CameraManager cameraManager(window); - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(0, 0, -3)); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - (swapchainHeight != core.getImageHeight(depthBuffer))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - } - - cameraManager.update(dt); - glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - - vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); - pushConstants.appendDrawcall(mvp); - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - core.recordDrawcallsToCmdStream( - cmdStream, - firstMeshPipeline, - pushConstants, - { drawcall }, - renderTargets, - windowHandle - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/fire_works/.gitignore b/projects/fire_works/.gitignore deleted file mode 100644 index a991f1c077c11db780beb6e3d01c5bd561336690..0000000000000000000000000000000000000000 --- a/projects/fire_works/.gitignore +++ /dev/null @@ -1 +0,0 @@ -fire_works diff --git a/projects/fire_works/CMakeLists.txt b/projects/fire_works/CMakeLists.txt deleted file mode 100644 index 7f9fd1fdd30bff0b331138821f10035f4b7dc64d..0000000000000000000000000000000000000000 --- a/projects/fire_works/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(fire_works) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(fire_works - src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(fire_works SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_camera_include} - ${vkcv_gui_include} - ${vkcv_shader_compiler_include} - ${vkcv_effects_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(fire_works - vkcv - vkcv_camera - vkcv_gui - vkcv_shader_compiler - vkcv_effects) diff --git a/projects/fire_works/shaders/add.comp b/projects/fire_works/shaders/add.comp deleted file mode 100644 index 737a1f3fd69e237f7692be8a6b36b1e14f1fd50a..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/add.comp +++ /dev/null @@ -1,64 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) uniform texture2D voxelTexture; -layout(set=0, binding=1) uniform sampler voxelSampler; - -layout(set=0, binding=2, rgba16f) restrict readonly uniform image2D inParticles; -layout(set=0, binding=3, rgba16f) restrict readonly uniform image2D inSmoke; -layout(set=0, binding=4, rgba16f) restrict readonly uniform image2D inTrails; -layout(set=0, binding=5, rgba16f) restrict writeonly uniform image2D outImage; - -layout(set=1, binding=0, std430) readonly buffer randomBuffer { - float randomData []; -}; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -#include "physics.inc" -#include "smoke.inc" - -#define NUM_VOXEL_SAMPLES 32 - -shared vec2 sc_data [NUM_VOXEL_SAMPLES]; - -void main() { - const float localRadian = 0.25f * pi * randomData[gl_LocalInvocationIndex % randomData.length()]; - - sc_data[gl_LocalInvocationIndex % NUM_VOXEL_SAMPLES] = vec2( - sin(localRadian), cos(localRadian) - ); - - memoryBarrierShared(); - barrier(); - - const ivec2 res = imageSize(outImage); - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, res))){ - return; - } - - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - - vec4 outParticles = imageLoad(inParticles, uv); - vec4 outSmoke = imageLoad(inSmoke, uv); - vec4 outTrails = imageLoad(inTrails, uv); - - vec2 pos = (vec2(uv) + vec2(0.5f)) / vec2(res); - - vec4 outSamples = texture(sampler2D(voxelTexture, voxelSampler), pos); - - vec4 result = vec4(0.0f); - - result = smokeBlend(result, outParticles); - result = smokeBlend(result, outTrails); - result = smokeBlend(result, outSmoke); - result = smokeBlend(result, outSamples * 0.1f); - - result.r = clamp(result.r, 0, 1); - result.g = clamp(result.g, 0, 1); - result.b = clamp(result.b, 0, 1); - result.a = clamp(result.a, 0, 1); - - imageStore(outImage, uv, result); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/clear.comp b/projects/fire_works/shaders/clear.comp deleted file mode 100644 index 4668538c4a38aefec868f1817a126b5278f8fd78..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/clear.comp +++ /dev/null @@ -1,25 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "physics.inc" -#include "voxel.inc" - -layout(set=0, binding=0, r32ui) restrict writeonly uniform uimage3D voxelRed; -layout(set=0, binding=1, r32ui) restrict writeonly uniform uimage3D voxelGreen; -layout(set=0, binding=2, r32ui) restrict writeonly uniform uimage3D voxelBlue; -layout(set=0, binding=3, r32ui) restrict writeonly uniform uimage3D voxelDensity; - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -void main() { - if(any(greaterThanEqual(gl_GlobalInvocationID.xyz, imageSize(voxelDensity)))){ - return; - } - - ivec3 pos = ivec3(gl_GlobalInvocationID.xyz); - - voxel_write(voxelRed, pos, 0.0f); - voxel_write(voxelGreen, pos, 0.0f); - voxel_write(voxelBlue, pos, 0.0f); - voxel_write(voxelDensity, pos, mediumDensity); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/event.inc b/projects/fire_works/shaders/event.inc deleted file mode 100644 index a2ab170c0894da68638b0e61e4af90a7a5fcdd64..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/event.inc +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef EVENT_INC -#define EVENT_INC - -struct event_t { - vec3 direction; - float startTime; - vec3 color; - float velocity; - - uint count; - uint index; - uint parent; - uint continuous; - - float lifetime; - float mass; - float size; - uint contCount; -}; - -#endif // EVENT_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/fluid.comp b/projects/fire_works/shaders/fluid.comp deleted file mode 100644 index 076a280739e542c0579a7b80eaeaf4993df13edf..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/fluid.comp +++ /dev/null @@ -1,80 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -#include "physics.inc" -#include "voxel.inc" - -layout(set=0, binding=0) uniform texture3D voxelTexture; -layout(set=0, binding=1) uniform sampler voxelSampler; -layout(set=0, binding=2, rgba16) restrict writeonly uniform image3D fluidImage; - -vec4 getDataFrom(vec3 position, vec3 offset) { - return texture( - sampler3D( - voxelTexture, - voxelSampler - ), - position + offset - ); -} - -shared vec4 cachedData [4][4][4]; - -void storeCachedData(vec3 position) { - uvec3 localId = gl_LocalInvocationID; - cachedData[localId.x][localId.y][localId.z] = getDataFrom(position, vec3(0)); -} - -vec4 getCachedData() { - uvec3 localId = gl_LocalInvocationID; - return cachedData[localId.x][localId.y][localId.z]; -} - -vec4 loadCachedData(vec3 position, ivec3 offset, ivec3 size) { - uvec3 localId = gl_LocalInvocationID; - ivec3 index = ivec3(localId) + offset; - - // TOO SPECIAL FOR GPU TO WORK..! - //if ((any(lessThan(index, ivec3(0)))) || (any(greaterThan(index, ivec3(gl_WorkGroupSize))))) { - return getDataFrom(position, vec3(offset) / vec3(size)); - //} else { - // return cachedData[index.x][index.y][index.z]; - //} -} - -void main() { - uvec3 id = gl_GlobalInvocationID; - ivec3 size = imageSize(fluidImage); - - if (any(greaterThanEqual(id, size))) { - return; - } - - vec3 position = (vec3(id) + vec3(0.5f)) / vec3(size); - - storeCachedData(position); - memoryBarrierShared(); - barrier(); - - vec4 extData [6]; - - extData[0] = loadCachedData(position, ivec3(+1, 0, 0), size); - extData[1] = loadCachedData(position, ivec3(-1, 0, 0), size); - extData[2] = loadCachedData(position, ivec3(0, +1, 0), size); - extData[3] = loadCachedData(position, ivec3(0, -1, 0), size); - extData[4] = loadCachedData(position, ivec3(0, 0, +1), size); - extData[5] = loadCachedData(position, ivec3(0, 0, -1), size); - - vec4 data = vec4(0); - - for (uint i = 0; i < 6; i++) { - data += extData[i]; - } - - data = mix(getCachedData(), (data / 6), flowRate); - - imageStore(fluidImage, ivec3(id), data); -} diff --git a/projects/fire_works/shaders/generation.comp b/projects/fire_works/shaders/generation.comp deleted file mode 100644 index eb585236d993099350d0c0e6b97adcbfd28fdf57..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/generation.comp +++ /dev/null @@ -1,179 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "particle.inc" - -layout(set=0, binding=0, std430) buffer particleBuffer { - particle_t particles []; -}; - -layout(set=0, binding=1, std430) readonly buffer particleBufferCopy { - particle_t particlesCopy []; -}; - -layout(set=1, binding=0, std430) readonly buffer randomBuffer { - float randomData []; -}; - -#include "event.inc" - -layout(set=1, binding=1, std430) buffer eventBuffer { - event_t events []; -}; - -layout(set=1, binding=2, std430) buffer startIndexBuffer { - uint startIndex []; -}; - -#include "smoke.inc" - -layout(set=2, binding=0, std430) writeonly buffer smokeBuffer { - smoke_t smokes []; -}; - -layout(set=2, binding=1, std430) buffer smokeIndexBuffer { - uint smokeIndex; - uint trailIndex; - uint pointIndex; -}; - -#include "trail.inc" - -layout(set=3, binding=0, std430) writeonly buffer trailBuffer { - trail_t trails []; -}; - -#include "point.inc" - -layout(set=3, binding=1, std430) readonly buffer pointBuffer { - point_t points []; -}; - -layout( push_constant ) uniform constants{ - float t; - float dt; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= particles.length()) { - return; - } - - float lifetime = particles[id].lifetime; - - if (lifetime > 0.0f) { - return; - } - - uint event_id = events.length(); - uint index = 0; - - for (uint i = 0; i < events.length(); i++) { - const float start = events[i].startTime; - - if ((events[i].continuous < 1) && (t < start)) { - continue; - } - - index = atomicAdd(events[i].index, 1); - - if (events[i].continuous < 1) { - if (events[i].count > index) { - event_id = i; - break; - } else { - atomicAdd(events[i].index, -1); - } - } else { - if (events[i].continuous > index){ - event_id = i; - break; - } else { - if (events[i].contCount > 0) { - atomicAdd(events[i].contCount, -1); - events[i].index = 0; - } - - atomicAdd(events[i].index, -1); - } - } - } - - if (event_id >= events.length()) { - return; - } - - lifetime = events[event_id].lifetime * (1.0f + 0.1f * randomData[(id + 1) % randomData.length()]); - - vec3 direction; - if (dot(events[event_id].direction, events[event_id].direction) <= 0.0f) { - direction = vec3( - randomData[(id * 3 + 0) % randomData.length()], - randomData[(id * 3 + 1) % randomData.length()], - randomData[(id * 3 + 2) % randomData.length()] - ); - } else { - direction = events[event_id].direction; - } - - vec3 color = normalize(events[event_id].color); - const float v = events[event_id].velocity; - - vec3 velocity = vec3(0.0f); - float size = events[event_id].size; - - const uint pid = events[event_id].parent; - - if (pid < events.length()) { - const uint spawnCount = events[pid].count; - const uint spawnId = startIndex[pid] + (id % spawnCount); - - if (spawnId < particlesCopy.length()) { - particles[id].position = particlesCopy[spawnId].position; - velocity += particlesCopy[spawnId].velocity; - size = particlesCopy[spawnId].size; - } - } - - if ((0 == index) && (events[event_id].continuous < 1)) { - const uint sid = atomicAdd(smokeIndex, 1) % smokes.length(); - - smokes[sid].position = particles[id].position; - smokes[sid].size = size * (1.0f + friction); - smokes[sid].velocity = velocity; - smokes[sid].scaling = v; - smokes[sid].color = mix(color, vec3(1.0f), 0.5f); - smokes[sid].eventID = event_id; - } - - velocity += normalize(direction) * v * (1.0f + 0.1f * randomData[(id + 2) % randomData.length()]);; - - const float split = pow(1.0f / events[event_id].count, 1.0f / 3.0f); - - particles[id].lifetime = lifetime; - particles[id].velocity = velocity; - particles[id].size = size * split; - particles[id].color = color; - particles[id].mass = events[event_id].mass / events[event_id].count; - particles[id].eventId = event_id; - - { - const uint tid = atomicAdd(trailIndex, 1) % trails.length(); - const uint trailLen = 96 + int(randomData[(tid + id) % randomData.length()] * 32); - - const uint startIndex = atomicAdd(pointIndex, trailLen) % points.length(); - - trails[tid].particleIndex = id; - trails[tid].startIndex = startIndex; - trails[tid].endIndex = (startIndex + trailLen - 1) % points.length(); - trails[tid].useCount = 0; - trails[tid].color = mix(color, vec3(1.0f), 0.75f); - trails[tid].lifetime = lifetime + (dt * trailLen) * 0.5f; - } -} diff --git a/projects/fire_works/shaders/motion.comp b/projects/fire_works/shaders/motion.comp deleted file mode 100644 index 51d6fc5f60f2eff380376fead6cc189af68b52e6..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/motion.comp +++ /dev/null @@ -1,49 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "particle.inc" - -layout(set=0, binding=0, std430) coherent buffer particleBuffer { - particle_t particles []; -}; - -layout( push_constant ) uniform constants{ - float t; - float dt; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= particles.length()) { - return; - } - - vec3 position = particles[id].position; - float lifetime = particles[id].lifetime; - vec3 velocity = particles[id].velocity; - - if (lifetime > dt) { - lifetime -= dt; - } else { - lifetime = 0.0f; - } - - const float fading = 1.0f / (1.0f + friction); - - position = position + velocity * dt; - - if (particles[id].mass > 0){ - velocity = velocity * fading + vec3(0.0f, -g, 0.0f) * dt; - } else { - velocity = velocity * fading; - } - - particles[id].position = position; - particles[id].lifetime = lifetime; - particles[id].velocity = velocity; -} diff --git a/projects/fire_works/shaders/particle.frag b/projects/fire_works/shaders/particle.frag deleted file mode 100644 index 173c83ef5d7a79bfd8446c5586b7a2f487fe7546..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/particle.frag +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -layout(location = 0) in vec2 passPos; -layout(location = 1) in flat vec3 passColor; -layout(location = 2) in flat float passLifetime; - -layout(location = 0) out vec4 outColor; - -void main() { - if (passLifetime <= 0.0f) { - discard; - } - - const float value = length(passPos); - - if (value < 0.5f) { - outColor = vec4(passColor, 1.0f - max(value * 2.0f, 0.0f)); - } else { - discard; - } -} \ No newline at end of file diff --git a/projects/fire_works/shaders/particle.inc b/projects/fire_works/shaders/particle.inc deleted file mode 100644 index 488c9349d72ac04d48e523d5c9a97057bdfb1f78..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/particle.inc +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PARTICLE_INC -#define PARTICLE_INC - -struct particle_t { - vec3 position; - float lifetime; - vec3 velocity; - float size; - vec3 color; - float mass; - vec3 pad0; - uint eventId; -}; - -#endif // PARTICLE_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/particle.vert b/projects/fire_works/shaders/particle.vert deleted file mode 100644 index ff0e862ebcf0f66c3412e9ce04b610cea760151d..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/particle.vert +++ /dev/null @@ -1,40 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -#include "particle.inc" - -layout(set=0, binding=0, std430) readonly buffer particleBuffer { - particle_t particles []; -}; - -layout(location = 0) in vec2 vertexPos; - -layout(location = 0) out vec2 passPos; -layout(location = 1) out flat vec3 passColor; -layout(location = 2) out flat float passLifetime; - -layout( push_constant ) uniform constants{ - mat4 mvp; - uint width; - uint height; -}; - -void main() { - vec3 position = particles[gl_InstanceIndex].position; - float lifetime = particles[gl_InstanceIndex].lifetime; - float size = particles[gl_InstanceIndex].size; - vec3 color = particles[gl_InstanceIndex].color; - - if (width > height) { - passPos = vertexPos * vec2(1.0f * width / height, 1.0f); - } else { - passPos = vertexPos * vec2(1.0f, 1.0f * height / width); - } - - passColor = color; - passLifetime = lifetime; - - // align particle to face camera - gl_Position = mvp * vec4(position, 1); // transform position into projected view space - gl_Position.xy += vertexPos * size * 2.0f; // move position directly in view space -} \ No newline at end of file diff --git a/projects/fire_works/shaders/physics.inc b/projects/fire_works/shaders/physics.inc deleted file mode 100644 index e14c62e33a6fd42ebfa8d31591394989de68a8d2..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/physics.inc +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PHYSICS_INC -#define PHYSICS_INC - -const float pi = 3.14159f; - -const float g = 9.81f; -const float friction = 0.004f; - -const float flowRate = 0.75f; -const float mediumDensity = 0.0002f; -const float trailWidth = 0.25f; - -#endif // PHYSICS_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/point.inc b/projects/fire_works/shaders/point.inc deleted file mode 100644 index 54663c1e2eae4c641fbe5485d4c0ac41cb323df6..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/point.inc +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef POINT_INC -#define POINT_INC - -struct point_t { - vec3 position; - float size; - vec3 velocity; - float scaling; -}; - -#endif // POINT_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/sample.comp b/projects/fire_works/shaders/sample.comp deleted file mode 100644 index 1eef49df639cfbc9f35c53ace21b1ce50ab62459..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/sample.comp +++ /dev/null @@ -1,39 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "voxel.inc" -#include "smoke.inc" - -layout(set=0, binding=0, rgba16) restrict readonly uniform image3D voxelImage; -layout(set=1, binding=0, rgba16f) restrict writeonly uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main() { - const ivec2 res = imageSize(outImage); - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, res))){ - return; - } - - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - - const ivec3 voxelRes = imageSize(voxelImage); - - vec4 voxel = vec4(0.0f); - - for (int i = 0; i < voxelRes.z; i++) { - const ivec3 voxelPos = ivec3(uv, i); - - vec4 data = imageLoad(voxelImage, voxelPos); - - voxel = smokeBlend(voxel, data); - } - - voxel.r = clamp(voxel.r, 0, 1); - voxel.g = clamp(voxel.g, 0, 1); - voxel.b = clamp(voxel.b, 0, 1); - voxel.a = clamp(voxel.a, 0, 1); - - imageStore(outImage, uv, voxel); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/scale.comp b/projects/fire_works/shaders/scale.comp deleted file mode 100644 index 44cfb8e48ad078f5ee8f63785b513a20f27ef542..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/scale.comp +++ /dev/null @@ -1,40 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "smoke.inc" - -layout(set=0, binding=0, std430) buffer smokeBuffer { - smoke_t smokes []; -}; - -layout( push_constant ) uniform constants{ - float t; - float dt; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= smokes.length()) { - return; - } - - vec3 position = smokes[id].position; - float size = smokes[id].size; - vec3 velocity = smokes[id].velocity; - - const float scaling = smokes[id].scaling; - const float fading = 1.0f / (1.0f + friction); - - position = position + velocity * dt; - velocity = velocity * fading + vec3(0.0f, 0.2f, 0.0f) * dt; //smoke is lighter than air right? + vec3(0.0f, -g, 0.0f) * dt; - size = size + scaling * dt; - - smokes[id].position = position; - smokes[id].size = size; - smokes[id].velocity = velocity; -} diff --git a/projects/fire_works/shaders/smoke.frag b/projects/fire_works/shaders/smoke.frag deleted file mode 100644 index 8ded98ac5fbae554959a83df5bbf7451d286e832..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/smoke.frag +++ /dev/null @@ -1,57 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "physics.inc" -#include "smoke.inc" - -layout(location = 0) in vec3 passPos; -layout(location = 1) in vec3 passDir; -layout(location = 2) in vec3 passColor; -layout(location = 3) in float passDensity; -layout(location = 4) in flat int passSmokeIndex; - -layout(location = 0) out vec4 outColor; - -layout(set=1, binding=0, std430) readonly buffer randomBuffer { - float randomData []; -}; - -#define NUM_SMOKE_SAMPLES 16 - -void main() { - if (passDensity <= mediumDensity) { - discard; - } - - vec3 start = passPos; - vec3 end = start + normalize(passDir) * 3.5f; - - vec4 result = vec4(0); - - for (uint i = 0; i < NUM_SMOKE_SAMPLES; i++) { - vec3 position = ( - end + (start - end) * i / (NUM_SMOKE_SAMPLES - 1) - ); - - vec4 data = vec4(passColor, passDensity); - - float fallOff = max(1.0f - length(position), 0.0f); - - const uint randomIndex = (passSmokeIndex * NUM_SMOKE_SAMPLES + i) % randomData.length(); - const float alpha = (1.0f + randomData[randomIndex] * 0.1f) * data.a * fallOff; - - result = smokeBlend(result, vec4(data.rgb, alpha)); - } - - result.r = clamp(result.r, 0, 1); - result.g = clamp(result.g, 0, 1); - result.b = clamp(result.b, 0, 1); - result.a = clamp(result.a, 0, 1); - - if (result.a < 1.0f) { - outColor = result; - } else { - discard; - } -} \ No newline at end of file diff --git a/projects/fire_works/shaders/smoke.inc b/projects/fire_works/shaders/smoke.inc deleted file mode 100644 index 8886a788273cd5fa5c871749e0c9012f2722ed41..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/smoke.inc +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef SMOKE_INC -#define SMOKE_INC - -struct smoke_t { - vec3 position; - float size; - vec3 velocity; - float scaling; - vec3 color; - uint eventID; -}; - -float smokeDensity(float size) { - if (size > 0.0f) { - return 0.025f / size; - } else { - return 0.0f; - } -} - -vec4 smokeBlend(vec4 dst, vec4 src) { - const float f = max(1.0f - dst.a, 0.0f); - const float a = clamp(0.0f, 1.0f, src.a); - - return vec4( - dst.rgb + src.rgb * a * f, - dst.a + a * f - ); -} - -#endif // SMOKE_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/smoke.vert b/projects/fire_works/shaders/smoke.vert deleted file mode 100644 index 634117f79789797cd68e00cac3dbd59fb6515f79..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/smoke.vert +++ /dev/null @@ -1,38 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -#include "smoke.inc" - -layout(set=0, binding=0, std430) readonly buffer smokeBuffer { - smoke_t smokes []; -}; - -layout(location = 0) in vec3 vertexPos; - -layout(location = 0) out vec3 passPos; -layout(location = 1) out vec3 passDir; -layout(location = 2) out vec3 passColor; -layout(location = 3) out float passDensity; -layout(location = 4) out flat int passSmokeIndex; - -layout( push_constant ) uniform constants{ - mat4 mvp; - vec3 camera; -}; - -void main() { - vec3 position = smokes[gl_InstanceIndex].position; - float size = smokes[gl_InstanceIndex].size; - vec3 color = smokes[gl_InstanceIndex].color; - - vec3 pos = position + vertexPos * size; - - passPos = vertexPos; - passDir = pos - camera; - passColor = color; - passDensity = smokeDensity(size); - passSmokeIndex = gl_InstanceIndex; - - // transform position into projected view space - gl_Position = mvp * vec4(pos, 1); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/tonemapping.comp b/projects/fire_works/shaders/tonemapping.comp deleted file mode 100644 index 5e6cc8412a77939888fc8e961ea5e9ef29534a81..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/tonemapping.comp +++ /dev/null @@ -1,21 +0,0 @@ -#version 440 - -layout(set=0, binding=0, rgba16f) readonly uniform image2D inImage; -layout(set=0, binding=1, rgba8) writeonly uniform image2D outImage; - - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main() { - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){ - return; - } - - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - vec3 linearColor = imageLoad(inImage, uv).rgb; - - vec3 tonemapped = linearColor / (dot(linearColor, vec3(0.21, 0.71, 0.08)) + 1); // reinhard tonemapping - vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); - - imageStore(outImage, uv, vec4(gammaCorrected, 0.f)); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/trail.comp b/projects/fire_works/shaders/trail.comp deleted file mode 100644 index 8e811a5251948e979fcacc0d2c1e95e27411fa87..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/trail.comp +++ /dev/null @@ -1,98 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "particle.inc" - -layout(set=0, binding=0, std430) readonly buffer particleBuffer { - particle_t particles []; -}; - -#include "trail.inc" - -layout(set=1, binding=0, std430) coherent buffer trailBuffer { - trail_t trails []; -}; - -#include "point.inc" - -layout(set=1, binding=1, std430) buffer pointBuffer { - point_t points []; -}; - -layout( push_constant ) uniform constants{ - float t; - float dt; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= trails.length()) { - return; - } - - const uint particleIndex = trails[id].particleIndex; - const uint startIndex = trails[id].startIndex; - const uint endIndex = trails[id].endIndex; - - uint useCount = trails[id].useCount; - float lifetime = trails[id].lifetime; - - if (lifetime > dt) { - lifetime -= dt; - } else { - lifetime = 0.0f; - } - - const uint available = (endIndex - startIndex) % points.length(); - - float trailLife = dt * available; - float fading = 1.0f / (1.0f + friction); - - if (lifetime <= trailLife) { - fading *= (lifetime / trailLife); - - if (useCount > 0) { - useCount--; - } - } else - if (available > useCount) { - useCount++; - } - - for (uint i = useCount; i > 1; i--) { - const uint x = (startIndex + (i - 1)) % points.length(); - const uint y = (startIndex + (i - 2)) % points.length(); - - vec3 position = points[y].position; - float size = points[y].size; - vec3 velocity = points[y].velocity; - - const float scaling = points[y].scaling; - - size = size * fading + scaling * dt; - - points[x].position = position; - points[x].size = size; - points[x].velocity = velocity; - points[x].scaling = scaling; - } - - vec3 position = particles[particleIndex].position; - float size = particles[particleIndex].size; - vec3 velocity = particles[particleIndex].velocity; - - const float trailFactor = mediumDensity / friction; - - points[startIndex].position = position * fading; - points[startIndex].size = trailWidth * size * fading; - points[startIndex].velocity = velocity * fading; - points[startIndex].scaling = trailFactor * length(velocity) * fading; - - trails[id].useCount = useCount; - trails[id].lifetime = lifetime; -} diff --git a/projects/fire_works/shaders/trail.geom b/projects/fire_works/shaders/trail.geom deleted file mode 100644 index 027943473d05cddc9db6019c7ee36771fcb91d2e..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/trail.geom +++ /dev/null @@ -1,96 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#define INSTANCE_LEN (16) - -layout(points) in; -layout (triangle_strip, max_vertices = (INSTANCE_LEN * 2)) out; -layout(invocations = 8) in; - -#include "physics.inc" -#include "point.inc" - -layout(set=0, binding=1, std430) readonly buffer pointBuffer { - point_t points []; -}; - -layout(location = 0) in vec3 geomColor [1]; -layout(location = 1) in uint geomTrailIndex [1]; -layout(location = 2) in vec3 geomTrailColor [1]; -layout(location = 3) in uint geomStartIndex [1]; -layout(location = 4) in uint geomUseCount [1]; - -layout(location = 0) out vec3 passPos; -layout(location = 1) out vec3 passDir; -layout(location = 2) out vec3 passColor; -layout(location = 3) out float passDensity; -layout(location = 4) out flat int passSmokeIndex; - -layout( push_constant ) uniform constants{ - mat4 mvp; - vec3 camera; -}; - -void main() { - const vec3 color = geomColor[0]; - const uint id = geomTrailIndex[0]; - - const vec3 trailColor = geomTrailColor[0]; - - const uint startIndex = geomStartIndex[0]; - const uint useCount = geomUseCount[0]; - - const uint indexOffset = (gl_InvocationID * (INSTANCE_LEN - 1)); - const uint instanceIndex = startIndex + indexOffset; - - uint count = min(INSTANCE_LEN, useCount); - - if ((indexOffset >= useCount) && (indexOffset + INSTANCE_LEN > useCount)) { - count = indexOffset - useCount; - } - - if (count <= 1) { - return; - } - - const float trailFactor = mediumDensity / friction; - - for (uint i = 0; i < count; i++) { - const float u = float(indexOffset + i + 1) / float(useCount); - - const uint index = (instanceIndex + i) % points.length(); - - const vec3 position = points[index].position; - const float size = points[index].size; - const vec3 velocity = points[index].velocity; - - const vec3 dir = normalize(cross(abs(velocity), position - camera)); - - vec3 offset = dir * size; - float density = trailFactor * (1.0f - u * u) / size; - - const vec3 p0 = position - offset; - const vec3 p1 = position + offset; - - passPos = vec3(u, -1.0f, -1.0f); - passDir = vec3(-0.1f * u, +0.2f, 2.0f); - passColor = mix(color, trailColor, u); - passDensity = density; - passSmokeIndex = int(id); - - gl_Position = mvp * vec4(p0, 1); - EmitVertex(); - - passPos = vec3(u, +1.0f, -1.0f); - passDir = vec3(-0.1f * u, -0.2f, 2.0f); - passColor = mix(color, trailColor, u); - passDensity = density; - passSmokeIndex = int(id); - - gl_Position = mvp * vec4(p1, 1); - EmitVertex(); - } - - EndPrimitive(); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/trail.inc b/projects/fire_works/shaders/trail.inc deleted file mode 100644 index 75cc49ad4038f28f27890e088fe4dd4e511d1f6b..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/trail.inc +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef TRAIL_INC -#define TRAIL_INC - -struct trail_t { - uint particleIndex; - uint startIndex; - uint endIndex; - uint useCount; - vec3 color; - float lifetime; -}; - -#endif // TRAIL_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/trail.vert b/projects/fire_works/shaders/trail.vert deleted file mode 100644 index 871beb9544c33ec790d079a050b4780efbec363f..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/trail.vert +++ /dev/null @@ -1,40 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -#include "trail.inc" - -layout(set=0, binding=0, std430) readonly buffer trailBuffer { - trail_t trails []; -}; - -#include "particle.inc" - -layout(set=2, binding=0, std430) readonly buffer particleBuffer { - particle_t particles []; -}; - -layout(location = 0) out vec3 geomColor; -layout(location = 1) out uint geomTrailIndex; -layout(location = 2) out vec3 geomTrailColor; -layout(location = 3) out uint geomStartIndex; -layout(location = 4) out uint geomUseCount; - -void main() { - const uint particleIndex = trails[gl_InstanceIndex].particleIndex; - const float lifetime = trails[gl_InstanceIndex].lifetime; - - geomColor = particles[particleIndex].color; - geomTrailIndex = gl_InstanceIndex; - geomTrailColor = trails[gl_InstanceIndex].color; - geomStartIndex = trails[gl_InstanceIndex].startIndex; - - const uint useCount = trails[gl_InstanceIndex].useCount; - - if (lifetime > 0.0f) { - geomUseCount = useCount; - } else { - geomUseCount = 0; - } - - gl_Position = vec4(gl_InstanceIndex, lifetime, useCount, 0.0f); -} \ No newline at end of file diff --git a/projects/fire_works/shaders/voxel.comp b/projects/fire_works/shaders/voxel.comp deleted file mode 100644 index 459c06f381c5c7c9cc26074cd22ecf2869e30350..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/voxel.comp +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -#include "physics.inc" -#include "voxel.inc" - -layout(set=0, binding=0, r32ui) restrict readonly uniform uimage3D voxelRed; -layout(set=0, binding=1, r32ui) restrict readonly uniform uimage3D voxelGreen; -layout(set=0, binding=2, r32ui) restrict readonly uniform uimage3D voxelBlue; -layout(set=0, binding=3, r32ui) restrict readonly uniform uimage3D voxelDensity; - -layout(set=1, binding=0, rgba16) restrict writeonly uniform image3D voxelImage; - -void main() { - ivec3 pos = ivec3(gl_GlobalInvocationID); - ivec3 size = imageSize(voxelImage); - - if (any(greaterThanEqual(pos, size))) { - return; - } - - const float red = voxel_read(voxelRed, pos); - const float green = voxel_read(voxelGreen, pos); - const float blue = voxel_read(voxelBlue, pos); - const float density = voxel_read(voxelDensity, pos); - - imageStore(voxelImage, pos, vec4( - red, - green, - blue, - density - )); -} diff --git a/projects/fire_works/shaders/voxel.inc b/projects/fire_works/shaders/voxel.inc deleted file mode 100644 index 9e2c895e4a0c688262de7404039aefe6650191bd..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/voxel.inc +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef VOXEL_INC -#define VOXEL_INC - -#define VOXEL_NORM_VALUE 0xFF - -#define voxel_add(img, pos, value) imageAtomicAdd(img, ivec3((imageSize(img) - ivec3(1)) * pos), uint(VOXEL_NORM_VALUE * value)) - -#define voxel_write(img, pos, value) imageStore(img, pos, uvec4(VOXEL_NORM_VALUE * value)); -#define voxel_read(img, pos) imageLoad(img, pos).r / float(VOXEL_NORM_VALUE); - -// https://stackoverflow.com/questions/51108596/linearize-depth -float linearize_depth(float d,float zNear,float zFar) { - return zNear * zFar / (zFar + d * (zNear - zFar)); -} - -#define voxel_pos(pos) vec3((pos.xy + vec2(1.0f)) * 0.5f, linearize_depth(pos.y, 0.1f, 50.0f)) - -#endif // VOXEL_INC \ No newline at end of file diff --git a/projects/fire_works/shaders/voxel_particle.comp b/projects/fire_works/shaders/voxel_particle.comp deleted file mode 100644 index 12b68eed09746f38286a5b1f1b4e9e56d4bfe105..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/voxel_particle.comp +++ /dev/null @@ -1,59 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "particle.inc" - -layout(set=0, binding=0, std430) readonly buffer particleBuffer { - particle_t particles []; -}; - -#include "voxel.inc" - -layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed; -layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen; -layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue; -layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= particles.length()) { - return; - } - - vec3 position = particles[id].position; - float lifetime = particles[id].lifetime; - - if (lifetime <= 0.0f) { - return; - } - - vec4 cs_pos = mvp * vec4(position, 1); - - if (abs(cs_pos.w) <= 0.0f) { - return; - } - - vec3 ndc_pos = cs_pos.xyz / cs_pos.w; - vec3 pos = voxel_pos(ndc_pos); - - if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) { - return; - } - - float size = particles[id].size; - vec3 color = particles[id].color; - - voxel_add(voxelRed, pos, color.r); - voxel_add(voxelGreen, pos, color.g); - voxel_add(voxelBlue, pos, color.b); - voxel_add(voxelDensity, pos, 1.0f); -} diff --git a/projects/fire_works/shaders/voxel_smoke.comp b/projects/fire_works/shaders/voxel_smoke.comp deleted file mode 100644 index de216ab29a6671e1547600d072edaf510b775154..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/voxel_smoke.comp +++ /dev/null @@ -1,72 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" -#include "smoke.inc" - -layout(set=0, binding=0, std430) readonly buffer smokeBuffer { - smoke_t smokes []; -}; - -#include "voxel.inc" - -layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed; -layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen; -layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue; -layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -#define NUM_SMOKE_SAMPLES 4 - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= smokes.length()) { - return; - } - - vec3 position = smokes[id].position; - float size = smokes[id].size; - - const float density = smokeDensity(size); - - if (density <= mediumDensity) { - return; - } - - vec3 offset = vec3(-size); - - for (;offset.x <= size; offset.x += size / NUM_SMOKE_SAMPLES) { - for (;offset.y <= size; offset.y += size / NUM_SMOKE_SAMPLES) { - for (;offset.z <= size; offset.z += size / NUM_SMOKE_SAMPLES) { - vec4 cs_pos = mvp * vec4(position + offset, 1); - - if (abs(cs_pos.w) <= 0.0f) { - return; - } - - vec3 ndc_pos = cs_pos.xyz / cs_pos.w; - vec3 pos = voxel_pos(ndc_pos); - - if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) { - return; - } - - vec3 color = smokes[id].color; - - float local_density = density * max(1.0f - length(offset / size), 0.0f); - - voxel_add(voxelRed, pos, color.r); - voxel_add(voxelGreen, pos, color.g); - voxel_add(voxelBlue, pos, color.b); - voxel_add(voxelDensity, pos, local_density); - } - } - } -} diff --git a/projects/fire_works/shaders/voxel_trail.comp b/projects/fire_works/shaders/voxel_trail.comp deleted file mode 100644 index 56971a1719075e0dd9a6a5bb6b52e89c11f8489c..0000000000000000000000000000000000000000 --- a/projects/fire_works/shaders/voxel_trail.comp +++ /dev/null @@ -1,87 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -#include "physics.inc" - -#include "trail.inc" - -layout(set=0, binding=0, std430) coherent buffer trailBuffer { - trail_t trails []; -}; - -#include "point.inc" - -layout(set=0, binding=1, std430) buffer pointBuffer { - point_t points []; -}; - -#include "voxel.inc" - -layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed; -layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen; -layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue; -layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity; - -#include "smoke.inc" - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= trails.length()) { - return; - } - - const uint particleIndex = trails[id].particleIndex; - const uint startIndex = trails[id].startIndex; - - uint useCount = trails[id].useCount; - - if (useCount <= 0) { - return; - } - - vec3 color = trails[id].color; - float lifetime = trails[id].lifetime; - - if (lifetime <= 0.0f) { - return; - } - - for (uint i = 0; i < useCount; i++) { - const uint x = (startIndex + i) % points.length(); - - vec3 position = points[x].position; - float size = points[x].size; - - const float density = smokeDensity(size); - - if (density <= mediumDensity) { - break; - } - - vec4 cs_pos = mvp * vec4(position, 1); - - if (abs(cs_pos.w) <= 0.0f) { - return; - } - - vec3 ndc_pos = cs_pos.xyz / cs_pos.w; - vec3 pos = voxel_pos(ndc_pos); - - if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) { - continue; - } - - voxel_add(voxelRed, pos, color.r); - voxel_add(voxelGreen, pos, color.g); - voxel_add(voxelBlue, pos, color.b); - voxel_add(voxelDensity, pos, density); - } -} diff --git a/projects/fire_works/src/main.cpp b/projects/fire_works/src/main.cpp deleted file mode 100644 index 472b781905fc446c592bef74bc0262792e8c3988..0000000000000000000000000000000000000000 --- a/projects/fire_works/src/main.cpp +++ /dev/null @@ -1,1379 +0,0 @@ - -#include <array> - -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> - -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/gui/GUI.hpp> -#include <vkcv/effects/BloomAndFlaresEffect.hpp> - -struct particle_t { - glm::vec3 position; - float lifetime; - glm::vec3 velocity; - float size; - glm::vec3 color; - float mass; - glm::vec3 pad0; - uint32_t eventId; -}; - -struct event_t { - glm::vec3 direction; - float startTime; - glm::vec3 color; - float velocity; - - uint32_t count; - uint32_t index; - uint32_t parent; - uint32_t continuous; - - float lifetime; - float mass; - float size; - uint32_t contCount; -}; - -struct smoke_t { - glm::vec3 position; - float size; - glm::vec3 velocity; - float scaling; - glm::vec3 color; - float eventID; -}; - -struct trail_t { - uint32_t particleIndex; - uint32_t startIndex; - uint32_t endIndex; - uint32_t useCount; - glm::vec3 color; - float lifetime; -}; - -struct point_t { - glm::vec3 position; - float size; - glm::vec3 velocity; - float scaling; -}; - -struct draw_particles_t { - glm::mat4 mvp; - uint32_t width; - uint32_t height; -}; - -struct draw_smoke_t { - glm::mat4 mvp; - glm::vec3 camera; -}; - -#define PARTICLE_COUNT (1024) -#define SMOKE_COUNT (512) -#define TRAIL_COUNT (2048) -#define RANDOM_DATA_LENGTH (4096) -#define POINT_COUNT (2048 * 256) - -void InitializeParticles(std::vector<particle_t> &particles) { - for (size_t i = 0; i < particles.size(); i++) { - particle_t particle; - particle.position = glm::vec3(2.0f * (std::rand() % RAND_MAX) / RAND_MAX - 1.0f, - 2.0f * (std::rand() % RAND_MAX) / RAND_MAX - 1.0f, - 2.0f * (std::rand() % RAND_MAX) / RAND_MAX - 1.0f); - - particle.lifetime = 0.0f; - particle.velocity = glm::vec3(0.0f); - particle.size = 0.01f; - particle.color = glm::vec3(1.0f, 0.0f, 0.0f); - - particles [i] = particle; - } -} - -void InitializeFireworkEvents(std::vector<event_t>& events) { - events.emplace_back(glm::vec3(0, 1, 0), 0.5f, glm::vec3(0.0f, 1.0f, 0.0f), 12.5f, - - 1, 0, UINT_MAX, 0, - - 1.0f, 1.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 1.5f, glm::vec3(0.0f, 1.0f, 1.0f), 10.0f, - - 100, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); - - events.emplace_back(glm::vec3(0.5, 1, 0), 0.25f, glm::vec3(0.0f, 1.5f, 0.0f), 15.0f, - - 1, 0, UINT_MAX, 0, - - 0.5f, 1.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 0.75f, glm::vec3(0.0f, 1.5f, 1.0f), 8.0f, - - 150, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); - - events.emplace_back(glm::vec3(-2.5, 3, 0.5), 1.0f, glm::vec3(246.0f, 189.0f, 255.0f), 12.5f, - - 1, 0, UINT_MAX, 0, - - 1.0f, 1.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 2.0f, glm::vec3(235.0f, 137.0f, 250.0f), 8.0f, - - 75, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); -} - -void InitializeSparklerEvents(std::vector<event_t> &events) { - events.emplace_back(glm::vec3(0, 1, 0), 0.0f, glm::vec3(251.0f, 255.0f, 145.0f), 1.0f, - - 1, 0, UINT_MAX, 0, - - 8.0f, 0.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 0.0f, glm::vec3(251.0f, 255.0f, 145.0f), 10.0f, - - 1000, 1, events.size() - 1, 10, - - 0.5f, -1.0f, 0.0f, 100); -} - -void InitializeNestedFireworkEvents(std::vector<event_t>& events) { - events.emplace_back(glm::vec3(0, 2, 0), 0.0f, glm::vec3(0.0f, 1.0f, 0.0f), 12.5f, - - 1, 0, UINT_MAX, 0, - - 1.0f, 1.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 0.9f, glm::vec3(0.0f, 1.0f, 1.0f), 7.0f, - - 100, 0, events.size() - 1, 0, - - 10.1f, 1.0f, 0.0f, 0); - - events.emplace_back(glm::vec3(0.0f), 2.0f, glm::vec3(0.0f, 0.0f, 0.0f), 10.0f, - - 100, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); - - events.emplace_back(glm::vec3(0.0f), 1.0f, glm::vec3(42.0f,0.0f, 1.0f), 12.5f, - - 100, 0, events.size() - 2, 0, - - 1.0f, 1.0f, 0.5f, 0); - - events.emplace_back(glm::vec3(0.0f), 1.5f, glm::vec3(42.0f, 0.0f, 1.0f), 10.0f, - - 100, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); - - events.emplace_back(glm::vec3(0.0f), 2.0f, glm::vec3(42.0f, 0.0f, 1.0f), 10.0f, - - 100, 0, events.size() - 1, 0, - - 10.0f, 1.0f, 0.0f, 0); -} - -void ChangeColor(std::vector<event_t>& events, glm::vec3 color) { - for (size_t i = 0; i < events.size(); i++) { - events [i].color = color; - } -} - -int main(int argc, const char **argv) { - vkcv::Features features; - - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - features.requireFeature([](vk::PhysicalDeviceFeatures& features) { - features.setGeometryShader(true); - }); - - vkcv::Core core = vkcv::Core::create( - "Firework", - VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - features - ); - - vkcv::WindowHandle windowHandle = core.createWindow("Firework", 800, 600, true); - vkcv::Window& window = core.getWindow (windowHandle); - vkcv::camera::CameraManager cameraManager (window); - - auto trackballHandle = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - auto pilotHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(trackballHandle).setCenter(glm::vec3(0.0f, 0.0f, 0.0f)); // set camera to look at the center of the particle volume - cameraManager.getCamera(trackballHandle).setNearFar(0.1f, 50.0f); - cameraManager.getCamera(trackballHandle).setPosition(glm::vec3(0, 0, -25)); - - cameraManager.getCamera(pilotHandle).setNearFar(0.1f, 50.0f); - cameraManager.getCamera(pilotHandle).setPosition(glm::vec3(0, 0, 25)); - - cameraManager.setActiveCamera(pilotHandle); - - vkcv::gui::GUI gui (core, windowHandle); - vkcv::shader::GLSLCompiler compiler; - - vkcv::DescriptorBindings descriptorBindings0; - vkcv::DescriptorBinding binding0 { - 0, - vkcv::DescriptorType::STORAGE_BUFFER, - 1, - vkcv::ShaderStage::VERTEX | vkcv::ShaderStage::COMPUTE, - false, - false - }; - vkcv::DescriptorBinding binding1 { - 1, - vkcv::DescriptorType::STORAGE_BUFFER, - - 1, - vkcv::ShaderStage::COMPUTE, - false, - false - }; - - descriptorBindings0.insert(std::make_pair(0, binding0)); - descriptorBindings0.insert(std::make_pair(1, binding1)); - - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings0); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); - - vkcv::ShaderProgram generationShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/generation.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - generationShader.addShader(shaderStage, path); - }); - - auto generationBindings = generationShader.getReflectedDescriptors().at(1); - generationBindings[0].shaderStages |= vkcv::ShaderStage::FRAGMENT; - - vkcv::DescriptorSetLayoutHandle generationDescriptorLayout = core.createDescriptorSetLayout( - generationBindings - ); - - vkcv::DescriptorSetHandle generationDescriptorSet = core.createDescriptorSet(generationDescriptorLayout); - - vkcv::DescriptorBindings descriptorBindings1; - - descriptorBindings1.insert(std::make_pair(0, binding0)); - descriptorBindings1.insert(std::make_pair(1, binding1)); - - vkcv::DescriptorSetLayoutHandle smokeDescriptorLayout = core.createDescriptorSetLayout(descriptorBindings1); - vkcv::DescriptorSetHandle smokeDescriptorSet = core.createDescriptorSet(smokeDescriptorLayout); - - vkcv::DescriptorBindings descriptorBindings2; - vkcv::DescriptorBinding binding2 { - 1, - vkcv::DescriptorType::STORAGE_BUFFER, - 1, - vkcv::ShaderStage::GEOMETRY | vkcv::ShaderStage::COMPUTE, - false, - false - }; - - descriptorBindings2.insert(std::make_pair(0, binding0)); - descriptorBindings2.insert(std::make_pair(1, binding2)); - - vkcv::DescriptorSetLayoutHandle trailDescriptorLayout = core.createDescriptorSetLayout( - descriptorBindings2 - ); - - vkcv::DescriptorSetHandle trailDescriptorSet = core.createDescriptorSet(trailDescriptorLayout); - - vkcv::ComputePipelineHandle generationPipeline = core.createComputePipeline({ - generationShader, - { - descriptorSetLayout, - generationDescriptorLayout, - smokeDescriptorLayout, - trailDescriptorLayout - } - }); - - vkcv::ShaderProgram trailShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/trail.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - trailShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle trailComputePipeline = core.createComputePipeline({ - trailShader, - { descriptorSetLayout, trailDescriptorLayout } - }); - - vkcv::ShaderProgram scaleShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/scale.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - scaleShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle scalePipeline = core.createComputePipeline({ - scaleShader, - { smokeDescriptorLayout } - }); - - auto swapchainHandle = core.getWindow(windowHandle).getSwapchain(); - auto swapchainExtent = core.getSwapchainExtent(swapchainHandle); - - const vk::Format colorFormat = vk::Format::eR16G16B16A16Sfloat; - - std::array<vkcv::ImageHandle, 4> colorBuffers; - for (size_t i = 0; i < colorBuffers.size(); i++) { - colorBuffers[i] = core.createImage( - colorFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - } - - vkcv::ShaderProgram particleShaderProgram; - compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/particle.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "shaders/particle.frag", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - - vkcv::ShaderProgram trailShaderProgram; - compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/trail.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - trailShaderProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::GEOMETRY, "shaders/trail.geom", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - trailShaderProgram.addShader(shaderStage, path); - }); - - vkcv::ShaderProgram smokeShaderProgram; - compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/smoke.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - smokeShaderProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "shaders/smoke.frag", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - smokeShaderProgram.addShader(shaderStage, path); - trailShaderProgram.addShader(shaderStage, path); - }); - - std::vector<particle_t> particles; - particles.resize(PARTICLE_COUNT); - InitializeParticles(particles); - - auto particleBuffer = vkcv::buffer<particle_t>( - core, - vkcv::BufferType::STORAGE, - particles.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL, - true - ); - - particleBuffer.fill(particles); - - auto particleBufferCopy = vkcv::buffer<particle_t>( - core, - vkcv::BufferType::STORAGE, - particles.size() - ); - - particleBufferCopy.fill(particles); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particleBuffer.getHandle()); - writes.writeStorageBuffer(1, particleBufferCopy.getHandle()); - core.writeDescriptorSet(descriptorSet, writes); - } - - std::vector<float> randomData; - randomData.reserve(RANDOM_DATA_LENGTH); - - for (size_t i = 0; i < RANDOM_DATA_LENGTH; i++) { - randomData.push_back( - 2.0f * static_cast<float>(std::rand() % RAND_MAX) / static_cast<float>(RAND_MAX) - 1.0f - ); - } - - auto randomBuffer = vkcv::buffer<float>( - core, - vkcv::BufferType::STORAGE, - randomData.size() - ); - - randomBuffer.fill(randomData); - - std::vector<event_t> events; - InitializeFireworkEvents(events); - - auto eventBuffer = vkcv::buffer<event_t>( - core, - vkcv::BufferType::STORAGE, - events.size() - ); - - eventBuffer.fill(events); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, randomBuffer.getHandle()); - writes.writeStorageBuffer(1, eventBuffer.getHandle()); - core.writeDescriptorSet(generationDescriptorSet, writes); - } - - auto startIndexBuffer = vkcv::buffer<uint32_t>( - core, - vkcv::BufferType::STORAGE, - eventBuffer.getCount() - ); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(2, startIndexBuffer.getHandle()); - core.writeDescriptorSet(generationDescriptorSet, writes); - } - - std::vector<smoke_t> smokes; - smokes.reserve(SMOKE_COUNT); - - for (size_t i = 0; i < SMOKE_COUNT; i++) { - smoke_t smoke; - smoke.position = glm::vec3(0.0f); - smoke.size = 0.0f; - - smoke.velocity = glm::vec3(0.0f); - smoke.scaling = 0.0f; - - smoke.color = glm::vec3(0.0f); - - smokes.push_back(smoke); - } - - auto smokeBuffer = vkcv::buffer<smoke_t>( - core, - vkcv::BufferType::STORAGE, - smokes.size() - ); - - smokeBuffer.fill(smokes); - - auto smokeIndexBuffer = vkcv::buffer<uint32_t>( - core, - vkcv::BufferType::STORAGE, - 3, - vkcv::BufferMemoryType::HOST_VISIBLE - ); - - uint32_t* smokeIndices = smokeIndexBuffer.map(); - memset(smokeIndices, 0, smokeIndexBuffer.getSize()); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, smokeBuffer.getHandle()); - writes.writeStorageBuffer(1, smokeIndexBuffer.getHandle()); - core.writeDescriptorSet(smokeDescriptorSet, writes); - } - - std::vector<trail_t> trails; - trails.reserve(TRAIL_COUNT); - - for (size_t i = 0; i < TRAIL_COUNT; i++) { - trail_t trail; - - trail.particleIndex = 0; - trail.startIndex = 0; - trail.endIndex = 0; - trail.useCount = 0; - trail.color = glm::vec3(0.0f); - trail.lifetime = 0.0f; - - trails.push_back(trail); - } - - auto trailBuffer = vkcv::buffer<trail_t>( - core, - vkcv::BufferType::STORAGE, - trails.size() - ); - - trailBuffer.fill(trails); - - std::vector<point_t> points; - points.reserve(POINT_COUNT); - - for (size_t i = 0; i < POINT_COUNT; i++) { - point_t point; - - point.position = glm::vec3(0.0f); - point.size = 0.0f; - point.velocity = glm::vec3(0.0f); - point.scaling = 0.0f; - - points.push_back(point); - } - - auto pointBuffer = vkcv::buffer<point_t>( - core, - vkcv::BufferType::STORAGE, - points.size() - ); - - pointBuffer.fill(points); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, trailBuffer.getHandle()); - writes.writeStorageBuffer(1, pointBuffer.getHandle()); - core.writeDescriptorSet(trailDescriptorSet, writes); - } - - auto cubePositions = vkcv::buffer<glm::vec3>( - core, - vkcv::BufferType::VERTEX, - 8 - ); - - cubePositions.fill({ - glm::vec3(-1.0f, -1.0f, -1.0f), - glm::vec3(+1.0f, -1.0f, -1.0f), - glm::vec3(-1.0f, +1.0f, -1.0f), - glm::vec3(+1.0f, +1.0f, -1.0f), - glm::vec3(-1.0f, -1.0f, +1.0f), - glm::vec3(+1.0f, -1.0f, +1.0f), - glm::vec3(-1.0f, +1.0f, +1.0f), - glm::vec3(+1.0f, +1.0f, +1.0f) - }); - - auto cubeIndices = vkcv::buffer<uint16_t>( - core, - vkcv::BufferType::INDEX, - 36 - ); - - cubeIndices.fill({ - 0, 2, 3, - 0, 3, 1, - 1, 3, 7, - 1, 7, 5, - - 5, 7, 6, - 5, 6, 4, - 4, 6, 2, - 4, 2, 0, - - 2, 6, 7, - 2, 7, 3, - 1, 5, 4, - 1, 4, 0 - }); - - vkcv::VertexData cubeData ({ vkcv::vertexBufferBinding(cubePositions.getHandle()) }); - cubeData.setIndexBuffer(cubeIndices.getHandle()); - cubeData.setCount(cubeIndices.getCount()); - - const std::vector<vkcv::VertexAttachment> vaSmoke = smokeShaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> vbSmoke; - for (size_t i = 0; i < vaSmoke.size(); i++) { - vbSmoke.push_back(vkcv::createVertexBinding(i, { vaSmoke[i] })); - } - - const vkcv::VertexLayout smokeLayout { vbSmoke }; - - vkcv::PassHandle renderPass = vkcv::passFormat(core, colorFormat); - - vkcv::GraphicsPipelineConfig smokePipelineDefinition ( - smokeShaderProgram, - renderPass, - {smokeLayout}, - {smokeDescriptorLayout, generationDescriptorLayout} - ); - - smokePipelineDefinition.setBlendMode(vkcv::BlendMode::Additive); - - vkcv::GraphicsPipelineHandle smokePipeline = core.createGraphicsPipeline(smokePipelineDefinition); - - const std::vector<vkcv::VertexAttachment> vaTrail = trailShaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> vbTrail; - for (size_t i = 0; i < vaTrail.size(); i++) { - vbTrail.push_back(vkcv::createVertexBinding(i, { vaTrail[i] })); - } - - const vkcv::VertexLayout trailLayout { vbTrail }; - - vkcv::GraphicsPipelineConfig trailPipelineDefinition ( - trailShaderProgram, - renderPass, - {trailLayout}, - {trailDescriptorLayout, generationDescriptorLayout, descriptorSetLayout} - ); - - trailPipelineDefinition.setPrimitiveTopology(vkcv::PrimitiveTopology::PointList); - trailPipelineDefinition.setBlendMode(vkcv::BlendMode::Additive); - - vkcv::GraphicsPipelineHandle trailPipeline = core.createGraphicsPipeline(trailPipelineDefinition); - - vkcv::InstanceDrawcall drawcallSmoke (cubeData, smokeBuffer.getCount()); - drawcallSmoke.useDescriptorSet(0, smokeDescriptorSet); - drawcallSmoke.useDescriptorSet(1, generationDescriptorSet); - - auto trianglePositions = vkcv::buffer<glm::vec2>( - core, - vkcv::BufferType::VERTEX, - 3 - ); - - trianglePositions.fill({ - glm::vec2(-1.0f, -1.0f), - glm::vec2(+0.0f, +1.5f), - glm::vec2(+1.0f, -1.0f) - }); - - auto triangleIndices = vkcv::buffer<uint16_t>( - core, - vkcv::BufferType::INDEX, - 3 - ); - - triangleIndices.fill({ - 0, 1, 2 - }); - - vkcv::VertexData triangleData ({ vkcv::vertexBufferBinding(trianglePositions.getHandle()) }); - triangleData.setIndexBuffer(triangleIndices.getHandle()); - triangleData.setCount(triangleIndices.getCount()); - - vkcv::VertexData trailData; - triangleData.setIndexBuffer(triangleIndices.getHandle()); - trailData.setCount(1); - - vkcv::InstanceDrawcall drawcallTrail (trailData, trailBuffer.getCount()); - drawcallTrail.useDescriptorSet(0, trailDescriptorSet); - drawcallTrail.useDescriptorSet(1, generationDescriptorSet); - drawcallTrail.useDescriptorSet(2, descriptorSet); - - const std::vector<vkcv::VertexAttachment> vaParticles = particleShaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> vbParticles; - for (size_t i = 0; i < vaParticles.size(); i++) { - vbParticles.push_back(vkcv::createVertexBinding(i, { vaParticles[i] })); - } - - const vkcv::VertexLayout particleLayout { vbParticles }; - - vkcv::GraphicsPipelineConfig particlePipelineDefinition ( - particleShaderProgram, - renderPass, - {particleLayout}, - {descriptorSetLayout} - ); - - particlePipelineDefinition.setBlendMode(vkcv::BlendMode::Additive); - - vkcv::GraphicsPipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition); - - vkcv::InstanceDrawcall drawcallParticle (triangleData, particleBuffer.getCount()); - drawcallParticle.useDescriptorSet(0, descriptorSet); - - vkcv::ShaderProgram motionShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/motion.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - motionShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle motionPipeline = core.createComputePipeline({ - motionShader, - { descriptorSetLayout } - }); - - const uint32_t voxelWidth = 160; - const uint32_t voxelHeight = 90; - const uint32_t voxelDepth = 64; - - std::vector<uint32_t> zeroVoxel; - zeroVoxel.resize(voxelWidth * voxelHeight * voxelDepth, 0); - - vkcv::Image voxelRed = vkcv::image( - core, - vk::Format::eR32Uint, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ); - - vkcv::Image voxelGreen = vkcv::image( - core, - vk::Format::eR32Uint, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ); - - vkcv::Image voxelBlue = vkcv::image( - core, - vk::Format::eR32Uint, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ); - - vkcv::Image voxelDensity = vkcv::image( - core, - vk::Format::eR32Uint, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ); - - std::array<vkcv::ImageHandle, 2> voxelData { - core.createImage( - vk::Format::eR16G16B16A16Sfloat, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ), - core.createImage( - vk::Format::eR16G16B16A16Sfloat, - voxelWidth, - voxelHeight, - voxelDepth, - false, true - ) - }; - - vkcv::Image voxelSamples = vkcv::image( - core, - colorFormat, - voxelWidth, - voxelHeight, - 1, false, true - ); - - vkcv::SamplerHandle voxelSampler = vkcv::samplerLinear(core, true); - - vkcv::ShaderProgram voxelClearShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/clear.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelClearShader.addShader(shaderStage, path); - }); - - const auto& voxelBindings = voxelClearShader.getReflectedDescriptors().at(0); - auto voxelDescriptorSetLayout = core.createDescriptorSetLayout(voxelBindings); - - vkcv::ComputePipelineHandle voxelClearPipeline = core.createComputePipeline({ - voxelClearShader, - { voxelDescriptorSetLayout } - }); - - vkcv::ShaderProgram voxelParticleShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_particle.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelParticleShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle voxelParticlePipeline = core.createComputePipeline({ - voxelParticleShader, - { descriptorSetLayout, voxelDescriptorSetLayout } - }); - - vkcv::ShaderProgram voxelSmokeShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_smoke.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelSmokeShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle voxelSmokePipeline = core.createComputePipeline({ - voxelSmokeShader, - { smokeDescriptorLayout, voxelDescriptorSetLayout } - }); - - vkcv::ShaderProgram voxelTrailShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_trail.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelTrailShader.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle voxelTrailPipeline = core.createComputePipeline({ - voxelTrailShader, - { trailDescriptorLayout, voxelDescriptorSetLayout } - }); - - vkcv::ShaderProgram voxelShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelShader.addShader(shaderStage, path); - }); - - const auto& voxelOutBindings = voxelShader.getReflectedDescriptors().at(1); - auto voxelOutDescriptorSetLayout = core.createDescriptorSetLayout(voxelOutBindings); - - vkcv::ComputePipelineHandle voxelPipeline = core.createComputePipeline({ - voxelShader, - { voxelDescriptorSetLayout, voxelOutDescriptorSetLayout } - }); - - vkcv::ShaderProgram fluidShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/fluid.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - fluidShader.addShader(shaderStage, path); - }); - - const auto& fluidBindings = fluidShader.getReflectedDescriptors().at(0); - auto fluidDescriptorSetLayout = core.createDescriptorSetLayout(fluidBindings); - - vkcv::ComputePipelineHandle fluidPipeline = core.createComputePipeline({ - fluidShader, - { fluidDescriptorSetLayout } - }); - - vkcv::ShaderProgram voxelSampleShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/sample.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - voxelSampleShader.addShader(shaderStage, path); - }); - - const auto& sampleBindings = voxelSampleShader.getReflectedDescriptors().at(1); - auto samplesDescriptorSetLayout = core.createDescriptorSetLayout(sampleBindings); - - vkcv::ComputePipelineHandle voxelSamplePipeline = core.createComputePipeline({ - voxelSampleShader, - { voxelOutDescriptorSetLayout, samplesDescriptorSetLayout } - }); - - auto voxelDescriptorSet = core.createDescriptorSet(voxelDescriptorSetLayout); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageImage(0, voxelRed.getHandle()); - writes.writeStorageImage(1, voxelGreen.getHandle()); - writes.writeStorageImage(2, voxelBlue.getHandle()); - writes.writeStorageImage(3, voxelDensity.getHandle()); - core.writeDescriptorSet(voxelDescriptorSet, writes); - } - - auto voxelOutDescriptorSet = core.createDescriptorSet(voxelOutDescriptorSetLayout); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageImage(0, voxelData[0]); - core.writeDescriptorSet(voxelOutDescriptorSet, writes); - } - - std::array<vkcv::DescriptorSetHandle, 2> fluidDescriptorSet { - core.createDescriptorSet(fluidDescriptorSetLayout), - core.createDescriptorSet(fluidDescriptorSetLayout) - }; - - { - vkcv::DescriptorWrites writes; - writes.writeSampledImage(0, voxelData[0]); - writes.writeSampler(1, voxelSampler); - writes.writeStorageImage(2, voxelData[1]); - core.writeDescriptorSet(fluidDescriptorSet[0], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeSampledImage(0, voxelData[1]); - writes.writeSampler(1, voxelSampler); - writes.writeStorageImage(2, voxelData[0]); - core.writeDescriptorSet(fluidDescriptorSet[1], writes); - } - - auto samplesDescriptorSet = core.createDescriptorSet(samplesDescriptorSetLayout); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageImage(0, voxelSamples.getHandle()); - core.writeDescriptorSet(samplesDescriptorSet, writes); - } - - vkcv::effects::BloomAndFlaresEffect bloomAndFlares (core); - bloomAndFlares.setUpsamplingLimit(3); - - vkcv::ShaderProgram addShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/add.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - addShader.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle addDescriptorLayout = core.createDescriptorSetLayout(addShader.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle addDescriptor = core.createDescriptorSet(addDescriptorLayout); - - vkcv::ComputePipelineHandle addPipe = core.createComputePipeline({ - addShader, - { addDescriptorLayout, generationDescriptorLayout } - }); - - vkcv::ShaderProgram tonemappingShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/tonemapping.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - tonemappingShader.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle tonemappingDescriptorLayout = core.createDescriptorSetLayout(tonemappingShader.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingDescriptorLayout); - vkcv::ComputePipelineHandle tonemappingPipe = core.createComputePipeline({ - tonemappingShader, - { tonemappingDescriptorLayout } - }); - - vkcv::ImageHandle swapchainImage = vkcv::ImageHandle::createSwapchainImageHandle(); - - auto start = std::chrono::system_clock::now(); - auto current = start; - - while (vkcv::Window::hasOpenWindow()) { - vkcv::Window::pollEvents(); - - uint32_t swapchainWidth, swapchainHeight; - if (!core.beginFrame(swapchainWidth, swapchainHeight, windowHandle)) { - continue; - } - - for (size_t i = 0; i < colorBuffers.size(); i++) { - if ((core.getImageWidth(colorBuffers[i]) != swapchainWidth) || - (core.getImageHeight(colorBuffers[i]) != swapchainHeight)) { - colorBuffers[i] = core.createImage( - colorFormat, - swapchainWidth, - swapchainHeight, - 1, false, true, true - ); - } - } - - auto next = std::chrono::system_clock::now(); - - auto time = std::chrono::duration_cast<std::chrono::microseconds>(next - start); - auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(next - current); - - current = next; - - float time_values [2]; - time_values[0] = 0.000001f * static_cast<float>(time.count()); - time_values[1] = 0.000001f * static_cast<float>(deltatime.count()); - - std::cout << time_values[0] << " " << time_values[1] << std::endl; - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - auto voxelDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(voxelWidth, voxelHeight, voxelDepth), - vkcv::DispatchSize(4, 4, 4) - ); - - core.recordBeginDebugLabel(cmdStream, "Voxel clear", { 0.5f, 0.25f, 0.8f, 1.0f }); - core.prepareImageForStorage(cmdStream, voxelRed.getHandle()); - core.prepareImageForStorage(cmdStream, voxelGreen.getHandle()); - core.prepareImageForStorage(cmdStream, voxelBlue.getHandle()); - core.prepareImageForStorage(cmdStream, voxelDensity.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelClearPipeline, - voxelDispatchCount, - { vkcv::useDescriptorSet(0, voxelDescriptorSet) }, - vkcv::PushConstants(0) - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, eventBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, smokeBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, smokeIndexBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, trailBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, pointBuffer.getHandle()); - - auto particleDispatchCount = vkcv::dispatchInvocations(particleBuffer.getCount(), 256); - - vkcv::PushConstants pushConstantsTime (2 * sizeof(float)); - pushConstantsTime.appendDrawcall(time_values); - - core.recordBeginDebugLabel(cmdStream, "Generation", { 0.0f, 0.0f, 1.0f, 1.0f }); - core.recordComputeDispatchToCmdStream( - cmdStream, - generationPipeline, - particleDispatchCount, - { - vkcv::useDescriptorSet(0, descriptorSet), - vkcv::useDescriptorSet(1, generationDescriptorSet), - vkcv::useDescriptorSet(2, smokeDescriptorSet), - vkcv::useDescriptorSet(3, trailDescriptorSet) - }, - pushConstantsTime - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, smokeBuffer.getHandle()); - - auto smokeDispatchCount = vkcv::dispatchInvocations(smokeBuffer.getCount(), 256); - - core.recordBeginDebugLabel(cmdStream, "Smoke scaling", { 0.0f, 0.0f, 1.0f, 1.0f }); - core.recordComputeDispatchToCmdStream( - cmdStream, - scalePipeline, - smokeDispatchCount, - { vkcv::useDescriptorSet(0, smokeDescriptorSet) }, - pushConstantsTime - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - - core.recordBeginDebugLabel(cmdStream, "Particle motion", { 0.0f, 0.0f, 1.0f, 1.0f }); - core.recordComputeDispatchToCmdStream( - cmdStream, - motionPipeline, - particleDispatchCount, - { vkcv::useDescriptorSet(0, descriptorSet) }, - pushConstantsTime - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, trailBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, pointBuffer.getHandle()); - - auto trailDispatchCount = vkcv::dispatchInvocations(trailBuffer.getCount(), 256); - - core.recordBeginDebugLabel(cmdStream, "Trail update", { 0.0f, 0.0f, 1.0f, 1.0f }); - core.recordComputeDispatchToCmdStream( - cmdStream, - trailComputePipeline, - trailDispatchCount, - { - vkcv::useDescriptorSet(0, descriptorSet), - vkcv::useDescriptorSet(1, trailDescriptorSet) - }, - pushConstantsTime - ); - core.recordEndDebugLabel(cmdStream); - - cameraManager.update(time_values[1]); - - const auto& camera = cameraManager.getActiveCamera(); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - - draw_particles_t draw_particles { - camera.getMVP(), - swapchainWidth, - swapchainHeight - }; - - vkcv::PushConstants pushConstantsDraw0 (sizeof(draw_particles_t)); - pushConstantsDraw0.appendDrawcall(draw_particles); - - core.recordBeginDebugLabel(cmdStream, "Draw particles", { 1.0f, 0.0f, 1.0f, 1.0f }); - core.recordDrawcallsToCmdStream( - cmdStream, - particlePipeline, - pushConstantsDraw0, - { drawcallParticle }, - { colorBuffers[0] }, - windowHandle - ); - core.recordEndDebugLabel(cmdStream); - - vkcv::PushConstants pushConstantsVoxel (sizeof(glm::mat4)); - pushConstantsVoxel.appendDrawcall(camera.getMVP()); - - core.recordBeginDebugLabel(cmdStream, "Particle voxel update", { 1.0f, 0.5f, 0.8f, 1.0f }); - core.prepareImageForStorage(cmdStream, voxelRed.getHandle()); - core.prepareImageForStorage(cmdStream, voxelGreen.getHandle()); - core.prepareImageForStorage(cmdStream, voxelBlue.getHandle()); - core.prepareImageForStorage(cmdStream, voxelDensity.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelParticlePipeline, - particleDispatchCount, - { - vkcv::useDescriptorSet(0, descriptorSet), - vkcv::useDescriptorSet(1, voxelDescriptorSet) - }, - pushConstantsVoxel - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, smokeBuffer.getHandle()); - - draw_smoke_t draw_smoke { - camera.getMVP(), - camera.getPosition() - }; - - core.recordBeginDebugLabel(cmdStream, "Draw smoke", { 1.0f, 0.5f, 1.0f, 1.0f }); - vkcv::PushConstants pushConstantsDraw1 (sizeof(draw_smoke_t)); - pushConstantsDraw1.appendDrawcall(draw_smoke); - - core.recordDrawcallsToCmdStream( - cmdStream, - smokePipeline, - pushConstantsDraw1, - { drawcallSmoke }, - { colorBuffers[1] }, - windowHandle - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Smoke voxel update", { 1.0f, 0.7f, 0.8f, 1.0f }); - core.prepareImageForStorage(cmdStream, voxelRed.getHandle()); - core.prepareImageForStorage(cmdStream, voxelGreen.getHandle()); - core.prepareImageForStorage(cmdStream, voxelBlue.getHandle()); - core.prepareImageForStorage(cmdStream, voxelDensity.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelSmokePipeline, - smokeDispatchCount, - { - vkcv::useDescriptorSet(0, smokeDescriptorSet), - vkcv::useDescriptorSet(1, voxelDescriptorSet) - }, - pushConstantsVoxel - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBufferMemoryBarrier(cmdStream, trailBuffer.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, pointBuffer.getHandle()); - - core.recordBeginDebugLabel(cmdStream, "Draw trails", { 0.75f, 0.5f, 1.0f, 1.0f }); - core.recordDrawcallsToCmdStream( - cmdStream, - trailPipeline, - pushConstantsDraw1, - { drawcallTrail }, - { colorBuffers[2] }, - windowHandle - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Trail voxel update", { 1.0f, 0.9f, 0.8f, 1.0f }); - core.prepareImageForStorage(cmdStream, voxelRed.getHandle()); - core.prepareImageForStorage(cmdStream, voxelGreen.getHandle()); - core.prepareImageForStorage(cmdStream, voxelBlue.getHandle()); - core.prepareImageForStorage(cmdStream, voxelDensity.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelTrailPipeline, - trailDispatchCount, - { - vkcv::useDescriptorSet(0, trailDescriptorSet), - vkcv::useDescriptorSet(1, voxelDescriptorSet) - }, - pushConstantsVoxel - ); - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Combine voxel data", { 0.5f, 0.5f, 0.5f, 1.0f }); - - core.prepareImageForStorage(cmdStream, voxelRed.getHandle()); - core.prepareImageForStorage(cmdStream, voxelGreen.getHandle()); - core.prepareImageForStorage(cmdStream, voxelBlue.getHandle()); - core.prepareImageForStorage(cmdStream, voxelDensity.getHandle()); - - core.prepareImageForStorage(cmdStream, voxelData[0]); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelPipeline, - voxelDispatchCount, - { - vkcv::useDescriptorSet(0, voxelDescriptorSet), - vkcv::useDescriptorSet(1, voxelOutDescriptorSet) - }, - vkcv::PushConstants(0) - ); - - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Fluid voxel data", { 0.2f, 0.2f, 0.9f, 1.0f }); - - for (size_t i = 0; i < 8; i++) { - core.prepareImageForSampling(cmdStream, voxelData[i % 2]); - core.prepareImageForStorage(cmdStream, voxelData[(i + 1) % 2]); - - core.recordComputeDispatchToCmdStream( - cmdStream, - fluidPipeline, - voxelDispatchCount, - { vkcv::useDescriptorSet(0, fluidDescriptorSet[i % 2]) }, - vkcv::PushConstants(0) - ); - } - - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Sample voxels", { 0.5f, 0.5f, 1.0f, 1.0f }); - - core.prepareImageForStorage(cmdStream, voxelData[0]); - core.prepareImageForStorage(cmdStream, voxelSamples.getHandle()); - - auto sampleDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(voxelWidth, voxelHeight), - vkcv::DispatchSize(8, 8) - ); - - core.recordComputeDispatchToCmdStream( - cmdStream, - voxelSamplePipeline, - sampleDispatchCount, - { - vkcv::useDescriptorSet(0, voxelOutDescriptorSet), - vkcv::useDescriptorSet(1, samplesDescriptorSet) - }, - vkcv::PushConstants(0) - ); - - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "Add rendered images", { 0.5f, 0.5f, 1.0f, 1.0f }); - - vkcv::DescriptorWrites addDescriptorWrites; - addDescriptorWrites.writeSampledImage(0, voxelSamples.getHandle()); - addDescriptorWrites.writeSampler(1, voxelSampler); - - for (size_t i = 0; i < colorBuffers.size(); i++) { - addDescriptorWrites.writeStorageImage(2 + i, colorBuffers[i]); - core.prepareImageForStorage(cmdStream, colorBuffers[i]); - } - - core.writeDescriptorSet(addDescriptor, addDescriptorWrites); - core.prepareImageForSampling(cmdStream, voxelSamples.getHandle()); - - auto colorDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(8, 8) - ); - - core.recordComputeDispatchToCmdStream( - cmdStream, - addPipe, - colorDispatchCount, - { - vkcv::useDescriptorSet(0, addDescriptor), - vkcv::useDescriptorSet(1, generationDescriptorSet) - }, - vkcv::PushConstants(0) - ); - - core.recordEndDebugLabel(cmdStream); - - bloomAndFlares.recordEffect(cmdStream, colorBuffers.back(), colorBuffers.back()); - - core.recordBeginDebugLabel(cmdStream, "Tonemapping", { 0.0f, 1.0f, 0.0f, 1.0f }); - core.prepareImageForStorage(cmdStream, colorBuffers.back()); - core.prepareImageForStorage(cmdStream, swapchainImage); - - vkcv::DescriptorWrites tonemappingDescriptorWrites; - tonemappingDescriptorWrites.writeStorageImage( - 0, colorBuffers.back() - ).writeStorageImage( - 1, swapchainImage - ); - - core.writeDescriptorSet(tonemappingDescriptor, tonemappingDescriptorWrites); - - core.recordComputeDispatchToCmdStream( - cmdStream, - tonemappingPipe, - colorDispatchCount, - { vkcv::useDescriptorSet(0, tonemappingDescriptor) }, - vkcv::PushConstants(0) - ); - - core.recordEndDebugLabel(cmdStream); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - ImGui::Begin("Settings"); - - bool firework, sparkler, nested; - if (ImGui::BeginListBox(" ")) { - firework = ImGui::Selectable("Firework"); - sparkler = ImGui::Selectable("Sparkler"); - nested = ImGui::Selectable("Nested Firework"); - - ImGui::EndListBox(); - } - - bool resetTime = ImGui::Button("Reset"); - auto color = glm::vec3(0.0f); - - if (!events.empty()) { - color = events[0].color; - } - - bool colorChanged = ImGui::ColorPicker3("Color", (float*) & color); - - ImGui::End(); - gui.endGUI(); - - core.endFrame(windowHandle); - - particleBuffer.read(particles); - sort(particles.begin(), particles.end(), - [](const particle_t p1, const particle_t p2) { - return p1.eventId < p2.eventId; - }); - - std::vector<uint32_t> startingIndex; - startingIndex.resize(events.size()); - uint32_t eventIdCheck = std::numeric_limits<uint32_t>::max(); - - for (size_t i = 0; i < particles.size(); i++) { - if (particles[i].eventId != eventIdCheck) { - eventIdCheck = particles [i].eventId; - if (eventIdCheck < startingIndex.size()) { - startingIndex [eventIdCheck] = i; - } - } - } - - startIndexBuffer.fill(startingIndex); - - if (firework) { - events.clear(); - InitializeFireworkEvents(events); - resetTime = true; - } else if (sparkler) { - events.clear(); - InitializeSparklerEvents(events); - resetTime = true; - } else if (nested) { - events.clear(); - InitializeNestedFireworkEvents(events); - resetTime = true; - } - - if (colorChanged) { - ChangeColor(events, color); - resetTime = true; - } - - if (resetTime) { - start = std::chrono::system_clock::now(); - InitializeParticles(particles); - particleBuffer.fill(particles); - eventBuffer.fill(events); - smokeBuffer.fill(smokes); - trailBuffer.fill(trails); - pointBuffer.fill(points); - - memset(smokeIndices, 0, smokeIndexBuffer.getSize()); - } - - particleBufferCopy.fill(particles); - } - - smokeIndexBuffer.unmap(); - return 0; -} diff --git a/projects/first_mesh/.gitignore b/projects/first_mesh/.gitignore deleted file mode 100644 index 85ce58a41ce7dcbe4f4a41bbf4779d82cede0106..0000000000000000000000000000000000000000 --- a/projects/first_mesh/.gitignore +++ /dev/null @@ -1 +0,0 @@ -first_mesh \ No newline at end of file diff --git a/projects/first_mesh/CMakeLists.txt b/projects/first_mesh/CMakeLists.txt deleted file mode 100644 index 1846c5276210ed6541bdaa9833f072ccc9836b8d..0000000000000000000000000000000000000000 --- a/projects/first_mesh/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(first_mesh) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(first_mesh src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(first_mesh SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_asset_loader_include} - ${vkcv_geometry_include} - ${vkcv_camera_include} - ${vkcv_shader_compiler_include} -) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(first_mesh - vkcv - ${vkcv_libraries} - vkcv_asset_loader - vkcv_geometry - vkcv_camera - vkcv_shader_compiler -) diff --git a/projects/first_mesh/assets/cube/boards2_vcyc_jpg.jpg b/projects/first_mesh/assets/cube/boards2_vcyc_jpg.jpg deleted file mode 100644 index 2636039e272289c0fba3fa2d88a060b857501248..0000000000000000000000000000000000000000 --- a/projects/first_mesh/assets/cube/boards2_vcyc_jpg.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 -size 1192476 diff --git a/projects/first_mesh/assets/shaders/shader.frag b/projects/first_mesh/assets/shaders/shader.frag deleted file mode 100644 index 71a1de69c57c0d7b7d4665095410e7acaf8dbd62..0000000000000000000000000000000000000000 --- a/projects/first_mesh/assets/shaders/shader.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform texture2D meshTexture; -layout(set=0, binding=1) uniform sampler textureSampler; - -void main() { - outColor = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; -} \ No newline at end of file diff --git a/projects/first_mesh/assets/shaders/shader.vert b/projects/first_mesh/assets/shaders/shader.vert deleted file mode 100644 index 76855152253b48b7400f016d063ed4f0e507435e..0000000000000000000000000000000000000000 --- a/projects/first_mesh/assets/shaders/shader.vert +++ /dev/null @@ -1,19 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = inNormal; - passUV = inUV; -} \ No newline at end of file diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp deleted file mode 100644 index 1350156140e4946599982a5057b2bab0bab276aa..0000000000000000000000000000000000000000 --- a/projects/first_mesh/src/main.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -#include <vkcv/geometry/Cuboid.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "First Mesh"; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); - vkcv::Window& window = core.getWindow(windowHandle); - - vkcv::PassHandle firstMeshPass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - if (!firstMeshPass) { - std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ShaderProgram firstMeshProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compileProgram(firstMeshProgram, { - { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, - { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } - }, nullptr); - - std::vector<vkcv::VertexBinding> bindings = vkcv::createVertexBindings( - firstMeshProgram.getVertexAttachments() - ); - - const vkcv::VertexLayout firstMeshLayout { bindings }; - - // since we only use one descriptor set (namely, desc set 0), directly address it - // recreate copies of the bindings and the handles (to check whether they are properly reused instead of actually recreated) - const vkcv::DescriptorBindings& set0Bindings = firstMeshProgram.getReflectedDescriptors().at(0); - auto set0BindingsExplicitCopy = set0Bindings; - - vkcv::DescriptorSetLayoutHandle setLayoutHandle = core.createDescriptorSetLayout(set0Bindings); - vkcv::DescriptorSetLayoutHandle setLayoutHandleCopy = core.createDescriptorSetLayout(set0BindingsExplicitCopy); - - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(setLayoutHandle); - - vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - firstMeshProgram, - firstMeshPass, - { firstMeshLayout }, - { setLayoutHandle } - ) - ); - - if (!firstMeshPipeline) { - std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::asset::Texture tex = vkcv::asset::loadTexture("assets/cube/boards2_vcyc_jpg.jpg"); - - if (tex.data.empty()) { - std::cerr << "Error. No texture found. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::Image texture = vkcv::image(core, vk::Format::eR8G8B8A8Srgb, tex.w, tex.h); - texture.fill(tex.data.data()); - - { - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - texture.recordMipChainGeneration(cmdStream, core.getDownsampler()); - core.submitCommandStream(cmdStream, false); - } - - vkcv::SamplerHandle sampler = vkcv::samplerLinear(core); - - vkcv::DescriptorWrites setWrites; - setWrites.writeSampledImage(0, texture.getHandle()); - setWrites.writeSampler(1, sampler); - - core.writeDescriptorSet(descriptorSet, setWrites); - - vkcv::ImageHandle depthBuffer; - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::geometry::Cuboid cube (glm::vec3(0), 1.0f); - - vkcv::InstanceDrawcall drawcall (cube.generateVertexData(core)); - drawcall.useDescriptorSet(0, descriptorSet); - - vkcv::camera::CameraManager cameraManager(window); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(camHandle).setPosition(glm::vec3(0, 0, -3)); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - (swapchainHeight != core.getImageHeight(depthBuffer))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - } - - cameraManager.update(dt); - glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - - vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); - pushConstants.appendDrawcall(mvp); - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - core.recordDrawcallsToCmdStream( - cmdStream, - firstMeshPipeline, - pushConstants, - { drawcall }, - renderTargets, - windowHandle - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/first_scene/.gitignore b/projects/first_scene/.gitignore deleted file mode 100644 index b0d802667a184267e6ee764264e976dfead8e9dd..0000000000000000000000000000000000000000 --- a/projects/first_scene/.gitignore +++ /dev/null @@ -1 +0,0 @@ -first_scene diff --git a/projects/first_scene/CMakeLists.txt b/projects/first_scene/CMakeLists.txt deleted file mode 100644 index 266630fae0de1d4d9696d454c101bf00085b7599..0000000000000000000000000000000000000000 --- a/projects/first_scene/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(first_scene) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(first_scene src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(first_scene SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(first_scene vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene vkcv_shader_compiler vkcv_gui) diff --git a/projects/first_scene/assets/Sponza/Sponza.bin b/projects/first_scene/assets/Sponza/Sponza.bin deleted file mode 100644 index cfedd26ca5a67b6d0a47d44d13a75e14a141717a..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/Sponza.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b809f7a17687dc99e6f41ca1ea32c06eded8779bf34d16f1f565d750b0ffd68 -size 6347696 diff --git a/projects/first_scene/assets/Sponza/Sponza.gltf b/projects/first_scene/assets/Sponza/Sponza.gltf deleted file mode 100644 index 172ea07e21c94465211c860cd805355704cef230..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/Sponza.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5cc0ecad5c4694088ff820e663619c370421afc1323ac487406e8e9b4735d787 -size 713962 diff --git a/projects/first_scene/assets/Sponza/SponzaFloor.bin b/projects/first_scene/assets/Sponza/SponzaFloor.bin deleted file mode 100644 index 684251288f35070d2e7d244877fd844cc00ca632..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/SponzaFloor.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:678455aca641cb1f449aa1a5054a7cae132be81c2b333aac283053967da66df0 -size 512 diff --git a/projects/first_scene/assets/Sponza/SponzaFloor.gltf b/projects/first_scene/assets/Sponza/SponzaFloor.gltf deleted file mode 100644 index b45f1c55ef85f2aa1d4bff01df3d9625aa38c809..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/SponzaFloor.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6deb75441b1138b50a6b0eec05e60df276fe8fb6d58118fdfce2090b6fbe734 -size 3139 diff --git a/projects/first_scene/assets/Sponza/background.png b/projects/first_scene/assets/Sponza/background.png deleted file mode 100644 index b64def129da38f4e23d89e21b4af1039008a4327..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/background.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5b5f900ff8ed83a31750ec8e428b5b91273794ddcbfc4e4b8a6a7e781f8c686 -size 1417666 diff --git a/projects/first_scene/assets/Sponza/chain_texture.png b/projects/first_scene/assets/Sponza/chain_texture.png deleted file mode 100644 index c1e1768cff78e0614ad707eca8602a4c4edab5e5..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/chain_texture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8362cfd472880daeaea37439326a4651d1338680ae69bb2513fc6b17c8de7d4 -size 490895 diff --git a/projects/first_scene/assets/Sponza/lion.png b/projects/first_scene/assets/Sponza/lion.png deleted file mode 100644 index c49c7f0ed31e762e19284d0d3624fbc47664e56b..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/lion.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f882f746c3a9cd51a9c6eedc1189b97668721d91a3fe49232036e789912c652 -size 2088728 diff --git a/projects/first_scene/assets/Sponza/spnza_bricks_a_diff.png b/projects/first_scene/assets/Sponza/spnza_bricks_a_diff.png deleted file mode 100644 index cde4c7a6511e9a5f03c63ad996437fcdba3ce2df..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/spnza_bricks_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b94219c2f5f943f3f4715c74e7d1038bf0ab3b3b3216a758eaee67f875df0851 -size 1928829 diff --git a/projects/first_scene/assets/Sponza/sponza_arch_diff.png b/projects/first_scene/assets/Sponza/sponza_arch_diff.png deleted file mode 100644 index bcd9bda2918d226039f9e2d03902d377b706fab6..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_arch_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c0df2c8a01b2843b1c792b494f7173cdbc4f834840fc2177af3e5d690fceda57 -size 1596151 diff --git a/projects/first_scene/assets/Sponza/sponza_ceiling_a_diff.png b/projects/first_scene/assets/Sponza/sponza_ceiling_a_diff.png deleted file mode 100644 index 59de631ffac4414cabf69b2dc794c46fc187d6cb..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_ceiling_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab6c187a81aa68f4eba30119e17fce2e4882a9ec320f70c90482dbe9da82b1c6 -size 1872074 diff --git a/projects/first_scene/assets/Sponza/sponza_column_a_diff.png b/projects/first_scene/assets/Sponza/sponza_column_a_diff.png deleted file mode 100644 index 01a82432d3f9939bbefe850bdb900f1ff9a3f6db..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_column_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c291507e2808bb83e160ab4b020689817df273baad3713a9ad19ac15fac6826 -size 1840992 diff --git a/projects/first_scene/assets/Sponza/sponza_column_b_diff.png b/projects/first_scene/assets/Sponza/sponza_column_b_diff.png deleted file mode 100644 index 10a660cce2a5a9b8997772c746058ce23e7d45d7..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_column_b_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2820b0267c4289c6cedbb42721792a57ef244ec2d0935941011c2a7d3fe88a9b -size 2170433 diff --git a/projects/first_scene/assets/Sponza/sponza_column_c_diff.png b/projects/first_scene/assets/Sponza/sponza_column_c_diff.png deleted file mode 100644 index bc46fd979044a938d3adca7601689e71504e48bf..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_column_c_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0bc993ff59865468ef4530798930c7dfefb07482d71db45bc2a520986b27735 -size 2066950 diff --git a/projects/first_scene/assets/Sponza/sponza_curtain_blue_diff.png b/projects/first_scene/assets/Sponza/sponza_curtain_blue_diff.png deleted file mode 100644 index 384c8c2c051160d530eb3ac8b05c9c60752a2d2b..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_curtain_blue_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b85c6bb3cd5105f48d3812ec8e7a1068521ce69e917300d79e136e19d45422fb -size 9510905 diff --git a/projects/first_scene/assets/Sponza/sponza_curtain_diff.png b/projects/first_scene/assets/Sponza/sponza_curtain_diff.png deleted file mode 100644 index af842e9f5fe18c1f609875e00899a6770fa4488b..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_curtain_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:563c56bdbbee395a6ef7f0c51c8ac9223c162e517b4cdba0d4654e8de27c98d8 -size 9189263 diff --git a/projects/first_scene/assets/Sponza/sponza_curtain_green_diff.png b/projects/first_scene/assets/Sponza/sponza_curtain_green_diff.png deleted file mode 100644 index 6c9b6391a199407637fa71033d79fb58b8b4f0d7..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_curtain_green_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:238fe1c7f481388d1c1d578c2da8d411b99e8f0030ab62060a306db333124476 -size 8785458 diff --git a/projects/first_scene/assets/Sponza/sponza_details_diff.png b/projects/first_scene/assets/Sponza/sponza_details_diff.png deleted file mode 100644 index 12656686362c3e0a297e060491f33bd7351551f9..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_details_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb1223b3bb82f8757e7df25a6891f1239cdd7ec59990340e952fb2d6b7ea570c -size 1522643 diff --git a/projects/first_scene/assets/Sponza/sponza_fabric_blue_diff.png b/projects/first_scene/assets/Sponza/sponza_fabric_blue_diff.png deleted file mode 100644 index 879d16ef84722a4fc13e83a771778de326e4bc54..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_fabric_blue_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:467d290bf5d4b2a017da140ba9e244ed8a8a9be5418a9ac9bcb4ad572ae2d7ab -size 2229440 diff --git a/projects/first_scene/assets/Sponza/sponza_fabric_diff.png b/projects/first_scene/assets/Sponza/sponza_fabric_diff.png deleted file mode 100644 index 3311287a219d2148620b87fe428fea071688d051..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_fabric_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1594f59cc2848db26add47361f4e665e3d8afa147760ed915d839fea42b20287 -size 2267382 diff --git a/projects/first_scene/assets/Sponza/sponza_fabric_green_diff.png b/projects/first_scene/assets/Sponza/sponza_fabric_green_diff.png deleted file mode 100644 index de110f369004388dae4cd5067c63428db3a07834..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_fabric_green_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:902b87faab221173bf370cea7c74cb9060b4d870ac6316b190dafded1cb12993 -size 2258220 diff --git a/projects/first_scene/assets/Sponza/sponza_flagpole_diff.png b/projects/first_scene/assets/Sponza/sponza_flagpole_diff.png deleted file mode 100644 index 5f6e0812a0df80346318baa3cb50a6888afc58f8..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_flagpole_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfffb62e770959c725d0f3db6dc7dbdd46a380ec55ef884dab94d44ca017b438 -size 1425673 diff --git a/projects/first_scene/assets/Sponza/sponza_floor_a_diff.png b/projects/first_scene/assets/Sponza/sponza_floor_a_diff.png deleted file mode 100644 index 788ed764f79ba724f04a2d603076a5b85013e188..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_floor_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a16f9230fa91f9f31dfca6216ce205f1ef132d44f3b012fbf6efc0fba69770ab -size 1996838 diff --git a/projects/first_scene/assets/Sponza/sponza_roof_diff.png b/projects/first_scene/assets/Sponza/sponza_roof_diff.png deleted file mode 100644 index c5b84261fdd1cc776a94b3ce398c7806b895f9a3..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_roof_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7fc412138c20da19f8173e53545e771f4652558dff624d4dc67143e40efe562b -size 2320533 diff --git a/projects/first_scene/assets/Sponza/sponza_thorn_diff.png b/projects/first_scene/assets/Sponza/sponza_thorn_diff.png deleted file mode 100644 index 7a9142674a7d4a6f94a48c5152cf0300743b597a..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/sponza_thorn_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a73a17c883cd0d0d67cfda2dc4118400a916366c05b9a5ac465f0c8b30fd9c8e -size 635001 diff --git a/projects/first_scene/assets/Sponza/vase_dif.png b/projects/first_scene/assets/Sponza/vase_dif.png deleted file mode 100644 index 61236a81cb324af8797b05099cd264cefe189e56..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/vase_dif.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53d06f52bf9e59df4cf00237707cca76c4f692bda61a62b06a30d321311d6dd9 -size 1842101 diff --git a/projects/first_scene/assets/Sponza/vase_hanging.png b/projects/first_scene/assets/Sponza/vase_hanging.png deleted file mode 100644 index 36a3cee71d8213225090c74f8c0dce33b9d44378..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/vase_hanging.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9d10b4f27a3c9a78d5bac882fdd4b6a6987c262f48fa490670fe5e235951e31 -size 1432804 diff --git a/projects/first_scene/assets/Sponza/vase_plant.png b/projects/first_scene/assets/Sponza/vase_plant.png deleted file mode 100644 index 7ad95e702e229f1ebd803e5203a266d15f2c07b9..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/vase_plant.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d2087371ff02212fb7014b6daefa191cf5676d2227193fff261a5d02f554cb8e -size 998089 diff --git a/projects/first_scene/assets/Sponza/vase_round.png b/projects/first_scene/assets/Sponza/vase_round.png deleted file mode 100644 index c17953abc000c44b8991e23c136c2b67348f3d1b..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/Sponza/vase_round.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aa23d48d492d5d4ada2ddb27d1ef22952b214e6eb3b301c65f9d88442723d20a -size 1871399 diff --git a/projects/first_scene/assets/shaders/shader.frag b/projects/first_scene/assets/shaders/shader.frag deleted file mode 100644 index cf96b4c20327fa3f1b1545cba7cebfdfaaf1ba7c..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/shaders/shader.frag +++ /dev/null @@ -1,31 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; - -layout(location = 0) out vec4 outColor; - -layout(set=0, binding=0) uniform texture2D meshTexture; -layout(set=0, binding=1) uniform sampler textureSampler; - -void main() { - vec3 lightDirection = normalize(vec3(0.1f, -0.9f, 0.1f)); - - float ambient = 0.35f; - float diffuse = max(0.0f, -dot(passNormal, lightDirection)); - float specular = pow(diffuse, 6.0f); - - float brightness = sqrt( - (ambient + diffuse + specular) / - (2.0f + ambient) - ); - - vec4 color = texture(sampler2D(meshTexture, textureSampler), passUV); - - if (color.a <= 0.0f) { - discard; - } - - outColor = vec4(color.rgb * brightness, color.a); -} \ No newline at end of file diff --git a/projects/first_scene/assets/shaders/shader.vert b/projects/first_scene/assets/shaders/shader.vert deleted file mode 100644 index 76855152253b48b7400f016d063ed4f0e507435e..0000000000000000000000000000000000000000 --- a/projects/first_scene/assets/shaders/shader.vert +++ /dev/null @@ -1,19 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = inNormal; - passUV = inUV; -} \ No newline at end of file diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp deleted file mode 100644 index 9fb7247ec6da805acd2312c3889c45e4a95a3d48..0000000000000000000000000000000000000000 --- a/projects/first_scene/src/main.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/gui/GUI.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/scene/Scene.hpp> -#include <vkcv/Features.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "First Scene"; - - uint32_t windowWidth = 800; - uint32_t windowHeight = 600; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - features - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - vkcv::camera::CameraManager cameraManager(window); - - vkcv::gui::GUI gui (core, windowHandle); - - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(-8, 1, -0.5)); - cameraManager.getCamera(camHandle0).setNearFar(0.1f, 30.0f); - - cameraManager.getCamera(camHandle1).setNearFar(0.1f, 30.0f); - - vkcv::scene::Scene scene = vkcv::scene::Scene::load( - core, - std::filesystem::path(argc > 1 ? argv[1] : "assets/Sponza/Sponza.gltf"), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL, - vkcv::asset::PrimitiveType::TEXCOORD_0 - } - ); - - vkcv::PassHandle scenePass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - if (!scenePass) { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ShaderProgram sceneShaderProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compileProgram(sceneShaderProgram, { - { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, - { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } - }, nullptr); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> bindings; - - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - - const vkcv::VertexLayout sceneLayout { bindings }; - const auto& material0 = scene.getMaterial(0); - - vkcv::GraphicsPipelineHandle scenePipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - sceneShaderProgram, - scenePass, - { sceneLayout }, - { material0.getDescriptorSetLayout() } - ) - ); - - if (!scenePipeline) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ImageHandle depthBuffer; - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - (swapchainHeight != core.getImageHeight(depthBuffer))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - } - - cameraManager.update(dt); - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - auto recordMesh = [](const glm::mat4& MVP, const glm::mat4& M, - vkcv::PushConstants &pushConstants, - vkcv::Drawcall& drawcall) { - pushConstants.appendDrawcall(MVP); - }; - - scene.recordDrawcalls( - cmdStream, - cameraManager.getActiveCamera(), - scenePass, - scenePipeline, - sizeof(glm::mat4), - recordMesh, - renderTargets, - windowHandle - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - - ImGui::Begin("Settings"); - ImGui::Text("Deltatime %fms, %f", dt * 1000, 1/dt); - ImGui::End(); - - gui.endGUI(); - }); - - return 0; -} diff --git a/projects/first_triangle/.gitignore b/projects/first_triangle/.gitignore deleted file mode 100644 index 7e24fd7b853bfb0a29d8b30879ef1cb95ad141c0..0000000000000000000000000000000000000000 --- a/projects/first_triangle/.gitignore +++ /dev/null @@ -1 +0,0 @@ -first_triangle \ No newline at end of file diff --git a/projects/first_triangle/CMakeLists.txt b/projects/first_triangle/CMakeLists.txt deleted file mode 100644 index 660979099b0fe0096478443a86ddf48c14bd61b0..0000000000000000000000000000000000000000 --- a/projects/first_triangle/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(first_triangle) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(first_triangle src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(first_triangle SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(first_triangle vkcv vkcv_testing vkcv_camera vkcv_shader_compiler vkcv_gui) diff --git a/projects/first_triangle/shaders/shader.frag b/projects/first_triangle/shaders/shader.frag deleted file mode 100644 index 080678beb011afe4b03aed3bf7ae7148b77932dc..0000000000000000000000000000000000000000 --- a/projects/first_triangle/shaders/shader.frag +++ /dev/null @@ -1,9 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 fragColor; -layout(location = 0) out vec4 outColor; - -void main() { - outColor = vec4(fragColor, 1.0); -} \ No newline at end of file diff --git a/projects/first_triangle/shaders/shader.vert b/projects/first_triangle/shaders/shader.vert deleted file mode 100644 index e129186a4f9b9f8ceca180391210ccaf2953c08e..0000000000000000000000000000000000000000 --- a/projects/first_triangle/shaders/shader.vert +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) out vec3 fragColor; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - vec3 positions[3] = { - vec3(-0.5, 0.5, -1), - vec3( 0.5, 0.5, -1), - vec3(0, -0.5, -1) - }; - - vec3 colors[3] = { - vec3(1, 0, 0), - vec3(0, 1, 0), - vec3(0, 0, 1) - }; - - gl_Position = mvp * vec4(positions[gl_VertexIndex], 1.0); - fragColor = colors[gl_VertexIndex]; -} \ No newline at end of file diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp deleted file mode 100644 index aae046da7f84bcf26017f5fe609732aa2e0e4df7..0000000000000000000000000000000000000000 --- a/projects/first_triangle/src/main.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "First Triangle"; - - const int windowWidth = 800; - const int windowHeight = 600; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics }, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - - vkcv::PassHandle trianglePass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined } - ); - - if (!trianglePass) { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - core.setDebugLabel(trianglePass, "Triangle Pass"); - - vkcv::ShaderProgram triangleShaderProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compileProgram(triangleShaderProgram, { - {vkcv::ShaderStage::VERTEX, "shaders/shader.vert"}, - { vkcv::ShaderStage::FRAGMENT, "shaders/shader.frag" } - }, nullptr); - - vkcv::GraphicsPipelineHandle trianglePipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - triangleShaderProgram, - trianglePass, - {}, - {} - ) - ); - - if (!trianglePipeline) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - core.setDebugLabel(trianglePipeline, "Triangle Pipeline"); - - vkcv::VertexData vertexData; - vertexData.setCount(3); - - vkcv::InstanceDrawcall drawcall (vertexData); - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::camera::CameraManager cameraManager(window); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(camHandle).setPosition(glm::vec3(0, 0, -2)); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - cameraManager.update(dt); - - glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - core.setDebugLabel(cmdStream, "Render Commands"); - - core.recordDrawcallsToCmdStream( - cmdStream, - trianglePipeline, - vkcv::pushConstants<glm::mat4>(mvp), - { drawcall }, - { swapchainInput }, - windowHandle - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/head_demo/.gitignore b/projects/head_demo/.gitignore deleted file mode 100644 index 151f56c5bb7098a3beb7b8e049c0ade02914cd91..0000000000000000000000000000000000000000 --- a/projects/head_demo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -head_demo \ No newline at end of file diff --git a/projects/head_demo/CMakeLists.txt b/projects/head_demo/CMakeLists.txt deleted file mode 100644 index 82aebb083054b80f3cf9cbb1bddb94f447e81903..0000000000000000000000000000000000000000 --- a/projects/head_demo/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(head_demo) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(head_demo src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(head_demo SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_asset_loader_include} - ${vkcv_camera_include} - ${vkcv_scene_include} - ${vkcv_shader_compiler_include} - ${vkcv_gui_include} - ${vkcv_effects_include} - ${vkcv_upscaling_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(head_demo - vkcv - ${vkcv_libraries} - vkcv_asset_loader - ${vkcv_asset_loader_libraries} - vkcv_camera vkcv_scene - vkcv_shader_compiler - vkcv_gui - vkcv_effects - vkcv_upscaling) diff --git a/projects/head_demo/assets/shaders/clip.inc b/projects/head_demo/assets/shaders/clip.inc deleted file mode 100644 index edb5ac3ccfe5d7f6ad1e59dd88bee4446b85118f..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/clip.inc +++ /dev/null @@ -1,19 +0,0 @@ - -#define CLIP_SCALE 10000.0f - -vec4 clipPosition(vec4 pos) { - return vec4( - max(clipX, pos.x), - max(clipY, pos.y), - max(clipZ, pos.z), - 1.0f / CLIP_SCALE - ); -} - -vec4 clipByLimit(vec4 pos) { - if (pos.x / pos.w < clipLimit) { - return vec4(pos.xyz / pos.w, 1.0f); - } else { - return vec4(clipLimit, pos.y / pos.w, pos.z / pos.w, 1.0f); - } -} diff --git a/projects/head_demo/assets/shaders/red.frag b/projects/head_demo/assets/shaders/red.frag deleted file mode 100644 index 35735be779edd0bf88890638329dc53f6b691f57..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/red.frag +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec3 passEdge; - -layout(location = 0) out vec3 outColor; - -void main() { - outColor = (0.1f + max(dot(passNormal, vec3(1.0f, -1.0f, 0.5f)), 0.0f) * 0.9f) * (passEdge + 0.5f); -} \ No newline at end of file diff --git a/projects/head_demo/assets/shaders/shader.frag b/projects/head_demo/assets/shaders/shader.frag deleted file mode 100644 index b8756a6b84af4e93f9ac932ec01d28e4f2e9638b..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/shader.frag +++ /dev/null @@ -1,10 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; - -layout(location = 0) out vec3 outColor; - -void main() { - outColor = (vec3(0.3f) + max(dot(passNormal, vec3(1.0f, -1.0f, 0.5f)), 0.0f) * vec3(0.7f)); -} \ No newline at end of file diff --git a/projects/head_demo/assets/shaders/shader.geom b/projects/head_demo/assets/shaders/shader.geom deleted file mode 100644 index 275b300ee3466e117876aa46a6ea1cde11f6f17d..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/shader.geom +++ /dev/null @@ -1,53 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -layout(triangles) in; -layout(triangle_strip, max_vertices = 3) out; - -layout(location = 0) in vec3 geomNormal[]; - -layout(location = 0) out vec3 passNormal; - -layout(set=1, binding=0) uniform clipBuffer { - float clipLimit; - float clipX; - float clipY; - float clipZ; -}; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -#include "clip.inc" - -void main() { - vec4 v0 = gl_in[0].gl_Position; - vec4 v1 = gl_in[1].gl_Position; - vec4 v2 = gl_in[2].gl_Position; - - v0 = clipPosition(v0 / CLIP_SCALE); - v1 = clipPosition(v1 / CLIP_SCALE); - v2 = clipPosition(v2 / CLIP_SCALE); - - float dx = abs(v0.x - clipX) + abs(v1.x - clipX) + abs(v2.x - clipX); - float dy = abs(v0.y - clipY) + abs(v1.y - clipY) + abs(v2.y - clipY); - float dz = abs(v0.z - clipZ) + abs(v1.z - clipZ) + abs(v2.z - clipZ); - - if (dx * dy * dz > 0.0f) { - gl_Position = mvp * (v0 * CLIP_SCALE); - passNormal = geomNormal[0]; - EmitVertex(); - - gl_Position = mvp * (v1 * CLIP_SCALE); - passNormal = geomNormal[1]; - EmitVertex(); - - gl_Position = mvp * (v2 * CLIP_SCALE); - passNormal = geomNormal[2]; - EmitVertex(); - - EndPrimitive(); - } -} diff --git a/projects/head_demo/assets/shaders/shader.vert b/projects/head_demo/assets/shaders/shader.vert deleted file mode 100644 index 26e43e9c89dc2ffb2355d60be8288fa9832f8baa..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/shader.vert +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; - -layout(location = 0) out vec3 geomNormal; - -void main() { - gl_Position = vec4(inPosition, 1.0); - geomNormal = inNormal; -} \ No newline at end of file diff --git a/projects/head_demo/assets/shaders/wired.geom b/projects/head_demo/assets/shaders/wired.geom deleted file mode 100644 index 689e073dde7fd993d164cfea0b7ca777d79f8508..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/shaders/wired.geom +++ /dev/null @@ -1,53 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -layout(triangles) in; -layout(points, max_vertices = 1) out; - -layout(location = 0) in vec3 geomNormal[]; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec3 passEdge; - -layout(set=1, binding=0) uniform clipBuffer { - float clipLimit; - float clipX; - float clipY; - float clipZ; -}; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -#include "clip.inc" - -void main() { - vec4 v0 = gl_in[0].gl_Position; - vec4 v1 = gl_in[1].gl_Position; - vec4 v2 = gl_in[2].gl_Position; - - v0 = clipPosition(v0 / CLIP_SCALE); - v1 = clipPosition(v1 / CLIP_SCALE); - v2 = clipPosition(v2 / CLIP_SCALE); - - float dx = abs(v0.x - clipX) + abs(v1.x - clipX) + abs(v2.x - clipX); - float dy = abs(v0.y - clipY) + abs(v1.y - clipY) + abs(v2.y - clipY); - float dz = abs(v0.z - clipZ) + abs(v1.z - clipZ) + abs(v2.z - clipZ); - - if (dx * dy * dz <= 0.0f) { - v0 = clipByLimit(mvp * gl_in[0].gl_Position); - v1 = clipByLimit(mvp * gl_in[1].gl_Position); - v2 = clipByLimit(mvp * gl_in[2].gl_Position); - - if ((v0.x < clipLimit) || (v1.x < clipLimit) || (v2.x < clipLimit)) { - gl_Position = (v0 + v1 + v2) / 3; - passNormal = (geomNormal[0] + geomNormal[1] + geomNormal[2]) / 3; - passEdge = vec3(dx, dy, dz); - EmitVertex(); - - EndPrimitive(); - } - } -} diff --git a/projects/head_demo/assets/skull/license.txt b/projects/head_demo/assets/skull/license.txt deleted file mode 100644 index 6816d6d659087b54dfc6b8e0c2c0e158daa001f0..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/skull/license.txt +++ /dev/null @@ -1,11 +0,0 @@ -Model Information: -* title: The Anatomy of the Human Skull -* source: https://sketchfab.com/3d-models/the-anatomy-of-the-human-skull-baf6ac7b781a46218dca2b59dee58817 -* author: HannahNewey (https://sketchfab.com/HannahNewey) - -Model License: -* license type: CC-BY-NC-SA-4.0 (http://creativecommons.org/licenses/by-nc-sa/4.0/) -* requirements: Author must be credited. No commercial use. Modified versions must have the same license. - -If you use this 3D model in your project be sure to copy paste this credit wherever you share it: -This work is based on "The Anatomy of the Human Skull" (https://sketchfab.com/3d-models/the-anatomy-of-the-human-skull-baf6ac7b781a46218dca2b59dee58817) by HannahNewey (https://sketchfab.com/HannahNewey) licensed under CC-BY-NC-SA-4.0 (http://creativecommons.org/licenses/by-nc-sa/4.0/) \ No newline at end of file diff --git a/projects/head_demo/assets/skull/scene.bin b/projects/head_demo/assets/skull/scene.bin deleted file mode 100644 index e995091c9d2f10b15959a65d3b0e0de3c9edb0e4..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/skull/scene.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df3cb5e715426a8e7a3c4883eb7c53022e09011ded9ae385cd6bc59824129ed8 -size 78176672 diff --git a/projects/head_demo/assets/skull/scene.gltf b/projects/head_demo/assets/skull/scene.gltf deleted file mode 100644 index 6a2b75fa5af1e826bf3851db576dd3051e7b77c3..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/skull/scene.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8cd4f673e0a555dc138b96e07be60546a799f9ef11837870eae27b16ffd5c1c7 -size 36442 diff --git a/projects/head_demo/assets/skull_scaled/scene.bin b/projects/head_demo/assets/skull_scaled/scene.bin deleted file mode 100644 index 3edc8865ed5465c33cb8c9d2f2b0eb83b1a5b599..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/skull_scaled/scene.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:685e971ce4e99be286464c56a373e528dc507ce18b5bfdff45f90db27e49176b -size 56596296 diff --git a/projects/head_demo/assets/skull_scaled/scene.gltf b/projects/head_demo/assets/skull_scaled/scene.gltf deleted file mode 100644 index 72087f182e4cd1ce1a73f7af9db1d36608df2029..0000000000000000000000000000000000000000 --- a/projects/head_demo/assets/skull_scaled/scene.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f05a4c8f979dab2793540bafe2b392133d64af028a0ff97f0159dbc52fc20230 -size 4843 diff --git a/projects/head_demo/src/main.cpp b/projects/head_demo/src/main.cpp deleted file mode 100644 index 1b6533cfdd3726ad8b1901ae5bbb800d5c65b81d..0000000000000000000000000000000000000000 --- a/projects/head_demo/src/main.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/gui/GUI.hpp> -#include <chrono> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/scene/Scene.hpp> -#include <vkcv/effects/BloomAndFlaresEffect.hpp> -#include <vkcv/upscaling/FSRUpscaling.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "First Scene"; - - uint32_t windowWidth = 800; - uint32_t windowHeight = 600; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } - ); - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - vkcv::camera::CameraManager cameraManager(window); - - vkcv::gui::GUI gui (core, windowHandle); - - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(15.5f, 0, 0)); - cameraManager.getCamera(camHandle0).setNearFar(0.1f, 30.0f); - - cameraManager.getCamera(camHandle1).setNearFar(0.1f, 30.0f); - - vkcv::scene::Scene scene = vkcv::scene::Scene::load( - core, - std::filesystem::path(argc > 1 ? argv[1] : "assets/skull_scaled/scene.gltf"), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL - } - ); - - vk::Format colorFormat = vk::Format::eR16G16B16A16Sfloat; - - vkcv::PassHandle linePass = vkcv::passFormats(core, { colorFormat, vk::Format::eD32Sfloat }); - vkcv::PassHandle scenePass = vkcv::passFormats(core, { colorFormat, vk::Format::eD32Sfloat }, false); - - if ((!scenePass) || (!linePass)) { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ShaderProgram sceneShaderProgram; - vkcv::ShaderProgram lineShaderProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compileProgram(sceneShaderProgram, { - { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, - { vkcv::ShaderStage::GEOMETRY, "assets/shaders/shader.geom" }, - { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } - }, nullptr); - - compiler.compileProgram(lineShaderProgram, { - { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, - { vkcv::ShaderStage::GEOMETRY, "assets/shaders/wired.geom" }, - { vkcv::ShaderStage::FRAGMENT, "assets/shaders/red.frag" } - }, nullptr); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> bindings; - - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - - const auto& clipBindings = sceneShaderProgram.getReflectedDescriptors().at(1); - - auto clipDescriptorSetLayout = core.createDescriptorSetLayout(clipBindings); - auto clipDescriptorSet = core.createDescriptorSet(clipDescriptorSetLayout); - - float clipLimit = 1.0f; - float clipX = 0.0f; - float clipY = 0.0f; - float clipZ = 0.0f; - - auto clipBuffer = vkcv::buffer<float>(core, vkcv::BufferType::UNIFORM, 4); - clipBuffer.fill({ clipLimit, -clipX, -clipY, -clipZ }); - - vkcv::DescriptorWrites clipWrites; - clipWrites.writeUniformBuffer(0, clipBuffer.getHandle()); - - core.writeDescriptorSet(clipDescriptorSet, clipWrites); - - float mouseX = -0.0f; - bool dragLimit = false; - - window.e_mouseMove.add([&](double x, double y) { - double cx = (x - window.getWidth() * 0.5); - double dx = cx / window.getWidth(); - - mouseX = 2.0f * static_cast<float>(dx); - - if (dragLimit) { - clipLimit = mouseX; - } - }); - - window.e_mouseButton.add([&](int button, int action, int mods) { - if ((std::abs(mouseX - clipLimit) < 0.1f) && (action == GLFW_PRESS)) { - dragLimit = true; - } else { - dragLimit = false; - } - }); - - const vkcv::VertexLayout sceneLayout { bindings }; - const auto& material0 = scene.getMaterial(0); - - vkcv::GraphicsPipelineHandle scenePipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - sceneShaderProgram, - scenePass, - { sceneLayout }, - { material0.getDescriptorSetLayout(), clipDescriptorSetLayout } - ) - ); - - vkcv::GraphicsPipelineHandle linePipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - lineShaderProgram, - linePass, - { sceneLayout }, - { material0.getDescriptorSetLayout(), clipDescriptorSetLayout } - ) - ); - - if ((!scenePipeline) || (!linePipeline)) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); - - vkcv::ImageHandle depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainExtent.width, - swapchainExtent.height - ); - - vkcv::ImageHandle colorBuffer = core.createImage( - colorFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::effects::BloomAndFlaresEffect bloomAndFlares (core); - vkcv::upscaling::FSRUpscaling upscaling (core); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((swapchainWidth != swapchainExtent.width) || ((swapchainHeight != swapchainExtent.height))) { - depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight); - - colorBuffer = core.createImage( - colorFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - - swapchainExtent.width = swapchainWidth; - swapchainExtent.height = swapchainHeight; - } - - cameraManager.update(dt); - - clipBuffer.fill({ clipLimit, -clipX, -clipY, -clipZ }); - - const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - auto recordMesh = [&](const glm::mat4& MVP, const glm::mat4& M, - vkcv::PushConstants &pushConstants, - vkcv::Drawcall& drawcall) { - pushConstants.appendDrawcall(MVP); - drawcall.useDescriptorSet(1, clipDescriptorSet); - }; - - scene.recordDrawcalls( - cmdStream, - cameraManager.getActiveCamera(), - linePass, - linePipeline, - sizeof(glm::mat4), - recordMesh, - renderTargets, - windowHandle - ); - - bloomAndFlares.recordEffect(cmdStream, colorBuffer, colorBuffer); - - scene.recordDrawcalls( - cmdStream, - cameraManager.getActiveCamera(), - scenePass, - scenePipeline, - sizeof(glm::mat4), - recordMesh, - renderTargets, - windowHandle - ); - - core.prepareImageForSampling(cmdStream, colorBuffer); - core.prepareImageForStorage(cmdStream, swapchainInput); - upscaling.recordUpscaling(cmdStream, colorBuffer, swapchainInput); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - - ImGui::Begin("Settings"); - ImGui::SliderFloat("Clip X", &clipX, -1.0f, 1.0f); - ImGui::SliderFloat("Clip Y", &clipY, -1.0f, 1.0f); - ImGui::SliderFloat("Clip Z", &clipZ, -1.0f, 1.0f); - ImGui::Text("Mesh by HannahNewey (https://sketchfab.com/HannahNewey)"); - ImGui::End(); - - gui.endGUI(); - }); - - return 0; -} diff --git a/projects/indirect_dispatch/.gitignore b/projects/indirect_dispatch/.gitignore deleted file mode 100644 index 5f18d9c205e538dabeb0282640bede0359edc33d..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -indirect_dispatch diff --git a/projects/indirect_dispatch/CMakeLists.txt b/projects/indirect_dispatch/CMakeLists.txt deleted file mode 100644 index 53b0d1b15dc2eeb32308e16ad81d476ed502d370..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(indirect_dispatch) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(indirect_dispatch src/main.cpp) - -target_sources(indirect_dispatch PRIVATE - src/App.hpp - src/App.cpp - - src/AppConfig.hpp - src/MotionBlurConfig.hpp - - src/AppSetup.hpp - src/AppSetup.cpp - - src/MotionBlur.hpp - src/MotionBlur.cpp - - src/MotionBlurSetup.hpp - src/MotionBlurSetup.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(indirect_dispatch SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(indirect_dispatch vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_testing vkcv_camera vkcv_shader_compiler vkcv_gui) \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/models/cube.bin b/projects/indirect_dispatch/assets/models/cube.bin deleted file mode 100644 index 728d38cd39cd10c30a93c15eef021cb0cf7dda74..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/models/cube.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccc59e0be3552b4347457bc935d8e548b52f12ca91716a0f0dc37d5bac65f123 -size 840 diff --git a/projects/indirect_dispatch/assets/models/cube.gltf b/projects/indirect_dispatch/assets/models/cube.gltf deleted file mode 100644 index ef975c326c71ec1a2fa650a422989534f1c32191..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/models/cube.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0072448af64bdebffe8eec5a7f32f110579b1a256cd97438bf227e4cc4a87328 -size 2571 diff --git a/projects/indirect_dispatch/assets/models/grid.png b/projects/indirect_dispatch/assets/models/grid.png deleted file mode 100644 index 5f40eee62f7f9dba3dc156ff6a3653ea2e7f5391..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/models/grid.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a11c33e4935d93723ab11f597f2aca1ca1ff84af66f2e2d10a01580eb0b7831a -size 40135 diff --git a/projects/indirect_dispatch/assets/models/ground.bin b/projects/indirect_dispatch/assets/models/ground.bin deleted file mode 100644 index e29e4f18552def1ac64c167d994be959f82e35c7..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/models/ground.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f8e20cd1c62da3111536283517b63a149f258ea82b1dff8ddafdb79020065b7c -size 140 diff --git a/projects/indirect_dispatch/assets/models/ground.gltf b/projects/indirect_dispatch/assets/models/ground.gltf deleted file mode 100644 index 6935d3e21a06da1629087c9b0b7f957c57feaf6e..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/models/ground.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a12b8d7cca8110d4ffa9bc4a2223286d1ccfd9c087739a75294e0a3fbfb65c5 -size 2840 diff --git a/projects/indirect_dispatch/assets/shaders/gammaCorrection.comp b/projects/indirect_dispatch/assets/shaders/gammaCorrection.comp deleted file mode 100644 index 7a6e129d7f8658d3ea424d35b809a3384d12bccc..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/gammaCorrection.comp +++ /dev/null @@ -1,24 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) uniform texture2D inTexture; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2, rgba8) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(outImage); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(coord, outImageRes))) - return; - - vec2 uv = vec2(coord) / outImageRes; - vec3 linearColor = texture(sampler2D(inTexture, textureSampler), uv).rgb; - - vec3 gammaCorrected = pow(linearColor, vec3(1 / 2.2)); - - imageStore(outImage, coord, vec4(gammaCorrected, 0.f)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/mesh.frag b/projects/indirect_dispatch/assets/shaders/mesh.frag deleted file mode 100644 index 531c9cbf8b5e097af618d2ca639821a62a30611d..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/mesh.frag +++ /dev/null @@ -1,17 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform texture2D albedoTexture; -layout(set=0, binding=1) uniform sampler textureSampler; - -void main() { - vec3 albedo = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; - vec3 N = normalize(passNormal); - float light = max(N.y * 0.5 + 0.5, 0); - outColor = light * albedo; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/mesh.vert b/projects/indirect_dispatch/assets/shaders/mesh.vert deleted file mode 100644 index 734fd63cdee66e5fbf61cc427ca21fae18a31d82..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/mesh.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; - -layout( push_constant ) uniform constants{ - mat4 mvp; - mat4 model; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = (model * vec4(inNormal, 0)).xyz; - passUV = inUV; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlur.comp b/projects/indirect_dispatch/assets/shaders/motionBlur.comp deleted file mode 100644 index 091c21aa7ddfe9db1780aa64adc77fd5457a3843..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlur.comp +++ /dev/null @@ -1,194 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlur.inc" -#include "motionBlurConfig.inc" -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) uniform texture2D inColor; -layout(set=0, binding=1) uniform texture2D inDepth; -layout(set=0, binding=2) uniform texture2D inMotionFullRes; -layout(set=0, binding=3) uniform texture2D inMotionNeighbourhoodMax; -layout(set=0, binding=4) uniform sampler nearestSampler; -layout(set=0, binding=5, r11f_g11f_b10f) uniform image2D outImage; - -layout(set=0, binding=6) buffer WorkTileBuffer { - WorkTiles workTiles; -}; - -layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - // computed from delta time and shutter speed - float motionScaleFactor; - // camera planes are needed to linearize depth - float cameraNearPlane; - float cameraFarPlane; - float motionTileOffsetLength; -}; - -float linearizeDepth(float depth, float near, float far){ - return near * far / (far + depth * (near - far)); -} - -struct SampleData{ - vec3 color; - float depthLinear; - vec2 coordinate; - vec2 motion; - float velocityPixels; -}; - -struct PointSpreadCompare{ - float foreground; - float background; -}; - -// results in range [0, 1] -// computes if the sample pixel in the foreground would blur over the main pixel and if the sample pixel in the background would be part of the main pixel background -// contribution depends on if the distance between pixels is smaller than it's velocity -// note that compared to the constant falloff used in McGuire's papers this function from Jimenez is constant until the last pixel -// this is important for the later gradient computation -PointSpreadCompare samplePointSpreadCompare(SampleData mainPixel, SampleData samplePixel){ - - float sampleOffset = distance(mainPixel.coordinate, samplePixel.coordinate); - - PointSpreadCompare pointSpread; - pointSpread.foreground = clamp(1 - sampleOffset + samplePixel.velocityPixels, 0, 1); - pointSpread.background = clamp(1 - sampleOffset + mainPixel.velocityPixels, 0, 1); - - return pointSpread; -} - -struct DepthClassification{ - float foreground; - float background; -}; - -// classifies depthSample compared to depthMain in regards to being in the fore- or background -// the range is [0, 1] and sums to 1 -DepthClassification sampleDepthClassification(SampleData mainPixel, SampleData samplePixel){ - - const float softDepthExtent = 0.1; - - DepthClassification classification; - // only the sign is different, so the latter term will cancel out on addition, so only two times 0.5 remains which sums to one - classification.foreground = clamp(0.5 + (mainPixel.depthLinear - samplePixel.depthLinear) / softDepthExtent, 0, 1); - classification.background = clamp(0.5 - (mainPixel.depthLinear - samplePixel.depthLinear) / softDepthExtent, 0, 1); - return classification; -} - -// reconstruction filter and helper functions from "Next Generation Post Processing in Call of Duty Advanced Warfare", Jimenez -// returns value in range [0, 1] -float computeSampleWeigth(SampleData mainPixel, SampleData samplePixel){ - - PointSpreadCompare pointSpread = samplePointSpreadCompare( mainPixel, samplePixel); - DepthClassification depthClassification = sampleDepthClassification(mainPixel, samplePixel); - - return - depthClassification.foreground * pointSpread.foreground + - depthClassification.background * pointSpread.background; -} - -SampleData loadSampleData(vec2 uv){ - - SampleData data; - data.color = texture(sampler2D(inColor, nearestSampler), uv).rgb; - data.coordinate = ivec2(uv * imageSize(outImage)); - data.motion = processMotionVector(texture(sampler2D(inMotionFullRes, nearestSampler), uv).rg, motionScaleFactor, imageSize(outImage)); - data.velocityPixels = length(data.motion * imageSize(outImage)); - data.depthLinear = texture(sampler2D(inDepth, nearestSampler), uv).r; - data.depthLinear = linearizeDepth(data.depthLinear, cameraNearPlane, cameraFarPlane); - - return data; -} - -void main(){ - - uint tileIndex = gl_WorkGroupID.x; - ivec2 tileCoordinates = workTiles.tileXY[tileIndex]; - ivec2 coord = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); - - if(any(greaterThanEqual(coord, imageSize(outImage)))) - return; - - ivec2 textureRes = textureSize(sampler2D(inColor, nearestSampler), 0); - vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center - - // the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise - // dither is shifted, so it does not line up with motion tiles - float motionOffset = motionTileOffsetLength * (dither(coord + ivec2(ditherSize / 2)) * 2 - 1); - vec2 motionNeighbourhoodMax = processMotionVector(texelFetch(sampler2D(inMotionNeighbourhoodMax, nearestSampler), ivec2(coord + motionOffset) / motionTileSize, 0).rg, motionScaleFactor, imageSize(outImage)); - - SampleData mainPixel = loadSampleData(uv); - - // early out on movement less than half a pixel - if(length(motionNeighbourhoodMax * imageSize(outImage)) <= 0.5){ - imageStore(outImage, coord, vec4(mainPixel.color, 0.f)); - return; - } - - vec3 color = vec3(0); - float weightSum = 0; - - // clamping start and end points avoids artifacts at image borders - // the sampler clamps the sample uvs anyways, but without clamping here, many samples can be stuck at the border - vec2 uvStart = clamp(uv - motionNeighbourhoodMax, 0, 1); - vec2 uvEnd = clamp(uv + motionNeighbourhoodMax, 0, 1); - - // samples are placed evenly, but the entire filter is jittered - // dither returns either 0 or 1 - // the sampleUV code expects an offset in range [-0.5, 0.5], so the dither is rescaled to a binary -0.25/0.25 - float random = dither(coord) * 0.5 - 0.25; - - const int sampleCountHalf = 8; - - // two samples are processed at a time to allow for mirrored background reconstruction - for(int i = 0; i < sampleCountHalf; i++){ - - vec2 sampleUV1 = mix(uv, uvEnd, (i + random + 1) / float(sampleCountHalf + 1)); - vec2 sampleUV2 = mix(uv, uvStart, (i + random + 1) / float(sampleCountHalf + 1)); - - SampleData sample1 = loadSampleData(sampleUV1); - SampleData sample2 = loadSampleData(sampleUV2); - - float weight1 = computeSampleWeigth(mainPixel, sample1); - float weight2 = computeSampleWeigth(mainPixel, sample2); - - bool mirroredBackgroundReconstruction = true; - if(mirroredBackgroundReconstruction){ - // see Jimenez paper for details and comparison - // problem is that in the foreground the background is reconstructed, which is blurry - // in the background the background is obviously known, so it is sharper - // at the border between fore- and background this causes a discontinuity - // to fix this the weights are mirrored on this border, effectively reconstructing the background, even though it is known - - // these bools check if sample1 is an affected background pixel (further away and slower moving than sample2) - bool inBackground = sample1.depthLinear > sample2.depthLinear; - bool blurredOver = sample1.velocityPixels < sample2.velocityPixels; - - // this mirrors the weights depending on the results: - // if both conditions are true, then weight2 is mirrored to weight1 - // if both conditions are false, then weight1 is mirrored to weight2, as sample2 is an affected background pixel - // if only one condition is true, then the weights are kept as is - weight1 = inBackground && blurredOver ? weight2 : weight1; - weight2 = inBackground || blurredOver ? weight2 : weight1; - } - - weightSum += weight1; - weightSum += weight2; - - color += sample1.color * weight1; - color += sample2.color * weight2; - } - - // normalize color and weight - weightSum /= sampleCountHalf * 2; - color /= sampleCountHalf * 2; - - // the main color is considered the background - // the weight sum can be interpreted as the alpha of the combined samples, see Jimenez paper - color += (1 - weightSum) * mainPixel.color; - - imageStore(outImage, coord, vec4(color, 0.f)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlur.inc b/projects/indirect_dispatch/assets/shaders/motionBlur.inc deleted file mode 100644 index 6fdaf4c5f5e4b07a3111946b0732137f42f295ef..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlur.inc +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MOTION_BLUR -#define MOTION_BLUR - -#include "motionBlurConfig.inc" - -// see "A Reconstruction Filter for Plausible Motion Blur", section 2.2 -vec2 processMotionVector(vec2 motion, float motionScaleFactor, ivec2 imageResolution){ - // every frame a pixel should blur over the distance it moves - // as we blur in two directions (where it was and where it will be) we must half the motion - vec2 motionHalf = motion * 0.5; - vec2 motionScaled = motionHalf * motionScaleFactor; // scale factor contains shutter speed and delta time - - // pixels are anisotropic, so the ratio for clamping the velocity is computed in pixels instead of uv coordinates - vec2 motionPixel = motionScaled * imageResolution; - float velocityPixels = length(motionPixel); - - float epsilon = 0.0001; - - // this clamps the motion to not exceed the radius given by the motion tile size - return motionScaled * max(0.5, min(velocityPixels, motionTileSize)) / (velocityPixels + epsilon); -} - -const int ditherSize = 4; - -// simple binary dither pattern -// could be optimized to avoid modulo and branch -float dither(ivec2 coord){ - - bool x = coord.x % ditherSize < (ditherSize / 2); - bool y = coord.y % ditherSize < (ditherSize / 2); - - return x ^^ y ? 1 : 0; -} - -#endif // #ifndef MOTION_BLUR \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurColorCopy.comp b/projects/indirect_dispatch/assets/shaders/motionBlurColorCopy.comp deleted file mode 100644 index 1d8f210c86c2670241fa1d011835b120a39eddc0..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurColorCopy.comp +++ /dev/null @@ -1,29 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlurConfig.inc" -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) uniform texture2D inColor; -layout(set=0, binding=1) uniform sampler nearestSampler; -layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; - -layout(set=0, binding=3) buffer WorkTileBuffer { - WorkTiles workTiles; -}; - -layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; - -void main(){ - - uint tileIndex = gl_WorkGroupID.x; - ivec2 tileCoordinates = workTiles.tileXY[tileIndex]; - ivec2 coordinate = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); - - if(any(greaterThanEqual(coordinate, imageSize(outImage)))) - return; - - vec3 color = texelFetch(sampler2D(inColor, nearestSampler), coordinate, 0).rgb; - - imageStore(outImage, coordinate, vec4(color, 0.f)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurConfig.inc b/projects/indirect_dispatch/assets/shaders/motionBlurConfig.inc deleted file mode 100644 index 5b8679da119d84242c55d7d89de80ed8b64e5cc9..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurConfig.inc +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MOTION_BLUR_CONFIG -#define MOTION_BLUR_CONFIG - -const int motionTileSize = 16; -const int maxMotionBlurWidth = 3840; -const int maxMotionBlurHeight = 2160; - -#endif // #ifndef MOTION_BLUR_CONFIG \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurFastPath.comp b/projects/indirect_dispatch/assets/shaders/motionBlurFastPath.comp deleted file mode 100644 index 2e27ebedcc4be1da93ff89a187fe1d3e992e8d22..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurFastPath.comp +++ /dev/null @@ -1,68 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlur.inc" -#include "motionBlurConfig.inc" -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) uniform texture2D inColor; -layout(set=0, binding=1) uniform texture2D inMotionNeighbourhoodMax; -layout(set=0, binding=2) uniform sampler nearestSampler; -layout(set=0, binding=3, r11f_g11f_b10f) uniform image2D outImage; - -layout(set=0, binding=4) buffer WorkTileBuffer { - WorkTiles workTiles; -}; - -layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - // computed from delta time and shutter speed - float motionScaleFactor; -}; - -void main(){ - - uint tileIndex = gl_WorkGroupID.x; - ivec2 tileCoordinates = workTiles.tileXY[tileIndex]; - ivec2 coord = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); - - if(any(greaterThanEqual(coord, imageSize(outImage)))) - return; - - ivec2 textureRes = textureSize(sampler2D(inColor, nearestSampler), 0); - vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center - - vec2 motionNeighbourhoodMax = processMotionVector(texelFetch(sampler2D(inMotionNeighbourhoodMax, nearestSampler), coord / motionTileSize, 0).rg, motionScaleFactor, imageSize(outImage)); - - // early out on movement less than half a pixel - if(length(motionNeighbourhoodMax * imageSize(outImage)) <= 0.5){ - vec3 color = texture(sampler2D(inColor, nearestSampler), uv).rgb; - imageStore(outImage, coord, vec4(color, 0.f)); - return; - } - - vec3 color = vec3(0); - - // clamping start and end points avoids artifacts at image borders - // the sampler clamps the sample uvs anyways, but without clamping here, many samples can be stuck at the border - vec2 uvStart = clamp(uv - motionNeighbourhoodMax, 0, 1); - vec2 uvEnd = clamp(uv + motionNeighbourhoodMax, 0, 1); - - // samples are placed evenly, but the entire filter is jittered - // dither returns either 0 or 1 - // the sampleUV code expects an offset in range [-0.5, 0.5], so the dither is rescaled to a binary -0.25/0.25 - float random = dither(coord) * 0.5 - 0.25; - - const int sampleCount = 16; - - for(int i = 0; i < sampleCount; i++){ - - vec2 sampleUV = mix(uvStart, uvEnd, (i + random + 1) / float(sampleCount + 1)); - color += texture(sampler2D(inColor, nearestSampler), sampleUV).rgb; - } - - color /= sampleCount; - - imageStore(outImage, coord, vec4(color, 0.f)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurTileClassification.comp b/projects/indirect_dispatch/assets/shaders/motionBlurTileClassification.comp deleted file mode 100644 index 3c6f9e3715951ac4fe6770725c3314590cbbff47..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurTileClassification.comp +++ /dev/null @@ -1,58 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) uniform texture2D inMotionMax; -layout(set=0, binding=1) uniform texture2D inMotionMin; -layout(set=0, binding=2) uniform sampler nearestSampler; - -layout(set=0, binding=3) buffer FullPathTileBuffer { - WorkTiles fullPathTiles; -}; - -layout(set=0, binding=4) buffer CopyPathTileBuffer { - WorkTiles copyPathTiles; -}; - -layout(set=0, binding=5) buffer FastPathTileBuffer { - WorkTiles fastPathTiles; -}; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - uint width; - uint height; - float fastPathThreshold; -}; - -void main(){ - - ivec2 tileCoord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, textureSize(sampler2D(inMotionMax, nearestSampler), 0)))) - return; - - vec2 motionMax = texelFetch(sampler2D(inMotionMax, nearestSampler), tileCoord, 0).rg; - vec2 motionMin = texelFetch(sampler2D(inMotionMin, nearestSampler), tileCoord, 0).rg; - - vec2 motionPixelMax = motionMax * vec2(width, height); - vec2 motionPixelMin = motionMin * vec2(width, height); - - float velocityPixelMax = length(motionPixelMax); - float minMaxDistance = distance(motionPixelMin, motionPixelMax); - - if(velocityPixelMax <= 0.5){ - uint index = atomicAdd(copyPathTiles.tileCount, 1); - copyPathTiles.tileXY[index] = tileCoord; - } - else if(minMaxDistance <= fastPathThreshold){ - uint index = atomicAdd(fastPathTiles.tileCount, 1); - fastPathTiles.tileXY[index] = tileCoord; - } - else{ - uint index = atomicAdd(fullPathTiles.tileCount, 1); - fullPathTiles.tileXY[index] = tileCoord; - } -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurTileClassificationVis.comp b/projects/indirect_dispatch/assets/shaders/motionBlurTileClassificationVis.comp deleted file mode 100644 index 3382ff5ef0b407b9a3a7785eda0d19efe5a8f96e..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurTileClassificationVis.comp +++ /dev/null @@ -1,56 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlurConfig.inc" -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) uniform texture2D inColor; -layout(set=0, binding=1) uniform sampler nearestSampler; -layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; - -layout(set=0, binding=3) buffer FullPathTileBuffer { - WorkTiles fullPathTiles; -}; - -layout(set=0, binding=4) buffer CopyPathTileBuffer { - WorkTiles copyPathTiles; -}; - -layout(set=0, binding=5) buffer FastPathTileBuffer { - WorkTiles fastPathTiles; -}; - -layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; - -void main(){ - - uint tileIndexFullPath = gl_WorkGroupID.x; - uint tileIndexCopyPath = gl_WorkGroupID.x - fullPathTiles.tileCount; - uint tileIndexFastPath = gl_WorkGroupID.x - fullPathTiles.tileCount - copyPathTiles.tileCount; - - vec3 debugColor; - ivec2 tileCoordinates; - - if(tileIndexFullPath < fullPathTiles.tileCount){ - debugColor = vec3(1, 0, 0); - tileCoordinates = fullPathTiles.tileXY[tileIndexFullPath]; - } - else if(tileIndexCopyPath < copyPathTiles.tileCount){ - debugColor = vec3(0, 1, 0); - tileCoordinates = copyPathTiles.tileXY[tileIndexCopyPath]; - } - else if(tileIndexFastPath < fastPathTiles.tileCount){ - debugColor = vec3(0, 0, 1); - tileCoordinates = fastPathTiles.tileXY[tileIndexFastPath]; - } - else{ - return; - } - - ivec2 coordinate = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); - vec3 color = texelFetch(sampler2D(inColor, nearestSampler), coordinate, 0).rgb; - - color = mix(color, debugColor, 0.5); - - imageStore(outImage, coordinate, vec4(color, 0)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurWorkTile.inc b/projects/indirect_dispatch/assets/shaders/motionBlurWorkTile.inc deleted file mode 100644 index 8577f100aac524b93eecac406606a962bc52d222..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurWorkTile.inc +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MOTION_BLUR_WORK_TILE -#define MOTION_BLUR_WORK_TILE - -#include "motionBlurConfig.inc" - -const int maxTileCount = - (maxMotionBlurWidth + motionTileSize - 1) / motionTileSize * - (maxMotionBlurHeight + motionTileSize - 1) / motionTileSize; - -struct WorkTiles{ - uint tileCount; - // dispatch Y/Z are here so the buffer can be used directly as an indirect dispatch argument buffer - uint dispatchY; - uint dispatchZ; - - ivec2 tileXY[maxTileCount]; -}; - -#endif // #ifndef MOTION_BLUR_WORK_TILE \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionBlurWorkTileReset.comp b/projects/indirect_dispatch/assets/shaders/motionBlurWorkTileReset.comp deleted file mode 100644 index d4b55582a0a18c0c6a3fecf1dd6ce69ed49ca2c1..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionBlurWorkTileReset.comp +++ /dev/null @@ -1,32 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlurWorkTile.inc" - -layout(set=0, binding=0) buffer FullPathTileBuffer { - WorkTiles fullPathTiles; -}; - -layout(set=0, binding=1) buffer CopyPathTileBuffer { - WorkTiles copyPathTiles; -}; - -layout(set=0, binding=2) buffer FastPathTileBuffer { - WorkTiles fastPathTiles; -}; - -layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; - -void main(){ - fullPathTiles.tileCount = 0; - fullPathTiles.dispatchY = 1; - fullPathTiles.dispatchZ = 1; - - copyPathTiles.tileCount = 0; - copyPathTiles.dispatchY = 1; - copyPathTiles.dispatchZ = 1; - - fastPathTiles.tileCount = 0; - fastPathTiles.dispatchY = 1; - fastPathTiles.dispatchZ = 1; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionVector.inc b/projects/indirect_dispatch/assets/shaders/motionVector.inc deleted file mode 100644 index 498478cbc38b9666366eaa3d3e1a715dfc30236b..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionVector.inc +++ /dev/null @@ -1,9 +0,0 @@ -vec2 computeMotionVector(vec4 NDC, vec4 NDCPrevious){ - vec2 ndc = NDC.xy / NDC.w; - vec2 ndcPrevious = NDCPrevious.xy / NDCPrevious.w; - - vec2 uv = ndc * 0.5 + 0.5; - vec2 uvPrevious = ndcPrevious * 0.5 + 0.5; - - return uvPrevious - uv; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionVectorMinMax.comp b/projects/indirect_dispatch/assets/shaders/motionVectorMinMax.comp deleted file mode 100644 index 06b1b98f37579ae33406691bf19999d42ab7eb83..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionVectorMinMax.comp +++ /dev/null @@ -1,57 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable -#include "motionBlurConfig.inc" - -layout(set=0, binding=0) uniform texture2D inMotion; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2, rg16) uniform image2D outMotionMax; -layout(set=0, binding=3, rg16) uniform image2D outMotionMin; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(outMotionMax); - ivec2 inImageRes = textureSize(sampler2D(inMotion, textureSampler), 0); - ivec2 motionTileCoord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(motionTileCoord, outImageRes))) - return; - - float velocityMax = 0; - vec2 motionMax = vec2(0); - - float velocityMin = 100000; - vec2 motionMin = vec2(0); - - ivec2 motionBufferBaseCoord = motionTileCoord * motionTileSize; - - for(int x = 0; x < motionTileSize; x++){ - for(int y = 0; y < motionTileSize; y++){ - ivec2 sampleCoord = motionBufferBaseCoord + ivec2(x, y); - - bool sampleIsOutsideImage = false; - sampleIsOutsideImage = sampleIsOutsideImage || any(greaterThanEqual(sampleCoord, inImageRes)); - sampleIsOutsideImage = sampleIsOutsideImage || any(lessThan(sampleCoord, ivec2(0))); - - if(sampleIsOutsideImage) - continue; - - vec2 motionSample = texelFetch(sampler2D(inMotion, textureSampler), sampleCoord, 0).rg; - float velocitySample = length(motionSample); - - if(velocitySample > velocityMax){ - velocityMax = velocitySample; - motionMax = motionSample; - } - - if(velocitySample < velocityMin){ - velocityMin = velocitySample; - motionMin = motionSample; - } - } - } - - imageStore(outMotionMax, motionTileCoord, vec4(motionMax, 0, 0)); - imageStore(outMotionMin, motionTileCoord, vec4(motionMin, 0, 0)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionVectorMinMaxNeighbourhood.comp b/projects/indirect_dispatch/assets/shaders/motionVectorMinMaxNeighbourhood.comp deleted file mode 100644 index 3f836341a97a683efe88f41416d541624be03a0e..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionVectorMinMaxNeighbourhood.comp +++ /dev/null @@ -1,59 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) uniform texture2D inMotionMax; -layout(set=0, binding=1) uniform texture2D inMotionMin; -layout(set=0, binding=2) uniform sampler textureSampler; -layout(set=0, binding=3, rg16) uniform image2D outMotionMaxNeighbourhood; -layout(set=0, binding=4, rg16) uniform image2D outMotionMinNeighbourhood; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(outMotionMaxNeighbourhood); - ivec2 inImageRes = textureSize(sampler2D(inMotionMax, textureSampler), 0); - ivec2 motionTileCoord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(motionTileCoord, outImageRes))) - return; - - float velocityMax = 0; - vec2 motionMax = vec2(0); - - float velocityMin = 10000; - vec2 motionMin = vec2(0); - - for(int x = -1; x <= 1; x++){ - for(int y = -1; y <= 1; y++){ - ivec2 sampleCoord = motionTileCoord + ivec2(x, y); - - bool sampleIsOutsideImage = false; - sampleIsOutsideImage = sampleIsOutsideImage || any(greaterThanEqual(sampleCoord, inImageRes)); - sampleIsOutsideImage = sampleIsOutsideImage || any(lessThan(sampleCoord, ivec2(0))); - - if(sampleIsOutsideImage) - continue; - - vec2 motionSampleMax = texelFetch(sampler2D(inMotionMax, textureSampler), sampleCoord, 0).rg; - float velocitySampleMax = length(motionSampleMax); - - if(velocitySampleMax > velocityMax){ - velocityMax = velocitySampleMax; - motionMax = motionSampleMax; - } - - - vec2 motionSampleMin = texelFetch(sampler2D(inMotionMin, textureSampler), sampleCoord, 0).rg; - float velocitySampleMin = length(motionSampleMin); - - if(velocitySampleMin < velocityMin){ - velocityMin = velocitySampleMin; - motionMin = motionSampleMin; - } - } - } - - imageStore(outMotionMaxNeighbourhood, motionTileCoord, vec4(motionMax, 0, 0)); - imageStore(outMotionMinNeighbourhood, motionTileCoord, vec4(motionMin, 0, 0)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/motionVectorVisualisation.comp b/projects/indirect_dispatch/assets/shaders/motionVectorVisualisation.comp deleted file mode 100644 index fdceb575feaf24e7114bbcf223585a28955f45b8..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/motionVectorVisualisation.comp +++ /dev/null @@ -1,33 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "motionBlurConfig.inc" - -layout(set=0, binding=0) uniform texture2D inMotion; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - float range; -}; - -void main(){ - - ivec2 outImageRes = imageSize(outImage); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(coord, outImageRes))) - return; - - vec2 uv = (coord + 0.5) / vec2(outImageRes); - ivec2 inTextureRes = textureSize(sampler2D(inMotion, textureSampler), 0); - - vec2 motionVector = texelFetch(sampler2D(inMotion, textureSampler), ivec2(uv * inTextureRes), 0).rg; - vec2 motionVectorNormalized = clamp(motionVector / range, -1, 1); - - vec2 color = motionVectorNormalized * 0.5 + 0.5; - - imageStore(outImage, coord, vec4(color, 0.5, 0)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/prepass.frag b/projects/indirect_dispatch/assets/shaders/prepass.frag deleted file mode 100644 index ccfc84d982253f7b89551c099a92b5686a811163..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/prepass.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "motionVector.inc" - -layout(location = 0) in vec4 passNDC; -layout(location = 1) in vec4 passNDCPrevious; - -layout(location = 0) out vec2 outMotion; - -void main() { - outMotion = computeMotionVector(passNDC, passNDCPrevious); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/prepass.vert b/projects/indirect_dispatch/assets/shaders/prepass.vert deleted file mode 100644 index 230346208007fae0bb7724b5b6d05f62726c4ded..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/prepass.vert +++ /dev/null @@ -1,18 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; - -layout(location = 0) out vec4 passNDC; -layout(location = 1) out vec4 passNDCPrevious; - -layout( push_constant ) uniform constants{ - mat4 mvp; - mat4 mvpPrevious; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNDC = gl_Position; - passNDCPrevious = mvpPrevious * vec4(inPosition, 1.0); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/sky.frag b/projects/indirect_dispatch/assets/shaders/sky.frag deleted file mode 100644 index efc0e03b2d6ee1c71930c866293da66857bd56c7..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/sky.frag +++ /dev/null @@ -1,8 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) out vec3 outColor; - -void main() { - outColor = vec3(0, 0.2, 0.9); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/sky.vert b/projects/indirect_dispatch/assets/shaders/sky.vert deleted file mode 100644 index 44b48cd7f3bfc44e2e43edef0d474581d50608de..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/sky.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; - -layout( push_constant ) uniform constants{ - mat4 viewProjection; -}; - -void main() { - gl_Position = viewProjection * vec4(inPosition, 0.0); - gl_Position.w = gl_Position.z; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/skyPrepass.frag b/projects/indirect_dispatch/assets/shaders/skyPrepass.frag deleted file mode 100644 index 64ec4f18bbcf89153d70019ace570da53d44a505..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/skyPrepass.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "motionVector.inc" - -layout(location = 0) out vec2 outMotion; - -layout(location = 0) in vec4 passNDC; -layout(location = 1) in vec4 passNDCPrevious; - -void main() { - outMotion = computeMotionVector(passNDC, passNDCPrevious); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/assets/shaders/skyPrepass.vert b/projects/indirect_dispatch/assets/shaders/skyPrepass.vert deleted file mode 100644 index 31b9016a592d097825a09e1daa888cb7b72b2cbc..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/assets/shaders/skyPrepass.vert +++ /dev/null @@ -1,22 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; - -layout( push_constant ) uniform constants{ - mat4 viewProjection; - mat4 viewProjectionPrevious; -}; - -layout(location = 0) out vec4 passNDC; -layout(location = 1) out vec4 passNDCPrevious; - -void main() { - gl_Position = viewProjection * vec4(inPosition, 0.0); - gl_Position.w = gl_Position.z; - - passNDC = gl_Position; - - passNDCPrevious = viewProjectionPrevious * vec4(inPosition, 0.0); - passNDCPrevious.w = passNDCPrevious.z; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp deleted file mode 100644 index f17a3df647359018411e5bebcc3175295359678b..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/App.cpp +++ /dev/null @@ -1,373 +0,0 @@ -#include "App.hpp" -#include "AppConfig.hpp" - -#include <vkcv/Sampler.hpp> -#include <vkcv/gui/GUI.hpp> - -#include <chrono> -#include <functional> - -const char* MotionVectorVisualisationModeLabels[6] = { - "None", - "Full resolution", - "Max tile", - "Tile neighbourhood max", - "Min Tile", - "Tile neighbourhood min" -}; - -const char* MotionBlurModeLabels[3] = { - "Default", - "Disabled", - "Tile visualisation" -}; - -App::App() : - m_applicationName("Indirect Dispatch"), - m_windowWidth(AppConfig::defaultWindowWidth), - m_windowHeight(AppConfig::defaultWindowHeight), - m_core(vkcv::Core::create( - m_applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME })), - m_windowHandle(m_core.createWindow(m_applicationName, m_windowWidth, m_windowHeight, true)), - m_cameraManager(m_core.getWindow(m_windowHandle)){} - -bool App::initialize() { - - if (!loadMeshPass(m_core, &m_meshPass)) - return false; - - if (!loadSkyPass(m_core, &m_skyPass)) - return false; - - if (!loadPrePass(m_core, &m_prePass)) - return false; - - if (!loadSkyPrePass(m_core, &m_skyPrePass)) - return false; - - if (!loadComputePass(m_core, "assets/shaders/gammaCorrection.comp", &m_gammaCorrectionPass)) - return false; - - if (!loadMesh(m_core, "assets/models/cube.gltf", &m_cubeMesh)) - return false; - - if (!loadMesh(m_core, "assets/models/ground.gltf", &m_groundMesh)) - return false; - - if(!loadImage(m_core, "assets/models/grid.png", &m_gridTexture)) - return false; - - if (!m_motionBlur.initialize(&m_core, m_windowWidth, m_windowHeight)) - return false; - - m_linearSampler = vkcv::samplerLinear(m_core, true); - m_renderTargets = createRenderTargets(m_core, m_windowWidth, m_windowHeight); - - auto cameraHandle = m_cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - m_cameraManager.getCamera(cameraHandle).setPosition(glm::vec3(0, 1, -3)); - m_cameraManager.getCamera(cameraHandle).setNearFar(0.1f, 30.f); - - vkcv::DescriptorWrites meshPassDescriptorWrites; - meshPassDescriptorWrites.writeSampledImage(0, m_gridTexture); - meshPassDescriptorWrites.writeSampler(1, m_linearSampler); - m_core.writeDescriptorSet(m_meshPass.descriptorSet, meshPassDescriptorWrites); - - return true; -} - -void App::run() { - - auto frameStartTime = std::chrono::system_clock::now(); - const auto appStartTime = std::chrono::system_clock::now(); - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - const vkcv::InstanceDrawcall skyDrawcall(m_cubeMesh.mesh); - - vkcv::gui::GUI gui(m_core, m_windowHandle); - - eMotionVectorVisualisationMode motionVectorVisualisationMode = eMotionVectorVisualisationMode::None; - eMotionBlurMode motionBlurMode = eMotionBlurMode::Default; - - bool freezeFrame = false; - float motionBlurTileOffsetLength = 3; - float objectVerticalSpeed = 5; - float objectAmplitude = 0; - float objectMeanHeight = 1; - float objectRotationSpeedX = 5; - float objectRotationSpeedY = 5; - int cameraShutterSpeedInverse = 24; - float motionVectorVisualisationRange = 0.008; - float motionBlurFastPathThreshold = 1; - - glm::mat4 viewProjection = m_cameraManager.getActiveCamera().getMVP(); - glm::mat4 viewProjectionPrevious = m_cameraManager.getActiveCamera().getMVP(); - - struct Object { - MeshResources meshResources; - glm::mat4 modelMatrix = glm::mat4(1.f); - glm::mat4 mvp = glm::mat4(1.f); - glm::mat4 mvpPrevious = glm::mat4(1.f); - std::function<void(float, Object&)> modelMatrixUpdate; - }; - std::vector<Object> sceneObjects; - - Object ground; - ground.meshResources = m_groundMesh; - sceneObjects.push_back(ground); - - Object sphere; - sphere.meshResources = m_cubeMesh; - sphere.modelMatrixUpdate = [&](float time, Object& obj) { - const float currentHeight = objectMeanHeight + objectAmplitude * glm::sin(time * objectVerticalSpeed); - const glm::mat4 translation = glm::translate(glm::mat4(1), glm::vec3(0, currentHeight, 0)); - const glm::mat4 rotationX = glm::rotate(glm::mat4(1), objectRotationSpeedX * time, glm::vec3(1, 0, 0)); - const glm::mat4 rotationY = glm::rotate(glm::mat4(1), objectRotationSpeedY * time, glm::vec3(0, 1, 0)); - obj.modelMatrix = translation * rotationX * rotationY; - }; - sceneObjects.push_back(sphere); - - bool spaceWasPressed = false; - - m_core.getWindow(m_windowHandle).e_key.add([&](int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_SPACE) { - if (action == GLFW_PRESS) { - if (!spaceWasPressed) { - freezeFrame = !freezeFrame; - } - spaceWasPressed = true; - } - else if (action == GLFW_RELEASE) { - spaceWasPressed = false; - } - } - }); - - auto frameEndTime = std::chrono::system_clock::now(); - - while (vkcv::Window::hasOpenWindow()) { - - vkcv::Window::pollEvents(); - - if (!freezeFrame) { - - frameStartTime = frameEndTime; - viewProjectionPrevious = viewProjection; - - for (Object& obj : sceneObjects) { - obj.mvpPrevious = obj.mvp; - } - } - - if (m_core.getWindow(m_windowHandle).getHeight() == 0 || m_core.getWindow(m_windowHandle).getWidth() == 0) - continue; - - uint32_t swapchainWidth, swapchainHeight; - if (!m_core.beginFrame(swapchainWidth, swapchainHeight,m_windowHandle)) - continue; - - const bool hasResolutionChanged = (swapchainWidth != m_windowWidth) || (swapchainHeight != m_windowHeight); - if (hasResolutionChanged) { - m_windowWidth = swapchainWidth; - m_windowHeight = swapchainHeight; - - m_renderTargets = createRenderTargets(m_core, m_windowWidth, m_windowHeight); - m_motionBlur.setResolution(m_windowWidth, m_windowHeight); - } - - if(!freezeFrame) - frameEndTime = std::chrono::system_clock::now(); - - const float microsecondToSecond = 0.000001; - const float fDeltaTimeSeconds = microsecondToSecond * std::chrono::duration_cast<std::chrono::microseconds>(frameEndTime - frameStartTime).count(); - - m_cameraManager.update(fDeltaTimeSeconds); - - const auto time = frameEndTime - appStartTime; - const float fCurrentTime = std::chrono::duration_cast<std::chrono::milliseconds>(time).count() * 0.001f; - - // update matrices - if (!freezeFrame) { - - viewProjection = m_cameraManager.getActiveCamera().getMVP(); - - for (Object& obj : sceneObjects) { - if (obj.modelMatrixUpdate) { - obj.modelMatrixUpdate(fCurrentTime, obj); - } - obj.mvp = viewProjection * obj.modelMatrix; - } - } - - const vkcv::CommandStreamHandle cmdStream = m_core.createCommandStream(vkcv::QueueType::Graphics); - - // prepass - vkcv::PushConstants prepassPushConstants(sizeof(glm::mat4) * 2); - - for (const Object& obj : sceneObjects) { - glm::mat4 prepassMatrices[2] = { obj.mvp, obj.mvpPrevious }; - prepassPushConstants.appendDrawcall(prepassMatrices); - } - - const std::vector<vkcv::ImageHandle> prepassRenderTargets = { - m_renderTargets.motionBuffer, - m_renderTargets.depthBuffer }; - - std::vector<vkcv::InstanceDrawcall> prepassSceneDrawcalls; - for (const Object& obj : sceneObjects) { - prepassSceneDrawcalls.push_back(vkcv::InstanceDrawcall(obj.meshResources.mesh)); - } - - m_core.recordDrawcallsToCmdStream( - cmdStream, - m_prePass.pipeline, - prepassPushConstants, - prepassSceneDrawcalls, - prepassRenderTargets, - m_windowHandle); - - // sky prepass - glm::mat4 skyPrepassMatrices[2] = { - viewProjection, - viewProjectionPrevious }; - vkcv::PushConstants skyPrepassPushConstants(sizeof(glm::mat4) * 2); - skyPrepassPushConstants.appendDrawcall(skyPrepassMatrices); - - m_core.recordDrawcallsToCmdStream( - cmdStream, - m_skyPrePass.pipeline, - skyPrepassPushConstants, - { skyDrawcall }, - prepassRenderTargets, - m_windowHandle); - - // main pass - const std::vector<vkcv::ImageHandle> renderTargets = { - m_renderTargets.colorBuffer, - m_renderTargets.depthBuffer }; - - vkcv::PushConstants meshPushConstants(2 * sizeof(glm::mat4)); - for (const Object& obj : sceneObjects) { - glm::mat4 matrices[2] = { obj.mvp, obj.modelMatrix }; - meshPushConstants.appendDrawcall(matrices); - } - - std::vector<vkcv::InstanceDrawcall> forwardSceneDrawcalls; - for (const Object& obj : sceneObjects) { - vkcv::InstanceDrawcall drawcall (obj.meshResources.mesh); - drawcall.useDescriptorSet(0, m_meshPass.descriptorSet); - forwardSceneDrawcalls.push_back(drawcall); - } - - m_core.recordDrawcallsToCmdStream( - cmdStream, - m_meshPass.pipeline, - meshPushConstants, - forwardSceneDrawcalls, - renderTargets, - m_windowHandle); - - // sky - vkcv::PushConstants skyPushConstants = vkcv::pushConstants<glm::mat4>(); - skyPushConstants.appendDrawcall(viewProjection); - - m_core.recordDrawcallsToCmdStream( - cmdStream, - m_skyPass.pipeline, - skyPushConstants, - { skyDrawcall }, - renderTargets, - m_windowHandle); - - // motion blur - vkcv::ImageHandle motionBlurOutput; - - if (motionVectorVisualisationMode == eMotionVectorVisualisationMode::None) { - float cameraNear; - float cameraFar; - m_cameraManager.getActiveCamera().getNearFar(cameraNear, cameraFar); - - motionBlurOutput = m_motionBlur.render( - cmdStream, - m_renderTargets.motionBuffer, - m_renderTargets.colorBuffer, - m_renderTargets.depthBuffer, - motionBlurMode, - cameraNear, - cameraFar, - fDeltaTimeSeconds, - static_cast<float>(cameraShutterSpeedInverse), - motionBlurTileOffsetLength, - motionBlurFastPathThreshold); - } - else { - motionBlurOutput = m_motionBlur.renderMotionVectorVisualisation( - cmdStream, - m_renderTargets.motionBuffer, - motionVectorVisualisationMode, - motionVectorVisualisationRange); - } - - // gamma correction - vkcv::DescriptorWrites gammaCorrectionDescriptorWrites; - gammaCorrectionDescriptorWrites.writeSampledImage(0, motionBlurOutput); - gammaCorrectionDescriptorWrites.writeSampler(1, m_linearSampler); - gammaCorrectionDescriptorWrites.writeStorageImage(2, swapchainInput); - - m_core.writeDescriptorSet(m_gammaCorrectionPass.descriptorSet, gammaCorrectionDescriptorWrites); - - m_core.prepareImageForSampling(cmdStream, motionBlurOutput); - m_core.prepareImageForStorage (cmdStream, swapchainInput); - - const auto fullScreenImageDispatch = vkcv::dispatchInvocations( - vkcv::DispatchSize(m_windowWidth, m_windowHeight), - vkcv::DispatchSize(8, 8) - ); - - m_core.recordComputeDispatchToCmdStream( - cmdStream, - m_gammaCorrectionPass.pipeline, - fullScreenImageDispatch, - { vkcv::useDescriptorSet(0, m_gammaCorrectionPass.descriptorSet) }, - vkcv::PushConstants(0)); - - m_core.prepareSwapchainImageForPresent(cmdStream); - m_core.submitCommandStream(cmdStream); - - gui.beginGUI(); - ImGui::Begin("Settings"); - - ImGui::Checkbox("Freeze frame", &freezeFrame); - ImGui::InputFloat("Motion tile offset length", &motionBlurTileOffsetLength); - ImGui::InputFloat("Motion blur fast path threshold", &motionBlurFastPathThreshold); - - ImGui::Combo( - "Motion blur mode", - reinterpret_cast<int*>(&motionBlurMode), - MotionBlurModeLabels, - static_cast<int>(eMotionBlurMode::OptionCount)); - - ImGui::Combo( - "Debug view", - reinterpret_cast<int*>(&motionVectorVisualisationMode), - MotionVectorVisualisationModeLabels, - static_cast<int>(eMotionVectorVisualisationMode::OptionCount)); - - if (motionVectorVisualisationMode != eMotionVectorVisualisationMode::None) - ImGui::InputFloat("Motion vector visualisation range", &motionVectorVisualisationRange); - - ImGui::InputInt("Camera shutter speed inverse", &cameraShutterSpeedInverse); - - ImGui::InputFloat("Object movement speed", &objectVerticalSpeed); - ImGui::InputFloat("Object movement amplitude", &objectAmplitude); - ImGui::InputFloat("Object mean height", &objectMeanHeight); - ImGui::InputFloat("Object rotation speed X", &objectRotationSpeedX); - ImGui::InputFloat("Object rotation speed Y", &objectRotationSpeedY); - - ImGui::End(); - gui.endGUI(); - - m_core.endFrame(m_windowHandle); - } -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/App.hpp b/projects/indirect_dispatch/src/App.hpp deleted file mode 100644 index a35c2342c4c90e39b089a7c33a73c3aa7ce8a83f..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/App.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include <vkcv/Core.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include "AppSetup.hpp" -#include "MotionBlur.hpp" - -class App { -public: - App(); - bool initialize(); - void run(); -private: - const char* m_applicationName; - - uint32_t m_windowWidth; - uint32_t m_windowHeight; - - vkcv::Core m_core; - vkcv::WindowHandle m_windowHandle; - vkcv::camera::CameraManager m_cameraManager; - - MotionBlur m_motionBlur; - - vkcv::ImageHandle m_gridTexture; - - MeshResources m_cubeMesh; - MeshResources m_groundMesh; - - GraphicPassHandles m_meshPass; - GraphicPassHandles m_skyPass; - GraphicPassHandles m_prePass; - GraphicPassHandles m_skyPrePass; - - ComputePassHandles m_gammaCorrectionPass; - - AppRenderTargets m_renderTargets; - vkcv::SamplerHandle m_linearSampler; -}; \ No newline at end of file diff --git a/projects/indirect_dispatch/src/AppConfig.hpp b/projects/indirect_dispatch/src/AppConfig.hpp deleted file mode 100644 index c89c34ea8e3c0c45708ca998a642faffb31403d3..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/AppConfig.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "vulkan/vulkan.hpp" - -namespace AppConfig{ - const int defaultWindowWidth = 1280; - const int defaultWindowHeight = 720; - const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; - const vk::Format colorBufferFormat = vk::Format::eB10G11R11UfloatPack32; - const vk::Format motionBufferFormat = vk::Format::eR16G16Sfloat; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/AppSetup.cpp b/projects/indirect_dispatch/src/AppSetup.cpp deleted file mode 100644 index 26cfbbc38e2a190326b8a17adde5b8e4f44ec1cc..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/AppSetup.cpp +++ /dev/null @@ -1,334 +0,0 @@ -#include "AppSetup.hpp" -#include "AppConfig.hpp" - -#include <vkcv/Buffer.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -bool loadMesh(vkcv::Core& core, const std::filesystem::path& path, MeshResources* outMesh) { - assert(outMesh); - - vkcv::asset::Scene scene; - const int meshLoadResult = vkcv::asset::loadScene(path.string(), scene); - - if (meshLoadResult != 1) { - vkcv_log(vkcv::LogLevel::ERROR, "Mesh loading failed"); - return false; - } - - if (scene.meshes.size() < 1) { - vkcv_log(vkcv::LogLevel::ERROR, "Cube mesh scene does not contain any vertex groups"); - return false; - } - assert(!scene.vertexGroups.empty()); - - auto& vertexData = scene.vertexGroups[0].vertexBuffer; - auto& indexData = scene.vertexGroups[0].indexBuffer; - - vkcv::Buffer<uint8_t> vertexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::VERTEX, - vertexData.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - - vkcv::Buffer<uint8_t> indexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::INDEX, - indexData.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - - vertexBuffer.fill(vertexData.data); - indexBuffer.fill(indexData.data); - - outMesh->vertexBuffer = vertexBuffer.getHandle(); - outMesh->indexBuffer = indexBuffer.getHandle(); - - const auto vertexBufferBindings = vkcv::asset::loadVertexBufferBindings( - vertexData.attributes, - vertexBuffer.getHandle(), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL, - vkcv::asset::PrimitiveType::TEXCOORD_0 - } - ); - - outMesh->mesh = vkcv::VertexData(vertexBufferBindings); - outMesh->mesh.setIndexBuffer(indexBuffer.getHandle()); - outMesh->mesh.setCount(scene.vertexGroups[0].numIndices); - - return true; -} - -bool loadImage(vkcv::Core& core, const std::filesystem::path& path, vkcv::ImageHandle* outImage) { - - assert(outImage); - - const vkcv::asset::Texture textureData = vkcv::asset::loadTexture(path); - - if (textureData.channels != 4) { - vkcv_log(vkcv::LogLevel::ERROR, "Expecting image with four components"); - return false; - } - - vkcv::Image image = vkcv::image( - core, - vk::Format::eR8G8B8A8Srgb, - textureData.width, - textureData.height, - 1, - true - ); - - image.fill(textureData.data.data(), textureData.data.size()); - - { - auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics); - image.recordMipChainGeneration(mipStream, core.getDownsampler()); - core.submitCommandStream(mipStream, false); - } - - *outImage = image.getHandle(); - return true; -} - -bool loadGraphicPass( - vkcv::Core& core, - const std::filesystem::path vertexPath, - const std::filesystem::path fragmentPath, - const vkcv::PassConfig& passConfig, - const vkcv::DepthTest depthTest, - GraphicPassHandles* outPassHandles) { - - assert(outPassHandles); - - outPassHandles->renderPass = core.createPass(passConfig); - - if (!outPassHandles->renderPass) { - vkcv_log(vkcv::LogLevel::ERROR, "Error: Could not create renderpass"); - return false; - } - - vkcv::ShaderProgram shaderProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compile(vkcv::ShaderStage::VERTEX, vertexPath, - [&shaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, fragmentPath, - [&shaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shaderProgram.addShader(shaderStage, path); - }); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = shaderProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> bindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - - const vkcv::VertexLayout vertexLayout { bindings }; - - const auto descriptorBindings = shaderProgram.getReflectedDescriptors(); - const bool hasDescriptor = descriptorBindings.size() > 0; - std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayouts = {}; - if (hasDescriptor) - { - outPassHandles->descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings.at(0)); - outPassHandles->descriptorSet = core.createDescriptorSet(outPassHandles->descriptorSetLayout); - descriptorSetLayouts.push_back(outPassHandles->descriptorSetLayout); - } - - vkcv::GraphicsPipelineConfig pipelineConfig( - shaderProgram, - outPassHandles->renderPass, - { vertexLayout }, - descriptorSetLayouts - ); - - pipelineConfig.setDepthTest(depthTest); - outPassHandles->pipeline = core.createGraphicsPipeline(pipelineConfig); - - if (!outPassHandles->pipeline) { - vkcv_log(vkcv::LogLevel::ERROR, "Error: Could not create graphics pipeline"); - return false; - } - - return true; -} - -bool loadMeshPass(vkcv::Core& core, GraphicPassHandles* outHandles) { - - assert(outHandles); - - vkcv::AttachmentDescription colorAttachment( - AppConfig::colorBufferFormat, - vkcv::AttachmentOperation::DONT_CARE, - vkcv::AttachmentOperation::STORE - ); - - vkcv::AttachmentDescription depthAttachment( - AppConfig::depthBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - return loadGraphicPass( - core, - "assets/shaders/mesh.vert", - "assets/shaders/mesh.frag", - vkcv::PassConfig( - { colorAttachment, depthAttachment }, - vkcv::Multisampling::None - ), - vkcv::DepthTest::Equal, - outHandles); -} - -bool loadSkyPass(vkcv::Core& core, GraphicPassHandles* outHandles) { - - assert(outHandles); - - vkcv::AttachmentDescription colorAttachment( - AppConfig::colorBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - vkcv::AttachmentDescription depthAttachment( - AppConfig::depthBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - return loadGraphicPass( - core, - "assets/shaders/sky.vert", - "assets/shaders/sky.frag", - vkcv::PassConfig( - { colorAttachment, depthAttachment }, - vkcv::Multisampling::None - ), - vkcv::DepthTest::Equal, - outHandles); -} - -bool loadPrePass(vkcv::Core& core, GraphicPassHandles* outHandles) { - assert(outHandles); - - vkcv::AttachmentDescription motionAttachment( - AppConfig::motionBufferFormat, - vkcv::AttachmentOperation::CLEAR, - vkcv::AttachmentOperation::STORE - ); - - vkcv::AttachmentDescription depthAttachment( - AppConfig::depthBufferFormat, - vkcv::AttachmentOperation::CLEAR, - vkcv::AttachmentOperation::STORE - ); - - return loadGraphicPass( - core, - "assets/shaders/prepass.vert", - "assets/shaders/prepass.frag", - vkcv::PassConfig( - { motionAttachment, depthAttachment }, - vkcv::Multisampling::None - ), - vkcv::DepthTest::LessEqual, - outHandles); -} - -bool loadSkyPrePass(vkcv::Core& core, GraphicPassHandles* outHandles) { - assert(outHandles); - - vkcv::AttachmentDescription motionAttachment( - AppConfig::motionBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - vkcv::AttachmentDescription depthAttachment( - AppConfig::depthBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - return loadGraphicPass( - core, - "assets/shaders/skyPrepass.vert", - "assets/shaders/skyPrepass.frag", - vkcv::PassConfig( - { motionAttachment, depthAttachment }, - vkcv::Multisampling::None - ), - vkcv::DepthTest::LessEqual, - outHandles); -} - -bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, ComputePassHandles* outComputePass) { - - assert(outComputePass); - vkcv::ShaderProgram shaderProgram; - vkcv::shader::GLSLCompiler compiler; - - compiler.compile(vkcv::ShaderStage::COMPUTE, path, - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shaderProgram.addShader(shaderStage, path); - }); - - if (shaderProgram.getReflectedDescriptors().size() < 1) { - vkcv_log(vkcv::LogLevel::ERROR, "Compute shader has no descriptor set"); - return false; - } - - outComputePass->descriptorSetLayout = core.createDescriptorSetLayout(shaderProgram.getReflectedDescriptors().at(0)); - outComputePass->descriptorSet = core.createDescriptorSet(outComputePass->descriptorSetLayout); - outComputePass->pipeline = core.createComputePipeline({ - shaderProgram, - { outComputePass->descriptorSetLayout }}); - - if (!outComputePass->pipeline) { - vkcv_log(vkcv::LogLevel::ERROR, "Compute shader pipeline creation failed"); - return false; - } - - return true; -} - -AppRenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height) { - AppRenderTargets targets; - - targets.depthBuffer = core.createImage( - AppConfig::depthBufferFormat, - width, - height, - 1, - false - ); - - targets.colorBuffer = core.createImage( - AppConfig::colorBufferFormat, - width, - height, - 1, - false, - false, - true - ); - - targets.motionBuffer = core.createImage( - AppConfig::motionBufferFormat, - width, - height, - 1, - false, - false, - true - ); - - return targets; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/AppSetup.hpp b/projects/indirect_dispatch/src/AppSetup.hpp deleted file mode 100644 index 41e020c357a3d868775a581170596e1748e39700..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/AppSetup.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -#include <vkcv/Core.hpp> - -struct AppRenderTargets { - vkcv::ImageHandle depthBuffer; - vkcv::ImageHandle colorBuffer; - vkcv::ImageHandle motionBuffer; -}; - -struct GraphicPassHandles { - vkcv::GraphicsPipelineHandle pipeline; - vkcv::PassHandle renderPass; - vkcv::DescriptorSetLayoutHandle descriptorSetLayout; - vkcv::DescriptorSetHandle descriptorSet; -}; - -struct ComputePassHandles { - vkcv::ComputePipelineHandle pipeline; - vkcv::DescriptorSetLayoutHandle descriptorSetLayout; - vkcv::DescriptorSetHandle descriptorSet; -}; - -struct MeshResources { - vkcv::VertexData mesh; - vkcv::BufferHandle vertexBuffer; - vkcv::BufferHandle indexBuffer; -}; - -// loads position, uv and normal of the first mesh in a scene -bool loadMesh(vkcv::Core& core, const std::filesystem::path& path, MeshResources* outMesh); - -bool loadImage(vkcv::Core& core, const std::filesystem::path& path, vkcv::ImageHandle* outImage); - -bool loadGraphicPass( - vkcv::Core& core, - std::filesystem::path vertexPath, - std::filesystem::path fragmentPath, - const vkcv::PassConfig& passConfig, - vkcv::DepthTest depthTest, - GraphicPassHandles* outPassHandles); - -bool loadMeshPass (vkcv::Core& core, GraphicPassHandles* outHandles); -bool loadSkyPass (vkcv::Core& core, GraphicPassHandles* outHandles); -bool loadPrePass (vkcv::Core& core, GraphicPassHandles* outHandles); -bool loadSkyPrePass(vkcv::Core& core, GraphicPassHandles* outHandles); - -bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, ComputePassHandles* outComputePass); - -AppRenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height); \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp deleted file mode 100644 index fe55a5821b042feb709deffee806513b18ed06ba..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ /dev/null @@ -1,433 +0,0 @@ -#include "MotionBlur.hpp" -#include "MotionBlurConfig.hpp" -#include "MotionBlurSetup.hpp" - -#include <vkcv/Buffer.hpp> -#include <vkcv/Sampler.hpp> - -#include <array> - -bool MotionBlur::initialize(vkcv::Core* corePtr, const uint32_t targetWidth, const uint32_t targetHeight) { - - if (!corePtr) { - vkcv_log(vkcv::LogLevel::ERROR, "MotionBlur got invalid corePtr") - return false; - } - - m_core = corePtr; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlur.comp", &m_motionBlurPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionVectorMinMax.comp", &m_motionVectorMinMaxPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionVectorMinMaxNeighbourhood.comp", &m_motionVectorMinMaxNeighbourhoodPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionVectorVisualisation.comp", &m_motionVectorVisualisationPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlurColorCopy.comp", &m_colorCopyPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlurTileClassification.comp", &m_tileClassificationPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlurWorkTileReset.comp", &m_tileResetPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlurTileClassificationVis.comp", &m_tileVisualisationPass)) - return false; - - if (!loadComputePass(*m_core, "assets/shaders/motionBlurFastPath.comp", &m_motionBlurFastPathPass)) - return false; - - // work tile buffers and descriptors - const uint32_t workTileBufferSize = static_cast<uint32_t>(2 * sizeof(uint32_t)) * (3 + - ((MotionBlurConfig::maxWidth + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize) * - ((MotionBlurConfig::maxHeight + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize)); - - m_copyPathWorkTileBuffer = vkcv::buffer<uint32_t>( - *m_core, - vkcv::BufferType::INDIRECT, - workTileBufferSize, - vkcv::BufferMemoryType::DEVICE_LOCAL).getHandle(); - - m_fullPathWorkTileBuffer = vkcv::buffer<uint32_t>( - *m_core, - vkcv::BufferType::INDIRECT, - workTileBufferSize, - vkcv::BufferMemoryType::DEVICE_LOCAL).getHandle(); - - m_fastPathWorkTileBuffer = vkcv::buffer<uint32_t>( - *m_core, - vkcv::BufferType::INDIRECT, - workTileBufferSize, - vkcv::BufferMemoryType::DEVICE_LOCAL).getHandle(); - - vkcv::DescriptorWrites tileResetDescriptorWrites; - tileResetDescriptorWrites.writeStorageBuffer( - 0, m_fullPathWorkTileBuffer - ).writeStorageBuffer( - 1, m_copyPathWorkTileBuffer - ).writeStorageBuffer( - 2, m_fastPathWorkTileBuffer - ); - - m_core->writeDescriptorSet(m_tileResetPass.descriptorSet, tileResetDescriptorWrites); - - m_renderTargets = MotionBlurSetup::createRenderTargets(targetWidth, targetHeight, *m_core); - - m_nearestSampler = vkcv::samplerNearest(*m_core, true); - - return true; -} - -void MotionBlur::setResolution(const uint32_t targetWidth, const uint32_t targetHeight) { - m_renderTargets = MotionBlurSetup::createRenderTargets(targetWidth, targetHeight, *m_core); -} - -vkcv::ImageHandle MotionBlur::render( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBufferFullRes, - const vkcv::ImageHandle colorBuffer, - const vkcv::ImageHandle depthBuffer, - const eMotionBlurMode mode, - const float cameraNear, - const float cameraFar, - const float deltaTimeSeconds, - const float cameraShutterSpeedInverse, - const float motionTileOffsetLength, - const float fastPathThreshold) { - - computeMotionTiles(cmdStream, motionBufferFullRes); - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_tileResetPass.pipeline, - 1, - { vkcv::useDescriptorSet(0, m_tileResetPass.descriptorSet) }, - vkcv::PushConstants(0) - ); - - m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); - m_core->recordBufferMemoryBarrier(cmdStream, m_copyPathWorkTileBuffer); - m_core->recordBufferMemoryBarrier(cmdStream, m_fastPathWorkTileBuffer); - - // work tile classification - vkcv::DescriptorWrites tileClassificationDescriptorWrites; - tileClassificationDescriptorWrites.writeSampledImage( - 0, m_renderTargets.motionMaxNeighbourhood - ).writeSampledImage( - 1, m_renderTargets.motionMinNeighbourhood - ); - - tileClassificationDescriptorWrites.writeSampler(2, m_nearestSampler); - tileClassificationDescriptorWrites.writeStorageBuffer( - 3, m_fullPathWorkTileBuffer - ).writeStorageBuffer( - 4, m_copyPathWorkTileBuffer - ).writeStorageBuffer( - 5, m_fastPathWorkTileBuffer - ); - - m_core->writeDescriptorSet(m_tileClassificationPass.descriptorSet, tileClassificationDescriptorWrites); - - const auto tileClassificationDispatch = vkcv::dispatchInvocations( - vkcv::DispatchSize( - m_core->getImageWidth(m_renderTargets.motionMaxNeighbourhood), - m_core->getImageHeight(m_renderTargets.motionMaxNeighbourhood) - ), - vkcv::DispatchSize(8, 8) - ); - - struct ClassificationConstants { - uint32_t width; - uint32_t height; - float fastPathThreshold; - }; - ClassificationConstants classificationConstants; - classificationConstants.width = m_core->getImageWidth(m_renderTargets.outputColor); - classificationConstants.height = m_core->getImageHeight(m_renderTargets.outputColor); - classificationConstants.fastPathThreshold = fastPathThreshold; - - vkcv::PushConstants classificationPushConstants = vkcv::pushConstants<ClassificationConstants>(); - classificationPushConstants.appendDrawcall(classificationConstants); - - m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMaxNeighbourhood); - m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMinNeighbourhood); - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_tileClassificationPass.pipeline, - tileClassificationDispatch, - { vkcv::useDescriptorSet(0, m_tileClassificationPass.descriptorSet) }, - classificationPushConstants); - - m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); - m_core->recordBufferMemoryBarrier(cmdStream, m_copyPathWorkTileBuffer); - m_core->recordBufferMemoryBarrier(cmdStream, m_fastPathWorkTileBuffer); - - vkcv::DescriptorWrites motionBlurDescriptorWrites; - motionBlurDescriptorWrites.writeSampledImage( - 0, colorBuffer - ).writeSampledImage( - 1, depthBuffer - ).writeSampledImage( - 2, motionBufferFullRes - ).writeSampledImage( - 3, m_renderTargets.motionMaxNeighbourhood - ); - - motionBlurDescriptorWrites.writeSampler(4, m_nearestSampler); - motionBlurDescriptorWrites.writeStorageImage(5, m_renderTargets.outputColor); - motionBlurDescriptorWrites.writeStorageBuffer(6, m_fullPathWorkTileBuffer); - - m_core->writeDescriptorSet(m_motionBlurPass.descriptorSet, motionBlurDescriptorWrites); - - vkcv::DescriptorWrites colorCopyDescriptorWrites; - colorCopyDescriptorWrites.writeSampledImage(0, colorBuffer); - colorCopyDescriptorWrites.writeSampler(1, m_nearestSampler); - colorCopyDescriptorWrites.writeStorageImage(2, m_renderTargets.outputColor); - colorCopyDescriptorWrites.writeStorageBuffer(3, m_copyPathWorkTileBuffer); - - m_core->writeDescriptorSet(m_colorCopyPass.descriptorSet, colorCopyDescriptorWrites); - - - vkcv::DescriptorWrites fastPathDescriptorWrites; - fastPathDescriptorWrites.writeSampledImage( - 0, colorBuffer - ).writeSampledImage( - 1, m_renderTargets.motionMaxNeighbourhood - ); - - fastPathDescriptorWrites.writeSampler(2, m_nearestSampler); - fastPathDescriptorWrites.writeStorageImage(3, m_renderTargets.outputColor); - fastPathDescriptorWrites.writeStorageBuffer(4, m_fastPathWorkTileBuffer); - - m_core->writeDescriptorSet(m_motionBlurFastPathPass.descriptorSet, fastPathDescriptorWrites); - - // must match layout in "motionBlur.comp" - struct MotionBlurConstantData { - float motionFactor; - float cameraNearPlane; - float cameraFarPlane; - float motionTileOffsetLength; - }; - MotionBlurConstantData motionBlurConstantData; - - const float deltaTimeMotionBlur = deltaTimeSeconds; - - motionBlurConstantData.motionFactor = 1 / (deltaTimeMotionBlur * cameraShutterSpeedInverse); - motionBlurConstantData.cameraNearPlane = cameraNear; - motionBlurConstantData.cameraFarPlane = cameraFar; - motionBlurConstantData.motionTileOffsetLength = motionTileOffsetLength; - - vkcv::PushConstants motionBlurPushConstants = vkcv::pushConstants<MotionBlurConstantData>(); - motionBlurPushConstants.appendDrawcall(motionBlurConstantData); - - struct FastPathConstants { - float motionFactor; - }; - FastPathConstants fastPathConstants; - fastPathConstants.motionFactor = motionBlurConstantData.motionFactor; - - vkcv::PushConstants fastPathPushConstants = vkcv::pushConstants<FastPathConstants>(); - fastPathPushConstants.appendDrawcall(fastPathConstants); - - m_core->prepareImageForStorage(cmdStream, m_renderTargets.outputColor); - m_core->prepareImageForSampling(cmdStream, colorBuffer); - m_core->prepareImageForSampling(cmdStream, depthBuffer); - m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMaxNeighbourhood); - - if (mode == eMotionBlurMode::Default) { - m_core->recordComputeIndirectDispatchToCmdStream( - cmdStream, - m_motionBlurPass.pipeline, - m_fullPathWorkTileBuffer, - 0, - { vkcv::useDescriptorSet(0, m_motionBlurPass.descriptorSet) }, - motionBlurPushConstants); - - m_core->recordComputeIndirectDispatchToCmdStream( - cmdStream, - m_colorCopyPass.pipeline, - m_copyPathWorkTileBuffer, - 0, - { vkcv::useDescriptorSet(0, m_colorCopyPass.descriptorSet) }, - vkcv::PushConstants(0)); - - m_core->recordComputeIndirectDispatchToCmdStream( - cmdStream, - m_motionBlurFastPathPass.pipeline, - m_fastPathWorkTileBuffer, - 0, - { vkcv::useDescriptorSet(0, m_motionBlurFastPathPass.descriptorSet) }, - fastPathPushConstants); - } - else if(mode == eMotionBlurMode::Disabled) { - return colorBuffer; - } - else if (mode == eMotionBlurMode::TileVisualisation) { - - vkcv::DescriptorWrites visualisationDescriptorWrites; - visualisationDescriptorWrites.writeSampledImage(0, colorBuffer); - visualisationDescriptorWrites.writeSampler(1, m_nearestSampler); - visualisationDescriptorWrites.writeStorageImage(2, m_renderTargets.outputColor); - - visualisationDescriptorWrites.writeStorageBuffer( - 3, m_fullPathWorkTileBuffer - ).writeStorageBuffer( - 4, m_copyPathWorkTileBuffer - ).writeStorageBuffer( - 5, m_fastPathWorkTileBuffer - ); - - m_core->writeDescriptorSet(m_tileVisualisationPass.descriptorSet, visualisationDescriptorWrites); - - const uint32_t tileCount = - (m_core->getImageWidth(m_renderTargets.outputColor) + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize * - (m_core->getImageHeight(m_renderTargets.outputColor) + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize; - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_tileVisualisationPass.pipeline, - tileCount, - { vkcv::useDescriptorSet(0, m_tileVisualisationPass.descriptorSet) }, - vkcv::PushConstants(0)); - } - else { - vkcv_log(vkcv::LogLevel::ERROR, "Unknown eMotionBlurMode enum option"); - return colorBuffer; - } - - return m_renderTargets.outputColor; -} - -vkcv::ImageHandle MotionBlur::renderMotionVectorVisualisation( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBuffer, - const eMotionVectorVisualisationMode mode, - const float velocityRange) { - - computeMotionTiles(cmdStream, motionBuffer); - - vkcv::ImageHandle visualisationInput; - if ( mode == eMotionVectorVisualisationMode::FullResolution) - visualisationInput = motionBuffer; - else if (mode == eMotionVectorVisualisationMode::MaxTile) - visualisationInput = m_renderTargets.motionMax; - else if (mode == eMotionVectorVisualisationMode::MaxTileNeighbourhood) - visualisationInput = m_renderTargets.motionMaxNeighbourhood; - else if (mode == eMotionVectorVisualisationMode::MinTile) - visualisationInput = m_renderTargets.motionMin; - else if (mode == eMotionVectorVisualisationMode::MinTileNeighbourhood) - visualisationInput = m_renderTargets.motionMinNeighbourhood; - else if (mode == eMotionVectorVisualisationMode::None) { - vkcv_log(vkcv::LogLevel::ERROR, "renderMotionVectorVisualisation called with visualisation mode 'None'"); - return motionBuffer; - } - else { - vkcv_log(vkcv::LogLevel::ERROR, "Unknown eDebugView enum value"); - return motionBuffer; - } - - vkcv::DescriptorWrites motionVectorVisualisationDescriptorWrites; - motionVectorVisualisationDescriptorWrites.writeSampledImage(0, visualisationInput); - motionVectorVisualisationDescriptorWrites.writeSampler(1, m_nearestSampler); - motionVectorVisualisationDescriptorWrites.writeStorageImage(2, m_renderTargets.outputColor); - - m_core->writeDescriptorSet( - m_motionVectorVisualisationPass.descriptorSet, - motionVectorVisualisationDescriptorWrites); - - m_core->prepareImageForSampling(cmdStream, visualisationInput); - m_core->prepareImageForStorage(cmdStream, m_renderTargets.outputColor); - - vkcv::PushConstants motionVectorVisualisationPushConstants = vkcv::pushConstants<float>(); - motionVectorVisualisationPushConstants.appendDrawcall(velocityRange); - - const auto dispatchSizes = vkcv::dispatchInvocations( - vkcv::DispatchSize( - m_core->getImageWidth(m_renderTargets.outputColor), - m_core->getImageHeight(m_renderTargets.outputColor) - ), - vkcv::DispatchSize(8, 8) - ); - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_motionVectorVisualisationPass.pipeline, - dispatchSizes, - { vkcv::useDescriptorSet(0, m_motionVectorVisualisationPass.descriptorSet) }, - motionVectorVisualisationPushConstants); - - return m_renderTargets.outputColor; -} - -void MotionBlur::computeMotionTiles( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBufferFullRes) { - - // motion vector min max tiles - vkcv::DescriptorWrites motionVectorMaxTilesDescriptorWrites; - motionVectorMaxTilesDescriptorWrites.writeSampledImage(0, motionBufferFullRes); - motionVectorMaxTilesDescriptorWrites.writeSampler(1, m_nearestSampler); - motionVectorMaxTilesDescriptorWrites.writeStorageImage( - 2, m_renderTargets.motionMax - ).writeStorageImage( - 3, m_renderTargets.motionMin - ); - - m_core->writeDescriptorSet(m_motionVectorMinMaxPass.descriptorSet, motionVectorMaxTilesDescriptorWrites); - - m_core->prepareImageForSampling(cmdStream, motionBufferFullRes); - m_core->prepareImageForStorage(cmdStream, m_renderTargets.motionMax); - m_core->prepareImageForStorage(cmdStream, m_renderTargets.motionMin); - - const auto motionTileDispatchCounts = vkcv::dispatchInvocations( - vkcv::DispatchSize( - m_core->getImageWidth( m_renderTargets.motionMax), - m_core->getImageHeight(m_renderTargets.motionMax) - ), - vkcv::DispatchSize(8, 8) - ); - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_motionVectorMinMaxPass.pipeline, - motionTileDispatchCounts, - { vkcv::useDescriptorSet(0, m_motionVectorMinMaxPass.descriptorSet) }, - vkcv::PushConstants(0)); - - // motion vector min max neighbourhood - vkcv::DescriptorWrites motionVectorMaxNeighbourhoodDescriptorWrites; - motionVectorMaxNeighbourhoodDescriptorWrites.writeSampledImage( - 0, m_renderTargets.motionMax - ).writeSampledImage( - 1, m_renderTargets.motionMin - ); - - motionVectorMaxNeighbourhoodDescriptorWrites.writeSampler(2, m_nearestSampler); - motionVectorMaxNeighbourhoodDescriptorWrites.writeStorageImage( - 3, m_renderTargets.motionMaxNeighbourhood - ).writeStorageImage( - 4, m_renderTargets.motionMinNeighbourhood - ); - - m_core->writeDescriptorSet(m_motionVectorMinMaxNeighbourhoodPass.descriptorSet, motionVectorMaxNeighbourhoodDescriptorWrites); - - m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMax); - m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMin); - - m_core->prepareImageForStorage(cmdStream, m_renderTargets.motionMaxNeighbourhood); - m_core->prepareImageForStorage(cmdStream, m_renderTargets.motionMinNeighbourhood); - - m_core->recordComputeDispatchToCmdStream( - cmdStream, - m_motionVectorMinMaxNeighbourhoodPass.pipeline, - motionTileDispatchCounts, - { vkcv::useDescriptorSet(0, m_motionVectorMinMaxNeighbourhoodPass.descriptorSet) }, - vkcv::PushConstants(0)); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlur.hpp b/projects/indirect_dispatch/src/MotionBlur.hpp deleted file mode 100644 index 4e6003799237f69f4a422dd9c20f99255fe711fa..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/MotionBlur.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once -#include <vkcv/Core.hpp> -#include "AppSetup.hpp" -#include "MotionBlurSetup.hpp" - -// selection for motion blur input and visualisation -enum class eMotionVectorVisualisationMode : int { - None = 0, - FullResolution = 1, - MaxTile = 2, - MaxTileNeighbourhood = 3, - MinTile = 4, - MinTileNeighbourhood = 5, - OptionCount = 6 }; - -enum class eMotionBlurMode : int { - Default = 0, - Disabled = 1, - TileVisualisation = 2, - OptionCount = 3 }; - -class MotionBlur { -public: - - bool initialize(vkcv::Core* corePtr, const uint32_t targetWidth, const uint32_t targetHeight); - void setResolution(const uint32_t targetWidth, const uint32_t targetHeight); - - vkcv::ImageHandle render( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBufferFullRes, - const vkcv::ImageHandle colorBuffer, - const vkcv::ImageHandle depthBuffer, - const eMotionBlurMode mode, - const float cameraNear, - const float cameraFar, - const float deltaTimeSeconds, - const float cameraShutterSpeedInverse, - const float motionTileOffsetLength, - const float fastPathThreshold); - - vkcv::ImageHandle renderMotionVectorVisualisation( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBuffer, - const eMotionVectorVisualisationMode mode, - const float velocityRange); - -private: - // computes max per tile and neighbourhood tile max - void computeMotionTiles( - const vkcv::CommandStreamHandle cmdStream, - const vkcv::ImageHandle motionBufferFullRes); - - vkcv::Core* m_core; - - MotionBlurRenderTargets m_renderTargets; - vkcv::SamplerHandle m_nearestSampler; - - ComputePassHandles m_motionBlurPass; - ComputePassHandles m_motionVectorMinMaxPass; - ComputePassHandles m_motionVectorMinMaxNeighbourhoodPass; - ComputePassHandles m_motionVectorVisualisationPass; - ComputePassHandles m_colorCopyPass; - ComputePassHandles m_tileClassificationPass; - ComputePassHandles m_tileResetPass; - ComputePassHandles m_tileVisualisationPass; - ComputePassHandles m_motionBlurFastPathPass; - - vkcv::BufferHandle m_fullPathWorkTileBuffer; - vkcv::BufferHandle m_copyPathWorkTileBuffer; - vkcv::BufferHandle m_fastPathWorkTileBuffer; -}; \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlurConfig.hpp b/projects/indirect_dispatch/src/MotionBlurConfig.hpp deleted file mode 100644 index 7552abd246ca8d2e7489c5065f43ef8b48af7cd2..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/MotionBlurConfig.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "vulkan/vulkan.hpp" - -namespace MotionBlurConfig { - const vk::Format motionVectorTileFormat = vk::Format::eR16G16Sfloat; - const vk::Format outputColorFormat = vk::Format::eB10G11R11UfloatPack32; - const uint32_t maxMotionTileSize = 16; // must match "motionTileSize" in motionBlurConfig.inc - const uint32_t maxWidth = 3840; - const uint32_t maxHeight = 2160; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlurSetup.cpp b/projects/indirect_dispatch/src/MotionBlurSetup.cpp deleted file mode 100644 index 0244c4ae9519ea6c6f818e024930e70c15e7a289..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/MotionBlurSetup.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "MotionBlurSetup.hpp" -#include "MotionBlurConfig.hpp" - -namespace MotionBlurSetup { - -MotionBlurRenderTargets createRenderTargets(const uint32_t width, const uint32_t height, vkcv::Core& core) { - - MotionBlurRenderTargets targets; - - // divide and ceil to int - const uint32_t motionMaxWidth = (width + (MotionBlurConfig::maxMotionTileSize - 1)) / MotionBlurConfig::maxMotionTileSize; - const uint32_t motionMaxheight = (height + (MotionBlurConfig::maxMotionTileSize - 1)) / MotionBlurConfig::maxMotionTileSize; - - targets.motionMax = core.createImage( - MotionBlurConfig::motionVectorTileFormat, - motionMaxWidth, - motionMaxheight, - 1, - false, - true - ); - - targets.motionMaxNeighbourhood = core.createImage( - MotionBlurConfig::motionVectorTileFormat, - motionMaxWidth, - motionMaxheight, - 1, - false, - true - ); - - targets.motionMin = core.createImage( - MotionBlurConfig::motionVectorTileFormat, - motionMaxWidth, - motionMaxheight, - 1, - false, - true - ); - - targets.motionMinNeighbourhood = core.createImage( - MotionBlurConfig::motionVectorTileFormat, - motionMaxWidth, - motionMaxheight, - 1, - false, - true - ); - - targets.outputColor = core.createImage( - MotionBlurConfig::outputColorFormat, - width, - height, - 1, - false, - true - ); - - return targets; -} - -} // namespace MotionBlurSetup \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlurSetup.hpp b/projects/indirect_dispatch/src/MotionBlurSetup.hpp deleted file mode 100644 index ca169d7c6b04aa152d42ba36c3d2e02e563bbd91..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/MotionBlurSetup.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include <vkcv/Core.hpp> - -struct MotionBlurRenderTargets { - vkcv::ImageHandle outputColor; - vkcv::ImageHandle motionMax; - vkcv::ImageHandle motionMaxNeighbourhood; - vkcv::ImageHandle motionMin; - vkcv::ImageHandle motionMinNeighbourhood; -}; - -namespace MotionBlurSetup { - MotionBlurRenderTargets createRenderTargets(const uint32_t width, const uint32_t height, vkcv::Core& core); -} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/main.cpp b/projects/indirect_dispatch/src/main.cpp deleted file mode 100644 index b27e0bcb8f1991d76b570b79da9cc4734cf52950..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/src/main.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "App.hpp" - -int main(int argc, const char** argv) { - - App app; - if (!app.initialize()) { - std::cerr << "Application initialization failed, exiting" << std::endl; - return 1; - } - app.run(); - - return 0; -} diff --git a/projects/indirect_draw/.gitignore b/projects/indirect_draw/.gitignore deleted file mode 100644 index 92714f6a3381225d29daff0d99efe51e12b40970..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/.gitignore +++ /dev/null @@ -1 +0,0 @@ -indirect_draw \ No newline at end of file diff --git a/projects/indirect_draw/CMakeLists.txt b/projects/indirect_draw/CMakeLists.txt deleted file mode 100644 index 2802210db6111d833172933452bb25abb90a5c5b..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(indirect_draw) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(indirect_draw src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(indirect_draw SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(indirect_draw vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler vkcv_gui) diff --git a/projects/indirect_draw/resources/Sponza/Sponza.bin b/projects/indirect_draw/resources/Sponza/Sponza.bin deleted file mode 100644 index cfedd26ca5a67b6d0a47d44d13a75e14a141717a..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/Sponza.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b809f7a17687dc99e6f41ca1ea32c06eded8779bf34d16f1f565d750b0ffd68 -size 6347696 diff --git a/projects/indirect_draw/resources/Sponza/Sponza.gltf b/projects/indirect_draw/resources/Sponza/Sponza.gltf deleted file mode 100644 index 172ea07e21c94465211c860cd805355704cef230..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/Sponza.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5cc0ecad5c4694088ff820e663619c370421afc1323ac487406e8e9b4735d787 -size 713962 diff --git a/projects/indirect_draw/resources/Sponza/SponzaFloor.bin b/projects/indirect_draw/resources/Sponza/SponzaFloor.bin deleted file mode 100644 index 684251288f35070d2e7d244877fd844cc00ca632..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/SponzaFloor.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:678455aca641cb1f449aa1a5054a7cae132be81c2b333aac283053967da66df0 -size 512 diff --git a/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf b/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf deleted file mode 100644 index b45f1c55ef85f2aa1d4bff01df3d9625aa38c809..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/SponzaFloor.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6deb75441b1138b50a6b0eec05e60df276fe8fb6d58118fdfce2090b6fbe734 -size 3139 diff --git a/projects/indirect_draw/resources/Sponza/background.png b/projects/indirect_draw/resources/Sponza/background.png deleted file mode 100644 index b64def129da38f4e23d89e21b4af1039008a4327..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/background.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5b5f900ff8ed83a31750ec8e428b5b91273794ddcbfc4e4b8a6a7e781f8c686 -size 1417666 diff --git a/projects/indirect_draw/resources/Sponza/chain_texture.png b/projects/indirect_draw/resources/Sponza/chain_texture.png deleted file mode 100644 index c1e1768cff78e0614ad707eca8602a4c4edab5e5..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/chain_texture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8362cfd472880daeaea37439326a4651d1338680ae69bb2513fc6b17c8de7d4 -size 490895 diff --git a/projects/indirect_draw/resources/Sponza/lion.png b/projects/indirect_draw/resources/Sponza/lion.png deleted file mode 100644 index c49c7f0ed31e762e19284d0d3624fbc47664e56b..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/lion.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f882f746c3a9cd51a9c6eedc1189b97668721d91a3fe49232036e789912c652 -size 2088728 diff --git a/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png b/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png deleted file mode 100644 index cde4c7a6511e9a5f03c63ad996437fcdba3ce2df..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/spnza_bricks_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b94219c2f5f943f3f4715c74e7d1038bf0ab3b3b3216a758eaee67f875df0851 -size 1928829 diff --git a/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png b/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png deleted file mode 100644 index bcd9bda2918d226039f9e2d03902d377b706fab6..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_arch_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c0df2c8a01b2843b1c792b494f7173cdbc4f834840fc2177af3e5d690fceda57 -size 1596151 diff --git a/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png deleted file mode 100644 index 59de631ffac4414cabf69b2dc794c46fc187d6cb..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_ceiling_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab6c187a81aa68f4eba30119e17fce2e4882a9ec320f70c90482dbe9da82b1c6 -size 1872074 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png deleted file mode 100644 index 01a82432d3f9939bbefe850bdb900f1ff9a3f6db..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_column_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c291507e2808bb83e160ab4b020689817df273baad3713a9ad19ac15fac6826 -size 1840992 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png deleted file mode 100644 index 10a660cce2a5a9b8997772c746058ce23e7d45d7..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_column_b_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2820b0267c4289c6cedbb42721792a57ef244ec2d0935941011c2a7d3fe88a9b -size 2170433 diff --git a/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png b/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png deleted file mode 100644 index bc46fd979044a938d3adca7601689e71504e48bf..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_column_c_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0bc993ff59865468ef4530798930c7dfefb07482d71db45bc2a520986b27735 -size 2066950 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png deleted file mode 100644 index 384c8c2c051160d530eb3ac8b05c9c60752a2d2b..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_curtain_blue_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b85c6bb3cd5105f48d3812ec8e7a1068521ce69e917300d79e136e19d45422fb -size 9510905 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png deleted file mode 100644 index af842e9f5fe18c1f609875e00899a6770fa4488b..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_curtain_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:563c56bdbbee395a6ef7f0c51c8ac9223c162e517b4cdba0d4654e8de27c98d8 -size 9189263 diff --git a/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png b/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png deleted file mode 100644 index 6c9b6391a199407637fa71033d79fb58b8b4f0d7..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_curtain_green_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:238fe1c7f481388d1c1d578c2da8d411b99e8f0030ab62060a306db333124476 -size 8785458 diff --git a/projects/indirect_draw/resources/Sponza/sponza_details_diff.png b/projects/indirect_draw/resources/Sponza/sponza_details_diff.png deleted file mode 100644 index 12656686362c3e0a297e060491f33bd7351551f9..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_details_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb1223b3bb82f8757e7df25a6891f1239cdd7ec59990340e952fb2d6b7ea570c -size 1522643 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png deleted file mode 100644 index 879d16ef84722a4fc13e83a771778de326e4bc54..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_fabric_blue_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:467d290bf5d4b2a017da140ba9e244ed8a8a9be5418a9ac9bcb4ad572ae2d7ab -size 2229440 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png deleted file mode 100644 index 3311287a219d2148620b87fe428fea071688d051..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_fabric_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1594f59cc2848db26add47361f4e665e3d8afa147760ed915d839fea42b20287 -size 2267382 diff --git a/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png b/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png deleted file mode 100644 index de110f369004388dae4cd5067c63428db3a07834..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_fabric_green_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:902b87faab221173bf370cea7c74cb9060b4d870ac6316b190dafded1cb12993 -size 2258220 diff --git a/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png b/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png deleted file mode 100644 index 5f6e0812a0df80346318baa3cb50a6888afc58f8..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_flagpole_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfffb62e770959c725d0f3db6dc7dbdd46a380ec55ef884dab94d44ca017b438 -size 1425673 diff --git a/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png b/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png deleted file mode 100644 index 788ed764f79ba724f04a2d603076a5b85013e188..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_floor_a_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a16f9230fa91f9f31dfca6216ce205f1ef132d44f3b012fbf6efc0fba69770ab -size 1996838 diff --git a/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png b/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png deleted file mode 100644 index c5b84261fdd1cc776a94b3ce398c7806b895f9a3..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_roof_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7fc412138c20da19f8173e53545e771f4652558dff624d4dc67143e40efe562b -size 2320533 diff --git a/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png b/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png deleted file mode 100644 index 7a9142674a7d4a6f94a48c5152cf0300743b597a..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/sponza_thorn_diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a73a17c883cd0d0d67cfda2dc4118400a916366c05b9a5ac465f0c8b30fd9c8e -size 635001 diff --git a/projects/indirect_draw/resources/Sponza/vase_dif.png b/projects/indirect_draw/resources/Sponza/vase_dif.png deleted file mode 100644 index 61236a81cb324af8797b05099cd264cefe189e56..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/vase_dif.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53d06f52bf9e59df4cf00237707cca76c4f692bda61a62b06a30d321311d6dd9 -size 1842101 diff --git a/projects/indirect_draw/resources/Sponza/vase_hanging.png b/projects/indirect_draw/resources/Sponza/vase_hanging.png deleted file mode 100644 index 36a3cee71d8213225090c74f8c0dce33b9d44378..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/vase_hanging.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9d10b4f27a3c9a78d5bac882fdd4b6a6987c262f48fa490670fe5e235951e31 -size 1432804 diff --git a/projects/indirect_draw/resources/Sponza/vase_plant.png b/projects/indirect_draw/resources/Sponza/vase_plant.png deleted file mode 100644 index 7ad95e702e229f1ebd803e5203a266d15f2c07b9..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/vase_plant.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d2087371ff02212fb7014b6daefa191cf5676d2227193fff261a5d02f554cb8e -size 998089 diff --git a/projects/indirect_draw/resources/Sponza/vase_round.png b/projects/indirect_draw/resources/Sponza/vase_round.png deleted file mode 100644 index c17953abc000c44b8991e23c136c2b67348f3d1b..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/Sponza/vase_round.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aa23d48d492d5d4ada2ddb27d1ef22952b214e6eb3b301c65f9d88442723d20a -size 1871399 diff --git a/projects/indirect_draw/resources/shaders/culling.comp b/projects/indirect_draw/resources/shaders/culling.comp deleted file mode 100644 index 5d5884b9e494baf56ab32576f094f34584b163b3..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/shaders/culling.comp +++ /dev/null @@ -1,58 +0,0 @@ -#version 460 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_EXT_nonuniform_qualifier : enable - -layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; - -struct Plane{ - vec3 pointOnPlane; - float padding0; - vec3 normal; - float padding1; -}; - -struct DrawCommand{ - uint indexCount; - uint instanceCount; - uint firstIndex; - int vertexOffset; - uint firstInstance; -}; - -layout(set=0, binding=0, std140) readonly uniform cameraPlaneBuffer{ - Plane cameraPlanes[6]; -}; - -layout(set=0, binding=1, std430) buffer DrawCommandsBuffer{ - DrawCommand commands[]; -}; - -layout(set=0, binding=2, std430) readonly buffer boundingBoxBuffer{ - // x,y,z for meanPosition; - // w for boundingSphereRadius - vec4 boundingBoxes[]; -}; - -bool isSphereInsideFrustum(vec3 spherePos, float sphereRadius){ - bool isInside = true; - for(int i = 0; i < 6; i++){ - Plane p = cameraPlanes[i]; - isInside = isInside && dot(p.normal, spherePos - p.pointOnPlane) - sphereRadius < 0; - } - return isInside; -} - -void main(){ - if(gl_GlobalInvocationID.x > commands.length()){ - return; - } - - vec4 bbox = boundingBoxes[gl_GlobalInvocationID.x]; - if (isSphereInsideFrustum(bbox.xyz, bbox.w)){ - commands[gl_GlobalInvocationID.x].instanceCount = 1; - } - else{ - commands[gl_GlobalInvocationID.x].instanceCount = 0; - } -} - diff --git a/projects/indirect_draw/resources/shaders/shader.frag b/projects/indirect_draw/resources/shaders/shader.frag deleted file mode 100644 index f0a0b49314926ef9195d9a145b805b55d17b8807..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/shaders/shader.frag +++ /dev/null @@ -1,18 +0,0 @@ -#version 460 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_EXT_nonuniform_qualifier : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; -layout(location = 2) in flat uint passDrawIndex; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform sampler standardSampler; -layout(set=0, binding=2) uniform texture2D baseColorTex[]; - - -void main() -{ - outColor = texture(sampler2D(baseColorTex[nonuniformEXT(passDrawIndex)], standardSampler), passUV).rgb; -} \ No newline at end of file diff --git a/projects/indirect_draw/resources/shaders/shader.vert b/projects/indirect_draw/resources/shaders/shader.vert deleted file mode 100644 index 10b250761437dce6eea01dd195e1248fc9c0bd90..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/resources/shaders/shader.vert +++ /dev/null @@ -1,27 +0,0 @@ -#version 460 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shader_draw_parameters : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(std430, binding=1) readonly buffer uModel { - mat4 modelMatrix[]; -}; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; -layout(location = 2) out flat uint passDrawIndex; - -layout( push_constant ) uniform constants{ - mat4 vp; -}; - -void main() -{ - gl_Position = vp * modelMatrix[gl_DrawID] * vec4(inPosition, 1.0); - passNormal = inNormal; - passUV = inUV; - passDrawIndex = gl_DrawID; -} \ No newline at end of file diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp deleted file mode 100644 index 5951c8c0653011810902a6e8499d02c96d07fd1c..0000000000000000000000000000000000000000 --- a/projects/indirect_draw/src/main.cpp +++ /dev/null @@ -1,590 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/gui/GUI.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -struct Plane { - glm::vec3 pointOnPlane; - float padding0; - glm::vec3 normal; - float padding1; -}; - -struct CameraPlanes { - Plane planes[6]; -}; - -CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) { - const float fov = camera.getFov(); - const glm::vec3 pos = camera.getPosition(); - const float ratio = camera.getRatio(); - const glm::vec3 forward = glm::normalize(camera.getFront()); - float near; - float far; - camera.getNearFar(near, far); - - glm::vec3 up = glm::vec3(0, -1, 0); - glm::vec3 right = glm::normalize(glm::cross(forward, up)); - up = glm::cross(forward, right); - - const glm::vec3 nearCenter = pos + forward * near; - const glm::vec3 farCenter = pos + forward * far; - - const float tanFovHalf = glm::tan(fov / 2); - - const glm::vec3 nearUpCenter = nearCenter + up * tanFovHalf * near; - const glm::vec3 nearDownCenter = nearCenter - up * tanFovHalf * near; - const glm::vec3 nearRightCenter = nearCenter + right * tanFovHalf * near * ratio; - const glm::vec3 nearLeftCenter = nearCenter - right * tanFovHalf * near * ratio; - - const glm::vec3 farUpCenter = farCenter + up * tanFovHalf * far; - const glm::vec3 farDownCenter = farCenter - up * tanFovHalf * far; - const glm::vec3 farRightCenter = farCenter + right * tanFovHalf * far * ratio; - const glm::vec3 farLeftCenter = farCenter - right * tanFovHalf * far * ratio; - - CameraPlanes cameraPlanes; - // near - cameraPlanes.planes[0].pointOnPlane = nearCenter; - cameraPlanes.planes[0].normal = -forward; - // far - cameraPlanes.planes[1].pointOnPlane = farCenter; - cameraPlanes.planes[1].normal = forward; - - // top - cameraPlanes.planes[2].pointOnPlane = nearUpCenter; - cameraPlanes.planes[2].normal = glm::normalize(glm::cross(farUpCenter - nearUpCenter, right)); - // bot - cameraPlanes.planes[3].pointOnPlane = nearDownCenter; - cameraPlanes.planes[3].normal = glm::normalize(glm::cross(right, farDownCenter - nearDownCenter)); - - // right - cameraPlanes.planes[4].pointOnPlane = nearRightCenter; - cameraPlanes.planes[4].normal = glm::normalize(glm::cross(up, farRightCenter - nearRightCenter)); - // left - cameraPlanes.planes[5].pointOnPlane = nearLeftCenter; - cameraPlanes.planes[5].normal = glm::normalize(glm::cross(farLeftCenter - nearLeftCenter, up)); - - return cameraPlanes; -} - -struct Vertex -{ - glm::vec3 position; - glm::vec3 normal; - glm::vec2 uv; -}; - -struct CompiledMaterial -{ - std::vector<vkcv::Image> baseColor; - std::vector<vkcv::Image> metalRough; - std::vector<vkcv::Image> normal; - std::vector<vkcv::Image> occlusion; -}; - -void interleaveScene(vkcv::asset::Scene scene, - std::vector<std::vector<Vertex>> &interleavedVertexBuffers, - std::vector<glm::vec4> &boundingBoxBuffers) { - - for(const auto &mesh : scene.meshes) { - for(auto vertexGroupIndex : mesh.vertexGroups) { - const auto &vertexGroup = scene.vertexGroups[vertexGroupIndex]; - - const vkcv::asset::VertexAttribute* positionAttribute = nullptr; - const vkcv::asset::VertexAttribute* normalAttribute = nullptr; - const vkcv::asset::VertexAttribute* uvAttribute = nullptr; - - for (const auto& attribute : vertexGroup.vertexBuffer.attributes) { - switch (attribute.type) { - case vkcv::asset::PrimitiveType::POSITION: - positionAttribute = &attribute; - break; - case vkcv::asset::PrimitiveType::NORMAL: - normalAttribute = &attribute; - break; - case vkcv::asset::PrimitiveType::TEXCOORD_0: - uvAttribute = &attribute; - break; - default: - break; - } - } - - assert(positionAttribute && normalAttribute && uvAttribute); - - const uint64_t &verticesCount = vertexGroup.numVertices; - const std::vector<uint8_t> &vertexData = vertexGroup.vertexBuffer.data; - - std::vector<Vertex> vertices; - vertices.reserve(verticesCount); - - const size_t positionStride = positionAttribute->stride == 0 ? sizeof(glm::vec3) : positionAttribute->stride; - const size_t normalStride = normalAttribute->stride == 0 ? sizeof(glm::vec3) : normalAttribute->stride; - const size_t uvStride = uvAttribute->stride == 0 ? sizeof(glm::vec2) : uvAttribute->stride; - - glm::vec3 max_pos(-std::numeric_limits<float>::max()); - glm::vec3 min_pos(std::numeric_limits<float>::max()); - - for(size_t i = 0; i < verticesCount; i++) - { - const size_t positionOffset = positionAttribute->offset + positionStride * i; - const size_t normalOffset = normalAttribute->offset + normalStride * i; - const size_t uvOffset = uvAttribute->offset + uvStride * i; - - Vertex v; - - v.position = *reinterpret_cast<const glm::vec3*>(&(vertexData[positionOffset])); - v.normal = *reinterpret_cast<const glm::vec3*>(&(vertexData[normalOffset])); - v.uv = *reinterpret_cast<const glm::vec3*>(&(vertexData[uvOffset])); - - glm::vec3 posWorld = glm::make_mat4(mesh.modelMatrix.data()) * glm::vec4(v.position, 1); - - max_pos.x = glm::max(max_pos.x, posWorld.x); - max_pos.y = glm::max(max_pos.y, posWorld.y); - max_pos.z = glm::max(max_pos.z, posWorld.z); - - min_pos.x = glm::min(min_pos.x, posWorld.x); - min_pos.y = glm::min(min_pos.y, posWorld.y); - min_pos.z = glm::min(min_pos.z, posWorld.z); - - vertices.push_back(v); - } - - const glm::vec3 boundingPosition = (max_pos + min_pos) / 2.0f; - const float radius = glm::distance(max_pos, min_pos) / 2.0f; - - boundingBoxBuffers.emplace_back(boundingPosition.x, - boundingPosition.y, - boundingPosition.z, - radius); - - interleavedVertexBuffers.push_back(vertices); - } - } -} - -// Assumes the meshes use index buffers -void compileMeshForIndirectDraw(vkcv::Core &core, - const vkcv::asset::Scene &scene, - std::vector<uint8_t> &compiledVertexBuffer, - std::vector<uint8_t> &compiledIndexBuffer, - CompiledMaterial &compiledMat, - std::vector<vk::DrawIndexedIndirectCommand> &indexedIndirectCommands) -{ - vkcv::Image pseudoImg = vkcv::image(core, vk::Format::eR8G8B8A8Srgb, 2, 2); - std::vector<uint8_t> pseudoData = {0, 0, 0, 0}; - pseudoImg.fill(pseudoData.data()); - - auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics); - pseudoImg.recordMipChainGeneration(mipStream, core.getDownsampler()); - - uint32_t vertexOffset = 0; - for (const auto &mesh : scene.meshes) - { - for(auto &vertexGroupIndex : mesh.vertexGroups) - { - auto &vertexGroup = scene.vertexGroups[vertexGroupIndex]; - - auto &material = scene.materials[vertexGroup.materialIndex]; - - if(material.baseColor == -1) - { - std::cout << "baseColor is -1! Pushing pseudo-texture!" << std::endl; - compiledMat.baseColor.push_back(pseudoImg); - } - else - { - auto &baseColor = scene.textures[material.baseColor]; - - vkcv::Image baseColorImg = vkcv::image(core, vk::Format::eR8G8B8A8Srgb, baseColor.w, baseColor.h); - baseColorImg.fill(baseColor.data.data()); - baseColorImg.recordMipChainGeneration(mipStream, core.getDownsampler()); - - compiledMat.baseColor.push_back(baseColorImg); - } - - indexedIndirectCommands.emplace_back(static_cast<uint32_t>(vertexGroup.numIndices), - 1, - static_cast<uint32_t>(compiledIndexBuffer.size() / 4), - vertexOffset, - static_cast<uint32_t>(indexedIndirectCommands.size())); - - vertexOffset += vertexGroup.numVertices; - - compiledVertexBuffer.insert(compiledVertexBuffer.end(), - vertexGroup.vertexBuffer.data.begin(), - vertexGroup.vertexBuffer.data.end()); - - if(vertexGroup.indexBuffer.type == vkcv::asset::IndexType::UINT8) - { - for(auto index : vertexGroup.indexBuffer.data) - { - uint32_t index32 = static_cast<uint32_t>(index); - uint8_t firstByte = index32; - uint8_t secondByte = index32 >> 8; - uint8_t thirdByte = index32 >> 16; - uint8_t fourthByte = index32 >> 24; - - compiledIndexBuffer.push_back(firstByte); - compiledIndexBuffer.push_back(secondByte); - compiledIndexBuffer.push_back(thirdByte); - compiledIndexBuffer.push_back(fourthByte); - } - } - else if(vertexGroup.indexBuffer.type == vkcv::asset::IndexType::UINT16) - { - for (size_t i = 0; i < vertexGroup.indexBuffer.data.size(); i += 2) - { - uint16_t index16 = *reinterpret_cast<const uint16_t*>(&vertexGroup.indexBuffer.data[i]); - uint32_t index32 = static_cast<uint32_t>(index16); - - uint8_t firstByte = index32; - uint8_t secondByte = index32 >> 8; - uint8_t thirdByte = index32 >> 16; - uint8_t fourthByte = index32 >> 24; - - compiledIndexBuffer.push_back(firstByte); - compiledIndexBuffer.push_back(secondByte); - compiledIndexBuffer.push_back(thirdByte); - compiledIndexBuffer.push_back(fourthByte); - } - } - else - { - compiledIndexBuffer.insert(compiledIndexBuffer.end(), - vertexGroup.indexBuffer.data.begin(), - vertexGroup.indexBuffer.data.end()); - } - } - } - - core.submitCommandStream(mipStream, false); -} - -int main(int argc, const char** argv) { - const std::string applicationName = "Indirect draw"; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - features.requireFeature([](vk::PhysicalDeviceFeatures &features){ - features.setMultiDrawIndirect(true); - }); - - features.requireExtension(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME); - features.requireExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, [](vk::PhysicalDeviceDescriptorIndexingFeatures &features) { - // features.setShaderInputAttachmentArrayDynamicIndexing(true); - features.setShaderUniformTexelBufferArrayDynamicIndexing(true); - features.setShaderStorageTexelBufferArrayDynamicIndexing(true); - features.setShaderUniformBufferArrayNonUniformIndexing(true); - features.setShaderSampledImageArrayNonUniformIndexing(true); - features.setShaderStorageBufferArrayNonUniformIndexing(true); - features.setShaderStorageImageArrayNonUniformIndexing(true); - // features.setShaderInputAttachmentArrayNonUniformIndexing(true); - features.setShaderUniformTexelBufferArrayNonUniformIndexing(true); - features.setShaderStorageTexelBufferArrayNonUniformIndexing(true); - - features.setDescriptorBindingUniformBufferUpdateAfterBind(true); - features.setDescriptorBindingSampledImageUpdateAfterBind(true); - features.setDescriptorBindingStorageImageUpdateAfterBind(true); - features.setDescriptorBindingStorageBufferUpdateAfterBind(true); - features.setDescriptorBindingUniformTexelBufferUpdateAfterBind(true); - features.setDescriptorBindingStorageTexelBufferUpdateAfterBind(true); - - features.setDescriptorBindingUpdateUnusedWhilePending(true); - features.setDescriptorBindingPartiallyBound(true); - features.setDescriptorBindingVariableDescriptorCount(true); - features.setRuntimeDescriptorArray(true); - } - ); - - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, - features - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName,800,600,true); - vkcv::Window& window = core.getWindow(windowHandle); - - vkcv::gui::GUI gui (core, windowHandle); - - vkcv::asset::Scene asset_scene; - const char* path = argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf"; - int result = vkcv::asset::loadScene(path, asset_scene); - - if (result == 1) { - std::cout << "Loading Sponza successful!" << std::endl; - } else { - std::cerr << "Loading Sponza failed: " << result << std::endl; - return 1; - } - assert(!asset_scene.vertexGroups.empty()); - if (asset_scene.textures.empty()) - { - std::cerr << "Error. No textures found. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::PassHandle passHandle = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - if (!passHandle) { - std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - - vkcv::ShaderProgram sponzaProgram; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), - [&sponzaProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - sponzaProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), - [&sponzaProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - sponzaProgram.addShader(shaderStage, path); - }); - - vkcv::ShaderProgram cullingProgram; - compiler.compile(vkcv::ShaderStage::COMPUTE, std::filesystem::path("resources/shaders/culling.comp"), - [&cullingProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - cullingProgram.addShader(shaderStage, path); - }); - - // vertex layout for the pipeline. (assumed to be) used by all sponza meshes. - const std::vector<vkcv::VertexAttachment> vertexAttachments = sponzaProgram.getVertexAttachments(); - const vkcv::VertexLayout sponzaVertexLayout { - { vkcv::createVertexBinding(0, { vertexAttachments }) } - }; - - std::vector<uint8_t> compiledVertexBuffer; // IGNORED, since the vertex buffer is not interleaved! - - std::vector<uint8_t> compiledIndexBuffer; - CompiledMaterial compiledMaterial; - std::vector<vk::DrawIndexedIndirectCommand> indexedIndirectCommands; - - compileMeshForIndirectDraw(core, - asset_scene, - compiledVertexBuffer, - compiledIndexBuffer, - compiledMaterial, - indexedIndirectCommands); - - std::vector<std::vector<Vertex>> interleavedVertices; - std::vector<glm::vec4> compiledBoundingBoxBuffer; - interleaveScene(asset_scene, - interleavedVertices, - compiledBoundingBoxBuffer); - - std::vector<Vertex> compiledInterleavedVertexBuffer; - for(auto& vertexGroup : interleavedVertices ) - { - compiledInterleavedVertexBuffer.insert(compiledInterleavedVertexBuffer.end(),vertexGroup.begin(),vertexGroup.end()); - } - - auto vkCompiledVertexBuffer = vkcv::buffer<Vertex>( - core, - vkcv::BufferType::VERTEX, - compiledInterleavedVertexBuffer.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - vkCompiledVertexBuffer.fill(compiledInterleavedVertexBuffer.data()); - - auto vkCompiledIndexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::INDEX, - compiledIndexBuffer.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - vkCompiledIndexBuffer.fill(compiledIndexBuffer.data()); - - vkcv::Buffer<vk::DrawIndexedIndirectCommand> indirectBuffer = vkcv::buffer<vk::DrawIndexedIndirectCommand>( - core, - vkcv::BufferType::INDIRECT, - indexedIndirectCommands.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - indirectBuffer.fill(indexedIndirectCommands); - - auto boundingBoxBuffer = vkcv::buffer<glm::vec4>( - core, - vkcv::BufferType::STORAGE, - compiledBoundingBoxBuffer.size()); - boundingBoxBuffer.fill(compiledBoundingBoxBuffer); - - std::vector<glm::mat4> modelMatrix; - for( auto& mesh : asset_scene.meshes) - { - modelMatrix.push_back(glm::make_mat4(mesh.modelMatrix.data())); - } - vkcv::Buffer<glm::mat4> modelBuffer = vkcv::buffer<glm::mat4>( - core, - vkcv::BufferType::STORAGE, - modelMatrix.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - modelBuffer.fill(modelMatrix); - - const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::vertexBufferBinding(vkCompiledVertexBuffer.getHandle()) - }; - - vkcv::VertexData vertexData (vertexBufferBindings); - vertexData.setIndexBuffer(vkCompiledIndexBuffer.getHandle(), vkcv::IndexBitCount::Bit32); - - //assert(compiledMaterial.baseColor.size() == compiledMaterial.metalRough.size()); - - vkcv::DescriptorBindings descriptorBindings = sponzaProgram.getReflectedDescriptors().at(0); - descriptorBindings[2].descriptorCount = compiledMaterial.baseColor.size(); - - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); - - vkcv::SamplerHandle standardSampler = vkcv::samplerLinear(core); - - vkcv::DescriptorWrites setWrites; - - std::vector<vkcv::SampledImageDescriptorWrite> textureArrayWrites; - for(uint32_t i = 0; i < compiledMaterial.baseColor.size(); i++) - { - setWrites.writeSampledImage(2, compiledMaterial.baseColor[i].getHandle(), 0, false, i); - } - - setWrites.writeSampler(0, standardSampler); - setWrites.writeStorageBuffer(1, modelBuffer.getHandle()); - core.writeDescriptorSet(descriptorSet, setWrites); - - vkcv::GraphicsPipelineHandle sponzaPipelineHandle = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - sponzaProgram, - passHandle, - { sponzaVertexLayout }, - { descriptorSetLayout } - ) - ); - - if (!sponzaPipelineHandle) { - std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::DescriptorBindings cullingBindings = cullingProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle cullingSetLayout = core.createDescriptorSetLayout(cullingBindings); - vkcv::DescriptorSetHandle cullingDescSet = core.createDescriptorSet(cullingSetLayout); - - vkcv::Buffer<CameraPlanes> cameraPlaneBuffer = vkcv::buffer<CameraPlanes>( - core, - vkcv::BufferType::UNIFORM, - 1); - - vkcv::DescriptorWrites cullingWrites; - cullingWrites.writeStorageBuffer(1, indirectBuffer.getHandle()); - cullingWrites.writeStorageBuffer(2, boundingBoxBuffer.getHandle()); - cullingWrites.writeUniformBuffer(0, cameraPlaneBuffer.getHandle()); - core.writeDescriptorSet(cullingDescSet, cullingWrites); - - - const vkcv::ComputePipelineConfig computeCullingConfig { - cullingProgram, - {cullingSetLayout} - }; - vkcv::ComputePipelineHandle cullingPipelineHandle = core.createComputePipeline(computeCullingConfig); - if (!cullingPipelineHandle) { - std::cerr << "Error. Could not create culling pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::camera::CameraManager cameraManager (window); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(camHandle).setPosition(glm::vec3(0, 0, -3)); - cameraManager.getCamera(camHandle).setNearFar(0.1f, 20.f); - - vkcv::ImageHandle depthBuffer; - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - float ceiledDispatchCount = static_cast<float>(indexedIndirectCommands.size()) / 64.0f; - ceiledDispatchCount = std::ceil(ceiledDispatchCount); - const vkcv::DispatchSize dispatchCount = static_cast<uint32_t>(ceiledDispatchCount); - - vkcv::DescriptorSetUsage cullingUsage = vkcv::useDescriptorSet(0, cullingDescSet); - vkcv::PushConstants emptyPushConstant(0); - - bool updateFrustumPlanes = true; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - (swapchainHeight != core.getImageHeight(depthBuffer))) { - depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight); - } - - cameraManager.update(dt); - - vkcv::camera::Camera cam = cameraManager.getActiveCamera(); - vkcv::PushConstants pushConstants = vkcv::pushConstants<glm::mat4>(); - pushConstants.appendDrawcall(cam.getProjection() * cam.getView()); - - if (updateFrustumPlanes) { - const CameraPlanes cameraPlanes = computeCameraPlanes(cam); - cameraPlaneBuffer.fill({ cameraPlanes }); - } - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - core.recordComputeDispatchToCmdStream( - cmdStream, - cullingPipelineHandle, - dispatchCount, - {cullingUsage}, - emptyPushConstant - ); - - core.recordBufferMemoryBarrier(cmdStream, indirectBuffer.getHandle()); - - vkcv::IndirectDrawcall drawcall ( - indirectBuffer.getHandle(), - vertexData, - indexedIndirectCommands.size() - ); - - drawcall.useDescriptorSet(0, descriptorSet); - - core.recordIndirectDrawcallsToCmdStream( - cmdStream, - sponzaPipelineHandle, - pushConstants, - { drawcall }, - renderTargets, - windowHandle - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - - ImGui::Begin("Settings"); - ImGui::Checkbox("Update frustum culling", &updateFrustumPlanes); - ImGui::Text("Deltatime %fms, %f", dt * 1000, 1/dt); - - ImGui::End(); - - gui.endGUI(); - }); - - return 0; -} diff --git a/projects/mesh_shader/.gitignore b/projects/mesh_shader/.gitignore deleted file mode 100644 index fd009a6281f4b2b6716e193d23829907f4bb5f33..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/.gitignore +++ /dev/null @@ -1 +0,0 @@ -mesh_shader \ No newline at end of file diff --git a/projects/mesh_shader/CMakeLists.txt b/projects/mesh_shader/CMakeLists.txt deleted file mode 100644 index 04b632effa28101a105100c768da712676378c99..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(mesh_shader) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(mesh_shader src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(mesh_shader SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_camera_include} ${vkcv_meshlet_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(mesh_shader vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_testing vkcv_camera vkcv_meshlet vkcv_shader_compiler vkcv_gui) \ No newline at end of file diff --git a/projects/mesh_shader/assets/Bunny/Bunny.glb b/projects/mesh_shader/assets/Bunny/Bunny.glb deleted file mode 100644 index 181f1f92f1906e1e1ba900768580203efe19e9be..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/Bunny/Bunny.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b8bc6fab11929ca11bdf4e892ffb03b621b10307f705cdea17d82d3dee3b9aae -size 4045836 diff --git a/projects/mesh_shader/assets/monke.glb b/projects/mesh_shader/assets/monke.glb deleted file mode 100644 index 47d0b9131f15a8f0697318d0a47302c71cad1db8..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/monke.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:597584db90a3f51088beea6652d8320e82cb025f9d3d036b89e54ad72c732a06 -size 98612 diff --git a/projects/mesh_shader/assets/shaders/common.inc b/projects/mesh_shader/assets/shaders/common.inc deleted file mode 100644 index 280ffee215a8b8342b78d1f5558d63a05e16859b..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/common.inc +++ /dev/null @@ -1,4 +0,0 @@ -struct ObjectMatrices{ - mat4 model; - mat4 mvp; -}; \ No newline at end of file diff --git a/projects/mesh_shader/assets/shaders/meshlet.inc b/projects/mesh_shader/assets/shaders/meshlet.inc deleted file mode 100644 index 0594f62ceead8ffca09b585305075eb6046f3c46..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/meshlet.inc +++ /dev/null @@ -1,8 +0,0 @@ -struct Meshlet{ - uint vertexOffset; - uint vertexCount; - uint indexOffset; - uint indexCount; - vec3 meanPosition; - float boundingSphereRadius; -}; \ No newline at end of file diff --git a/projects/mesh_shader/assets/shaders/shader.frag b/projects/mesh_shader/assets/shaders/shader.frag deleted file mode 100644 index f4f6982f2089e6c8e102027f3b8763bb38f8e59c..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/shader.frag +++ /dev/null @@ -1,32 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in flat uint passTaskIndex; -layout(location = 0) out vec3 outColor; - -uint lowbias32(uint x) -{ - x ^= x >> 16; - x *= 0x7feb352dU; - x ^= x >> 15; - x *= 0x846ca68bU; - x ^= x >> 16; - return x; -} - -float hashToFloat(uint hash){ - return (hash % 255) / 255.f; -} - -vec3 colorFromIndex(uint i){ - return vec3( - hashToFloat(lowbias32(i+0)), - hashToFloat(lowbias32(i+1)), - hashToFloat(lowbias32(i+2))); -} - -void main() { - outColor = normalize(passNormal) * 0.5 + 0.5; - outColor = colorFromIndex(passTaskIndex); -} \ No newline at end of file diff --git a/projects/mesh_shader/assets/shaders/shader.mesh b/projects/mesh_shader/assets/shaders/shader.mesh deleted file mode 100644 index 30c98610f4776204ff526c57c1f793e371194629..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/shader.mesh +++ /dev/null @@ -1,78 +0,0 @@ -#version 460 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable -#extension GL_NV_mesh_shader : require - -#include "meshlet.inc" - -layout(local_size_x=32) in; - -layout(triangles) out; -layout(max_vertices=64, max_primitives=126) out; - -layout(location = 0) out vec3 passNormal[]; -layout(location = 1) out uint passTaskIndex[]; - -struct Vertex -{ - vec3 position; float padding0; - vec3 normal; float padding1; -}; - -layout(std430, binding = 0) readonly buffer vertexBuffer -{ - Vertex vertices[]; -}; - -layout(std430, binding = 1) readonly buffer indexBuffer -{ - uint localIndices[]; // breaks for 16 bit indices -}; - -layout(std430, binding = 2) readonly buffer meshletBuffer -{ - Meshlet meshlets[]; -}; - -taskNV in Task { - uint meshletIndices[32]; - mat4 mvp; -} IN; - -void main() { - - uint meshletIndex = IN.meshletIndices[gl_WorkGroupID.x]; - Meshlet meshlet = meshlets[meshletIndex]; - - // set vertices - for(uint i = 0; i < 2; i++){ - - uint workIndex = gl_LocalInvocationID.x + 32 * i; - if(workIndex >= meshlet.vertexCount){ - break; - } - - uint vertexIndex = meshlet.vertexOffset + workIndex; - Vertex vertex = vertices[vertexIndex]; - - gl_MeshVerticesNV[workIndex].gl_Position = IN.mvp * vec4(vertex.position, 1); - passNormal[workIndex] = vertex.normal; - passTaskIndex[workIndex] = meshletIndex; - } - - // set local indices - for(uint i = 0; i < 12; i++){ - - uint workIndex = gl_LocalInvocationID.x + i * 32; - if(workIndex >= meshlet.indexCount){ - break; - } - - uint indexBufferIndex = meshlet.indexOffset + workIndex; - gl_PrimitiveIndicesNV[workIndex] = localIndices[indexBufferIndex]; - } - - if(gl_LocalInvocationID.x == 0){ - gl_PrimitiveCountNV = meshlet.indexCount / 3; - } -} \ No newline at end of file diff --git a/projects/mesh_shader/assets/shaders/shader.task b/projects/mesh_shader/assets/shaders/shader.task deleted file mode 100644 index 7a692e98e6384767191d76cef940e295ca127d62..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/shader.task +++ /dev/null @@ -1,78 +0,0 @@ -#version 460 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_NV_mesh_shader : require -#extension GL_GOOGLE_include_directive : enable - -#include "meshlet.inc" -#include "common.inc" - -layout(local_size_x=32) in; - -taskNV out Task { - uint meshletIndices[32]; - mat4 mvp; -} OUT; - -layout( push_constant ) uniform constants{ - uint matrixIndex; - uint meshletCount; -}; - -// TODO: reuse mesh stage binding at location 2 after required fix in framework -layout(std430, binding = 5) readonly buffer meshletBuffer -{ - Meshlet meshlets[]; -}; - -struct Plane{ - vec3 pointOnPlane; - float padding0; - vec3 normal; - float padding1; -}; - -layout(set=0, binding=3, std140) uniform cameraPlaneBuffer{ - Plane cameraPlanes[6]; -}; - -layout(std430, binding = 4) readonly buffer matrixBuffer -{ - ObjectMatrices objectMatrices[]; -}; - -shared uint taskCount; - -bool isSphereInsideFrustum(vec3 spherePos, float sphereRadius, Plane cameraPlanes[6]){ - bool isInside = true; - for(int i = 0; i < 6; i++){ - Plane p = cameraPlanes[i]; - isInside = isInside && dot(p.normal, spherePos - p.pointOnPlane) - sphereRadius < 0; - } - return isInside; -} - -void main() { - - if(gl_LocalInvocationID.x >= meshletCount){ - return; - } - - uint meshletIndex = gl_GlobalInvocationID.x; - Meshlet meshlet = meshlets[meshletIndex]; - - if(gl_LocalInvocationID.x == 0){ - taskCount = 0; - } - - // TODO: scaling support - vec3 meshletPositionWorld = (vec4(meshlet.meanPosition, 1) * objectMatrices[matrixIndex].model).xyz; - if(isSphereInsideFrustum(meshletPositionWorld, meshlet.boundingSphereRadius, cameraPlanes)){ - uint outIndex = atomicAdd(taskCount, 1); - OUT.meshletIndices[outIndex] = gl_GlobalInvocationID.x; - } - - if(gl_LocalInvocationID.x == 0){ - gl_TaskCountNV = taskCount; - OUT.mvp = objectMatrices[matrixIndex].mvp; - } -} \ No newline at end of file diff --git a/projects/mesh_shader/assets/shaders/shader.vert b/projects/mesh_shader/assets/shaders/shader.vert deleted file mode 100644 index fca5057976f995183c040195bdbd592c63f1074e..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/assets/shaders/shader.vert +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "common.inc" - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out uint dummyOutput; - -layout(std430, binding = 0) readonly buffer matrixBuffer -{ - ObjectMatrices objectMatrices[]; -}; - -layout( push_constant ) uniform constants{ - uint matrixIndex; - uint padding; // pad to same size as mesh shader constants -}; - - -void main() { - gl_Position = objectMatrices[matrixIndex].mvp * vec4(inPosition, 1.0); - passNormal = inNormal; - - dummyOutput = padding * 0; // padding must be used, else compiler shrinks constant size -} \ No newline at end of file diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp deleted file mode 100644 index 512e1e6d1e6ea694289cb862ecae425b6bf8ee66..0000000000000000000000000000000000000000 --- a/projects/mesh_shader/src/main.cpp +++ /dev/null @@ -1,401 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> - -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/gui/GUI.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/meshlet/Meshlet.hpp> -#include <vkcv/meshlet/Tipsify.hpp> -#include <vkcv/meshlet/Forsyth.hpp> - -struct Plane { - glm::vec3 pointOnPlane; - float padding0; - glm::vec3 normal; - float padding1; -}; - -struct CameraPlanes { - Plane planes[6]; -}; - -CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) { - const float fov = camera.getFov(); - const glm::vec3 pos = camera.getPosition(); - const float ratio = camera.getRatio(); - const glm::vec3 forward = glm::normalize(camera.getFront()); - float near; - float far; - camera.getNearFar(near, far); - - glm::vec3 up = glm::vec3(0, -1, 0); - glm::vec3 right = glm::normalize(glm::cross(forward, up)); - up = glm::cross(forward, right); - - const glm::vec3 nearCenter = pos + forward * near; - const glm::vec3 farCenter = pos + forward * far; - - const float tanFovHalf = glm::tan(fov / 2); - - const glm::vec3 nearUpCenter = nearCenter + up * tanFovHalf * near; - const glm::vec3 nearDownCenter = nearCenter - up * tanFovHalf * near; - const glm::vec3 nearRightCenter = nearCenter + right * tanFovHalf * near * ratio; - const glm::vec3 nearLeftCenter = nearCenter - right * tanFovHalf * near * ratio; - - const glm::vec3 farUpCenter = farCenter + up * tanFovHalf * far; - const glm::vec3 farDownCenter = farCenter - up * tanFovHalf * far; - const glm::vec3 farRightCenter = farCenter + right * tanFovHalf * far * ratio; - const glm::vec3 farLeftCenter = farCenter - right * tanFovHalf * far * ratio; - - CameraPlanes cameraPlanes; - // near - cameraPlanes.planes[0].pointOnPlane = nearCenter; - cameraPlanes.planes[0].normal = -forward; - // far - cameraPlanes.planes[1].pointOnPlane = farCenter; - cameraPlanes.planes[1].normal = forward; - - // top - cameraPlanes.planes[2].pointOnPlane = nearUpCenter; - cameraPlanes.planes[2].normal = glm::normalize(glm::cross(farUpCenter - nearUpCenter, right)); - // bot - cameraPlanes.planes[3].pointOnPlane = nearDownCenter; - cameraPlanes.planes[3].normal = glm::normalize(glm::cross(right, farDownCenter - nearDownCenter)); - - // right - cameraPlanes.planes[4].pointOnPlane = nearRightCenter; - cameraPlanes.planes[4].normal = glm::normalize(glm::cross(up, farRightCenter - nearRightCenter)); - // left - cameraPlanes.planes[5].pointOnPlane = nearLeftCenter; - cameraPlanes.planes[5].normal = glm::normalize(glm::cross(farLeftCenter - nearLeftCenter, up)); - - return cameraPlanes; -} - -int main(int argc, const char** argv) { - const std::string applicationName = "Mesh shader"; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - features.requireExtensionFeature<vk::PhysicalDeviceMeshShaderFeaturesNV>( - VK_NV_MESH_SHADER_EXTENSION_NAME, [](vk::PhysicalDeviceMeshShaderFeaturesNV& features) { - features.setTaskShader(true); - features.setMeshShader(true); - }); - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - features - ); - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 1280, 720, true); - vkcv::Window &window = core.getWindow(windowHandle); - - vkcv::gui::GUI gui (core, windowHandle); - - vkcv::asset::Scene mesh; - const char* path = argc > 1 ? argv[1] : "assets/Bunny/Bunny.glb"; - vkcv::asset::loadScene(path, mesh); - - assert(!mesh.vertexGroups.empty()); - - auto vertexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::VERTEX, - mesh.vertexGroups[0].vertexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); - - auto indexBuffer = vkcv::buffer<uint8_t>( - core, - vkcv::BufferType::INDEX, - mesh.vertexGroups[0].indexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); - - const auto vertexBufferBindings = vkcv::asset::loadVertexBufferBindings( - mesh.vertexGroups[0].vertexBuffer.attributes, - vertexBuffer.getHandle(), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL - } - ); - - const vkcv::asset::VertexAttribute* positionAttribute = nullptr; - const vkcv::asset::VertexAttribute* normalAttribute = nullptr; - - for (const auto& attribute : mesh.vertexGroups[0].vertexBuffer.attributes) { - switch (attribute.type) { - case vkcv::asset::PrimitiveType::POSITION: - positionAttribute = &attribute; - break; - case vkcv::asset::PrimitiveType::NORMAL: - normalAttribute = &attribute; - break; - default: - break; - } - } - - assert(positionAttribute && normalAttribute); - - const auto& bunny = mesh.vertexGroups[0]; - std::vector<vkcv::meshlet::Vertex> interleavedVertices = vkcv::meshlet::convertToVertices( - bunny.vertexBuffer.data, - bunny.numVertices, - *positionAttribute, - *normalAttribute - ); - - // mesh shader buffers - const auto& assetLoaderIndexBuffer = mesh.vertexGroups[0].indexBuffer; - std::vector<uint32_t> indexBuffer32Bit = vkcv::meshlet::assetLoaderIndicesTo32BitIndices(assetLoaderIndexBuffer.data, assetLoaderIndexBuffer.type); - vkcv::meshlet::VertexCacheReorderResult tipsifyResult = vkcv::meshlet::tipsifyMesh(indexBuffer32Bit, interleavedVertices.size()); - vkcv::meshlet::VertexCacheReorderResult forsythResult = vkcv::meshlet::forsythReorder(indexBuffer32Bit, interleavedVertices.size()); - - const auto meshShaderModelData = createMeshShaderModelData(interleavedVertices, forsythResult.indexBuffer, forsythResult.skippedIndices); - - auto meshShaderVertexBuffer = vkcv::buffer<vkcv::meshlet::Vertex>( - core, - vkcv::BufferType::STORAGE, - meshShaderModelData.vertices.size()); - meshShaderVertexBuffer.fill(meshShaderModelData.vertices); - - auto meshShaderIndexBuffer = vkcv::buffer<uint32_t>( - core, - vkcv::BufferType::STORAGE, - meshShaderModelData.localIndices.size()); - meshShaderIndexBuffer.fill(meshShaderModelData.localIndices); - - auto meshletBuffer = vkcv::buffer<vkcv::meshlet::Meshlet>( - core, - vkcv::BufferType::STORAGE, - meshShaderModelData.meshlets.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - meshletBuffer.fill(meshShaderModelData.meshlets); - - vkcv::PassHandle renderPass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - if (!renderPass) - { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ShaderProgram bunnyShaderProgram{}; - vkcv::shader::GLSLCompiler compiler; - - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/shader.vert"), - [&bunnyShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - bunnyShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&bunnyShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - bunnyShaderProgram.addShader(shaderStage, path); - }); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = bunnyShaderProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> bindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - const vkcv::VertexLayout bunnyLayout { bindings }; - - vkcv::DescriptorSetLayoutHandle vertexShaderDescriptorSetLayout = core.createDescriptorSetLayout(bunnyShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle vertexShaderDescriptorSet = core.createDescriptorSet(vertexShaderDescriptorSetLayout); - - struct ObjectMatrices { - glm::mat4 model; - glm::mat4 mvp; - }; - const size_t objectCount = 1; - vkcv::Buffer<ObjectMatrices> matrixBuffer = vkcv::buffer<ObjectMatrices>(core, vkcv::BufferType::STORAGE, objectCount); - - vkcv::DescriptorWrites vertexShaderDescriptorWrites; - vertexShaderDescriptorWrites.writeStorageBuffer(0, matrixBuffer.getHandle()); - core.writeDescriptorSet(vertexShaderDescriptorSet, vertexShaderDescriptorWrites); - - vkcv::GraphicsPipelineHandle bunnyPipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - bunnyShaderProgram, - renderPass, - { bunnyLayout }, - { vertexShaderDescriptorSetLayout } - ) - ); - - if (!bunnyPipeline) - { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - // mesh shader - vkcv::ShaderProgram meshShaderProgram; - compiler.compile(vkcv::ShaderStage::TASK, std::filesystem::path("assets/shaders/shader.task"), - [&meshShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - meshShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::MESH, std::filesystem::path("assets/shaders/shader.mesh"), - [&meshShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - meshShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&meshShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - meshShaderProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle meshShaderDescriptorSetLayout = core.createDescriptorSetLayout(meshShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet(meshShaderDescriptorSetLayout); - const vkcv::VertexLayout meshShaderLayout(bindings); - - vkcv::GraphicsPipelineHandle meshShaderPipeline = core.createGraphicsPipeline( - vkcv::GraphicsPipelineConfig( - meshShaderProgram, - renderPass, - { meshShaderLayout }, - { meshShaderDescriptorSetLayout } - ) - ); - - if (!meshShaderPipeline) - { - std::cout << "Error. Could not create mesh shader pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::Buffer<CameraPlanes> cameraPlaneBuffer = vkcv::buffer<CameraPlanes>(core, vkcv::BufferType::UNIFORM, 1); - - vkcv::DescriptorWrites meshShaderWrites; - meshShaderWrites.writeStorageBuffer( - 0, meshShaderVertexBuffer.getHandle() - ).writeStorageBuffer( - 1, meshShaderIndexBuffer.getHandle() - ).writeStorageBuffer( - 2, meshletBuffer.getHandle() - ).writeStorageBuffer( - 4, matrixBuffer.getHandle() - ).writeStorageBuffer( - 5, meshletBuffer.getHandle() - ); - - meshShaderWrites.writeUniformBuffer(3, cameraPlaneBuffer.getHandle()); - - core.writeDescriptorSet( meshShaderDescriptorSet, meshShaderWrites); - - vkcv::ImageHandle depthBuffer; - vkcv::ImageHandle swapchainImageHandle = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::VertexData vertexData (vertexBufferBindings); - vertexData.setIndexBuffer(indexBuffer.getHandle(), vkcv::IndexBitCount::Bit32); - vertexData.setCount(mesh.vertexGroups[0].numIndices); - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::camera::CameraManager cameraManager(window); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(camHandle).setPosition(glm::vec3(0, 0, -2)); - - bool useMeshShader = true; - bool updateFrustumPlanes = true; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - (swapchainHeight != core.getImageHeight(depthBuffer))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - } - - cameraManager.update(dt); - - const vkcv::camera::Camera& camera = cameraManager.getActiveCamera(); - - ObjectMatrices objectMatrices; - objectMatrices.model = *reinterpret_cast<glm::mat4*>(&mesh.meshes.front().modelMatrix); - objectMatrices.mvp = camera.getMVP() * objectMatrices.model; - - matrixBuffer.fill({ objectMatrices }); - - struct PushConstants { - uint32_t matrixIndex; - uint32_t meshletCount; - }; - PushConstants pushConstants{ 0, static_cast<uint32_t>(meshShaderModelData.meshlets.size()) }; - - if (updateFrustumPlanes) { - const CameraPlanes cameraPlanes = computeCameraPlanes(camera); - cameraPlaneBuffer.fill({ cameraPlanes }); - } - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - vkcv::PushConstants pushConstantData = vkcv::pushConstants<PushConstants>(); - pushConstantData.appendDrawcall(pushConstants); - - if (useMeshShader) { - const uint32_t taskCount = (meshShaderModelData.meshlets.size() + 31) / 32; - - vkcv::TaskDrawcall drawcall (taskCount); - drawcall.useDescriptorSet(0, meshShaderDescriptorSet); - - core.recordMeshShaderDrawcalls( - cmdStream, - meshShaderPipeline, - pushConstantData, - { drawcall }, - { renderTargets }, - windowHandle - ); - } else { - vkcv::InstanceDrawcall drawcall (vertexData); - drawcall.useDescriptorSet(0, vertexShaderDescriptorSet); - - core.recordDrawcallsToCmdStream( - cmdStream, - bunnyPipeline, - pushConstantData, - { drawcall }, - { renderTargets }, - windowHandle - ); - } - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - - ImGui::Begin("Settings"); - ImGui::Checkbox("Use mesh shader", &useMeshShader); - ImGui::Checkbox("Update frustum culling", &updateFrustumPlanes); - - ImGui::End(); - gui.endGUI(); - }); - - return 0; -} diff --git a/projects/particle_simulation/.gitignore b/projects/particle_simulation/.gitignore deleted file mode 100644 index 4964f89e973f38358aa57f564f56d3d4b0c328a9..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/.gitignore +++ /dev/null @@ -1 +0,0 @@ -particle_simulation \ No newline at end of file diff --git a/projects/particle_simulation/CMakeLists.txt b/projects/particle_simulation/CMakeLists.txt deleted file mode 100644 index 860bfa15a4b77b71ac79e3433326feb6aa3d7123..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(particle_simulation) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(particle_simulation - src/main.cpp - src/ParticleSystem.hpp - src/ParticleSystem.cpp - src/Particle.hpp - src/Particle.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(particle_simulation SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_testing_include} - ${vkcv_camera_include} - ${vkcv_shader_compiler_include} - ${vkcv_effects_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(particle_simulation - vkcv - vkcv_testing - vkcv_camera - vkcv_shader_compiler - vkcv_effects) diff --git a/projects/particle_simulation/shaders/particleShading.inc b/projects/particle_simulation/shaders/particleShading.inc deleted file mode 100644 index b2d1832b9ccd6ba05a585b59bdfdedd4729e80f8..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/particleShading.inc +++ /dev/null @@ -1,6 +0,0 @@ -float circleFactor(vec2 triangleCoordinates){ - // percentage of distance from center to circle edge - float p = clamp((0.4 - length(triangleCoordinates)) / 0.4, 0, 1); - // remapping for nice falloff - return sqrt(p); -} \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader.vert b/projects/particle_simulation/shaders/shader.vert deleted file mode 100644 index 0a889b35dbb750dc932de57b611f22acaa1ac3f2..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader.vert +++ /dev/null @@ -1,45 +0,0 @@ -#version 460 core -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 particle; - -struct Particle -{ - vec3 position; - float lifeTime; - vec3 velocity; - float padding_2; - vec3 reset_velocity; - float padding_3; -}; - -layout(std430, binding = 2) coherent buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout( push_constant ) uniform constants{ - mat4 view; - mat4 projection; -}; - -layout(location = 0) out vec2 passTriangleCoordinates; -layout(location = 1) out vec3 passVelocity; -layout(location = 2) out float passlifeTime; - -void main() -{ - int id = gl_InstanceIndex; - passVelocity = inParticle[id].velocity; - passlifeTime = inParticle[id].lifeTime; - // particle position in view space - vec4 positionView = view * vec4(inParticle[id].position, 1); - // by adding the triangle position in view space the mesh is always camera facing - positionView.xyz += particle; - // multiply with projection matrix for final position - gl_Position = projection * positionView; - - // 0.01 corresponds to vertex position size in main - float normalizationDivider = 0.012; - passTriangleCoordinates = particle.xy / normalizationDivider; -} \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader_gravity.comp b/projects/particle_simulation/shaders/shader_gravity.comp deleted file mode 100644 index 77954958c694a3c6c620818dd3b5d999e51b4a42..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader_gravity.comp +++ /dev/null @@ -1,80 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float lifeTime; - vec3 velocity; - float mass; - vec3 reset_velocity; - float _padding; -}; - -layout(std430, binding = 0) coherent buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout( push_constant ) uniform constants{ - float deltaTime; - float rand; -}; - -const int n = 4; -vec4 gravityPoint[n] = vec4[n]( - vec4(-0.8, -0.5, 0.0, 3), - vec4(-0.4, 0.5, 0.8, 2), - vec4( 0.8, 0.8, -0.3, 4), - vec4( 0.5, -0.7, -0.5, 1) -); - -const float G = 6.6743015e-11; -const float sim_d_factor = 10e11; -const float sim_g_factor = 10e30; -const float sim_t_factor = 5; -const float c = 299792458; - -void main() { - uint id = gl_GlobalInvocationID.x; - inParticle[id].lifeTime -= deltaTime; - vec3 pos = inParticle[id].position; - vec3 vel = inParticle[id].velocity; - float mass = inParticle[id].mass; - - if(inParticle[id].lifeTime < 0.f) - { - inParticle[id].lifeTime = 5.f * rand; - inParticle[id].mass *= rand; - - pos = vec3(0); - vel *= rand; - } - - for(int i = 0; i < n; i++) - { - vec3 d = (gravityPoint[i].xyz - pos) * sim_d_factor; - float r = length(d); - float g = G * (gravityPoint[i].w * sim_g_factor) / (r * r); - - if (r > 0) { - vec3 dvel = (deltaTime * sim_t_factor) * g * (d / r); - - vel = (vel + dvel) / (1.0 + dot(vel, dvel) / (c*c)); - } - } - - pos += vel * (deltaTime * sim_t_factor); - - vec3 a_pos = abs(pos); - - if ((a_pos.x > 2.0) || (a_pos.y > 2.0) || (a_pos.z > 2.0)) - { - inParticle[id].lifeTime *= 0.9; - } - - inParticle[id].position = pos; - inParticle[id].velocity = vel; -} diff --git a/projects/particle_simulation/shaders/shader_space.comp b/projects/particle_simulation/shaders/shader_space.comp deleted file mode 100644 index 6e25fff8aec8ceab7c1ffdd9be65d9b8fa8f0974..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader_space.comp +++ /dev/null @@ -1,73 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float lifeTime; - vec3 velocity; - float padding_2; - vec3 reset_velocity; - float padding_3; -}; - -layout(std430, binding = 0) coherent buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout( push_constant ) uniform constants{ - float deltaTime; - float rand; -}; - -vec3 attraction(vec3 pos, vec3 attractPos) -{ - vec3 delta = attractPos - pos; - const float damp = 0.5; - float dDampedDot = dot(delta, delta) + damp; - float invDist = 1.0f / sqrt(dDampedDot); - float invDistCubed = invDist*invDist*invDist; - return delta * invDistCubed * 0.0035; -} - -vec3 repulsion(vec3 pos, vec3 attractPos) -{ - vec3 delta = attractPos - pos; - float targetDistance = sqrt(dot(delta, delta)); - return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035; -} - - -const int n = 4; -vec3 gravity = vec3(0,-9.8,0); -vec3 gravityPoint[n] = vec3[n](vec3(-0.3, .5, -0.6),vec3(-0.2, 0.6, -0.3),vec3(.4, -0.4, 0.6),vec3(-.4, -0.4, -0.6)); -//vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0)); -void main() { - uint id = gl_GlobalInvocationID.x; - inParticle[id].lifeTime -= deltaTime; - vec3 pos = inParticle[id].position; - vec3 vel = inParticle[id].velocity; - if(inParticle[id].lifeTime < 0.f) - { - inParticle[id].lifeTime = 5.f; - pos = vec3(0); - } - // inParticle[id].position += deltaTime * -normalize(max(2 - distance(inParticle[id].position,respawnPos),0.0) * respawnPos - inParticle[id].position); - - for(int i = 0; i < n; i++) - { - vel += deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos); - } - - if((pos.x <= -2.0) || (pos.x > 2.0) || (pos.y <= -2.0) || (pos.y > 2.0)|| (pos.z <= -2.0) || (pos.z > 2.0)){ - vel = (-vel * 0.1); - } - - pos += normalize(vel) * deltaTime; - inParticle[id].position = pos; - float rand1 = rand; - inParticle[id].velocity = vel; -} diff --git a/projects/particle_simulation/shaders/shader_space.frag b/projects/particle_simulation/shaders/shader_space.frag deleted file mode 100644 index 7f6d22065caa3c4b3ab2b1f697c9545a66d7bd54..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader_space.frag +++ /dev/null @@ -1,46 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "particleShading.inc" - -layout(location = 0) in vec2 passTriangleCoordinates; -layout(location = 1) in vec3 passVelocity; -layout(location = 2) in float passlifeTime; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform uColor { - vec4 color; -} Color; - -layout(set=0,binding=1) uniform uPosition{ - vec2 position; -} Position; - - -void main() -{ - vec2 mouse = vec2(Position.position.x, Position.position.y); - - vec3 c0 = vec3(1, 1, 0.05); - vec3 c1 = vec3(1, passlifeTime * 0.5, 0.05); - vec3 c2 = vec3(passlifeTime * 0.5,passlifeTime * 0.5,0.05); - vec3 c3 = vec3(1, 0.05, 0.05); - - if(passlifeTime < 1){ - outColor = mix(c0, c1, passlifeTime ); - } - else if(passlifeTime < 2){ - outColor = mix(c1, c2, passlifeTime - 1); - } - else{ - outColor = mix(c2, c3, clamp((passlifeTime - 2) * 0.5, 0, 1)); - } - - // make the triangle look like a circle - outColor *= circleFactor(passTriangleCoordinates); - - // fade out particle shortly before it dies - outColor *= clamp(passlifeTime * 2, 0, 1); -} \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader_water.comp b/projects/particle_simulation/shaders/shader_water.comp deleted file mode 100644 index d1a0e761038b5fb367a33454c746871f1a6a4553..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader_water.comp +++ /dev/null @@ -1,84 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float lifeTime; - vec3 velocity; - float padding_2; - vec3 reset_velocity; - float padding_3; -}; - -layout(std430, binding = 0) coherent buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout( push_constant ) uniform constants{ - float deltaTime; - float rand; -}; - -vec3 attraction(vec3 pos, vec3 attractPos) -{ - vec3 delta = attractPos - pos; - const float damp = 0.5; - float dDampedDot = dot(delta, delta) + damp; - float invDist = 1.0f / sqrt(dDampedDot); - float invDistCubed = invDist*invDist*invDist; - return delta * invDistCubed * 0.0035; -} - -vec3 repulsion(vec3 pos, vec3 attractPos) -{ - vec3 delta = attractPos - pos; - float targetDistance = sqrt(dot(delta, delta)); - return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035; -} - - -const int n = 3; -vec3 gravity = vec3(0,-9.8,0); -vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0),vec3(0.5, 0.5, 0),vec3(0, -0.5, 0)); -//vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0)); -void main() { - uint id = gl_GlobalInvocationID.x; - inParticle[id].lifeTime -= deltaTime; - vec3 pos = inParticle[id].position; - vec3 vel = inParticle[id].velocity; - if(inParticle[id].lifeTime < 0.f) - { - inParticle[id].lifeTime = 7.f; - pos = vec3(0); - vel = inParticle[id].reset_velocity; - inParticle[id].velocity = inParticle[id].reset_velocity; - } - // inParticle[id].position += deltaTime * -normalize(max(2 - distance(inParticle[id].position,respawnPos),0.0) * respawnPos - inParticle[id].position); - - for(int i = 0; i < n; i++) - { - vel += deltaTime * deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos); - } - - //vec3 delta = respawnPos - pos; - //float targetDistane = sqrt(dot(delta,delta)); - //vel += repulsion(pos, respawnPos); - - //if((pos.x <= -1.0) || (pos.x > 1.0) || (pos.y <= -1.0) || (pos.y > 1.0)|| (pos.z <= -1.0) || (pos.z > 1.0)) - vel = (-vel * 0.01); - - if((pos.y <= -1.0) || (pos.y > 1.0)){ - vel = reflect(vel, vec3(0,1,0)); - } - - pos += normalize(vel) * deltaTime; - inParticle[id].position = pos; - - float weight = 1.0; - float rand1 = rand; - inParticle[id].velocity = vel; -} diff --git a/projects/particle_simulation/shaders/shader_water.frag b/projects/particle_simulation/shaders/shader_water.frag deleted file mode 100644 index b68f9572a91b05e836c3fead9ae9afd7ce16ba8e..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/shader_water.frag +++ /dev/null @@ -1,46 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "particleShading.inc" - -layout(location = 0) in vec2 passTriangleCoordinates; -layout(location = 1) in vec3 passVelocity; -layout(location = 2) in float passlifeTime; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform uColor { - vec4 color; -} Color; - -layout(set=0,binding=1) uniform uPosition{ - vec2 position; -} Position; - -void main() -{ - float normlt = 1-normalize(passlifeTime); - vec2 mouse = vec2(Position.position.x, Position.position.y); - - vec3 c0 = vec3(0.2,0.5,1); - vec3 c1 = vec3(0.3, 0.7,1); - vec3 c2 = vec3(0.5,0.9,1); - vec3 c3 = vec3(0.9,1,1); - - if(passlifeTime < 1){ - outColor = mix(c0, c1, passlifeTime ); - } - else if(passlifeTime < 2){ - outColor = mix(c1, c2, passlifeTime - 1); - } - else{ - outColor = mix(c2, c3, clamp((passlifeTime - 2) * 0.5, 0, 1)); - } - - // make the triangle look like a circle - outColor *= circleFactor(passTriangleCoordinates); - - // fade out particle shortly before it dies - outColor *= clamp(passlifeTime * 2, 0, 1); -} diff --git a/projects/particle_simulation/shaders/tonemapping.comp b/projects/particle_simulation/shaders/tonemapping.comp deleted file mode 100644 index 26f0232d66e3475afdd1266c0cc6288b47ed1c38..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/shaders/tonemapping.comp +++ /dev/null @@ -1,19 +0,0 @@ -#version 440 - -layout(set=0, binding=0, rgba16f) uniform image2D inImage; -layout(set=0, binding=1, rgba8) uniform image2D outImage; - - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){ - return; - } - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - vec3 linearColor = imageLoad(inImage, uv).rgb; - vec3 tonemapped = linearColor / (dot(linearColor, vec3(0.21, 0.71, 0.08)) + 1); // reinhard tonemapping - vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); - imageStore(outImage, uv, vec4(gammaCorrected, 0.f)); -} \ No newline at end of file diff --git a/projects/particle_simulation/src/Particle.cpp b/projects/particle_simulation/src/Particle.cpp deleted file mode 100644 index b80d063d382c9ae1cb63887388cce065b8289b63..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/src/Particle.cpp +++ /dev/null @@ -1,42 +0,0 @@ - -#include "Particle.hpp" - -Particle::Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime) -: m_position(position), - m_lifeTime(lifeTime), - m_velocity(velocity), - m_mass(1.0f), - m_reset_velocity(velocity) -{} - -const glm::vec3& Particle::getPosition()const{ - return m_position; -} - -bool Particle::isAlive()const{ - return m_lifeTime > 0.f; -} - -void Particle::setPosition( const glm::vec3 pos ){ - m_position = pos; -} - -const glm::vec3& Particle::getVelocity()const{ - return m_velocity; -} - -void Particle::setVelocity( const glm::vec3 vel ){ - m_velocity = vel; -} - -void Particle::update( const float delta ){ - m_position += m_velocity * delta; -} - -void Particle::setLifeTime( const float lifeTime ){ - m_lifeTime = lifeTime; -} - -const float& Particle::getLifeTime()const{ - return m_lifeTime; -} \ No newline at end of file diff --git a/projects/particle_simulation/src/Particle.hpp b/projects/particle_simulation/src/Particle.hpp deleted file mode 100644 index 73e7cbf517709ee03274cfd199081ade3f756545..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/src/Particle.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include <glm/glm.hpp> - -class Particle { - -public: - Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime = 1.f); - - const glm::vec3& getPosition()const; - - void setPosition( const glm::vec3 pos ); - - const glm::vec3& getVelocity()const; - - void setVelocity( const glm::vec3 vel ); - - void update( const float delta ); - - bool isAlive()const; - - void setLifeTime( const float lifeTime ); - - const float& getLifeTime()const; - -private: - // all properties of the Particle - glm::vec3 m_position; - float m_lifeTime; - glm::vec3 m_velocity; - float m_mass; - glm::vec3 m_reset_velocity; - float padding_3; -}; diff --git a/projects/particle_simulation/src/ParticleSystem.cpp b/projects/particle_simulation/src/ParticleSystem.cpp deleted file mode 100644 index b3162d6bea685640d3949577271affc8b2080407..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/src/ParticleSystem.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "ParticleSystem.hpp" - -ParticleSystem::ParticleSystem(uint32_t particleCount ,glm::vec3 minVelocity , glm::vec3 maxVelocity , glm::vec2 lifeTime ) -{ - m_rdmVel.resize(3); - m_rdmVel[0] = std::uniform_real_distribution<float>(minVelocity.x, maxVelocity.x); - m_rdmVel[1] = std::uniform_real_distribution<float>(minVelocity.y, maxVelocity.y); - m_rdmVel[2] = std::uniform_real_distribution<float>(minVelocity.z, maxVelocity.z); - m_rdmLifeTime = std::uniform_real_distribution<float>(lifeTime.x, lifeTime.y); - - for(uint32_t i = 0; i < particleCount ;i++ ){ - addParticle(Particle(m_respawnPos, getRandomVelocity(), getRandomLifeTime())); - } -} - -const std::vector<Particle>& ParticleSystem::getParticles() const{ - return m_particles; -} - -void ParticleSystem::addParticle( const Particle particle ){ - m_particles.push_back(particle); -} -void ParticleSystem::addParticles( const std::vector<Particle> particles ){ - m_particles.insert(m_particles.end(), particles.begin(), particles.end()); -} - -void ParticleSystem::updateParticles( const float deltaTime ){ - for(Particle& particle :m_particles){ - bool alive = particle.isAlive(); - particle.setPosition( particle.getPosition() * static_cast<float>(alive) + static_cast<float>(!alive) * m_respawnPos ); - particle.setVelocity( particle.getVelocity() * static_cast<float>(alive) + static_cast<float>(!alive) * getRandomVelocity()); - particle.setLifeTime( (particle.getLifeTime() * alive + !alive * getRandomLifeTime() ) - deltaTime ); - particle.update(deltaTime); - } -} - -glm::vec3 ParticleSystem::getRandomVelocity(){ - return glm::vec3(m_rdmVel[0](m_rdmEngine), m_rdmVel[1](m_rdmEngine),m_rdmVel[2](m_rdmEngine)); -} - -float ParticleSystem::getRandomLifeTime(){ - return m_rdmLifeTime(m_rdmEngine); -} - -void ParticleSystem::setRespawnPos( const glm::vec3 respawnPos){ - m_respawnPos = respawnPos; -} -void ParticleSystem::setRdmLifeTime( const glm::vec2 lifeTime ){ - m_rdmLifeTime = std::uniform_real_distribution<float> (lifeTime.x,lifeTime.y); -} - -void ParticleSystem::setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity ){ - m_rdmVel[0] = std::uniform_real_distribution<float> (minVelocity.x,maxVelocity.x); - m_rdmVel[1] = std::uniform_real_distribution<float> (minVelocity.y,maxVelocity.y); - m_rdmVel[2] = std::uniform_real_distribution<float> (minVelocity.z,maxVelocity.z); -} - -const glm::vec3 ParticleSystem::getRespawnPos() const{ - return m_respawnPos; -} diff --git a/projects/particle_simulation/src/ParticleSystem.hpp b/projects/particle_simulation/src/ParticleSystem.hpp deleted file mode 100644 index fe5c99f9b407b9dbdfd414e265e7cd91bbe790b9..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/src/ParticleSystem.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <vector> -#include "Particle.hpp" -#include <random> -#include "vkcv/Buffer.hpp" - -class ParticleSystem { - -public: - ParticleSystem(uint32_t particleCount , glm::vec3 minVelocity = glm::vec3(0.f,0.f,0.f), glm::vec3 maxVelocity = glm::vec3(1.f,1.f,0.f), glm::vec2 lifeTime = glm::vec2(2.f,3.f)); - const std::vector<Particle> &getParticles() const; - void updateParticles( const float deltaTime ); - void setRespawnPos( const glm::vec3 respawnPos ); - void setRdmLifeTime( const glm::vec2 lifeTime ); - void setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity ); - const glm::vec3 getRespawnPos() const; - -private: - - void addParticle( const Particle particle ); - void addParticles( const std::vector<Particle> particles ); - glm::vec3 getRandomVelocity(); - float getRandomLifeTime(); - - std::vector<Particle> m_particles; - glm::vec3 m_respawnPos = glm::vec3(0.f); - - std::vector<std::uniform_real_distribution<float>> m_rdmVel; - std::uniform_real_distribution<float> m_rdmLifeTime; - std::default_random_engine m_rdmEngine; -}; \ No newline at end of file diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp deleted file mode 100644 index 00bb497b9798064c4b5ac449d6bac8495a1783e8..0000000000000000000000000000000000000000 --- a/projects/particle_simulation/src/main.cpp +++ /dev/null @@ -1,323 +0,0 @@ -#include <iostream> -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> -#include "ParticleSystem.hpp" -#include <random> -#include <glm/gtc/matrix_access.hpp> -#include <ctime> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/effects/BloomAndFlaresEffect.hpp> - -int main(int argc, const char **argv) { - const std::string applicationName = "Particlesystem"; - - uint32_t windowWidth = 800; - uint32_t windowHeight = 600; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } - ); - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - vkcv::camera::CameraManager cameraManager(window); - - auto particleIndexBuffer = vkcv::buffer<uint16_t>(core, vkcv::BufferType::INDEX, 3, - vkcv::BufferMemoryType::DEVICE_LOCAL); - uint16_t indices[3] = {0, 1, 2}; - particleIndexBuffer.fill(&indices[0], sizeof(indices)); - - vk::Format colorFormat = vk::Format::eR16G16B16A16Sfloat; - vkcv::PassHandle particlePass = vkcv::passFormat(core, colorFormat); - - if (!particlePass) - { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - // use space or use water or gravity - std::string shaderPathCompute = "shaders/shader_space.comp"; - std::string shaderPathFragment = "shaders/shader_space.frag"; - - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--space") == 0) { - shaderPathCompute = "shaders/shader_space.comp"; - shaderPathFragment = "shaders/shader_space.frag"; - } else - if (strcmp(argv[i], "--water") == 0) { - shaderPathCompute = "shaders/shader_water1.comp"; - shaderPathFragment = "shaders/shader_water.frag"; - } else - if (strcmp(argv[i], "--gravity") == 0) { - shaderPathCompute = "shaders/shader_gravity.comp"; - shaderPathFragment = "shaders/shader_space.frag"; - } - } - - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram computeShaderProgram{}; - compiler.compile(vkcv::ShaderStage::COMPUTE, shaderPathCompute, [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - computeShaderProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle computeDescriptorSetLayout = core.createDescriptorSetLayout(computeShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeDescriptorSetLayout); - - const std::vector<vkcv::VertexAttachment> computeVertexAttachments = computeShaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> computeBindings; - for (size_t i = 0; i < computeVertexAttachments.size(); i++) { - computeBindings.push_back(vkcv::createVertexBinding(i, { computeVertexAttachments[i] })); - } - const vkcv::VertexLayout computeLayout { computeBindings }; - - vkcv::ShaderProgram particleShaderProgram{}; - compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/shader.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, shaderPathFragment, [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout( - particleShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); - - vkcv::Buffer<glm::vec3> vertexBuffer = vkcv::buffer<glm::vec3>( - core, - vkcv::BufferType::VERTEX, - 3 - ); - const std::vector<vkcv::VertexAttachment> vertexAttachments = particleShaderProgram.getVertexAttachments(); - - const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::vertexBufferBinding(vertexBuffer.getHandle()) - }; - - std::vector<vkcv::VertexBinding> bindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, {vertexAttachments[i]})); - } - - const vkcv::VertexLayout particleLayout { bindings }; - - vkcv::GraphicsPipelineConfig particlePipelineDefinition ( - particleShaderProgram, - particlePass, - {particleLayout}, - {descriptorSetLayout} - ); - - particlePipelineDefinition.setBlendMode(vkcv::BlendMode::Additive); - - const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0), - glm::vec3(0.012, 0.012, 0), - glm::vec3(0, -0.012, 0)}; - - vertexBuffer.fill(vertices); - - vkcv::GraphicsPipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition); - - vkcv::ComputePipelineHandle computePipeline = core.createComputePipeline({ - computeShaderProgram, {computeDescriptorSetLayout} - }); - - vkcv::Buffer<glm::vec4> color = vkcv::buffer<glm::vec4>( - core, - vkcv::BufferType::UNIFORM, - 1 - ); - - vkcv::Buffer<glm::vec2> position = vkcv::buffer<glm::vec2>( - core, - vkcv::BufferType::UNIFORM, - 1 - ); - - glm::vec3 minVelocity = glm::vec3(-0.1f,-0.1f,-0.1f); - glm::vec3 maxVelocity = glm::vec3(0.1f,0.1f,0.1f); - glm::vec2 lifeTime = glm::vec2(-1.f,8.f); - ParticleSystem particleSystem = ParticleSystem( 100000 , minVelocity, maxVelocity, lifeTime); - - vkcv::Buffer<Particle> particleBuffer = vkcv::buffer<Particle>( - core, - vkcv::BufferType::STORAGE, - particleSystem.getParticles().size() - ); - - particleBuffer.fill(particleSystem.getParticles()); - - vkcv::DescriptorWrites setWrites; - setWrites.writeUniformBuffer(0, color.getHandle()).writeUniformBuffer(1, position.getHandle()); - setWrites.writeStorageBuffer(2, particleBuffer.getHandle()); - core.writeDescriptorSet(descriptorSet, setWrites); - - vkcv::DescriptorWrites computeWrites; - computeWrites.writeStorageBuffer(0, particleBuffer.getHandle()); - core.writeDescriptorSet(computeDescriptorSet, computeWrites); - - if (!particlePipeline || !computePipeline) - { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::VertexData vertexData (vertexBufferBindings); - vertexData.setIndexBuffer(particleIndexBuffer.getHandle()); - vertexData.setCount(particleIndexBuffer.getCount()); - - auto descriptorUsage = vkcv::useDescriptorSet(0, descriptorSet); - - auto pos = glm::vec2(0.f); - auto spawnPosition = glm::vec3(0.f); - - window.e_mouseMove.add([&](double offsetX, double offsetY) { - pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY)); - pos.x = (-2 * pos.x + static_cast<float>(window.getWidth())) / static_cast<float>(window.getWidth()); - pos.y = (-2 * pos.y + static_cast<float>(window.getHeight())) / static_cast<float>(window.getHeight()); - spawnPosition = glm::vec3(pos.x, pos.y, 0.f); - particleSystem.setRespawnPos(glm::vec3(-spawnPosition.x, spawnPosition.y, spawnPosition.z)); - }); - - std::vector<glm::mat4> modelMatrices; - - vkcv::InstanceDrawcall drawcall (vertexData, particleSystem.getParticles().size()); - drawcall.useDescriptorSet(0, descriptorSet); - - glm::vec4 colorData = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setNearFar(0.1, 30); - cameraManager.getCamera(camHandle0).setNearFar(0.1, 30); - - cameraManager.setActiveCamera(camHandle1); - - cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0, 0, -2)); - cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0.0f, 0.0f, -2.0f)); - cameraManager.getCamera(camHandle1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f)); - - const auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); - - vkcv::ImageHandle colorBuffer = core.createImage( - colorFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - - vkcv::effects::BloomAndFlaresEffect bloomAndFlares (core); - bloomAndFlares.setUpsamplingLimit(3); - - vkcv::ShaderProgram tonemappingShader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/tonemapping.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - tonemappingShader.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle tonemappingDescriptorLayout = core.createDescriptorSetLayout(tonemappingShader.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingDescriptorLayout); - vkcv::ComputePipelineHandle tonemappingPipe = core.createComputePipeline({ - tonemappingShader, - { tonemappingDescriptorLayout } - }); - - std::uniform_real_distribution<float> rdm = std::uniform_real_distribution<float>(0.95f, 1.05f); - std::default_random_engine rdmEngine; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((core.getImageWidth(colorBuffer) != swapchainWidth) || - (core.getImageHeight(colorBuffer) != swapchainHeight)) { - colorBuffer = core.createImage( - colorFormat, - swapchainWidth, - swapchainHeight, - 1, false, true, true - ); - } - - color.fill(&colorData); - position.fill(&pos); - - cameraManager.update(dt); - - // split view and projection to allow for easy billboarding in shader - struct { - glm::mat4 view; - glm::mat4 projection; - } renderingMatrices; - - renderingMatrices.view = cameraManager.getActiveCamera().getView(); - renderingMatrices.projection = cameraManager.getActiveCamera().getProjection(); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - float random = rdm(rdmEngine); - glm::vec2 pushData = glm::vec2(dt, random); - - vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<glm::vec2>(); - pushConstantsCompute.appendDrawcall(pushData); - - core.recordComputeDispatchToCmdStream( - cmdStream, - computePipeline, - vkcv::dispatchInvocations(particleSystem.getParticles().size(), 256), - {vkcv::useDescriptorSet(0, computeDescriptorSet)}, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle()); - - vkcv::PushConstants pushConstantsDraw (sizeof(renderingMatrices)); - pushConstantsDraw.appendDrawcall(renderingMatrices); - - core.recordDrawcallsToCmdStream( - cmdStream, - particlePipeline, - pushConstantsDraw, - { drawcall }, - { colorBuffer }, - windowHandle - ); - - bloomAndFlares.recordEffect(cmdStream, colorBuffer, colorBuffer); - - core.prepareImageForStorage(cmdStream, colorBuffer); - core.prepareImageForStorage(cmdStream, swapchainInput); - - vkcv::DescriptorWrites tonemappingDescriptorWrites; - tonemappingDescriptorWrites.writeStorageImage( - 0, colorBuffer - ).writeStorageImage( - 1, swapchainInput - ); - - core.writeDescriptorSet(tonemappingDescriptor, tonemappingDescriptorWrites); - - const auto tonemappingDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(8, 8) - ); - - core.recordComputeDispatchToCmdStream( - cmdStream, - tonemappingPipe, - tonemappingDispatchCount, - { vkcv::useDescriptorSet(0, tonemappingDescriptor) }, - vkcv::PushConstants(0) - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/path_tracer/.gitignore b/projects/path_tracer/.gitignore deleted file mode 100644 index 24a57cda822232aa24d513fab3901ff7db36adb1..0000000000000000000000000000000000000000 --- a/projects/path_tracer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -path_tracer \ No newline at end of file diff --git a/projects/path_tracer/CMakeLists.txt b/projects/path_tracer/CMakeLists.txt deleted file mode 100644 index 56f14090ce68b91d0d7163360faaf413fb9e3de9..0000000000000000000000000000000000000000 --- a/projects/path_tracer/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(path_tracer) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(path_tracer src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(path_tracer SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(path_tracer vkcv vkcv_testing vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler vkcv_gui) diff --git a/projects/path_tracer/shaders/clearImage.comp b/projects/path_tracer/shaders/clearImage.comp deleted file mode 100644 index 97998e945112d166be7d00df98ee44ea8322a633..0000000000000000000000000000000000000000 --- a/projects/path_tracer/shaders/clearImage.comp +++ /dev/null @@ -1,17 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0, rgba32f) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(outImage); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(coord, outImageRes))) - return; - - imageStore(outImage, coord, vec4(0)); -} \ No newline at end of file diff --git a/projects/path_tracer/shaders/combineImages.comp b/projects/path_tracer/shaders/combineImages.comp deleted file mode 100644 index d1a4e85caf175dfc3125afd847d7458ddec2fef1..0000000000000000000000000000000000000000 --- a/projects/path_tracer/shaders/combineImages.comp +++ /dev/null @@ -1,21 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0, rgba32f) uniform image2D newImage; -layout(set=0, binding=1, rgba32f) uniform image2D meanImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(meanImage); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(coord, outImageRes))) - return; - - vec4 colorNew = imageLoad(newImage, coord); - vec4 colorMean = imageLoad(meanImage, coord); - - imageStore(meanImage, coord, colorNew + colorMean); -} \ No newline at end of file diff --git a/projects/path_tracer/shaders/path_tracer.comp b/projects/path_tracer/shaders/path_tracer.comp deleted file mode 100644 index f08bdfd123ede964befe5feed4ba9f438dc0a498..0000000000000000000000000000000000000000 --- a/projects/path_tracer/shaders/path_tracer.comp +++ /dev/null @@ -1,430 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable - -const float pi = 3.1415926535897932384626433832795; -const float hitBias = 0.0001; // used to offset hits to avoid self intersection -const float denomMin = 0.001; - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -struct Material { - vec3 emission; - float ks; // specular percentage - vec3 albedo; - float r; // roughness - vec3 f0; - float padding; -}; - -struct Sphere{ - vec3 center; - float radius; - int materialIndex; - float padding[3]; -}; - -struct Plane{ - vec3 center; - int materialIndex; - vec3 N; - float padding1; - vec2 extent; - vec2 padding2; -}; - -layout(std430, binding = 0) buffer spheres{ - Sphere inSpheres[]; -}; - -layout(std430, binding = 1) buffer planes{ - Plane inPlanes[]; -}; - -layout(std430, binding = 2) buffer materials{ - Material inMaterials[]; -}; - -layout(set=0, binding = 3, rgba32f) uniform image2D outImage; - -layout( push_constant ) uniform constants{ - mat4 viewToWorld; - vec3 skyColor; - int sphereCount; - int planeCount; - int frameIndex; -}; - -// ---- Intersection functions ---- - -struct Ray{ - vec3 origin; - vec3 direction; -}; - -struct Intersection{ - bool hit; - float distance; - vec3 pos; - vec3 N; - Material material; -}; - -// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection -Intersection raySphereIntersect(Ray ray, Sphere sphere){ - - Intersection intersection; - intersection.hit = false; - - vec3 L = sphere.center - ray.origin; - float tca = dot(L, ray.direction); - float d2 = dot(L, L) - tca * tca; - - if (d2 > sphere.radius * sphere.radius){ - return intersection; - } - float thc = float(sqrt(sphere.radius * sphere.radius - d2)); - float t0 = tca - thc; - float t1 = tca + thc; - - if (t0 < 0) - t0 = t1; - - if (t0 < 0) - return intersection; - - intersection.hit = true; - intersection.distance = t0; - intersection.pos = ray.origin + ray.direction * intersection.distance; - intersection.N = normalize(intersection.pos - sphere.center); - intersection.material = inMaterials[sphere.materialIndex]; - - return intersection; -} - -struct Basis{ - vec3 right; - vec3 up; - vec3 forward; -}; - -Basis buildBasisAroundNormal(vec3 N){ - Basis basis; - basis.up = N; - basis.right = abs(basis.up.x) < 0.99 ? vec3(1, 0, 0) : vec3(0, 0, 1); - basis.forward = normalize(cross(basis.up, basis.right)); - basis.right = cross(basis.up, basis.forward); - return basis; -} - -// see: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersection -Intersection rayPlaneIntersect(Ray ray, Plane plane){ - - Intersection intersection; - intersection.hit = false; - - vec3 toPlane = plane.center - ray.origin; - float denom = dot(ray.direction, plane.N); - if(abs(denom) < 0.001) - return intersection; - - intersection.distance = dot(toPlane, plane.N) / denom; - - if(intersection.distance < 0) - return intersection; - - intersection.pos = ray.origin + ray.direction * intersection.distance; - - vec3 centerToIntersection = intersection.pos - plane.center; - Basis planeBasis = buildBasisAroundNormal(plane.N); - float projectedRight = dot(centerToIntersection, planeBasis.right); - float projectedUp = dot(centerToIntersection, planeBasis.forward); - - intersection.hit = abs(projectedRight) <= plane.extent.x && abs(projectedUp) <= plane.extent.y; - intersection.N = plane.N; - intersection.material = inMaterials[plane.materialIndex]; - - return intersection; -} - -Intersection sceneIntersect(Ray ray) { - float minDistance = 100000; // lets start with something big - - Intersection intersection; - intersection.hit = false; - - for (int i = 0; i < sphereCount; i++) { - Intersection sphereIntersection = raySphereIntersect(ray, inSpheres[i]); - if (sphereIntersection.hit && sphereIntersection.distance < minDistance) { - intersection = sphereIntersection; - minDistance = intersection.distance; - } - } - for (int i = 0; i < planeCount; i++){ - Intersection planeIntersection = rayPlaneIntersect(ray, inPlanes[i]); - if (planeIntersection.hit && planeIntersection.distance < minDistance) { - intersection = planeIntersection; - minDistance = intersection.distance; - } - } - return intersection; -} - -vec3 biasHitPosition(vec3 hitPos, vec3 rayDirection, vec3 N){ - // return hitPos + N * hitBias; // works as long as no refraction/transmission is used and camera is outside sphere - return hitPos + sign(dot(rayDirection, N)) * N * hitBias; -} - -// ---- noise/hash functions for pseudorandom variables ---- - -// extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences -vec2 r2Sequence(uint n){ - n = n % 42000; - const float g = 1.32471795724474602596; - return fract(vec2( - n / g, - n / (g*g))); -} - -// random() and helpers from: https://www.shadertoy.com/view/XlycWh -float g_seed = 0; - -uint base_hash(uvec2 p) { - p = 1103515245U*((p >> 1U)^(p.yx)); - uint h32 = 1103515245U*((p.x)^(p.y>>3U)); - return h32^(h32 >> 16); -} - -vec2 hash2(inout float seed) { - uint n = base_hash(floatBitsToUint(vec2(seed+=.1,seed+=.1))); - uvec2 rz = uvec2(n, n*48271U); - return vec2(rz.xy & uvec2(0x7fffffffU))/float(0x7fffffff); -} - -void initRandom(ivec2 coord){ - g_seed = float(base_hash(coord)/float(0xffffffffU)+frameIndex); -} - -vec2 random(){ - return hash2(g_seed); -} - -// ---- shading ---- - -vec3 lambertBRDF(vec3 albedo){ - return albedo / pi; -} - -vec3 computeDiffuseBRDF(Material material){ - return lambertBRDF(material.albedo); -} - -float distributionGGX(float r, float NoH){ - float r2 = r*r; - float denom = pi * pow(NoH*NoH * (r2-1) + 1, 2); - return r2 / max(denom, denomMin); -} - -float geometryGGXSmith(float r, float NoL){ - float r2 = r*r; - float denom = NoL + sqrt(r2 + (1-r2) * NoL*NoL); - return 2 * NoL / max(denom, denomMin); -} - -float geometryGGX(float r, float NoV, float NoL){ - return geometryGGXSmith(r, NoV) * geometryGGXSmith(r, NoL); -} - -vec3 fresnelSchlick(vec3 f0, float NoH){ - return f0 + (1 - f0) * pow(1 - NoH, 5); -} - -vec3 computeSpecularBRDF(vec3 f0, float r, float NoV, float NoL, float NoH){ - float denom = 4 * NoV * NoL; - float D = distributionGGX(r, NoH); - float G = geometryGGX(r, NoV, NoL); - vec3 F = fresnelSchlick(f0, NoH); - return D * F * G / max(denom, denomMin); -} - -// ---- pathtracing and main ---- - -// distributions: https://link.springer.com/content/pdf/10.1007/978-1-4842-4427-2_16.pdf -float cosineDistributionPDF(float NoL){ - return NoL / pi; -} - -vec3 sampleCosineDistribution(vec2 xi){ - float phi = 2 * pi * xi.y; - return vec3( - sqrt(xi.x) * cos(phi), - sqrt(1 - xi.x), - sqrt(xi.x) * sin(phi)); -} - -float uniformDistributionPDF(){ - return 1.f / (2 * pi); -} - -vec3 sampleUniformDistribution(vec2 xi){ - float phi = 2 * pi * xi.y; - return vec3( - sqrt(xi.x) * cos(phi), - 1 - xi.x, - sqrt(xi.x) * sin(phi)); -} - -float ggxDistributionPDF(float r, float NoH){ - return distributionGGX(r, NoH) * NoH; -} - -float ggxDistributionPDFReflected(float r, float NoH, float NoV){ - float jacobian = 0.25 / max(NoV, denomMin); - return ggxDistributionPDF(r, NoH) * jacobian; -} - -vec3 sampleGGXDistribution(vec2 xi, float r){ - float phi = 2 * pi * xi.y; - float cosTheta = sqrt((1 - xi.x) / ((r*r - 1) * xi.x + 1)); - float sinTheta = sqrt(1 - cosTheta*cosTheta); - return vec3( - cos(phi) * sinTheta, - cosTheta, - sin(phi) * sinTheta); -} - -vec3 sampleTangentToWorldSpace(vec3 tangentSpaceSample, vec3 N){ - Basis tangentBasis = buildBasisAroundNormal(N); - return - tangentBasis.right * tangentSpaceSample.x + - tangentBasis.up * tangentSpaceSample.y + - tangentBasis.forward * tangentSpaceSample.z; -} - -vec3 castRay(Ray ray) { - - vec3 throughput = vec3(1); - vec3 color = vec3(0); - - const int maxDepth = 10; - for(int i = 0; i < maxDepth; i++){ - - Intersection intersection = sceneIntersect(ray); - - vec3 hitLighting = vec3(0); - vec3 brdf = vec3(1); - - // V is where the ray came from and will lead back to the camera (over multiple bounces) - vec3 V = -normalize(ray.direction); - vec3 R = reflect(-V, intersection.N); - float NoV = max(dot(intersection.N, V), 0); - - intersection.material.r *= intersection.material.r; // remapping for perceuptual linearity - intersection.material.r = max(intersection.material.r, 0.01); - - float kd = 1 - intersection.material.ks; - bool sampleDiffuse = random().x < kd; - - vec3 sampleTangentSpace; - float pdf; - if(sampleDiffuse){ - sampleTangentSpace = sampleCosineDistribution(random()); - ray.direction = sampleTangentToWorldSpace(sampleTangentSpace, intersection.N); - - float NoL = max(dot(intersection.N, ray.direction), 0); - pdf = cosineDistributionPDF(NoL); - } - else{ - #define IMPORTANCE - - #ifdef IMPORTANCE - sampleTangentSpace = sampleGGXDistribution(random(), intersection.material.r); - ray.direction = sampleTangentToWorldSpace(sampleTangentSpace, R); - vec3 L = normalize(ray.direction); - pdf = ggxDistributionPDFReflected(intersection.material.r, max(sampleTangentSpace.y, 0.01), max(dot(intersection.N, V), 0.01)); - #else - sampleTangentSpace = sampleUniformDistribution(random()); - ray.direction = sampleTangentToWorldSpace(sampleTangentSpace, intersection.N); - pdf = uniformDistributionPDF(); - #endif - } - - ray.origin = biasHitPosition(intersection.pos, ray.direction, intersection.N); - - // L is where the ray is going, as that is the direction where light will from - vec3 L = normalize(ray.direction); - vec3 H = normalize(L + V); - - float NoL = max(dot(intersection.N, L), 0); - float NoH = max(dot(intersection.N, H), 0); - - if(intersection.hit){ - vec3 diffuseBRDF = computeDiffuseBRDF(intersection.material); - - vec3 specularBRDF = computeSpecularBRDF(intersection.material.f0, intersection.material.r, NoV, NoL, NoH); - brdf = mix(diffuseBRDF, specularBRDF, intersection.material.ks); - - - hitLighting = intersection.material.emission * max(sign(NoV), 0); // objects only emit in direction of normal - } - else{ - hitLighting = skyColor; - } - - color += hitLighting * throughput; - throughput *= brdf * NoL / max(pdf, denomMin); - - if(!intersection.hit) - break; - } - - return color; -} - -// coord must be in pixel coordinates, but already shifted to pixel center -vec3 computeCameraRay(vec2 coord){ - - ivec2 outImageRes = imageSize(outImage); - float fovDegree = 45; - float fov = fovDegree * pi / 180; - - vec2 uv = coord / vec2(outImageRes); - vec2 ndc = 2 * uv - 1; - - float tanFovHalf = tan(fov / 2.f); - float aspectRatio = outImageRes.x / float(outImageRes.y); - float x = ndc.x * tanFovHalf * aspectRatio; - float y = -ndc.y * tanFovHalf; - - // view direction goes through pixel on image plane with z=1 - vec3 directionViewSpace = normalize(vec3(x, y, 1)); - vec3 directionWorldSpace = mat3(viewToWorld) * directionViewSpace; - return directionWorldSpace; -} - -void main(){ - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec2 pixelSize = 1.f / coord; - initRandom(coord); - - Ray cameraRay; - cameraRay.origin = viewToWorld[3].xyz; - vec2 coordCentered = coord + 0.5; - - vec3 color = vec3(0); - - const int samplesPerPixel = 1; - for(int i = 0; i < samplesPerPixel; i++){ - vec2 jitter = r2Sequence(i + frameIndex) - 0.5; - cameraRay.direction = computeCameraRay(coordCentered + jitter); - color += castRay(cameraRay); - } - color /= samplesPerPixel; - - vec4 final = vec4(color, 1); - - // occasional NaNs in reflection, should be fixed properly - if(any(isnan(color))) - final = vec4(0); - - imageStore(outImage, coord, final); -} \ No newline at end of file diff --git a/projects/path_tracer/shaders/presentImage.comp b/projects/path_tracer/shaders/presentImage.comp deleted file mode 100644 index a52159c0c6173779b091e5d4153b15b0a6361780..0000000000000000000000000000000000000000 --- a/projects/path_tracer/shaders/presentImage.comp +++ /dev/null @@ -1,23 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0, rgba32f) uniform image2D inImage; -layout(set=0, binding=1, rgba8) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - ivec2 outImageRes = imageSize(outImage); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - if(any(greaterThanEqual(coord, outImageRes))) - return; - - vec4 colorRaw = imageLoad(inImage, coord); - vec3 colorNormalized = colorRaw.rgb / colorRaw.a; - vec3 colorTonemapped = colorNormalized / (1 + dot(colorNormalized, vec3(0.71, 0.21, 0.08))); // reinhard tonemapping - vec3 colorGammaCorrected = pow(colorTonemapped, vec3(1.f / 2.2)); - - imageStore(outImage, coord, vec4(colorGammaCorrected, 0)); -} \ No newline at end of file diff --git a/projects/path_tracer/src/main.cpp b/projects/path_tracer/src/main.cpp deleted file mode 100644 index 53f52c3d724b8db14641108d9b8a0e33e1844600..0000000000000000000000000000000000000000 --- a/projects/path_tracer/src/main.cpp +++ /dev/null @@ -1,450 +0,0 @@ -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include "vkcv/gui/GUI.hpp" -#include <chrono> -#include <vector> - -int main(int argc, const char** argv) { - - // structs must match shader version - struct Material { - Material(const glm::vec3& emission, const glm::vec3& albedo, float ks, float roughness, const glm::vec3& f0) - : emission(emission), ks(ks), albedo(albedo), roughness(roughness), f0(f0), padding() {} - - glm::vec3 emission; - float ks; - glm::vec3 albedo; - float roughness; - glm::vec3 f0; - float padding; - }; - - struct Sphere { - Sphere(const glm::vec3& c, const float& r, const int m) - : center(c), radius(r), materialIndex(m), padding() {} - - glm::vec3 center; - float radius; - uint32_t materialIndex; - float padding[3]; - }; - - struct Plane { - Plane(const glm::vec3& c, const glm::vec3& n, const glm::vec2 e, int m) - : center(c), materialIndex(m), normal(n), padding1(), extent(e), padding3() {} - - glm::vec3 center; - uint32_t materialIndex; - glm::vec3 normal; - float padding1; - glm::vec2 extent; - glm::vec2 padding3; - }; - - const std::string applicationName = "Path Tracer"; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { "VK_KHR_swapchain" } - ); - - const int initialWidth = 1280; - const int initialHeight = 720; - - vkcv::WindowHandle windowHandle = core.createWindow( - applicationName, - initialWidth, - initialHeight, - true - ); - - // images - vkcv::ImageHandle outputImage = core.createImage( - vk::Format::eR32G32B32A32Sfloat, - initialWidth, - initialHeight, - 1, - false, - true - ); - - vkcv::ImageHandle meanImage = core.createImage( - vk::Format::eR32G32B32A32Sfloat, - initialWidth, - initialHeight, - 1, - false, - true - ); - - vkcv::shader::GLSLCompiler compiler; - - // path tracing shader - vkcv::ShaderProgram traceShaderProgram{}; - - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/path_tracer.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - traceShaderProgram.addShader(shaderStage, path); - }); - - const vkcv::DescriptorBindings& traceDescriptorBindings = traceShaderProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle traceDescriptorSetLayout = core.createDescriptorSetLayout(traceDescriptorBindings); - vkcv::DescriptorSetHandle traceDescriptorSet = core.createDescriptorSet(traceDescriptorSetLayout); - - // image combine shader - vkcv::ShaderProgram imageCombineShaderProgram{}; - - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/combineImages.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - imageCombineShaderProgram.addShader(shaderStage, path); - }); - - const vkcv::DescriptorBindings& imageCombineDescriptorBindings = imageCombineShaderProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle imageCombineDescriptorSetLayout = core.createDescriptorSetLayout(imageCombineDescriptorBindings); - vkcv::DescriptorSetHandle imageCombineDescriptorSet = core.createDescriptorSet(imageCombineDescriptorSetLayout); - vkcv::ComputePipelineHandle imageCombinePipeline = core.createComputePipeline({ - imageCombineShaderProgram, - { imageCombineDescriptorSetLayout } - }); - - vkcv::DescriptorWrites imageCombineDescriptorWrites; - imageCombineDescriptorWrites.writeStorageImage(0, outputImage).writeStorageImage(1, meanImage); - core.writeDescriptorSet(imageCombineDescriptorSet, imageCombineDescriptorWrites); - - // image present shader - vkcv::ShaderProgram presentShaderProgram{}; - - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/presentImage.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - presentShaderProgram.addShader(shaderStage, path); - }); - - const vkcv::DescriptorBindings& presentDescriptorBindings = presentShaderProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle presentDescriptorSetLayout = core.createDescriptorSetLayout(presentDescriptorBindings); - vkcv::DescriptorSetHandle presentDescriptorSet = core.createDescriptorSet(presentDescriptorSetLayout); - vkcv::ComputePipelineHandle presentPipeline = core.createComputePipeline({ - presentShaderProgram, - { presentDescriptorSetLayout } - }); - - // clear shader - vkcv::ShaderProgram clearShaderProgram{}; - - compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/clearImage.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - clearShaderProgram.addShader(shaderStage, path); - }); - - const vkcv::DescriptorBindings& imageClearDescriptorBindings = clearShaderProgram.getReflectedDescriptors().at(0); - vkcv::DescriptorSetLayoutHandle imageClearDescriptorSetLayout = core.createDescriptorSetLayout(imageClearDescriptorBindings); - vkcv::DescriptorSetHandle imageClearDescriptorSet = core.createDescriptorSet(imageClearDescriptorSetLayout); - vkcv::ComputePipelineHandle imageClearPipeline = core.createComputePipeline({ - clearShaderProgram, - { imageClearDescriptorSetLayout } - }); - - vkcv::DescriptorWrites imageClearDescriptorWrites; - imageClearDescriptorWrites.writeStorageImage(0, meanImage); - core.writeDescriptorSet(imageClearDescriptorSet, imageClearDescriptorWrites); - - // buffers - typedef std::pair<std::string, Material> MaterialSetting; - - std::vector<MaterialSetting> materialSettings; - materialSettings.emplace_back(MaterialSetting("white", Material(glm::vec3(0), glm::vec3(0.65), 0, 0.25, glm::vec3(0.04)))); - materialSettings.emplace_back(MaterialSetting("red", Material(glm::vec3(0), glm::vec3(0.5, 0.0, 0.0), 0, 0.25, glm::vec3(0.04)))); - materialSettings.emplace_back(MaterialSetting("green", Material(glm::vec3(0), glm::vec3(0.0, 0.5, 0.0), 0, 0.25, glm::vec3(0.04)))); - materialSettings.emplace_back(MaterialSetting("light", Material(glm::vec3(20), glm::vec3(0), 0, 0.25, glm::vec3(0.04)))); - materialSettings.emplace_back(MaterialSetting("sphere", Material(glm::vec3(0), glm::vec3(0.65), 1, 0.25, glm::vec3(0.04)))); - materialSettings.emplace_back(MaterialSetting("ground", Material(glm::vec3(0), glm::vec3(0.65), 0, 0.25, glm::vec3(0.04)))); - - const uint32_t whiteMaterialIndex = 0; - const uint32_t redMaterialIndex = 1; - const uint32_t greenMaterialIndex = 2; - const uint32_t lightMaterialIndex = 3; - const uint32_t sphereMaterialIndex = 4; - const uint32_t groundMaterialIndex = 5; - - std::vector<Sphere> spheres; - spheres.emplace_back(Sphere(glm::vec3(0, -1.5, 0), 0.5, sphereMaterialIndex)); - - std::vector<Plane> planes; - planes.emplace_back(Plane(glm::vec3( 0, -2, 0), glm::vec3( 0, 1, 0), glm::vec2(2), groundMaterialIndex)); - planes.emplace_back(Plane(glm::vec3( 0, 2, 0), glm::vec3( 0, -1, 0), glm::vec2(2), whiteMaterialIndex)); - planes.emplace_back(Plane(glm::vec3( 2, 0, 0), glm::vec3(-1, 0, 0), glm::vec2(2), redMaterialIndex)); - planes.emplace_back(Plane(glm::vec3(-2, 0, 0), glm::vec3( 1, 0, 0), glm::vec2(2), greenMaterialIndex)); - planes.emplace_back(Plane(glm::vec3( 0, 0, 2), glm::vec3( 0, 0, -1), glm::vec2(2), whiteMaterialIndex)); - planes.emplace_back(Plane(glm::vec3( 0, 1.9, 0), glm::vec3( 0, -1, 0), glm::vec2(1), lightMaterialIndex)); - - vkcv::Buffer<Sphere> sphereBuffer = vkcv::buffer<Sphere>( - core, - vkcv::BufferType::STORAGE, - spheres.size()); - sphereBuffer.fill(spheres); - - vkcv::Buffer<Plane> planeBuffer = vkcv::buffer<Plane>( - core, - vkcv::BufferType::STORAGE, - planes.size()); - planeBuffer.fill(planes); - - vkcv::Buffer<Material> materialBuffer = vkcv::buffer<Material>( - core, - vkcv::BufferType::STORAGE, - materialSettings.size()); - - vkcv::DescriptorWrites traceDescriptorWrites; - traceDescriptorWrites.writeStorageBuffer( - 0, sphereBuffer.getHandle() - ).writeStorageBuffer( - 1, planeBuffer.getHandle() - ).writeStorageBuffer( - 2, materialBuffer.getHandle() - ); - - traceDescriptorWrites.writeStorageImage(3, outputImage); - core.writeDescriptorSet(traceDescriptorSet, traceDescriptorWrites); - - vkcv::ComputePipelineHandle tracePipeline = core.createComputePipeline({ - traceShaderProgram, - { traceDescriptorSetLayout } - }); - - if (!tracePipeline) - { - vkcv_log(vkcv::LogLevel::ERROR, "Could not create graphics pipeline. Exiting."); - return EXIT_FAILURE; - } - - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - cameraManager.getCamera(camHandle).setPosition(glm::vec3(0, 0, -2)); - - int frameIndex = 0; - bool clearMeanImage = true; - bool updateMaterials = true; - - float cameraPitchPrevious = 0; - float cameraYawPrevious = 0; - glm::vec3 cameraPositionPrevious = glm::vec3(0); - - uint32_t widthPrevious = initialWidth; - uint32_t heightPrevious = initialHeight; - - vkcv::gui::GUI gui(core, windowHandle); - - bool renderUI = true; - core.getWindow(windowHandle).e_key.add([&renderUI](int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_I && action == GLFW_PRESS) { - renderUI = !renderUI; - } - }); - - glm::vec3 skyColor = glm::vec3(0.2, 0.7, 0.8); - float skyColorMultiplier = 1; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if (swapchainWidth != widthPrevious || swapchainHeight != heightPrevious) { - - // resize images - outputImage = core.createImage( - vk::Format::eR32G32B32A32Sfloat, - swapchainWidth, - swapchainHeight, - 1, - false, - true - ); - - meanImage = core.createImage( - vk::Format::eR32G32B32A32Sfloat, - swapchainWidth, - swapchainHeight, - 1, - false, - true - ); - - // update descriptor sets - traceDescriptorWrites.writeStorageImage(3, outputImage); - core.writeDescriptorSet(traceDescriptorSet, traceDescriptorWrites); - - vkcv::DescriptorWrites imageCombineDescriptorWrites; - imageCombineDescriptorWrites.writeStorageImage( - 0, outputImage - ).writeStorageImage( - 1, meanImage - ); - - core.writeDescriptorSet(imageCombineDescriptorSet, imageCombineDescriptorWrites); - - vkcv::DescriptorWrites imageClearDescriptorWrites; - imageClearDescriptorWrites.writeStorageImage(0, meanImage); - core.writeDescriptorSet(imageClearDescriptorSet, imageClearDescriptorWrites); - - widthPrevious = swapchainWidth; - heightPrevious = swapchainHeight; - - clearMeanImage = true; - } - - cameraManager.update(dt); - - const vkcv::CommandStreamHandle cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - const auto fullscreenDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(8, 8) - ); - - if (updateMaterials) { - std::vector<Material> materials; - for (const auto& settings : materialSettings) { - materials.push_back(settings.second); - } - materialBuffer.fill(materials); - updateMaterials = false; - clearMeanImage = true; - } - - float cameraPitch; - float cameraYaw; - cameraManager.getActiveCamera().getAngles(cameraPitch, cameraYaw); - - if (glm::abs(cameraPitch - cameraPitchPrevious) > 0.01 || glm::abs(cameraYaw - cameraYawPrevious) > 0.01) - clearMeanImage = true; // camera rotated - - cameraPitchPrevious = cameraPitch; - cameraYawPrevious = cameraYaw; - - glm::vec3 cameraPosition = cameraManager.getActiveCamera().getPosition(); - - if(glm::distance(cameraPosition, cameraPositionPrevious) > 0.0001) - clearMeanImage = true; // camera moved - - cameraPositionPrevious = cameraPosition; - - if (clearMeanImage) { - core.prepareImageForStorage(cmdStream, meanImage); - - core.recordComputeDispatchToCmdStream(cmdStream, - imageClearPipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, imageClearDescriptorSet) }, - vkcv::PushConstants(0)); - - clearMeanImage = false; - } - - // path tracing - struct RaytracingPushConstantData { - glm::mat4 viewToWorld; - glm::vec3 skyColor; - int32_t sphereCount; - int32_t planeCount; - int32_t frameIndex; - }; - - RaytracingPushConstantData raytracingPushData; - raytracingPushData.viewToWorld = glm::inverse(cameraManager.getActiveCamera().getView()); - raytracingPushData.skyColor = skyColor * skyColorMultiplier; - raytracingPushData.sphereCount = spheres.size(); - raytracingPushData.planeCount = planes.size(); - raytracingPushData.frameIndex = frameIndex; - - vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<RaytracingPushConstantData>(); - pushConstantsCompute.appendDrawcall(raytracingPushData); - - const auto traceDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(16, 16) - ); - - core.prepareImageForStorage(cmdStream, outputImage); - - core.recordComputeDispatchToCmdStream(cmdStream, - tracePipeline, - traceDispatchCount, - { vkcv::useDescriptorSet(0, traceDescriptorSet) }, - pushConstantsCompute); - - core.prepareImageForStorage(cmdStream, meanImage); - core.recordImageMemoryBarrier(cmdStream, outputImage); - - // combine images - core.recordComputeDispatchToCmdStream(cmdStream, - imageCombinePipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, imageCombineDescriptorSet) }, - vkcv::PushConstants(0)); - - core.recordImageMemoryBarrier(cmdStream, meanImage); - - // present image - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::DescriptorWrites presentDescriptorWrites; - presentDescriptorWrites.writeStorageImage( - 0, meanImage - ).writeStorageImage( - 1, swapchainInput - ); - - core.writeDescriptorSet(presentDescriptorSet, presentDescriptorWrites); - - core.prepareImageForStorage(cmdStream, swapchainInput); - - core.recordComputeDispatchToCmdStream(cmdStream, - presentPipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, presentDescriptorSet) }, - vkcv::PushConstants(0)); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - if (renderUI) { - gui.beginGUI(); - - ImGui::Begin("Settings"); - - clearMeanImage |= ImGui::ColorEdit3("Sky color", &skyColor.x); - clearMeanImage |= ImGui::InputFloat("Sky color multiplier", &skyColorMultiplier); - - if (ImGui::CollapsingHeader("Materials")) { - - for (auto& setting : materialSettings) { - if (ImGui::CollapsingHeader(setting.first.c_str())) { - - const glm::vec3 emission = setting.second.emission; - float emissionStrength = glm::max(glm::max(glm::max(emission.x, emission.y), emission.z), 1.f); - glm::vec3 emissionColor = emission / emissionStrength; - - updateMaterials |= ImGui::ColorEdit3((std::string("Emission color ") + setting.first).c_str(), &emissionColor.x); - updateMaterials |= ImGui::InputFloat((std::string("Emission strength ") + setting.first).c_str(), &emissionStrength); - - setting.second.emission = emissionStrength * emissionColor; - - updateMaterials |= ImGui::ColorEdit3((std::string("Albedo color ") + setting.first).c_str(), &setting.second.albedo.x); - updateMaterials |= ImGui::ColorEdit3((std::string("F0 ") + setting.first).c_str(), &setting.second.f0.x); - updateMaterials |= ImGui::DragFloat(( std::string("ks ") + setting.first).c_str(), &setting.second.ks, 0.01, 0, 1); - updateMaterials |= ImGui::DragFloat(( std::string("roughness ") + setting.first).c_str(), &setting.second.roughness, 0.01, 0, 1); - - } - } - } - - ImGui::End(); - - gui.endGUI(); - } - - frameIndex++; - }); - - return 0; -} diff --git a/projects/rtx_ambient_occlusion/.gitignore b/projects/rtx_ambient_occlusion/.gitignore deleted file mode 100644 index 61b2ff94710af817f199d848e4253062c024a6bf..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rtx_ambient_occlusion \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/CMakeLists.txt b/projects/rtx_ambient_occlusion/CMakeLists.txt deleted file mode 100644 index 2c784a4f173ea5d6e0de1df1a2cfe514a5787153..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(rtx_ambient_occlusion) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(rtx_source ${PROJECT_SOURCE_DIR}/src/RTX) - -set(rtx_sources - ${rtx_source}/RTX.hpp - ${rtx_source}/RTX.cpp - - ${rtx_source}/ASManager.hpp - ${rtx_source}/ASManager.cpp - - ${rtx_source}/RTXExtensions.hpp - ${rtx_source}/RTXExtensions.cpp -) - -# adding source files to the project -add_project(rtx_ambient_occlusion src/main.cpp src/teapot.hpp ${rtx_sources}) - -# including headers of dependencies and the VkCV framework -target_include_directories(rtx_ambient_occlusion SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include} ${vkcv_shader_compiler_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(rtx_ambient_occlusion vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene vkcv_shader_compiler) diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit b/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit deleted file mode 100644 index b073916e4eaf992d5e6ae4186013478634263fbd..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit +++ /dev/null @@ -1,48 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : require -#extension GL_EXT_scalar_block_layout : require - -hitAttributeEXT vec2 attributes; - -layout(location = 0) rayPayloadInEXT Payload { - float hitSky; - vec3 worldPosition; - vec3 worldNormal; -} payload; - -layout(binding = 2, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure - -layout(binding = 3, set = 0, scalar) buffer rtxVertices -{ - float vertices[]; -}; - -layout(binding = 4, set = 0, scalar) buffer rtxIndices -{ - uint indices[]; -}; - -void main() { - payload.worldPosition = vec3(1.0, 0.0, 0.5); - - ivec3 indicesVec = ivec3(indices[3 * gl_PrimitiveID + 0], indices[3 * gl_PrimitiveID + 1], indices[3 * gl_PrimitiveID + 2]); - - // current triangle - const vec3 v0 = vec3(vertices[3 * indicesVec.x + 0],vertices[3 * indicesVec.x + 1],vertices[3 * indicesVec.x + 2]); - const vec3 v1 = vec3(vertices[3 * indicesVec.y + 0],vertices[3 * indicesVec.y + 1],vertices[3 * indicesVec.y + 2]); - const vec3 v2 = vec3(vertices[3 * indicesVec.z + 0],vertices[3 * indicesVec.z + 1],vertices[3 * indicesVec.z + 2]); - - // use barycentric coordinates to compute intersection - const vec3 barycentrics = vec3(1.0 - attributes.x - attributes.y, attributes.xy); - const vec3 objectPosition = v0 * barycentrics.x + v1 * barycentrics.y + v2 * barycentrics.z; - - payload.worldPosition = gl_ObjectToWorldEXT * vec4(objectPosition, 1.0); - - const vec3 objectNormal = cross(v1 - v0, v2 - v0); - - payload.worldNormal = normalize((objectNormal * gl_WorldToObjectEXT).xyz); - - payload.worldNormal = faceforward(payload.worldNormal, gl_WorldRayDirectionEXT, payload.worldNormal); - - payload.hitSky = 0.0f; -} diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rgen b/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rgen deleted file mode 100644 index 711070fcf1eec18253f331cbd133330791fa6be6..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rgen +++ /dev/null @@ -1,158 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : require - -#define M_PI 3.1415926535897932384626433832795 - -// A location for a ray payload (we can have multiple of these) -layout(location = 0) rayPayloadEXT Payload { - float hitSky; - vec3 worldPosition; - vec3 worldNormal; -} payload; - -layout(binding = 0, set = 0, rgba16) uniform image2D outImg; // the output image -> maybe use 16 bit values? -layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure - -layout( push_constant ) uniform constants { - vec4 camera_position; // as origin for ray generation - vec4 camera_right; // for computing ray direction - vec4 camera_up; // for computing ray direction - vec4 camera_forward; // for computing ray direction -} camera; - -// random() and helpers from: https://www.shadertoy.com/view/XlycWh -float g_seed = 0; - -uint base_hash(uvec2 p) { - p = 1103515245U*((p >> 1U)^(p.yx)); - uint h32 = 1103515245U*((p.x)^(p.y>>3U)); - return h32^(h32 >> 16); -} - -vec2 hash2(inout float seed) { - uint n = base_hash(floatBitsToUint(vec2(seed+=.1,seed+=.1))); - uvec2 rz = uvec2(n, n*48271U); - return vec2(rz.xy & uvec2(0x7fffffffU))/float(0x7fffffff); -} - -void initRandom(uvec2 coord){ - g_seed = float(base_hash(coord)/float(0xffffffffU)); -} - -vec2 random(){ - return hash2(g_seed); -} - -/** - * Traces the ray from the camera and provides the intersection information. - * @param[in,out] hitSky Defines if the ray has hit the sky - * @param[in,out] pos The position of intersection - * @param[in,out] norm The normal at the position of intersection - */ -void TraceCameraRay(out bool hitSky, out vec3 pos, out vec3 norm){ - // Use a camera model to generate a ray for this pixel. - vec2 uv = gl_LaunchIDEXT.xy + vec2(random()); // random breaks up aliasing - uv /= vec2(gl_LaunchSizeEXT.xy); - uv = (uv * 2.0 - 1.0) // normalize uv coordinates into Vulkan viewport space - * vec2(1.0, -1.0); // flips y-axis - const vec3 orig = camera.camera_position.xyz; - const vec3 dir = normalize(uv.x * camera.camera_right + uv.y * camera.camera_up + camera.camera_forward).xyz; - - // Trace a ray into the scene; get back data in the payload. - traceRayEXT(tlas, // Acceleration structure - gl_RayFlagsOpaqueEXT, // Ray flags, here saying "ignore intersection shaders" - 0xFF, // 8-bit instance mask, here saying "trace against all instances" - 0, // SBT record offset - 0, // SBT record stride for offset - 0, // Miss index - orig, // Ray origin - 0.0, // Minimum t-value - dir, // Ray direction - 1000.0, // Maximum t-value - 0); // Location of payload - - // Read the values from the payload: - hitSky = (payload.hitSky > 0.0); - pos = payload.worldPosition; - norm = payload.worldNormal; -} - -/** - * @brief Casts a shadow ray. Returns @p true, if the shadow ray hit the sky. - * @param[in] orig The point of origin of the shadow ray. - * @param[in] dir The direction of the shadow ray. - */ -float CastShadowRay(vec3 orig, vec3 dir){ - payload.hitSky = 0.0f; // Assume ray is occluded - traceRayEXT(tlas, // Acceleration structure - gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT | gl_RayFlagsTerminateOnFirstHitEXT, // Ray flags, here saying "ignore any hit shaders and closest hit shaders, and terminate the ray on the first found intersection" - 0xFF, // 8-bit instance mask, here saying "trace against all instances" - 0, // SBT record offset - 0, // SBT record stride for offset - 0, // Miss index - orig, // Ray origin - 0.0001, // Minimum t-value - avoid self intersection - dir, // Ray direction - 1000.0, // Maximum t-value - 0); // Location of payload - return payload.hitSky; -} - -vec3 sampleCosineDistribution(vec2 xi){ - float phi = 2 * M_PI * xi.y; - return vec3( - sqrt(xi.x) * cos(phi), - sqrt(1 - xi.x), - sqrt(xi.x) * sin(phi)); -} - -struct Basis{ - vec3 right; - vec3 up; - vec3 forward; -}; - -Basis buildBasisAroundNormal(vec3 N){ - Basis basis; - basis.up = N; - basis.right = abs(basis.up.x) < 0.99 ? vec3(1, 0, 0) : vec3(0, 0, 1); - basis.forward = normalize(cross(basis.up, basis.right)); - basis.right = cross(basis.up, basis.forward); - return basis; -} - -vec3 sampleTangentToWorldSpace(vec3 tangentSpaceSample, vec3 N){ - Basis tangentBasis = buildBasisAroundNormal(N); - return - tangentBasis.right * tangentSpaceSample.x + - tangentBasis.up * tangentSpaceSample.y + - tangentBasis.forward * tangentSpaceSample.z; -} - -void main(){ - uint rayCount = 64; // the amount of rays to be casted - - initRandom(gl_LaunchIDEXT.xy); - - uvec2 pixel = gl_LaunchIDEXT.xy; - bool pixelIsSky; // Does the pixel show the sky (not an object)? - vec3 pos, norm; // AO rays from where? - TraceCameraRay(pixelIsSky, pos, norm); - - if(pixelIsSky){ - // Don't compute ambient occlusion for the sky - imageStore(outImg, ivec2(pixel), vec4(0.8,0.8,0.8,1.0)); - return; - } - - // Compute ambient occlusion - float aoValue = 0.0; - for(uint i = 0; i < rayCount; i++){ - vec3 sampleTangentSpace = sampleCosineDistribution(random()); - vec3 sampleWorldSpace = sampleTangentToWorldSpace(sampleTangentSpace, norm); - aoValue += CastShadowRay(pos, sampleWorldSpace); - } - aoValue /= rayCount; - - imageStore(outImg, ivec2(pixel), vec4(vec3(aoValue), 1)); -} diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss b/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss deleted file mode 100644 index c107dbd03e6a8fdfdd84d2b8d280cb6264307c14..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss +++ /dev/null @@ -1,12 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : require - -layout(location = 0) rayPayloadInEXT Payload { - float hitSky; - vec3 worldPosition; - vec3 worldNormal; -} payload; - -void main() { - payload.hitSky = 1.0f; -} diff --git a/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp b/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp deleted file mode 100644 index fefd468067658cde88eefe02834b2e7328672af6..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp +++ /dev/null @@ -1,460 +0,0 @@ -#include "ASManager.hpp" -#include <array> - -namespace vkcv::rtx { - - - ASManager::ASManager(vkcv::Core *core) : - m_core(core), - m_device(&(core->getContext().getDevice())){ - // INFO: Using RTX extensions implies that we cannot use the standard dispatcher from Vulkan because using RTX - // specific functions via vk::Device will result in validation errors. Instead we need to use a - // vk::DispatchLoaderDynamic which is used as dispatcher parameter of the device functions. - m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); - m_rtxDispatcher.init(m_core->getContext().getInstance()); - - // TODO: Recursive call of buildBLAS for bigger scenes. Currently, the RTX module only supports one mesh. - } - - ASManager::~ASManager() noexcept { - m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); - m_rtxDispatcher.init(m_core->getContext().getInstance()); - - // destroy every BLAS, its data containers and free used memory blocks - for (size_t i=0; i < m_bottomLevelAccelerationStructures.size(); i++) { - BottomLevelAccelerationStructure blas = m_bottomLevelAccelerationStructures[i]; - m_core->getContext().getDevice().destroyAccelerationStructureKHR(blas.vulkanHandle, nullptr, m_rtxDispatcher); - m_core->getContext().getDevice().destroy(blas.accelerationBuffer.vulkanHandle); - m_core->getContext().getDevice().destroy(blas.indexBuffer.vulkanHandle); - m_core->getContext().getDevice().destroy(blas.vertexBuffer.vulkanHandle); - - m_core->getContext().getDevice().freeMemory(blas.accelerationBuffer.deviceMemory); - m_core->getContext().getDevice().freeMemory(blas.indexBuffer.deviceMemory); - m_core->getContext().getDevice().freeMemory(blas.vertexBuffer.deviceMemory); - } - - // destroy the TLAS, its data containers and free used memory blocks - TopLevelAccelerationStructure tlas = m_topLevelAccelerationStructure; - m_core->getContext().getDevice().destroyAccelerationStructureKHR(tlas.vulkanHandle, nullptr, m_rtxDispatcher); - m_core->getContext().getDevice().destroy(tlas.tlasBuffer.vulkanHandle); - m_core->getContext().getDevice().destroy(tlas.gpuBufferInstances.vulkanHandle); - - m_core->getContext().getDevice().freeMemory(tlas.tlasBuffer.deviceMemory); - m_core->getContext().getDevice().freeMemory(tlas.gpuBufferInstances.deviceMemory); - } - - - - vk::CommandPool ASManager::createCommandPool() { - vk::CommandPool commandPool; - vk::CommandPoolCreateInfo commandPoolCreateInfo; - commandPoolCreateInfo.setQueueFamilyIndex(m_core->getContext().getQueueManager().getComputeQueues()[0].familyIndex); - vk::Result res = m_device->createCommandPool(&commandPoolCreateInfo, nullptr, &commandPool); - if (res != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "ASManager: command pool could not be created! (%s)", vk::to_string(res).c_str()); - } - return commandPool; - }; - - vk::CommandBuffer ASManager::createAndBeginCommandBuffer(vk::CommandPool commandPool) - { - vk::CommandBufferAllocateInfo commandBufferAllocateInfo{}; - commandBufferAllocateInfo.setLevel(vk::CommandBufferLevel::ePrimary); - commandBufferAllocateInfo.setCommandPool(commandPool); - commandBufferAllocateInfo.setCommandBufferCount(1); - vk::CommandBuffer commandBuffer; - vk::Result result = m_device->allocateCommandBuffers(&commandBufferAllocateInfo, &commandBuffer); - if (result != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "ASManager: command buffer for Acceleration Strucutre Build could not be allocated! (%s)", vk::to_string(result).c_str()); - } - - const vk::CommandBufferBeginInfo beginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - commandBuffer.begin(beginInfo); - return commandBuffer; - } - - void ASManager::submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer) - { - commandBuffer.end(); - - vk::SubmitInfo submitInfo; - submitInfo.setCommandBufferCount(1); - submitInfo.setPCommandBuffers(&commandBuffer); - - vkcv::Queue queue = m_core->getContext().getQueueManager().getComputeQueues()[0]; - - queue.handle.submit(submitInfo); - queue.handle.waitIdle(); - - m_device->freeCommandBuffers(commandPool, 1, &commandBuffer); - m_device->destroyCommandPool(commandPool); - } - - vk::DeviceAddress ASManager::getBufferDeviceAddress(vk::Buffer buffer) - { - vk::BufferDeviceAddressInfo bufferDeviceAddressInfo(buffer); - return m_device->getBufferAddress(bufferDeviceAddressInfo); - } - - void ASManager::createBuffer(RTXBuffer& buffer) { - - vk::BufferCreateInfo bufferCreateInfo; - bufferCreateInfo.setFlags(vk::BufferCreateFlags()); - bufferCreateInfo.setUsage(buffer.bufferUsageFlagBits); - bufferCreateInfo.setSize(buffer.deviceSize); - - buffer.vulkanHandle = m_device->createBuffer(bufferCreateInfo); - vk::MemoryRequirements2 memoryRequirements2; - vk::MemoryDedicatedRequirements dedicatedRequirements; - vk::BufferMemoryRequirementsInfo2 bufferRequirements; - - bufferRequirements.setBuffer(buffer.vulkanHandle); - memoryRequirements2.pNext = &dedicatedRequirements; - m_device->getBufferMemoryRequirements2(&bufferRequirements, &memoryRequirements2); - - vk::PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties = m_core->getContext().getPhysicalDevice().getMemoryProperties(); - - uint32_t memoryTypeIndex = -1; - for (size_t i = 0; i < physicalDeviceMemoryProperties.memoryTypeCount; i++) { - if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i)) - && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) { - memoryTypeIndex = i; - break; - } - } - - vk::MemoryAllocateInfo memoryAllocateInfo( - memoryRequirements2.memoryRequirements.size, // size of allocation in bytes - memoryTypeIndex // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure. - ); - vk::MemoryAllocateFlagsInfo allocateFlagsInfo( - vk::MemoryAllocateFlagBits::eDeviceAddress // vk::MemoryAllocateFlags - ); - memoryAllocateInfo.setPNext(&allocateFlagsInfo); // extend memory allocate info with allocate flag info - buffer.deviceMemory = m_device->allocateMemory(memoryAllocateInfo); - - uint32_t memoryOffset = 0; - m_device->bindBufferMemory(buffer.vulkanHandle, buffer.deviceMemory, memoryOffset); - - // only fill data in case of CPU buffer - if (buffer.bufferType == RTXBufferType::STAGING) { - void* mapped = m_device->mapMemory(buffer.deviceMemory, memoryOffset, buffer.deviceSize); - std::memcpy(mapped, buffer.data, buffer.deviceSize); - m_device->unmapMemory(buffer.deviceMemory); - } - } - - void ASManager::copyFromCPUToGPU(RTXBuffer& cpuBuffer, RTXBuffer& gpuBuffer) { - vk::CommandPool commandPool= createCommandPool(); - vk::CommandBuffer commandBuffer= createAndBeginCommandBuffer(commandPool); - vk::BufferCopy bufferCopy; - bufferCopy.size = cpuBuffer.deviceSize; - commandBuffer.copyBuffer(cpuBuffer.vulkanHandle, gpuBuffer.vulkanHandle, 1, &bufferCopy); - - submitCommandBuffer(commandPool,commandBuffer); - - m_device->destroyBuffer(cpuBuffer.vulkanHandle); - m_device->freeMemory(cpuBuffer.deviceMemory); - } - - void ASManager::buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount) { - // TODO: organize hierarchical structure of multiple BLAS - - vk::DeviceAddress vertexBufferAddress = getBufferDeviceAddress(vertexBuffer.vulkanHandle); - vk::DeviceAddress indexBufferAddress = getBufferDeviceAddress(indexBuffer.vulkanHandle); - - // triangle mesh data - vk::AccelerationStructureGeometryTrianglesDataKHR asTriangles( - vk::Format::eR32G32B32Sfloat, // vertex format - vertexBufferAddress, // vertex buffer address (vk::DeviceOrHostAddressConstKHR) - 3 * sizeof(float), // vertex stride (vk::DeviceSize) - uint32_t(vertexCount - 1), // maxVertex (uint32_t) - vk::IndexType::eUint32, // indexType (vk::IndexType) --> INFO: UINT16 oder UINT32! - indexBufferAddress, // indexData (vk::DeviceOrHostAddressConstKHR) - {} // transformData (vk::DeviceOrHostAddressConstKHR) - ); - - // Geometry data - vk::AccelerationStructureGeometryKHR asGeometry( - vk::GeometryTypeKHR::eTriangles, // The geometry type, e.g. triangles, AABBs, instances - asTriangles, // the geometry data - vk::GeometryFlagBitsKHR::eOpaque // This flag disables any-hit shaders to increase ray tracing performance - ); - - // Ranges for data lists - vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo( - uint32_t(indexCount / 3), // the primitiveCount (uint32_t) - 0, // primitiveOffset (uint32_t) - 0, // firstVertex (uint32_t) - 0 // transformOffset (uint32_t) - ); - - // Settings and array of geometries to build into BLAS - vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo( - vk::AccelerationStructureTypeKHR::eBottomLevel, // type of the AS: bottom vs. top - vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency - vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update - {}, // src AS (this seems to be for copying AS) - {}, // dst AS (this seems to be for copying AS) - 1, // the geometryCount. TODO: how many do we need? - &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry? - ); - - // Calculate memory needed for AS - vk::AccelerationStructureBuildSizesInfoKHR asBuildSizesInfo; - m_device->getAccelerationStructureBuildSizesKHR( - vk::AccelerationStructureBuildTypeKHR::eDevice, // build on device instead of host - &asBuildInfo, // pointer to build info - &asRangeInfo.primitiveCount, // array of number of primitives per geometry - &asBuildSizesInfo, // output pointer to store sizes - m_rtxDispatcher - ); - - // create buffer for acceleration structure - RTXBuffer blasBuffer; - blasBuffer.bufferType = RTXBufferType::ACCELERATION; - blasBuffer.deviceSize = asBuildSizesInfo.accelerationStructureSize; - blasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR - | vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - blasBuffer.memoryPropertyFlagBits = { vk::MemoryPropertyFlagBits::eDeviceLocal }; - - createBuffer(blasBuffer); - - // Create an empty AS object - vk::AccelerationStructureCreateInfoKHR asCreateInfo( - vk::AccelerationStructureCreateFlagsKHR(), // creation flags - blasBuffer.vulkanHandle, // allocated AS buffer. - 0, - asBuildSizesInfo.accelerationStructureSize, // size of the AS - asBuildInfo.type // type of the AS - ); - - // Create the intended AS object - vk::AccelerationStructureKHR blasKHR; - vk::Result res = m_device->createAccelerationStructureKHR( - &asCreateInfo, // AS create info - nullptr, // allocator callbacks - &blasKHR, // the AS - m_rtxDispatcher - ); - if (res != vk::Result::eSuccess) { - vkcv_log(vkcv::LogLevel::ERROR, "The Bottom Level Acceleration Structure could not be build! (%s)", vk::to_string(res).c_str()); - } - asBuildInfo.setDstAccelerationStructure(blasKHR); - - // Create temporary scratch buffer used for building the AS - RTXBuffer scratchBuffer; - scratchBuffer.bufferType = RTXBufferType::SCRATCH; - scratchBuffer.deviceSize = asBuildSizesInfo.buildScratchSize; - scratchBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - scratchBuffer.memoryPropertyFlagBits = { vk::MemoryPropertyFlagBits::eDeviceLocal }; - - createBuffer(scratchBuffer); - - asBuildInfo.setScratchData(getBufferDeviceAddress(scratchBuffer.vulkanHandle)); - - // Pointer to rangeInfo, used later for build - vk::AccelerationStructureBuildRangeInfoKHR* pointerToRangeInfo = &asRangeInfo; - - vk::CommandPool commandPool = createCommandPool(); - vk::CommandBuffer commandBuffer = createAndBeginCommandBuffer(commandPool); - - commandBuffer.buildAccelerationStructuresKHR(1, &asBuildInfo, &pointerToRangeInfo, m_rtxDispatcher); - - submitCommandBuffer(commandPool, commandBuffer); - - m_core->getContext().getDevice().destroyBuffer(scratchBuffer.vulkanHandle, nullptr, m_rtxDispatcher); - m_core->getContext().getDevice().freeMemory(scratchBuffer.deviceMemory, nullptr, m_rtxDispatcher); - - BottomLevelAccelerationStructure blas = { - vertexBuffer, - indexBuffer, - blasBuffer, - blasKHR - }; - m_bottomLevelAccelerationStructures.push_back(blas); - } - - void ASManager::buildTLAS() { - // TODO: organize hierarchical structure of multiple BLAS - - // We need an the device address of each BLAS --> TODO: for loop for bigger scenes - vk::AccelerationStructureDeviceAddressInfoKHR addressInfo( - m_bottomLevelAccelerationStructures[0].vulkanHandle - ); - vk::DeviceAddress blasAddress = m_device->getAccelerationStructureAddressKHR(&addressInfo, m_rtxDispatcher); - - std::array<std::array<float, 4>, 3> transformMatrix = { - std::array<float, 4>{1.f, 0.f, 0.f, 0.f}, - std::array<float, 4>{0.f, 1.f, 0.f, 0.f}, - std::array<float, 4>{0.f, 0.f, 1.f, 0.f}, - }; - - vk::TransformMatrixKHR transformMatrixKhr( - transformMatrix // std::array<std::array<float,4>,3> const& - ); - - vk::AccelerationStructureInstanceKHR accelerationStructureInstanceKhr( - transformMatrixKhr, // vk::TransformMatrixKHR transform_ = {}, - 0, // uint32_t instanceCustomIndex, - 0xFF, //uint32_t mask_ = {}, - 0, // uint32_t instanceShaderBindingTableRecordOffset, - vk::GeometryInstanceFlagBitsKHR::eTriangleFacingCullDisable, // vk::GeometryInstanceFlagsKHR - blasAddress // uint64_t accelerationStructureReference (the device address of the BLAS) - ); - - // create a buffer of instances on the device and upload the array of instances to it - RTXBuffer stagingBufferInstances; - stagingBufferInstances.bufferType = RTXBufferType::STAGING; - stagingBufferInstances.deviceSize = sizeof(accelerationStructureInstanceKhr); - stagingBufferInstances.data = &accelerationStructureInstanceKhr; - stagingBufferInstances.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eTransferSrc; - stagingBufferInstances.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostCoherent - | vk::MemoryPropertyFlagBits::eHostVisible; - - createBuffer(stagingBufferInstances); - - RTXBuffer bufferInstances; - bufferInstances.bufferType = RTXBufferType::GPU; - bufferInstances.deviceSize = sizeof(accelerationStructureInstanceKhr); - bufferInstances.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eTransferDst - | vk::BufferUsageFlagBits::eTransferSrc - | vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR; - bufferInstances.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eDeviceLocal; - - createBuffer(bufferInstances); - copyFromCPUToGPU(stagingBufferInstances, bufferInstances); // automatically deletes and frees memory of stagingBufferInstances - - vk::MemoryBarrier barrier; - barrier.setSrcAccessMask(vk::AccessFlagBits::eTransferWrite); - barrier.setDstAccessMask(vk::AccessFlagBits::eAccelerationStructureWriteKHR); - vk::CommandPool commandPool = createCommandPool(); - vk::CommandBuffer commandBuffer = createAndBeginCommandBuffer(commandPool); - commandBuffer.pipelineBarrier( - vk::PipelineStageFlagBits::eTransfer, - vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR, - {},1,&barrier,0, nullptr,0,nullptr); - submitCommandBuffer(commandPool, commandBuffer); - - - // ranging information for TLAS build - vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo( - 1, // primitiveCount -> number of instances - 0, // primitiveOffset - 0, // firstVertex - 0 //transformOffset - ); - - vk::DeviceAddress bufferInstancesAddress = getBufferDeviceAddress(bufferInstances.vulkanHandle); - - vk::AccelerationStructureGeometryInstancesDataKHR asInstances( - false, // vk::Bool32 arrayOfPointers - bufferInstancesAddress // vk::DeviceOrHostAddressConstKHR data_ = {} - ); - - // Geometry, in this case instances of BLAS - vk::AccelerationStructureGeometryKHR asGeometry( - vk::GeometryTypeKHR::eInstances, // vk::GeometryTypeKHR geometryType_ = vk::GeometryTypeKHR::eTriangles - asInstances, // vk::AccelerationStructureGeometryDataKHR geometry_ = {} - {} // vk::GeometryFlagsKHR flags_ = {} - ); - - // Finally, create the TLAS - vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo( - vk::AccelerationStructureTypeKHR::eTopLevel, // type of the AS: bottom vs. top - vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency - vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update - {}, // src AS (this seems to be for copying AS) - {}, // dst AS (this seems to be for copying AS) - 1, // the geometryCount. - &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry? - ); - - // AS size and scratch space size, given by count of instances (1) - vk::AccelerationStructureBuildSizesInfoKHR asSizeInfo; - m_core->getContext().getDevice().getAccelerationStructureBuildSizesKHR( - vk::AccelerationStructureBuildTypeKHR::eDevice, - &asBuildInfo, - &asRangeInfo.primitiveCount, - &asSizeInfo, - m_rtxDispatcher - ); - - // Create buffer for the TLAS - RTXBuffer tlasBuffer; - tlasBuffer.bufferType = RTXBufferType::ACCELERATION; - tlasBuffer.deviceSize = asSizeInfo.accelerationStructureSize; - tlasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR - | vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - - createBuffer(tlasBuffer); - - // Create empty TLAS object - vk::AccelerationStructureCreateInfoKHR asCreateInfo( - {}, // creation flags - tlasBuffer.vulkanHandle, // allocated AS buffer. - 0, - asSizeInfo.accelerationStructureSize, // size of the AS - asBuildInfo.type // type of the AS - ); - - vk::AccelerationStructureKHR tlas; - vk::Result res = m_device->createAccelerationStructureKHR(&asCreateInfo, nullptr, &tlas, m_rtxDispatcher); - if (res != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "Top Level Acceleration Structure could not be created! (%s)", vk::to_string(res).c_str()); - } - asBuildInfo.setDstAccelerationStructure(tlas); - - // Create temporary scratch buffer used for building the AS - RTXBuffer tlasScratchBuffer; // scratch buffer - tlasScratchBuffer.bufferType = RTXBufferType::ACCELERATION; - tlasScratchBuffer.deviceSize = asSizeInfo.buildScratchSize; - tlasScratchBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddressKHR - | vk::BufferUsageFlagBits::eStorageBuffer; - - createBuffer(tlasScratchBuffer); - - vk::BufferDeviceAddressInfo tempBuildDataBufferDeviceAddressInfo(tlasScratchBuffer.vulkanHandle); - vk::DeviceAddress tempBuildBufferDataAddress = m_core->getContext().getDevice().getBufferAddressKHR(tempBuildDataBufferDeviceAddressInfo, m_rtxDispatcher); - asBuildInfo.setScratchData(tempBuildBufferDataAddress); - - // Pointer to rangeInfo, used later for build - vk::AccelerationStructureBuildRangeInfoKHR* pointerToRangeInfo = &asRangeInfo; - - // Build the TLAS. - - vk::CommandPool commandPool2 = createCommandPool(); - vk::CommandBuffer commandBuffer2 = createAndBeginCommandBuffer(commandPool2); - commandBuffer2.buildAccelerationStructuresKHR(1, &asBuildInfo, &pointerToRangeInfo, m_rtxDispatcher); - submitCommandBuffer(commandPool2, commandBuffer2); - - m_device->destroyBuffer(tlasScratchBuffer.vulkanHandle, nullptr, m_rtxDispatcher); - m_device->freeMemory(tlasScratchBuffer.deviceMemory, nullptr, m_rtxDispatcher); - - m_topLevelAccelerationStructure = { - bufferInstances, - tlasBuffer, - tlasScratchBuffer, - tlas - }; - } - - TopLevelAccelerationStructure ASManager::getTLAS() - { - return m_topLevelAccelerationStructure; - } - - BottomLevelAccelerationStructure ASManager::getBLAS(uint32_t id) - { - return m_bottomLevelAccelerationStructures[id]; - } - - const vk::DispatchLoaderDynamic& ASManager::getDispatcher() { - return m_rtxDispatcher; - } -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp b/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp deleted file mode 100644 index 9a1374356cf4afdb04b0231f3c65e823ebe26dac..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once - -#include <vkcv/Core.hpp> - -namespace vkcv::rtx { - - /** - * @brief Used for @#RTXBuffer creation depending on the @#RTXBufferType. - */ - enum class RTXBufferType { - STAGING, - GPU, - ACCELERATION, - SHADER_BINDING, - SCRATCH - }; - - /** - * @brief Used as a container to handle buffer creation and destruction in RTX-specific use cases. - */ - struct RTXBuffer { - RTXBufferType bufferType; - void* data; - vk::DeviceSize deviceSize; - vk::DeviceMemory deviceMemory; - vk::BufferUsageFlags bufferUsageFlagBits; - vk::MemoryPropertyFlags memoryPropertyFlagBits; - vk::Buffer vulkanHandle; - }; - - /** - * @brief Used as a container to handle bottom-level acceleration structure (BLAS) construction and destruction. - */ - struct BottomLevelAccelerationStructure { - RTXBuffer vertexBuffer; - RTXBuffer indexBuffer; - RTXBuffer accelerationBuffer; - vk::AccelerationStructureKHR vulkanHandle; - }; - - /** - * @brief Used as a container to handle top-level acceleration structure (TLAS) construction and destruction. - */ - struct TopLevelAccelerationStructure { - RTXBuffer gpuBufferInstances; - RTXBuffer tlasBuffer; - RTXBuffer tempBuildDataBuffer; // scratch buffer - vk::AccelerationStructureKHR vulkanHandle; - }; - - /** - * @brief A class for managing acceleration structures (bottom, top). - */ - class ASManager { - private: - Core* m_core; - const vk::Device* m_device; - std::vector<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructures; - TopLevelAccelerationStructure m_topLevelAccelerationStructure; - vk::DispatchLoaderDynamic m_rtxDispatcher; - - /** - * Creates a command pool. - */ - vk::CommandPool createCommandPool(); - - /** - * @brief Takes a @p cmdPool, allocates a command buffer and starts recording it. - * @param cmdPool The command pool. - * @return The allocated command buffer. - */ - vk::CommandBuffer createAndBeginCommandBuffer( vk::CommandPool cmdPool); - - /** - * @brief Ends the @p commandBuffer,submits it and waits. Afterwards frees the @p commandBuffer. - * @param commandPool The command pool. - * @param commandBuffer The command buffer. - */ - void submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer); - - /** - * @brief Gets the device address of a @p buffer. - * @param buffer The buffer. - * @return The device address of the @p buffer. - */ - vk::DeviceAddress getBufferDeviceAddress(vk::Buffer buffer); - - /** - * @brief Copies @p cpuBuffer data into a @p gpuBuffer. Typical use case is a staging buffer (namely, - * @p cpuBuffer) used to fill a @p gpuBuffer with @p vk::MemoryPropertyFlagBits::eDeviceLocal flag set. - * @p cpuBuffer is destroyed and freed after copying. - * @param cpuBuffer - * @param gpuBuffer - */ - void copyFromCPUToGPU(RTXBuffer &cpuBuffer, RTXBuffer &gpuBuffer); - - public: - - /** - * @brief Constructor of @#ASManager . - * @param core - */ - ASManager(vkcv::Core *core); - - /** - * @brief Default destructor of @#ASManager. - */ - ~ASManager(); - - /** - * @brief Returns a @#RTXBuffer object holding data of type @p T. - * @param data The input data of type @p T. - * @return A @#RTXBuffer object holding @p data of type @p T. - */ - template<class T> - RTXBuffer makeBufferFromData(std::vector<T>& data) { - - // first: Staging Buffer creation - RTXBuffer stagingBuffer; - stagingBuffer.bufferType = RTXBufferType::STAGING; - stagingBuffer.deviceSize = sizeof(T) * data.size(); - stagingBuffer.data = data.data(); - stagingBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eTransferSrc; - stagingBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible; - - createBuffer(stagingBuffer); - - // second: create AS Buffer - RTXBuffer targetBuffer; - targetBuffer.bufferType = RTXBufferType::GPU; - targetBuffer.deviceSize = sizeof(T) * data.size(); - targetBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR - | vk::BufferUsageFlagBits::eTransferDst - | vk::BufferUsageFlagBits::eStorageBuffer - | vk::BufferUsageFlagBits::eShaderDeviceAddress; - targetBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eDeviceLocal; - - createBuffer(targetBuffer); - - // copy from CPU to GPU - copyFromCPUToGPU(stagingBuffer, targetBuffer); - - return targetBuffer; - } - - /** - * @brief A helper function used by @#ASManager::makeBufferFromData. Creates a fully initialized @#RTXBuffer object - * from partially specified @p buffer. All missing data of @p buffer will be completed by this function. - * @param buffer The partially specified @#RTXBuffer holding that part of information which is required for - * successfully creating a @p vk::Buffer object. - */ - void createBuffer(RTXBuffer& buffer); - - /** - * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertexBuffer and @p indexBuffer. - * @param[in] vertexBuffer The vertex data. - * @param[in] vertexCount The amount of vertices in @p vertexBuffer. - * @param[in] indexBuffer The index data. - * @param[in] indexCount The amount of indices in @p indexBuffer. - */ - void buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount); - - /** - * @brief Build a Top Level Acceleration Structure (TLAS) object from the created - * @#ASManager::m_accelerationStructures objects. - */ - void buildTLAS(); - - /** - * @brief Returns the top-level acceleration structure (TLAS) buffer. - * @return A @#TopLevelAccelerationStructure object holding the TLAS. - */ - TopLevelAccelerationStructure getTLAS(); - - /** - * @brief Returns the bottom-level acceleration structure at @p id. - * @param id The ID used for indexing. - * @return The specified @#BottomLevelAccelerationStructure object. - */ - BottomLevelAccelerationStructure getBLAS(uint32_t id); - - /** - * @brief Returns the dispatcher member variable for access in the @#RTXModule. - * @return The dispatcher member variable. - */ - const vk::DispatchLoaderDynamic& getDispatcher(); - }; -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp deleted file mode 100644 index bd5453abae353eed6739c41dbff084a0c909aaca..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp +++ /dev/null @@ -1,330 +0,0 @@ -#include "RTX.hpp" - -namespace vkcv::rtx { - - RTXModule::RTXModule(Core* core, ASManager* asManager, std::vector<float>& vertices, - std::vector<uint32_t>& indices, std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles){ - m_core = core; - m_asManager = asManager; - // build acceleration structures BLAS then TLAS --> see ASManager - RTXBuffer vertexBuffer = m_asManager->makeBufferFromData(vertices); - RTXBuffer indexBuffer = m_asManager->makeBufferFromData(indices); - m_asManager->buildBLAS(vertexBuffer, vertices.size(), indexBuffer,indices.size()); - m_asManager->buildTLAS(); - RTXDescriptors(descriptorSetHandles); - } - - - RTXModule::~RTXModule() - { - m_core->getContext().getDevice().destroy(m_pipeline); - m_core->getContext().getDevice().destroy(m_pipelineLayout); - m_core->getContext().getDevice().destroy(m_shaderBindingTableBuffer.vulkanHandle); - m_core->getContext().getDevice().freeMemory(m_shaderBindingTableBuffer.deviceMemory); - } - - void RTXModule::createShaderBindingTable(uint32_t shaderCount) { - vk::PhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProperties; - - vk::PhysicalDeviceProperties2 physicalProperties; - physicalProperties.pNext = &rayTracingProperties; - - m_core->getContext().getPhysicalDevice().getProperties2(&physicalProperties); - - vk::DeviceSize shaderBindingTableSize = rayTracingProperties.shaderGroupHandleSize * shaderCount; - - - m_shaderBindingTableBuffer.bufferType = RTXBufferType::SHADER_BINDING; - m_shaderBindingTableBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderBindingTableKHR | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR; - m_shaderBindingTableBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostVisible; - m_shaderBindingTableBuffer.deviceSize = shaderBindingTableSize; - - m_asManager->createBuffer(m_shaderBindingTableBuffer); - - void* shaderHandleStorage = (void*)malloc(sizeof(uint8_t) * shaderBindingTableSize); - - if (m_core->getContext().getDevice().getRayTracingShaderGroupHandlesKHR(m_pipeline, 0, shaderCount, shaderBindingTableSize, - shaderHandleStorage, m_asManager->getDispatcher()) != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "Could not retrieve shader binding table group handles."); - } - - m_shaderGroupBaseAlignment = rayTracingProperties.shaderGroupBaseAlignment; - uint8_t* mapped = (uint8_t*) m_core->getContext().getDevice().mapMemory(m_shaderBindingTableBuffer.deviceMemory, 0, shaderBindingTableSize); - for (size_t i = 0; i < shaderCount; i++) { - memcpy(mapped, (uint8_t*)shaderHandleStorage + (i * rayTracingProperties.shaderGroupHandleSize), rayTracingProperties.shaderGroupHandleSize); - mapped += m_shaderGroupBaseAlignment; - } - - m_core->getContext().getDevice().unmapMemory(m_shaderBindingTableBuffer.deviceMemory); - free(shaderHandleStorage); - } - - ShaderBindingTableRegions RTXModule::createRegions() { - // Define offsets for the RTX shaders. RayGen is the first allocated shader. Each following shader is - // shifted by shaderGroupBaseAlignment. - // Offset Calculation: offset = count of previous shaders * m_shaderGroupBaseAlignment - // Regions are hard coded - vk::DeviceSize rayGenOffset = 0; //First Shader group -> offset 0 * m_shaderGroupBaseAlignment =0 - vk::DeviceSize missOffset = m_shaderGroupBaseAlignment;//Second group, offset = 1 * m_shaderGroupBaseAlignment - vk::DeviceSize closestHitOffset = 2 * m_shaderGroupBaseAlignment; //Third group, offset = 2 * m_shaderGroupBaseAlignment - vk::DeviceSize shaderBindingTableSize = m_shaderGroupBaseAlignment * 3; // 3 hardcoded to rtx-shader count - - auto m_rtxDispatcher = vk::DispatchLoaderDynamic((PFN_vkGetInstanceProcAddr)m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr")); - m_rtxDispatcher.init(m_core->getContext().getInstance()); - - - // Create regions for the shader binding table buffer which are used for vk::CommandBuffer::traceRaysKHR - vk::StridedDeviceAddressRegionKHR rgenRegion; - vk::BufferDeviceAddressInfoKHR shaderBindingTableAddressInfo(m_shaderBindingTableBuffer.vulkanHandle); - rgenRegion.deviceAddress = m_core->getContext().getDevice().getBufferAddressKHR(shaderBindingTableAddressInfo, m_rtxDispatcher) + rayGenOffset; - rgenRegion.setStride(shaderBindingTableSize); - rgenRegion.setSize(shaderBindingTableSize); - vk::StridedDeviceAddressRegionKHR rmissRegion; - rmissRegion.deviceAddress = m_core->getContext().getDevice().getBufferAddressKHR(shaderBindingTableAddressInfo, m_rtxDispatcher) + missOffset; - rmissRegion.setStride(shaderBindingTableSize); - rmissRegion.setSize(shaderBindingTableSize); - vk::StridedDeviceAddressRegionKHR rchitRegion; - rchitRegion.deviceAddress = m_core->getContext().getDevice().getBufferAddressKHR(shaderBindingTableAddressInfo, m_rtxDispatcher) + closestHitOffset; - rchitRegion.setStride(shaderBindingTableSize); - rchitRegion.setSize(shaderBindingTableSize); - vk::StridedDeviceAddressRegionKHR rcallRegion = {}; - - return ShaderBindingTableRegions{ rgenRegion, rmissRegion, rchitRegion, rcallRegion }; - } - - - void RTXModule::RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles) - { - //TLAS-Descriptor-Write - TopLevelAccelerationStructure tlas = m_asManager->getTLAS(); - vk::WriteDescriptorSetAccelerationStructureKHR AccelerationDescriptor = {}; - AccelerationDescriptor.accelerationStructureCount = 1; - const TopLevelAccelerationStructure constTLAS = tlas; - AccelerationDescriptor.pAccelerationStructures = &constTLAS.vulkanHandle; - - vk::WriteDescriptorSet tlasWrite; - tlasWrite.setPNext(&AccelerationDescriptor); - tlasWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0])); - tlasWrite.setDstBinding(1); - tlasWrite.setDstArrayElement(0); - tlasWrite.setDescriptorCount(1); - tlasWrite.setDescriptorType(vk::DescriptorType::eAccelerationStructureKHR); - m_core->getContext().getDevice().updateDescriptorSets(tlasWrite, nullptr); - tlasWrite.setDstBinding(2); - m_core->getContext().getDevice().updateDescriptorSets(tlasWrite, nullptr); - - //INDEX & VERTEX BUFFER - BottomLevelAccelerationStructure blas = m_asManager->getBLAS(0);//HARD CODED - - //VERTEX BUFFER - vk::DescriptorBufferInfo vertexInfo = {}; - vertexInfo.setBuffer(blas.vertexBuffer.vulkanHandle); - vertexInfo.setOffset(0); - vertexInfo.setRange(blas.vertexBuffer.deviceSize); //maybe check if size is correct - - vk::WriteDescriptorSet vertexWrite; - vertexWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0])); - vertexWrite.setDstBinding(3); - vertexWrite.setDescriptorCount(1); - vertexWrite.setDescriptorType(vk::DescriptorType::eStorageBuffer); - vertexWrite.setPBufferInfo(&vertexInfo); - m_core->getContext().getDevice().updateDescriptorSets(vertexWrite, nullptr); - - //INDEXBUFFER - vk::DescriptorBufferInfo indexInfo = {}; - indexInfo.setBuffer(blas.indexBuffer.vulkanHandle); - indexInfo.setOffset(0); - indexInfo.setRange(blas.indexBuffer.deviceSize); //maybe check if size is correct - - vk::WriteDescriptorSet indexWrite; - indexWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0])); - indexWrite.setDstBinding(4); - indexWrite.setDescriptorCount(1); - indexWrite.setDescriptorType(vk::DescriptorType::eStorageBuffer); - indexWrite.setPBufferInfo(&indexInfo); - m_core->getContext().getDevice().updateDescriptorSets(indexWrite, nullptr); - } - - void RTXModule::createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader) { - // -- process vkcv::ShaderProgram into vk::ShaderModule - std::vector<uint32_t> rayGenShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_GEN); - - vk::ShaderModuleCreateInfo rayGenShaderModuleInfo( - vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_, - rayGenShaderCode.size() * sizeof(uint32_t), // size_t codeSize - rayGenShaderCode.data() // const uint32_t* pCode - ); - vk::ShaderModule rayGenShaderModule = m_core->getContext().getDevice().createShaderModule(rayGenShaderModuleInfo); - if (!rayGenShaderModule) { - vkcv_log(LogLevel::ERROR, "The Ray Generation Shader Module could not be created!"); - } - - std::vector<uint32_t> rayMissShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_MISS); - vk::ShaderModuleCreateInfo rayMissShaderModuleInfo( - vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_, - rayMissShaderCode.size() * sizeof(uint32_t), //size_t codeSize - rayMissShaderCode.data() // const uint32_t* pCode - ); - - vk::ShaderModule rayMissShaderModule = m_core->getContext().getDevice().createShaderModule(rayMissShaderModuleInfo); - if (!rayMissShaderModule) { - vkcv_log(LogLevel::ERROR, "The Ray Miss Shader Module could not be created!"); - } - - std::vector<uint32_t> rayClosestHitShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_CLOSEST_HIT); - vk::ShaderModuleCreateInfo rayClosestHitShaderModuleInfo( - vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_, - rayClosestHitShaderCode.size() * sizeof(uint32_t), //size_t codeSize - rayClosestHitShaderCode.data() // const uint32_t* pCode_ - ); - vk::ShaderModule rayClosestHitShaderModule = m_core->getContext().getDevice().createShaderModule(rayClosestHitShaderModuleInfo); - if (!rayClosestHitShaderModule) { - vkcv_log(LogLevel::ERROR, "The Ray Closest Hit Shader Module could not be created!"); - } - - // -- PipelineShaderStages - - // ray generation - vk::PipelineShaderStageCreateInfo rayGenShaderStageInfo( - vk::PipelineShaderStageCreateFlags(), // vk::PipelineShaderStageCreateFlags flags_ = {} - vk::ShaderStageFlagBits::eRaygenKHR, // vk::ShaderStageFlagBits stage_ = vk::ShaderStageFlagBits::eVertex, - rayGenShaderModule, // vk::ShaderModule module_ = {}, - "main" // const char* pName_ = {}, - ); - - // ray miss - vk::PipelineShaderStageCreateInfo rayMissShaderStageInfo( - vk::PipelineShaderStageCreateFlags(), // vk::PipelineShaderStageCreateFlags flags_ = {} - vk::ShaderStageFlagBits::eMissKHR, // vk::ShaderStageFlagBits stage_ = vk::ShaderStageFlagBits::eVertex, - rayMissShaderModule, // vk::ShaderModule module_ = {}, - "main" // const char* pName_ = {}, - ); - - // ray closest hit - vk::PipelineShaderStageCreateInfo rayClosestHitShaderStageInfo( - vk::PipelineShaderStageCreateFlags(), // vk::PipelineShaderStageCreateFlags flags_ = {} - vk::ShaderStageFlagBits::eClosestHitKHR, // vk::ShaderStageFlagBits stage_ = vk::ShaderStageFlagBits::eVertex, - rayClosestHitShaderModule, // vk::ShaderModule module_ = {}, - "main" // const char* pName_ = {}, - ); - - std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = { // HARD CODED. TODO: Support more shader stages. - rayGenShaderStageInfo, rayMissShaderStageInfo, rayClosestHitShaderStageInfo - }; - - // -- PipelineLayouts - - std::vector<vk::RayTracingShaderGroupCreateInfoKHR> shaderGroups(shaderStages.size()); - // Ray Gen - shaderGroups[0] = vk::RayTracingShaderGroupCreateInfoKHR( - vk::RayTracingShaderGroupTypeKHR::eGeneral, // vk::RayTracingShaderGroupTypeKHR type_ = vk::RayTracingShaderGroupTypeKHR::eGeneral - 0, // uint32_t generalShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t closestHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t anyHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t intersectionShader_ = {} - nullptr // const void* pShaderGroupCaptureReplayHandle_ = {} - ); - // Ray Miss - shaderGroups[1] = vk::RayTracingShaderGroupCreateInfoKHR( - vk::RayTracingShaderGroupTypeKHR::eGeneral, // vk::RayTracingShaderGroupTypeKHR type_ = vk::RayTracingShaderGroupTypeKHR::eGeneral - 1, // uint32_t generalShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t closestHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t anyHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t intersectionShader_ = {} - nullptr // const void* pShaderGroupCaptureReplayHandle_ = {} - ); - // Ray Closest Hit - shaderGroups[2] = vk::RayTracingShaderGroupCreateInfoKHR( - vk::RayTracingShaderGroupTypeKHR::eTrianglesHitGroup, // vk::RayTracingShaderGroupTypeKHR type_ = vk::RayTracingShaderGroupTypeKHR::eGeneral - VK_SHADER_UNUSED_KHR, // uint32_t generalShader_ = {} - 2, // uint32_t closestHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t anyHitShader_ = {} - VK_SHADER_UNUSED_KHR, // uint32_t intersectionShader_ = {} - nullptr // const void* pShaderGroupCaptureReplayHandle_ = {} - ); - - std::vector<vk::DescriptorSetLayout> descriptorSetLayoutsVulkan; - for (size_t i=0; i<descriptorSetLayouts.size(); i++) { - descriptorSetLayoutsVulkan.push_back(m_core->getVulkanDescriptorSetLayout(descriptorSetLayouts[i])); - } - - vk::PushConstantRange pushConstant( - vk::ShaderStageFlagBits::eRaygenKHR | vk::ShaderStageFlagBits::eClosestHitKHR | vk::ShaderStageFlagBits::eMissKHR, // vk::ShaderStageFlags stageFlags_ = {}, - 0, // uint32_t offset_ = {}, - pushConstantSize // uint32_t size_ = {} - ); - - vk::PipelineLayoutCreateInfo rtxPipelineLayoutCreateInfo( - vk::PipelineLayoutCreateFlags(), // vk::PipelineLayoutCreateFlags flags_ = {} - (uint32_t) descriptorSetLayoutsVulkan.size(), // uint32_t setLayoutCount_ = {} HARD CODED (2) - descriptorSetLayoutsVulkan.data(), // const vk::DescriptorSetLayout* pSetLayouts_ = {} - 1, // 0, // uint32_t pushConstantRangeCount_ = {} - &pushConstant // nullptr // const vk::PushConstantRange* pPushConstantRanges_ = {} - ); - - m_pipelineLayout = m_core->getContext().getDevice().createPipelineLayout(rtxPipelineLayoutCreateInfo); - if (!m_pipelineLayout) { - vkcv_log(LogLevel::ERROR, "The RTX Pipeline Layout could not be created!"); - } - - vk::PipelineLibraryCreateInfoKHR rtxPipelineLibraryCreateInfo( - 0, // uint32_t libraryCount_ = {} - nullptr // const vk::Pipeline* pLibraries_ = {} - ); - - // -- RTX Pipeline - - vk::RayTracingPipelineCreateInfoKHR rtxPipelineInfo( - vk::PipelineCreateFlags(), // vk::PipelineCreateFlags flags_ = {} - (uint32_t) shaderStages.size(), // uint32_t stageCount_ = {} - shaderStages.data(), // const vk::PipelineShaderStageCreateInfo* pStages_ = {} - (uint32_t) shaderGroups.size(), // uint32_t groupCount_ = {} - shaderGroups.data(), // const vk::RayTracingShaderGroupCreateInfoKHR* pGroups_ = {} - 16, // uint32_t maxPipelineRayRecursionDepth_ = {} - &rtxPipelineLibraryCreateInfo, // const vk::PipelineLibraryCreateInfoKHR* pLibraryInfo_ = {} - nullptr, // const vk::RayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface_ = {} - nullptr, // const vk::PipelineDynamicStateCreateInfo* pDynamicState_ = {} - m_pipelineLayout // vk::PipelineLayout layout_ = {} - ); - - auto pipelineResult = m_core->getContext().getDevice().createRayTracingPipelineKHR( - vk::DeferredOperationKHR(), - vk::PipelineCache(), - rtxPipelineInfo, - nullptr, - m_asManager->getDispatcher() - ); - - if (pipelineResult.result != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "The RTX Pipeline could not be created!"); - } - - m_pipeline = pipelineResult.value; - - m_core->getContext().getDevice().destroy(rayGenShaderModule); - m_core->getContext().getDevice().destroy(rayMissShaderModule); - m_core->getContext().getDevice().destroy(rayClosestHitShaderModule); - - // TODO: add possibility of more than one shader per stage - createShaderBindingTable(shaderStages.size()); - } - - vk::Pipeline RTXModule::getPipeline() { - return m_pipeline; - } - - vk::Buffer RTXModule::getShaderBindingTableBuffer() - { - return m_shaderBindingTableBuffer.vulkanHandle; - } - - vk::DeviceSize RTXModule::getShaderGroupBaseAlignment() - { - return m_shaderGroupBaseAlignment; - } - - vk::PipelineLayout RTXModule::getPipelineLayout() { - return m_pipelineLayout; - } - -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp deleted file mode 100644 index ece4ac8e6707039ab3fe166750140a8040aed924..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include <vector> -#include "vulkan/vulkan.hpp" -#include <vkcv/Core.hpp> -#include "ASManager.hpp" - -namespace vkcv::rtx { - - //struct that holds all shader binding table regions - struct ShaderBindingTableRegions { - vk::StridedDeviceAddressRegionKHR rgenRegion; - vk::StridedDeviceAddressRegionKHR rmissRegion; - vk::StridedDeviceAddressRegionKHR rchitRegion; - vk::StridedDeviceAddressRegionKHR rcallRegion; - }; - - class RTXModule { - private: - - Core* m_core; - ASManager* m_asManager; - vk::Pipeline m_pipeline; - vk::PipelineLayout m_pipelineLayout; - RTXBuffer m_shaderBindingTableBuffer; - vk::DeviceSize m_shaderGroupBaseAlignment; - - public: - - /** - * @brief Initializes the @#RTXModule with scene data. - * @param core The reference to the @#Core. - * @param asManager The reference to the @#ASManager. - * @param vertices The vertex data of the scene. - * @param indices The index data of the scene. - * @param descriptorSetHandles The descriptor set handles for RTX. - */ - RTXModule(Core* core, ASManager* asManager, std::vector<float>& vertices, - std::vector<uint32_t>& indices, std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); - - /** - * @brief Default #RTXModule destructor. - */ - ~RTXModule(); - - /** - * @brief Returns the RTX pipeline. - * @return The RTX pipeline. - */ - vk::Pipeline getPipeline(); - - /** - * @brief Returns the shader binding table buffer. - * @return The shader binding table buffer. - */ - vk::Buffer getShaderBindingTableBuffer(); - - /** - * @brief Returns the shader group base alignment for partitioning the shader binding table buffer. - * @return The shader group base alignment. - */ - vk::DeviceSize getShaderGroupBaseAlignment(); - - /** - * @brief Returns the RTX pipeline layout. - * @return The RTX pipeline layout. - */ - vk::PipelineLayout getPipelineLayout(); - - /** - * @brief Sets the shader group base alignment and creates the shader binding table by allocating a shader - * binding table buffer. The allocation depends on @p shaderCount and the shader group base alignment. - * @param shaderCount The amount of shaders to be used for RTX. - */ - void createShaderBindingTable(uint32_t shaderCount); - - /** - * @brief Divides the shader binding table into regions for each shader type - * (ray generation, ray miss, ray closest hit, callable) and returns them as a struct. - * @return The struct holding all four regions of type vk::StridedDeviceAddressRegionKHR. - */ - ShaderBindingTableRegions createRegions(); - - /** - * @brief Creates Descriptor-Writes for RTX - * @param descriptorSetHandles The descriptorSetHandles for RTX. - */ - void RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); - - /** - * @brief Creates the RTX pipeline and the RTX pipeline layout. Currently, only RayGen, RayClosestHit and - * RayMiss are supported. - * @param pushConstantSize The size of the push constant used in the RTX shaders. - * @param descriptorSetLayouts The descriptor set layout handles. - * @param rtxShader The RTX shader program. - */ - void createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader); - }; - -} diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.cpp b/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.cpp deleted file mode 100644 index 0bc6a4d3dff358bdeab74d9d5da695f81c3675c7..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "RTXExtensions.hpp" - -namespace vkcv::rtx{ - -RTXExtensions::RTXExtensions() -{ - - // prepare needed raytracing extensions - m_instanceExtensions = { - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME - }; - m_deviceExtensions = { - VK_KHR_MAINTENANCE3_EXTENSION_NAME, - VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, - VK_KHR_SPIRV_1_4_EXTENSION_NAME, - VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME - }; - - // get all features required by the device extensions - for (auto deviceExtension : m_deviceExtensions) { - m_features.requireExtension(deviceExtension); - } - - m_features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, - [](vk::PhysicalDeviceDescriptorIndexingFeatures& features) {} - ); - - m_features.requireExtensionFeature<vk::PhysicalDeviceBufferDeviceAddressFeatures>( - VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - [](vk::PhysicalDeviceBufferDeviceAddressFeatures& features) { - features.setBufferDeviceAddress(true); - } - ); - - m_features.requireExtensionFeature<vk::PhysicalDeviceAccelerationStructureFeaturesKHR>( - VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, - [](vk::PhysicalDeviceAccelerationStructureFeaturesKHR& features) { - features.setAccelerationStructure(true); - } - ); - - m_features.requireExtensionFeature<vk::PhysicalDeviceRayTracingPipelineFeaturesKHR>( - VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, - [](vk::PhysicalDeviceRayTracingPipelineFeaturesKHR& features) { - features.setRayTracingPipeline(true); - } - ); -} - -std::vector<const char*> RTXExtensions::getInstanceExtensions() -{ - return m_instanceExtensions; -} - -std::vector<const char*> RTXExtensions::getDeviceExtensions() -{ - return m_deviceExtensions; -} - -vkcv::Features RTXExtensions::getFeatures() -{ - return m_features; -} - -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.hpp b/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.hpp deleted file mode 100644 index 5ad5ae0769b75aa18672648b5eb3cb598b6f8d47..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTXExtensions.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include <vector> -#include <vkcv/Core.hpp> - -namespace vkcv::rtx{ - -class RTXExtensions { -private: - std::vector<const char*> m_instanceExtensions; // the instance extensions needed for using RTX - std::vector<const char*> m_deviceExtensions; // the device extensions needed for using RTX - vkcv::Features m_features; // the features needed to be enabled for using RTX -public: - - RTXExtensions(); - ~RTXExtensions()=default; - /** - * @brief Returns the raytracing instance extensions. - * @return The raytracing instance extensions. - */ - std::vector<const char*> getInstanceExtensions(); - - /** - * @brief Returns the raytracing device extensions. - * @return The raytracing device extensions. - */ - std::vector<const char*> getDeviceExtensions(); - - /** - * @brief Returns the raytracing features. - * @return The raytracing features. - */ - vkcv::Features getFeatures(); - - -}; -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/main.cpp b/projects/rtx_ambient_occlusion/src/main.cpp deleted file mode 100644 index f5d8a46feefd070967d0f68742ad0c3b2749f160..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/main.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include <vkcv/Core.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> -#include <vkcv/shader/GLSLCompiler.hpp> -#include "RTX/RTX.hpp" -#include "RTX/RTXExtensions.hpp" -#include "teapot.hpp" - -/** - * Note: This project is based on the following tutorial https://github.com/Apress/Ray-Tracing-Gems-II/tree/main/Chapter_16. - */ - -int main(int argc, const char** argv) { - const std::string applicationName = "RTX Ambient Occlusion"; - - // prepare raytracing extensions. IMPORTANT: configure compiler to build in 64 bit mode - vkcv::rtx::RTXExtensions rtxExtensions; - std::vector<const char*> raytracingInstanceExtensions = rtxExtensions.getInstanceExtensions(); - - std::vector<const char*> instanceExtensions = {}; // add some more instance extensions, if needed - instanceExtensions.insert(instanceExtensions.end(), raytracingInstanceExtensions.begin(), raytracingInstanceExtensions.end()); // merge together all instance extensions - - vkcv::Features features = rtxExtensions.getFeatures(); // all features required by the RTX device extensions - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, - features, - instanceExtensions - ); - - vkcv::rtx::ASManager asManager(&core); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); - - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); - auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - cameraManager.getCamera(camHandle).setNearFar(0.1f, 30.0f); - - // get Teapot vertices and indices - Teapot teapot; - std::vector<float> vertices = teapot.getVertices(); - std::vector<uint32_t> indices = teapot.getIndices(); - - vkcv::shader::GLSLCompiler compiler (vkcv::shader::GLSLCompileTarget::RAY_TRACING); - - vkcv::ShaderProgram rtxShaderProgram; - compiler.compile(vkcv::ShaderStage::RAY_GEN, std::filesystem::path("resources/shaders/ambientOcclusion.rgen"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::RAY_CLOSEST_HIT, std::filesystem::path("resources/shaders/ambientOcclusion.rchit"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); - }); - - compiler.compile(vkcv::ShaderStage::RAY_MISS, std::filesystem::path("resources/shaders/ambientOcclusion.rmiss"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); - }); - - std::vector<vkcv::DescriptorSetHandle> descriptorSetHandles; - std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayoutHandles; - - vkcv::DescriptorSetLayoutHandle rtxShaderDescriptorSetLayout = core.createDescriptorSetLayout(rtxShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle rtxShaderDescriptorSet = core.createDescriptorSet(rtxShaderDescriptorSetLayout); - descriptorSetHandles.push_back(rtxShaderDescriptorSet); - descriptorSetLayoutHandles.push_back(rtxShaderDescriptorSetLayout); - - // init RTXModule - vkcv::rtx::RTXModule rtxModule(&core, &asManager, vertices, indices,descriptorSetHandles); - - struct RaytracingPushConstantData { - glm::vec4 camera_position; // as origin for ray generation - glm::vec4 camera_right; // for computing ray direction - glm::vec4 camera_up; // for computing ray direction - glm::vec4 camera_forward; // for computing ray direction - }; - - uint32_t pushConstantSize = sizeof(RaytracingPushConstantData); - - rtxModule.createRTXPipelineAndLayout(pushConstantSize, descriptorSetLayoutHandles, rtxShaderProgram); - - vk::Pipeline rtxPipeline = rtxModule.getPipeline(); - vk::PipelineLayout rtxPipelineLayout = rtxModule.getPipelineLayout(); - - vkcv::rtx::ShaderBindingTableRegions rtxRegions = rtxModule.createRegions(); - - vkcv::ImageHandle depthBuffer; - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::DescriptorWrites rtxWrites; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((!depthBuffer) || - (swapchainWidth != core.getImageWidth(depthBuffer)) || - ((swapchainHeight != core.getImageHeight(depthBuffer)))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - } - - cameraManager.update(dt); - - const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - - RaytracingPushConstantData raytracingPushData; - raytracingPushData.camera_position = glm::vec4(cameraManager.getActiveCamera().getPosition(),0); - raytracingPushData.camera_right = glm::vec4(glm::cross(cameraManager.getActiveCamera().getUp(), cameraManager.getActiveCamera().getFront()), 0); - raytracingPushData.camera_up = glm::vec4(cameraManager.getActiveCamera().getUp(),0); - raytracingPushData.camera_forward = glm::vec4(cameraManager.getActiveCamera().getFront(),0); - - vkcv::PushConstants pushConstantsRTX = vkcv::pushConstants<RaytracingPushConstantData>(); - pushConstantsRTX.appendDrawcall(raytracingPushData); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - rtxWrites.writeStorageImage(0, swapchainInput); - core.writeDescriptorSet(rtxShaderDescriptorSet, rtxWrites); - - core.prepareImageForStorage(cmdStream, swapchainInput); - - core.recordRayGenerationToCmdStream( - cmdStream, - rtxPipeline, - rtxPipelineLayout, - rtxRegions.rgenRegion, - rtxRegions.rmissRegion, - rtxRegions.rchitRegion, - rtxRegions.rcallRegion, - { vkcv::useDescriptorSet(0, rtxShaderDescriptorSet) }, - pushConstantsRTX, - windowHandle); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/rtx_ambient_occlusion/src/teapot.hpp b/projects/rtx_ambient_occlusion/src/teapot.hpp deleted file mode 100644 index 1f35400a313b230f92098fa2ef59cc3c8f3a30df..0000000000000000000000000000000000000000 --- a/projects/rtx_ambient_occlusion/src/teapot.hpp +++ /dev/null @@ -1,7114 +0,0 @@ -#pragma once -#include <vector> - -class Teapot { -public: - /** - * @brief The default constructor. - */ - Teapot() = default; - - /** - * default destructor - */ - ~Teapot() = default; - - /** - * @brief Returns the vertex data of the teapot. - * @return The vertex data of the teapot. - */ - std::vector<float> getVertices() { - return m_teapotVertices; - } - - /** - * @brief Returns the index data of the teapot. - * @return The index data of the teapot. - */ - std::vector<uint32_t> getIndices() { - return m_teapotIndices; - } - -private: - - std::vector<float> m_teapotVertices = - { - 0.69999999f, 0.45000005f, 0.00000001f, - 0.69098389f, 0.44999996f, 0.11485600f, - 0.66483200f, 0.45000011f, 0.22332802f, - 0.62288797f, 0.45000002f, 0.32407200f, - 0.56649601f, 0.45000008f, 0.41574404f, - 0.49699998f, 0.45000005f, 0.49700001f, - 0.41574395f, 0.45000005f, 0.56649601f, - 0.32407200f, 0.45000008f, 0.62288797f, - 0.22332799f, 0.45000005f, 0.66483200f, - 0.11485596f, 0.45000005f, 0.69098401f, - 0.00000000f, 0.45000005f, 0.69999999f, - 0.69296241f, 0.46771872f, 0.00000001f, - 0.68403697f, 0.46771869f, 0.11370128f, - 0.65814799f, 0.46771878f, 0.22108276f, - 0.61662567f, 0.46771872f, 0.32081389f, - 0.56080067f, 0.46771872f, 0.41156429f, - 0.49200332f, 0.46771872f, 0.49200332f, - 0.41156423f, 0.46771872f, 0.56080067f, - 0.32081389f, 0.46771872f, 0.61662567f, - 0.22108275f, 0.46771872f, 0.65814799f, - 0.11370124f, 0.46771872f, 0.68403703f, - 0.00000000f, 0.46771872f, 0.69296241f, - 0.69020003f, 0.48150003f, 0.00000001f, - 0.68131018f, 0.48149997f, 0.11324803f, - 0.65552443f, 0.48150006f, 0.22020143f, - 0.61416763f, 0.48150000f, 0.31953502f, - 0.55856514f, 0.48150009f, 0.40992361f, - 0.49004203f, 0.48150003f, 0.49004203f, - 0.40992361f, 0.48150006f, 0.55856514f, - 0.31953505f, 0.48150003f, 0.61416763f, - 0.22020143f, 0.48150003f, 0.65552437f, - 0.11324799f, 0.48150003f, 0.68131030f, - 0.00000000f, 0.48150003f, 0.69020003f, - 0.69111252f, 0.49134374f, 0.00000001f, - 0.68221092f, 0.49134374f, 0.11339775f, - 0.65639102f, 0.49134377f, 0.22049254f, - 0.61497957f, 0.49134377f, 0.31995746f, - 0.55930358f, 0.49134377f, 0.41046557f, - 0.49068987f, 0.49134374f, 0.49068987f, - 0.41046554f, 0.49134374f, 0.55930358f, - 0.31995746f, 0.49134374f, 0.61497957f, - 0.22049253f, 0.49134377f, 0.65639102f, - 0.11339770f, 0.49134374f, 0.68221098f, - 0.00000000f, 0.49134374f, 0.69111252f, - 0.69510001f, 0.49725008f, 0.00000001f, - 0.68614709f, 0.49725005f, 0.11405202f, - 0.66017824f, 0.49725014f, 0.22176473f, - 0.61852777f, 0.49725008f, 0.32180351f, - 0.56253058f, 0.49725008f, 0.41283381f, - 0.49352103f, 0.49725008f, 0.49352100f, - 0.41283381f, 0.49725008f, 0.56253058f, - 0.32180351f, 0.49725008f, 0.61852777f, - 0.22176471f, 0.49725008f, 0.66017818f, - 0.11405198f, 0.49725008f, 0.68614715f, - 0.00000000f, 0.49725008f, 0.69510001f, - 0.70156252f, 0.49921876f, 0.00000001f, - 0.69252634f, 0.49921870f, 0.11511238f, - 0.66631603f, 0.49921876f, 0.22382653f, - 0.62427837f, 0.49921873f, 0.32479537f, - 0.56776059f, 0.49921879f, 0.41667202f, - 0.49810940f, 0.49921876f, 0.49810940f, - 0.41667199f, 0.49921879f, 0.56776053f, - 0.32479542f, 0.49921876f, 0.62427843f, - 0.22382650f, 0.49921876f, 0.66631603f, - 0.11511234f, 0.49921876f, 0.69252640f, - 0.00000000f, 0.49921876f, 0.70156252f, - 0.70989996f, 0.49725002f, 0.00000001f, - 0.70075637f, 0.49724996f, 0.11648039f, - 0.67423457f, 0.49725008f, 0.22648652f, - 0.63169742f, 0.49724999f, 0.32865530f, - 0.57450789f, 0.49725002f, 0.42162383f, - 0.50402898f, 0.49725002f, 0.50402898f, - 0.42162377f, 0.49725002f, 0.57450783f, - 0.32865530f, 0.49725002f, 0.63169742f, - 0.22648649f, 0.49725005f, 0.67423463f, - 0.11648035f, 0.49725002f, 0.70075643f, - 0.00000000f, 0.49725002f, 0.70989996f, - 0.71951252f, 0.49134377f, 0.00000001f, - 0.71024513f, 0.49134374f, 0.11805762f, - 0.68336421f, 0.49134380f, 0.22955328f, - 0.64025098f, 0.49134377f, 0.33310553f, - 0.58228713f, 0.49134383f, 0.42733288f, - 0.51085389f, 0.49134377f, 0.51085389f, - 0.42733288f, 0.49134377f, 0.58228713f, - 0.33310553f, 0.49134377f, 0.64025104f, - 0.22955328f, 0.49134380f, 0.68336427f, - 0.11805756f, 0.49134377f, 0.71024519f, - 0.00000000f, 0.49134377f, 0.71951252f, - 0.72979999f, 0.48150003f, 0.00000001f, - 0.72040009f, 0.48149997f, 0.11974559f, - 0.69313490f, 0.48150006f, 0.23283541f, - 0.64940518f, 0.48150000f, 0.33786824f, - 0.59061253f, 0.48150009f, 0.43344283f, - 0.51815796f, 0.48150003f, 0.51815796f, - 0.43344280f, 0.48150006f, 0.59061259f, - 0.33786821f, 0.48150003f, 0.64940524f, - 0.23283540f, 0.48150003f, 0.69313484f, - 0.11974555f, 0.48150003f, 0.72040015f, - 0.00000000f, 0.48150003f, 0.72979999f, - 0.74016249f, 0.46771878f, 0.00000001f, - 0.73062909f, 0.46771872f, 0.12144586f, - 0.70297670f, 0.46771881f, 0.23614147f, - 0.65862614f, 0.46771878f, 0.34266564f, - 0.59899879f, 0.46771878f, 0.43959734f, - 0.52551538f, 0.46771878f, 0.52551538f, - 0.43959731f, 0.46771878f, 0.59899873f, - 0.34266564f, 0.46771878f, 0.65862620f, - 0.23614144f, 0.46771878f, 0.70297670f, - 0.12144582f, 0.46771878f, 0.73062921f, - 0.00000000f, 0.46771878f, 0.74016249f, - 0.75000000f, 0.45000005f, 0.00000001f, - 0.74033999f, 0.44999996f, 0.12306000f, - 0.71232003f, 0.45000011f, 0.23928000f, - 0.66737998f, 0.45000002f, 0.34721997f, - 0.60696000f, 0.45000008f, 0.44544002f, - 0.53250003f, 0.45000005f, 0.53250003f, - 0.44543999f, 0.45000005f, 0.60696000f, - 0.34722000f, 0.45000008f, 0.66738003f, - 0.23927999f, 0.45000005f, 0.71231997f, - 0.12305996f, 0.45000005f, 0.74033999f, - 0.00000000f, 0.45000005f, 0.75000000f, - 0.00000000f, 0.45000005f, -0.69999999f, - 0.11485599f, 0.44999996f, -0.69098389f, - 0.22332802f, 0.45000011f, -0.66483200f, - 0.32407200f, 0.45000002f, -0.62288797f, - 0.41574404f, 0.45000008f, -0.56649601f, - 0.49700001f, 0.45000005f, -0.49699998f, - 0.56649601f, 0.45000005f, -0.41574395f, - 0.62288797f, 0.45000008f, -0.32407200f, - 0.66483200f, 0.45000005f, -0.22332799f, - 0.69098401f, 0.45000005f, -0.11485595f, - 0.69999999f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.46771872f, -0.69296241f, - 0.11370128f, 0.46771869f, -0.68403697f, - 0.22108276f, 0.46771878f, -0.65814799f, - 0.32081389f, 0.46771872f, -0.61662567f, - 0.41156429f, 0.46771872f, -0.56080067f, - 0.49200332f, 0.46771872f, -0.49200332f, - 0.56080067f, 0.46771872f, -0.41156423f, - 0.61662567f, 0.46771872f, -0.32081389f, - 0.65814799f, 0.46771872f, -0.22108275f, - 0.68403703f, 0.46771872f, -0.11370123f, - 0.69296241f, 0.46771872f, 0.00000001f, - 0.00000000f, 0.48150003f, -0.69020003f, - 0.11324802f, 0.48149997f, -0.68131018f, - 0.22020143f, 0.48150006f, -0.65552443f, - 0.31953502f, 0.48150000f, -0.61416763f, - 0.40992361f, 0.48150009f, -0.55856514f, - 0.49004203f, 0.48150003f, -0.49004203f, - 0.55856514f, 0.48150006f, -0.40992361f, - 0.61416763f, 0.48150003f, -0.31953505f, - 0.65552437f, 0.48150003f, -0.22020143f, - 0.68131030f, 0.48150003f, -0.11324798f, - 0.69020003f, 0.48150003f, 0.00000001f, - 0.00000000f, 0.49134374f, -0.69111252f, - 0.11339774f, 0.49134374f, -0.68221092f, - 0.22049254f, 0.49134377f, -0.65639102f, - 0.31995746f, 0.49134377f, -0.61497957f, - 0.41046557f, 0.49134377f, -0.55930358f, - 0.49068987f, 0.49134374f, -0.49068987f, - 0.55930358f, 0.49134374f, -0.41046554f, - 0.61497957f, 0.49134374f, -0.31995746f, - 0.65639102f, 0.49134377f, -0.22049253f, - 0.68221098f, 0.49134374f, -0.11339770f, - 0.69111252f, 0.49134374f, 0.00000001f, - 0.00000000f, 0.49725008f, -0.69510001f, - 0.11405201f, 0.49725005f, -0.68614709f, - 0.22176473f, 0.49725014f, -0.66017824f, - 0.32180351f, 0.49725008f, -0.61852777f, - 0.41283381f, 0.49725008f, -0.56253058f, - 0.49352100f, 0.49725008f, -0.49352103f, - 0.56253058f, 0.49725008f, -0.41283381f, - 0.61852777f, 0.49725008f, -0.32180351f, - 0.66017818f, 0.49725008f, -0.22176471f, - 0.68614715f, 0.49725008f, -0.11405197f, - 0.69510001f, 0.49725008f, 0.00000001f, - 0.00000000f, 0.49921876f, -0.70156252f, - 0.11511238f, 0.49921870f, -0.69252634f, - 0.22382653f, 0.49921876f, -0.66631603f, - 0.32479537f, 0.49921873f, -0.62427837f, - 0.41667202f, 0.49921879f, -0.56776059f, - 0.49810940f, 0.49921876f, -0.49810940f, - 0.56776053f, 0.49921879f, -0.41667199f, - 0.62427843f, 0.49921876f, -0.32479542f, - 0.66631603f, 0.49921876f, -0.22382650f, - 0.69252640f, 0.49921876f, -0.11511233f, - 0.70156252f, 0.49921876f, 0.00000001f, - 0.00000000f, 0.49725002f, -0.70989996f, - 0.11648039f, 0.49724996f, -0.70075637f, - 0.22648652f, 0.49725008f, -0.67423457f, - 0.32865530f, 0.49724999f, -0.63169742f, - 0.42162383f, 0.49725002f, -0.57450789f, - 0.50402898f, 0.49725002f, -0.50402898f, - 0.57450783f, 0.49725002f, -0.42162377f, - 0.63169742f, 0.49725002f, -0.32865530f, - 0.67423463f, 0.49725005f, -0.22648649f, - 0.70075643f, 0.49725002f, -0.11648034f, - 0.70989996f, 0.49725002f, 0.00000001f, - 0.00000000f, 0.49134377f, -0.71951252f, - 0.11805761f, 0.49134374f, -0.71024513f, - 0.22955328f, 0.49134380f, -0.68336421f, - 0.33310553f, 0.49134377f, -0.64025098f, - 0.42733288f, 0.49134383f, -0.58228713f, - 0.51085389f, 0.49134377f, -0.51085389f, - 0.58228713f, 0.49134377f, -0.42733288f, - 0.64025104f, 0.49134377f, -0.33310553f, - 0.68336427f, 0.49134380f, -0.22955328f, - 0.71024519f, 0.49134377f, -0.11805756f, - 0.71951252f, 0.49134377f, 0.00000001f, - 0.00000000f, 0.48150003f, -0.72979999f, - 0.11974558f, 0.48149997f, -0.72040009f, - 0.23283541f, 0.48150006f, -0.69313490f, - 0.33786824f, 0.48150000f, -0.64940518f, - 0.43344283f, 0.48150009f, -0.59061253f, - 0.51815796f, 0.48150003f, -0.51815796f, - 0.59061259f, 0.48150006f, -0.43344280f, - 0.64940524f, 0.48150003f, -0.33786821f, - 0.69313484f, 0.48150003f, -0.23283540f, - 0.72040015f, 0.48150003f, -0.11974554f, - 0.72979999f, 0.48150003f, 0.00000001f, - 0.00000000f, 0.46771878f, -0.74016249f, - 0.12144586f, 0.46771872f, -0.73062909f, - 0.23614147f, 0.46771881f, -0.70297670f, - 0.34266564f, 0.46771878f, -0.65862614f, - 0.43959734f, 0.46771878f, -0.59899879f, - 0.52551538f, 0.46771878f, -0.52551538f, - 0.59899873f, 0.46771878f, -0.43959731f, - 0.65862620f, 0.46771878f, -0.34266564f, - 0.70297670f, 0.46771878f, -0.23614144f, - 0.73062921f, 0.46771878f, -0.12144581f, - 0.74016249f, 0.46771878f, 0.00000001f, - 0.00000000f, 0.45000005f, -0.75000000f, - 0.12305999f, 0.44999996f, -0.74033999f, - 0.23928000f, 0.45000011f, -0.71232003f, - 0.34721997f, 0.45000002f, -0.66737998f, - 0.44544002f, 0.45000008f, -0.60696000f, - 0.53250003f, 0.45000005f, -0.53250003f, - 0.60696000f, 0.45000005f, -0.44543999f, - 0.66738003f, 0.45000008f, -0.34722000f, - 0.71231997f, 0.45000005f, -0.23927999f, - 0.74033999f, 0.45000005f, -0.12305995f, - 0.75000000f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.45000005f, 0.69999999f, - -0.11485599f, 0.44999996f, 0.69098389f, - -0.22332802f, 0.45000011f, 0.66483200f, - -0.32407200f, 0.45000002f, 0.62288797f, - -0.41574404f, 0.45000008f, 0.56649601f, - -0.49700001f, 0.45000005f, 0.49699998f, - -0.56649601f, 0.45000005f, 0.41574395f, - -0.62288797f, 0.45000008f, 0.32407200f, - -0.66483200f, 0.45000005f, 0.22332799f, - -0.69098401f, 0.45000005f, 0.11485597f, - -0.69999999f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.46771872f, 0.69296241f, - -0.11370128f, 0.46771869f, 0.68403697f, - -0.22108276f, 0.46771878f, 0.65814799f, - -0.32081389f, 0.46771872f, 0.61662567f, - -0.41156429f, 0.46771872f, 0.56080067f, - -0.49200332f, 0.46771872f, 0.49200332f, - -0.56080067f, 0.46771872f, 0.41156423f, - -0.61662567f, 0.46771872f, 0.32081389f, - -0.65814799f, 0.46771872f, 0.22108275f, - -0.68403703f, 0.46771872f, 0.11370125f, - -0.69296241f, 0.46771872f, 0.00000001f, - 0.00000000f, 0.48150003f, 0.69020003f, - -0.11324802f, 0.48149997f, 0.68131018f, - -0.22020143f, 0.48150006f, 0.65552443f, - -0.31953502f, 0.48150000f, 0.61416763f, - -0.40992361f, 0.48150009f, 0.55856514f, - -0.49004203f, 0.48150003f, 0.49004203f, - -0.55856514f, 0.48150006f, 0.40992361f, - -0.61416763f, 0.48150003f, 0.31953505f, - -0.65552437f, 0.48150003f, 0.22020143f, - -0.68131030f, 0.48150003f, 0.11324800f, - -0.69020003f, 0.48150003f, 0.00000001f, - 0.00000000f, 0.49134374f, 0.69111252f, - -0.11339774f, 0.49134374f, 0.68221092f, - -0.22049254f, 0.49134377f, 0.65639102f, - -0.31995746f, 0.49134377f, 0.61497957f, - -0.41046557f, 0.49134377f, 0.55930358f, - -0.49068987f, 0.49134374f, 0.49068987f, - -0.55930358f, 0.49134374f, 0.41046554f, - -0.61497957f, 0.49134374f, 0.31995746f, - -0.65639102f, 0.49134377f, 0.22049253f, - -0.68221098f, 0.49134374f, 0.11339771f, - -0.69111252f, 0.49134374f, 0.00000001f, - 0.00000000f, 0.49725008f, 0.69510001f, - -0.11405201f, 0.49725005f, 0.68614709f, - -0.22176473f, 0.49725014f, 0.66017824f, - -0.32180351f, 0.49725008f, 0.61852777f, - -0.41283381f, 0.49725008f, 0.56253058f, - -0.49352100f, 0.49725008f, 0.49352103f, - -0.56253058f, 0.49725008f, 0.41283381f, - -0.61852777f, 0.49725008f, 0.32180351f, - -0.66017818f, 0.49725008f, 0.22176471f, - -0.68614715f, 0.49725008f, 0.11405198f, - -0.69510001f, 0.49725008f, 0.00000001f, - 0.00000000f, 0.49921876f, 0.70156252f, - -0.11511238f, 0.49921870f, 0.69252634f, - -0.22382653f, 0.49921876f, 0.66631603f, - -0.32479537f, 0.49921873f, 0.62427837f, - -0.41667202f, 0.49921879f, 0.56776059f, - -0.49810940f, 0.49921876f, 0.49810940f, - -0.56776053f, 0.49921879f, 0.41667199f, - -0.62427843f, 0.49921876f, 0.32479542f, - -0.66631603f, 0.49921876f, 0.22382650f, - -0.69252640f, 0.49921876f, 0.11511235f, - -0.70156252f, 0.49921876f, 0.00000001f, - 0.00000000f, 0.49725002f, 0.70989996f, - -0.11648039f, 0.49724996f, 0.70075637f, - -0.22648652f, 0.49725008f, 0.67423457f, - -0.32865530f, 0.49724999f, 0.63169742f, - -0.42162383f, 0.49725002f, 0.57450789f, - -0.50402898f, 0.49725002f, 0.50402898f, - -0.57450783f, 0.49725002f, 0.42162377f, - -0.63169742f, 0.49725002f, 0.32865530f, - -0.67423463f, 0.49725005f, 0.22648649f, - -0.70075643f, 0.49725002f, 0.11648036f, - -0.70989996f, 0.49725002f, 0.00000001f, - 0.00000000f, 0.49134377f, 0.71951252f, - -0.11805761f, 0.49134374f, 0.71024513f, - -0.22955328f, 0.49134380f, 0.68336421f, - -0.33310553f, 0.49134377f, 0.64025098f, - -0.42733288f, 0.49134383f, 0.58228713f, - -0.51085389f, 0.49134377f, 0.51085389f, - -0.58228713f, 0.49134377f, 0.42733288f, - -0.64025104f, 0.49134377f, 0.33310553f, - -0.68336427f, 0.49134380f, 0.22955328f, - -0.71024519f, 0.49134377f, 0.11805757f, - -0.71951252f, 0.49134377f, 0.00000001f, - 0.00000000f, 0.48150003f, 0.72979999f, - -0.11974558f, 0.48149997f, 0.72040009f, - -0.23283541f, 0.48150006f, 0.69313490f, - -0.33786824f, 0.48150000f, 0.64940518f, - -0.43344283f, 0.48150009f, 0.59061253f, - -0.51815796f, 0.48150003f, 0.51815796f, - -0.59061259f, 0.48150006f, 0.43344280f, - -0.64940524f, 0.48150003f, 0.33786821f, - -0.69313484f, 0.48150003f, 0.23283540f, - -0.72040015f, 0.48150003f, 0.11974555f, - -0.72979999f, 0.48150003f, 0.00000001f, - 0.00000000f, 0.46771878f, 0.74016249f, - -0.12144586f, 0.46771872f, 0.73062909f, - -0.23614147f, 0.46771881f, 0.70297670f, - -0.34266564f, 0.46771878f, 0.65862614f, - -0.43959734f, 0.46771878f, 0.59899879f, - -0.52551538f, 0.46771878f, 0.52551538f, - -0.59899873f, 0.46771878f, 0.43959731f, - -0.65862620f, 0.46771878f, 0.34266564f, - -0.70297670f, 0.46771878f, 0.23614144f, - -0.73062921f, 0.46771878f, 0.12144583f, - -0.74016249f, 0.46771878f, 0.00000001f, - 0.00000000f, 0.45000005f, 0.75000000f, - -0.12305999f, 0.44999996f, 0.74033999f, - -0.23928000f, 0.45000011f, 0.71232003f, - -0.34721997f, 0.45000002f, 0.66737998f, - -0.44544002f, 0.45000008f, 0.60696000f, - -0.53250003f, 0.45000005f, 0.53250003f, - -0.60696000f, 0.45000005f, 0.44543999f, - -0.66738003f, 0.45000008f, 0.34722000f, - -0.71231997f, 0.45000005f, 0.23927999f, - -0.74033999f, 0.45000005f, 0.12305997f, - -0.75000000f, 0.45000005f, 0.00000001f, - -0.69999999f, 0.45000005f, 0.00000001f, - -0.69098389f, 0.44999996f, -0.11485598f, - -0.66483200f, 0.45000011f, -0.22332802f, - -0.62288797f, 0.45000002f, -0.32407200f, - -0.56649601f, 0.45000008f, -0.41574404f, - -0.49699998f, 0.45000005f, -0.49700001f, - -0.41574395f, 0.45000005f, -0.56649601f, - -0.32407200f, 0.45000008f, -0.62288797f, - -0.22332799f, 0.45000005f, -0.66483200f, - -0.11485596f, 0.45000005f, -0.69098401f, - 0.00000000f, 0.45000005f, -0.69999999f, - -0.69296241f, 0.46771872f, 0.00000001f, - -0.68403697f, 0.46771869f, -0.11370127f, - -0.65814799f, 0.46771878f, -0.22108276f, - -0.61662567f, 0.46771872f, -0.32081389f, - -0.56080067f, 0.46771872f, -0.41156429f, - -0.49200332f, 0.46771872f, -0.49200332f, - -0.41156423f, 0.46771872f, -0.56080067f, - -0.32081389f, 0.46771872f, -0.61662567f, - -0.22108275f, 0.46771872f, -0.65814799f, - -0.11370124f, 0.46771872f, -0.68403703f, - 0.00000000f, 0.46771872f, -0.69296241f, - -0.69020003f, 0.48150003f, 0.00000001f, - -0.68131018f, 0.48149997f, -0.11324801f, - -0.65552443f, 0.48150006f, -0.22020143f, - -0.61416763f, 0.48150000f, -0.31953502f, - -0.55856514f, 0.48150009f, -0.40992361f, - -0.49004203f, 0.48150003f, -0.49004203f, - -0.40992361f, 0.48150006f, -0.55856514f, - -0.31953505f, 0.48150003f, -0.61416763f, - -0.22020143f, 0.48150003f, -0.65552437f, - -0.11324799f, 0.48150003f, -0.68131030f, - 0.00000000f, 0.48150003f, -0.69020003f, - -0.69111252f, 0.49134374f, 0.00000001f, - -0.68221092f, 0.49134374f, -0.11339773f, - -0.65639102f, 0.49134377f, -0.22049254f, - -0.61497957f, 0.49134377f, -0.31995746f, - -0.55930358f, 0.49134377f, -0.41046557f, - -0.49068987f, 0.49134374f, -0.49068987f, - -0.41046554f, 0.49134374f, -0.55930358f, - -0.31995746f, 0.49134374f, -0.61497957f, - -0.22049253f, 0.49134377f, -0.65639102f, - -0.11339770f, 0.49134374f, -0.68221098f, - 0.00000000f, 0.49134374f, -0.69111252f, - -0.69510001f, 0.49725008f, 0.00000001f, - -0.68614709f, 0.49725005f, -0.11405201f, - -0.66017824f, 0.49725014f, -0.22176473f, - -0.61852777f, 0.49725008f, -0.32180351f, - -0.56253058f, 0.49725008f, -0.41283381f, - -0.49352103f, 0.49725008f, -0.49352100f, - -0.41283381f, 0.49725008f, -0.56253058f, - -0.32180351f, 0.49725008f, -0.61852777f, - -0.22176471f, 0.49725008f, -0.66017818f, - -0.11405198f, 0.49725008f, -0.68614715f, - 0.00000000f, 0.49725008f, -0.69510001f, - -0.70156252f, 0.49921876f, 0.00000001f, - -0.69252634f, 0.49921870f, -0.11511236f, - -0.66631603f, 0.49921876f, -0.22382653f, - -0.62427837f, 0.49921873f, -0.32479537f, - -0.56776059f, 0.49921879f, -0.41667202f, - -0.49810940f, 0.49921876f, -0.49810940f, - -0.41667199f, 0.49921879f, -0.56776053f, - -0.32479542f, 0.49921876f, -0.62427843f, - -0.22382650f, 0.49921876f, -0.66631603f, - -0.11511234f, 0.49921876f, -0.69252640f, - 0.00000000f, 0.49921876f, -0.70156252f, - -0.70989996f, 0.49725002f, 0.00000001f, - -0.70075637f, 0.49724996f, -0.11648037f, - -0.67423457f, 0.49725008f, -0.22648652f, - -0.63169742f, 0.49724999f, -0.32865530f, - -0.57450789f, 0.49725002f, -0.42162383f, - -0.50402898f, 0.49725002f, -0.50402898f, - -0.42162377f, 0.49725002f, -0.57450783f, - -0.32865530f, 0.49725002f, -0.63169742f, - -0.22648649f, 0.49725005f, -0.67423463f, - -0.11648035f, 0.49725002f, -0.70075643f, - 0.00000000f, 0.49725002f, -0.70989996f, - -0.71951252f, 0.49134377f, 0.00000001f, - -0.71024513f, 0.49134374f, -0.11805760f, - -0.68336421f, 0.49134380f, -0.22955328f, - -0.64025098f, 0.49134377f, -0.33310553f, - -0.58228713f, 0.49134383f, -0.42733288f, - -0.51085389f, 0.49134377f, -0.51085389f, - -0.42733288f, 0.49134377f, -0.58228713f, - -0.33310553f, 0.49134377f, -0.64025104f, - -0.22955328f, 0.49134380f, -0.68336427f, - -0.11805756f, 0.49134377f, -0.71024519f, - 0.00000000f, 0.49134377f, -0.71951252f, - -0.72979999f, 0.48150003f, 0.00000001f, - -0.72040009f, 0.48149997f, -0.11974557f, - -0.69313490f, 0.48150006f, -0.23283541f, - -0.64940518f, 0.48150000f, -0.33786824f, - -0.59061253f, 0.48150009f, -0.43344283f, - -0.51815796f, 0.48150003f, -0.51815796f, - -0.43344280f, 0.48150006f, -0.59061259f, - -0.33786821f, 0.48150003f, -0.64940524f, - -0.23283540f, 0.48150003f, -0.69313484f, - -0.11974555f, 0.48150003f, -0.72040015f, - 0.00000000f, 0.48150003f, -0.72979999f, - -0.74016249f, 0.46771878f, 0.00000001f, - -0.73062909f, 0.46771872f, -0.12144585f, - -0.70297670f, 0.46771881f, -0.23614147f, - -0.65862614f, 0.46771878f, -0.34266564f, - -0.59899879f, 0.46771878f, -0.43959734f, - -0.52551538f, 0.46771878f, -0.52551538f, - -0.43959731f, 0.46771878f, -0.59899873f, - -0.34266564f, 0.46771878f, -0.65862620f, - -0.23614144f, 0.46771878f, -0.70297670f, - -0.12144582f, 0.46771878f, -0.73062921f, - 0.00000000f, 0.46771878f, -0.74016249f, - -0.75000000f, 0.45000005f, 0.00000001f, - -0.74033999f, 0.44999996f, -0.12305998f, - -0.71232003f, 0.45000011f, -0.23928000f, - -0.66737998f, 0.45000002f, -0.34721997f, - -0.60696000f, 0.45000008f, -0.44544002f, - -0.53250003f, 0.45000005f, -0.53250003f, - -0.44543999f, 0.45000005f, -0.60696000f, - -0.34722000f, 0.45000008f, -0.66738003f, - -0.23927999f, 0.45000005f, -0.71231997f, - -0.12305996f, 0.45000005f, -0.74033999f, - 0.00000000f, 0.45000005f, -0.75000000f, - 0.75000000f, 0.45000005f, 0.00000001f, - 0.74033999f, 0.44999996f, 0.12306000f, - 0.71232003f, 0.45000011f, 0.23928000f, - 0.66737998f, 0.45000002f, 0.34721997f, - 0.60696000f, 0.45000008f, 0.44544002f, - 0.53250003f, 0.45000005f, 0.53250003f, - 0.44543999f, 0.45000005f, 0.60696000f, - 0.34722000f, 0.45000008f, 0.66738003f, - 0.23927999f, 0.45000005f, 0.71231997f, - 0.12305996f, 0.45000005f, 0.74033999f, - 0.00000000f, 0.45000005f, 0.75000000f, - 0.78737491f, 0.37128749f, 0.00000000f, - 0.77723348f, 0.37128747f, 0.12919247f, - 0.74781722f, 0.37128752f, 0.25120407f, - 0.70063770f, 0.37128749f, 0.36452308f, - 0.63720679f, 0.37128752f, 0.46763775f, - 0.55903620f, 0.37128749f, 0.55903620f, - 0.46763766f, 0.37128749f, 0.63720679f, - 0.36452311f, 0.37128749f, 0.70063770f, - 0.25120407f, 0.37128752f, 0.74781728f, - 0.12919241f, 0.37128749f, 0.77723348f, - 0.00000000f, 0.37128749f, 0.78737491f, - 0.82400006f, 0.29280004f, 0.00000000f, - 0.81338686f, 0.29280004f, 0.13520193f, - 0.78260237f, 0.29280004f, 0.26288900f, - 0.73322815f, 0.29280004f, 0.38147905f, - 0.66684681f, 0.29280004f, 0.48939016f, - 0.58504003f, 0.29280001f, 0.58504003f, - 0.48939011f, 0.29280004f, 0.66684675f, - 0.38147908f, 0.29280007f, 0.73322821f, - 0.26288897f, 0.29280004f, 0.78260231f, - 0.13520187f, 0.29280004f, 0.81338698f, - 0.00000000f, 0.29280004f, 0.82400006f, - 0.85912502f, 0.21476251f, 0.00000000f, - 0.84805942f, 0.21476249f, 0.14096522f, - 0.81596267f, 0.21476252f, 0.27409527f, - 0.76448381f, 0.21476249f, 0.39774051f, - 0.69527274f, 0.21476252f, 0.51025152f, - 0.60997874f, 0.21476251f, 0.60997874f, - 0.51025152f, 0.21476251f, 0.69527274f, - 0.39774054f, 0.21476251f, 0.76448381f, - 0.27409524f, 0.21476251f, 0.81596261f, - 0.14096518f, 0.21476251f, 0.84805954f, - 0.00000000f, 0.21476251f, 0.85912502f, - 0.89200008f, 0.13740003f, 0.00000000f, - 0.88051099f, 0.13740002f, 0.14635937f, - 0.84718603f, 0.13740005f, 0.28458369f, - 0.79373735f, 0.13740002f, 0.41296035f, - 0.72187787f, 0.13740005f, 0.52977669f, - 0.63332003f, 0.13740002f, 0.63332003f, - 0.52977669f, 0.13740002f, 0.72187781f, - 0.41296035f, 0.13740002f, 0.79373741f, - 0.28458369f, 0.13740000f, 0.84718597f, - 0.14635932f, 0.13740000f, 0.88051111f, - 0.00000000f, 0.13740000f, 0.89200008f, - 0.92187500f, 0.06093751f, 0.00000000f, - 0.91000110f, 0.06093750f, 0.15126126f, - 0.87556010f, 0.06093751f, 0.29411504f, - 0.82032120f, 0.06093750f, 0.42679128f, - 0.74605507f, 0.06093750f, 0.54752004f, - 0.65453124f, 0.06093751f, 0.65453124f, - 0.54751998f, 0.06093750f, 0.74605501f, - 0.42679128f, 0.06093750f, 0.82032126f, - 0.29411501f, 0.06093750f, 0.87556005f, - 0.15126120f, 0.06093750f, 0.91000128f, - 0.00000000f, 0.06093750f, 0.92187500f, - 0.94800001f, -0.01440001f, -0.00000000f, - 0.93578976f, -0.01440001f, 0.15554784f, - 0.90037251f, -0.01440001f, 0.30244994f, - 0.84356833f, -0.01440001f, 0.43888608f, - 0.76719749f, -0.01440001f, 0.56303620f, - 0.67308003f, -0.01440001f, 0.67308003f, - 0.56303614f, -0.01440002f, 0.76719743f, - 0.43888611f, -0.01440002f, 0.84356833f, - 0.30244991f, -0.01440002f, 0.90037251f, - 0.15554780f, -0.01440002f, 0.93578976f, - 0.00000000f, -0.01440002f, 0.94800001f, - 0.96962506f, -0.08838750f, -0.00000000f, - 0.95713621f, -0.08838749f, 0.15909605f, - 0.92091113f, -0.08838750f, 0.30934918f, - 0.86281121f, -0.08838750f, 0.44889757f, - 0.78469825f, -0.08838750f, 0.57587969f, - 0.68843377f, -0.08838750f, 0.68843377f, - 0.57587969f, -0.08838750f, 0.78469819f, - 0.44889760f, -0.08838750f, 0.86281121f, - 0.30934915f, -0.08838750f, 0.92091107f, - 0.15909600f, -0.08838750f, 0.95713627f, - 0.00000000f, -0.08838750f, 0.96962506f, - 0.98600000f, -0.16080001f, -0.00000000f, - 0.97330022f, -0.16080000f, 0.16178288f, - 0.93646342f, -0.16080002f, 0.31457347f, - 0.87738222f, -0.16080001f, 0.45647857f, - 0.79795015f, -0.16080002f, 0.58560514f, - 0.70006001f, -0.16080001f, 0.70006001f, - 0.58560514f, -0.16080001f, 0.79795015f, - 0.45647860f, -0.16080001f, 0.87738228f, - 0.31457344f, -0.16080001f, 0.93646336f, - 0.16178282f, -0.16080001f, 0.97330034f, - 0.00000000f, -0.16080001f, 0.98600000f, - 0.99637496f, -0.23141253f, -0.00000000f, - 0.98354161f, -0.23141250f, 0.16348520f, - 0.94631720f, -0.23141254f, 0.31788349f, - 0.88661432f, -0.23141253f, 0.46128178f, - 0.80634636f, -0.23141254f, 0.59176707f, - 0.70742619f, -0.23141253f, 0.70742619f, - 0.59176701f, -0.23141253f, 0.80634630f, - 0.46128178f, -0.23141253f, 0.88661432f, - 0.31788346f, -0.23141253f, 0.94631708f, - 0.16348514f, -0.23141253f, 0.98354173f, - 0.00000000f, -0.23141253f, 0.99637496f, - 1.00000000f, -0.30000001f, -0.00000000f, - 0.98711991f, -0.29999998f, 0.16407999f, - 0.94976002f, -0.30000004f, 0.31904000f, - 0.88984001f, -0.30000004f, 0.46296000f, - 0.80928004f, -0.30000001f, 0.59392005f, - 0.71000004f, -0.30000001f, 0.71000004f, - 0.59391999f, -0.30000001f, 0.80928004f, - 0.46296003f, -0.30000001f, 0.88984001f, - 0.31904000f, -0.30000001f, 0.94976002f, - 0.16407993f, -0.30000001f, 0.98712003f, - 0.00000000f, -0.30000001f, 1.00000000f, - 0.00000000f, 0.45000005f, -0.75000000f, - 0.12305999f, 0.44999996f, -0.74033999f, - 0.23928000f, 0.45000011f, -0.71232003f, - 0.34721997f, 0.45000002f, -0.66737998f, - 0.44544002f, 0.45000008f, -0.60696000f, - 0.53250003f, 0.45000005f, -0.53250003f, - 0.60696000f, 0.45000005f, -0.44543999f, - 0.66738003f, 0.45000008f, -0.34722000f, - 0.71231997f, 0.45000005f, -0.23927999f, - 0.74033999f, 0.45000005f, -0.12305995f, - 0.75000000f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.37128749f, -0.78737491f, - 0.12919247f, 0.37128747f, -0.77723348f, - 0.25120407f, 0.37128752f, -0.74781722f, - 0.36452308f, 0.37128749f, -0.70063770f, - 0.46763775f, 0.37128752f, -0.63720679f, - 0.55903620f, 0.37128749f, -0.55903620f, - 0.63720679f, 0.37128749f, -0.46763766f, - 0.70063770f, 0.37128749f, -0.36452311f, - 0.74781728f, 0.37128752f, -0.25120407f, - 0.77723348f, 0.37128749f, -0.12919241f, - 0.78737491f, 0.37128749f, 0.00000000f, - 0.00000000f, 0.29280004f, -0.82400006f, - 0.13520193f, 0.29280004f, -0.81338686f, - 0.26288900f, 0.29280004f, -0.78260237f, - 0.38147905f, 0.29280004f, -0.73322815f, - 0.48939016f, 0.29280004f, -0.66684681f, - 0.58504003f, 0.29280001f, -0.58504003f, - 0.66684675f, 0.29280004f, -0.48939011f, - 0.73322821f, 0.29280007f, -0.38147908f, - 0.78260231f, 0.29280004f, -0.26288897f, - 0.81338698f, 0.29280004f, -0.13520187f, - 0.82400006f, 0.29280004f, 0.00000000f, - 0.00000000f, 0.21476251f, -0.85912502f, - 0.14096522f, 0.21476249f, -0.84805942f, - 0.27409527f, 0.21476252f, -0.81596267f, - 0.39774051f, 0.21476249f, -0.76448381f, - 0.51025152f, 0.21476252f, -0.69527274f, - 0.60997874f, 0.21476251f, -0.60997874f, - 0.69527274f, 0.21476251f, -0.51025152f, - 0.76448381f, 0.21476251f, -0.39774054f, - 0.81596261f, 0.21476251f, -0.27409524f, - 0.84805954f, 0.21476251f, -0.14096518f, - 0.85912502f, 0.21476251f, 0.00000000f, - 0.00000000f, 0.13740005f, -0.89200008f, - 0.14635937f, 0.13740005f, -0.88051099f, - 0.28458369f, 0.13740005f, -0.84718603f, - 0.41296035f, 0.13740005f, -0.79373735f, - 0.52977669f, 0.13740005f, -0.72187787f, - 0.63332003f, 0.13740003f, -0.63332003f, - 0.72187781f, 0.13740003f, -0.52977669f, - 0.79373741f, 0.13740005f, -0.41296035f, - 0.84718597f, 0.13740003f, -0.28458369f, - 0.88051111f, 0.13740003f, -0.14635932f, - 0.89200008f, 0.13740003f, 0.00000000f, - 0.00000000f, 0.06093752f, -0.92187500f, - 0.15126126f, 0.06093751f, -0.91000110f, - 0.29411504f, 0.06093752f, -0.87556010f, - 0.42679128f, 0.06093752f, -0.82032120f, - 0.54752004f, 0.06093752f, -0.74605507f, - 0.65453124f, 0.06093752f, -0.65453124f, - 0.74605501f, 0.06093752f, -0.54751998f, - 0.82032126f, 0.06093751f, -0.42679128f, - 0.87556005f, 0.06093752f, -0.29411501f, - 0.91000128f, 0.06093751f, -0.15126120f, - 0.92187500f, 0.06093751f, 0.00000000f, - 0.00000000f, -0.01440000f, -0.94800001f, - 0.15554784f, -0.01440000f, -0.93578976f, - 0.30244994f, -0.01440000f, -0.90037251f, - 0.43888608f, -0.01440000f, -0.84356833f, - 0.56303620f, -0.01440000f, -0.76719749f, - 0.67308003f, -0.01440000f, -0.67308003f, - 0.76719743f, -0.01440001f, -0.56303614f, - 0.84356833f, -0.01440001f, -0.43888611f, - 0.90037251f, -0.01440001f, -0.30244991f, - 0.93578976f, -0.01440001f, -0.15554780f, - 0.94800001f, -0.01440001f, -0.00000000f, - 0.00000000f, -0.08838749f, -0.96962506f, - 0.15909605f, -0.08838748f, -0.95713621f, - 0.30934918f, -0.08838750f, -0.92091113f, - 0.44889757f, -0.08838750f, -0.86281121f, - 0.57587969f, -0.08838750f, -0.78469825f, - 0.68843377f, -0.08838749f, -0.68843377f, - 0.78469819f, -0.08838750f, -0.57587969f, - 0.86281121f, -0.08838750f, -0.44889760f, - 0.92091107f, -0.08838750f, -0.30934915f, - 0.95713627f, -0.08838749f, -0.15909600f, - 0.96962506f, -0.08838750f, -0.00000000f, - 0.00000000f, -0.16080000f, -0.98600000f, - 0.16178288f, -0.16079998f, -0.97330022f, - 0.31457347f, -0.16080001f, -0.93646342f, - 0.45647857f, -0.16080000f, -0.87738222f, - 0.58560514f, -0.16080001f, -0.79795015f, - 0.70006001f, -0.16080000f, -0.70006001f, - 0.79795015f, -0.16080000f, -0.58560514f, - 0.87738228f, -0.16080001f, -0.45647860f, - 0.93646336f, -0.16080001f, -0.31457344f, - 0.97330034f, -0.16080001f, -0.16178282f, - 0.98600000f, -0.16080001f, -0.00000000f, - 0.00000000f, -0.23141253f, -0.99637496f, - 0.16348520f, -0.23141250f, -0.98354161f, - 0.31788349f, -0.23141254f, -0.94631720f, - 0.46128178f, -0.23141253f, -0.88661432f, - 0.59176707f, -0.23141254f, -0.80634636f, - 0.70742619f, -0.23141253f, -0.70742619f, - 0.80634630f, -0.23141253f, -0.59176701f, - 0.88661432f, -0.23141253f, -0.46128178f, - 0.94631708f, -0.23141253f, -0.31788346f, - 0.98354173f, -0.23141253f, -0.16348514f, - 0.99637496f, -0.23141253f, -0.00000000f, - 0.00000000f, -0.30000001f, -1.00000000f, - 0.16407999f, -0.29999998f, -0.98711991f, - 0.31904000f, -0.30000004f, -0.94976002f, - 0.46296000f, -0.30000004f, -0.88984001f, - 0.59392005f, -0.30000001f, -0.80928004f, - 0.71000004f, -0.30000001f, -0.71000004f, - 0.80928004f, -0.30000001f, -0.59391999f, - 0.88984001f, -0.30000001f, -0.46296003f, - 0.94976002f, -0.30000001f, -0.31904000f, - 0.98712003f, -0.30000001f, -0.16407993f, - 1.00000000f, -0.30000001f, -0.00000000f, - 0.00000000f, 0.45000005f, 0.75000000f, - -0.12305999f, 0.44999996f, 0.74033999f, - -0.23928000f, 0.45000011f, 0.71232003f, - -0.34721997f, 0.45000002f, 0.66737998f, - -0.44544002f, 0.45000008f, 0.60696000f, - -0.53250003f, 0.45000005f, 0.53250003f, - -0.60696000f, 0.45000005f, 0.44543999f, - -0.66738003f, 0.45000008f, 0.34722000f, - -0.71231997f, 0.45000005f, 0.23927999f, - -0.74033999f, 0.45000005f, 0.12305997f, - -0.75000000f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.37128749f, 0.78737491f, - -0.12919247f, 0.37128747f, 0.77723348f, - -0.25120407f, 0.37128752f, 0.74781722f, - -0.36452308f, 0.37128749f, 0.70063770f, - -0.46763775f, 0.37128752f, 0.63720679f, - -0.55903620f, 0.37128749f, 0.55903620f, - -0.63720679f, 0.37128749f, 0.46763766f, - -0.70063770f, 0.37128749f, 0.36452311f, - -0.74781728f, 0.37128752f, 0.25120407f, - -0.77723348f, 0.37128749f, 0.12919241f, - -0.78737491f, 0.37128749f, 0.00000000f, - 0.00000000f, 0.29280004f, 0.82400006f, - -0.13520193f, 0.29280004f, 0.81338686f, - -0.26288900f, 0.29280004f, 0.78260237f, - -0.38147905f, 0.29280004f, 0.73322815f, - -0.48939016f, 0.29280004f, 0.66684681f, - -0.58504003f, 0.29280001f, 0.58504003f, - -0.66684675f, 0.29280004f, 0.48939011f, - -0.73322821f, 0.29280007f, 0.38147908f, - -0.78260231f, 0.29280004f, 0.26288897f, - -0.81338698f, 0.29280004f, 0.13520187f, - -0.82400006f, 0.29280004f, 0.00000000f, - 0.00000000f, 0.21476251f, 0.85912502f, - -0.14096522f, 0.21476249f, 0.84805942f, - -0.27409527f, 0.21476252f, 0.81596267f, - -0.39774051f, 0.21476249f, 0.76448381f, - -0.51025152f, 0.21476252f, 0.69527274f, - -0.60997874f, 0.21476251f, 0.60997874f, - -0.69527274f, 0.21476251f, 0.51025152f, - -0.76448381f, 0.21476251f, 0.39774054f, - -0.81596261f, 0.21476251f, 0.27409524f, - -0.84805954f, 0.21476251f, 0.14096518f, - -0.85912502f, 0.21476251f, 0.00000000f, - 0.00000000f, 0.13740000f, 0.89200008f, - -0.14635937f, 0.13740000f, 0.88051099f, - -0.28458369f, 0.13740002f, 0.84718603f, - -0.41296035f, 0.13740002f, 0.79373735f, - -0.52977669f, 0.13740002f, 0.72187787f, - -0.63332003f, 0.13740002f, 0.63332003f, - -0.72187781f, 0.13740002f, 0.52977669f, - -0.79373741f, 0.13740003f, 0.41296035f, - -0.84718597f, 0.13740003f, 0.28458369f, - -0.88051111f, 0.13740003f, 0.14635932f, - -0.89200008f, 0.13740003f, 0.00000000f, - 0.00000000f, 0.06093750f, 0.92187500f, - -0.15126126f, 0.06093750f, 0.91000110f, - -0.29411504f, 0.06093751f, 0.87556010f, - -0.42679128f, 0.06093750f, 0.82032120f, - -0.54752004f, 0.06093750f, 0.74605507f, - -0.65453124f, 0.06093750f, 0.65453124f, - -0.74605501f, 0.06093750f, 0.54751998f, - -0.82032126f, 0.06093751f, 0.42679128f, - -0.87556005f, 0.06093751f, 0.29411501f, - -0.91000128f, 0.06093751f, 0.15126120f, - -0.92187500f, 0.06093751f, 0.00000000f, - 0.00000000f, -0.01440002f, 0.94800001f, - -0.15554784f, -0.01440002f, 0.93578976f, - -0.30244994f, -0.01440002f, 0.90037251f, - -0.43888608f, -0.01440002f, 0.84356833f, - -0.56303620f, -0.01440002f, 0.76719749f, - -0.67308003f, -0.01440001f, 0.67308003f, - -0.76719743f, -0.01440001f, 0.56303614f, - -0.84356833f, -0.01440001f, 0.43888611f, - -0.90037251f, -0.01440001f, 0.30244991f, - -0.93578976f, -0.01440001f, 0.15554780f, - -0.94800001f, -0.01440001f, -0.00000000f, - 0.00000000f, -0.08838750f, 0.96962506f, - -0.15909605f, -0.08838750f, 0.95713621f, - -0.30934918f, -0.08838750f, 0.92091113f, - -0.44889757f, -0.08838750f, 0.86281121f, - -0.57587969f, -0.08838751f, 0.78469825f, - -0.68843377f, -0.08838750f, 0.68843377f, - -0.78469819f, -0.08838750f, 0.57587969f, - -0.86281121f, -0.08838750f, 0.44889760f, - -0.92091107f, -0.08838750f, 0.30934915f, - -0.95713627f, -0.08838750f, 0.15909600f, - -0.96962506f, -0.08838750f, -0.00000000f, - 0.00000000f, -0.16080001f, 0.98600000f, - -0.16178288f, -0.16080000f, 0.97330022f, - -0.31457347f, -0.16080002f, 0.93646342f, - -0.45647857f, -0.16080001f, 0.87738222f, - -0.58560514f, -0.16080002f, 0.79795015f, - -0.70006001f, -0.16080001f, 0.70006001f, - -0.79795015f, -0.16080001f, 0.58560514f, - -0.87738228f, -0.16080001f, 0.45647860f, - -0.93646336f, -0.16080001f, 0.31457344f, - -0.97330034f, -0.16080001f, 0.16178282f, - -0.98600000f, -0.16080001f, -0.00000000f, - 0.00000000f, -0.23141253f, 0.99637496f, - -0.16348520f, -0.23141250f, 0.98354161f, - -0.31788349f, -0.23141254f, 0.94631720f, - -0.46128178f, -0.23141253f, 0.88661432f, - -0.59176707f, -0.23141254f, 0.80634636f, - -0.70742619f, -0.23141253f, 0.70742619f, - -0.80634630f, -0.23141253f, 0.59176701f, - -0.88661432f, -0.23141253f, 0.46128178f, - -0.94631708f, -0.23141253f, 0.31788346f, - -0.98354173f, -0.23141253f, 0.16348514f, - -0.99637496f, -0.23141253f, -0.00000000f, - 0.00000000f, -0.30000001f, 1.00000000f, - -0.16407999f, -0.29999998f, 0.98711991f, - -0.31904000f, -0.30000004f, 0.94976002f, - -0.46296000f, -0.30000004f, 0.88984001f, - -0.59392005f, -0.30000001f, 0.80928004f, - -0.71000004f, -0.30000001f, 0.71000004f, - -0.80928004f, -0.30000001f, 0.59391999f, - -0.88984001f, -0.30000001f, 0.46296003f, - -0.94976002f, -0.30000001f, 0.31904000f, - -0.98712003f, -0.30000001f, 0.16407993f, - -1.00000000f, -0.30000001f, -0.00000000f, - -0.75000000f, 0.45000005f, 0.00000001f, - -0.74033999f, 0.44999996f, -0.12305998f, - -0.71232003f, 0.45000011f, -0.23928000f, - -0.66737998f, 0.45000002f, -0.34721997f, - -0.60696000f, 0.45000008f, -0.44544002f, - -0.53250003f, 0.45000005f, -0.53250003f, - -0.44543999f, 0.45000005f, -0.60696000f, - -0.34722000f, 0.45000008f, -0.66738003f, - -0.23927999f, 0.45000005f, -0.71231997f, - -0.12305996f, 0.45000005f, -0.74033999f, - 0.00000000f, 0.45000005f, -0.75000000f, - -0.78737491f, 0.37128749f, 0.00000000f, - -0.77723348f, 0.37128747f, -0.12919247f, - -0.74781722f, 0.37128752f, -0.25120407f, - -0.70063770f, 0.37128749f, -0.36452308f, - -0.63720679f, 0.37128752f, -0.46763775f, - -0.55903620f, 0.37128749f, -0.55903620f, - -0.46763766f, 0.37128749f, -0.63720679f, - -0.36452311f, 0.37128749f, -0.70063770f, - -0.25120407f, 0.37128752f, -0.74781728f, - -0.12919241f, 0.37128749f, -0.77723348f, - 0.00000000f, 0.37128749f, -0.78737491f, - -0.82400006f, 0.29280004f, 0.00000000f, - -0.81338686f, 0.29280004f, -0.13520193f, - -0.78260237f, 0.29280004f, -0.26288900f, - -0.73322815f, 0.29280004f, -0.38147905f, - -0.66684681f, 0.29280004f, -0.48939016f, - -0.58504003f, 0.29280001f, -0.58504003f, - -0.48939011f, 0.29280004f, -0.66684675f, - -0.38147908f, 0.29280007f, -0.73322821f, - -0.26288897f, 0.29280004f, -0.78260231f, - -0.13520187f, 0.29280004f, -0.81338698f, - 0.00000000f, 0.29280004f, -0.82400006f, - -0.85912502f, 0.21476251f, 0.00000000f, - -0.84805942f, 0.21476249f, -0.14096522f, - -0.81596267f, 0.21476252f, -0.27409527f, - -0.76448381f, 0.21476249f, -0.39774051f, - -0.69527274f, 0.21476252f, -0.51025152f, - -0.60997874f, 0.21476251f, -0.60997874f, - -0.51025152f, 0.21476251f, -0.69527274f, - -0.39774054f, 0.21476251f, -0.76448381f, - -0.27409524f, 0.21476251f, -0.81596261f, - -0.14096518f, 0.21476251f, -0.84805954f, - 0.00000000f, 0.21476251f, -0.85912502f, - -0.89200008f, 0.13740003f, 0.00000000f, - -0.88051099f, 0.13740003f, -0.14635937f, - -0.84718603f, 0.13740005f, -0.28458369f, - -0.79373735f, 0.13740005f, -0.41296035f, - -0.72187787f, 0.13740005f, -0.52977669f, - -0.63332003f, 0.13740005f, -0.63332003f, - -0.52977669f, 0.13740005f, -0.72187781f, - -0.41296035f, 0.13740005f, -0.79373741f, - -0.28458369f, 0.13740005f, -0.84718597f, - -0.14635932f, 0.13740005f, -0.88051111f, - 0.00000000f, 0.13740005f, -0.89200008f, - -0.92187500f, 0.06093751f, 0.00000000f, - -0.91000110f, 0.06093751f, -0.15126126f, - -0.87556010f, 0.06093752f, -0.29411504f, - -0.82032120f, 0.06093751f, -0.42679128f, - -0.74605507f, 0.06093752f, -0.54752004f, - -0.65453124f, 0.06093752f, -0.65453124f, - -0.54751998f, 0.06093752f, -0.74605501f, - -0.42679128f, 0.06093752f, -0.82032126f, - -0.29411501f, 0.06093752f, -0.87556005f, - -0.15126120f, 0.06093752f, -0.91000128f, - 0.00000000f, 0.06093752f, -0.92187500f, - -0.94800001f, -0.01440001f, -0.00000000f, - -0.93578976f, -0.01440001f, -0.15554784f, - -0.90037251f, -0.01440001f, -0.30244994f, - -0.84356833f, -0.01440001f, -0.43888608f, - -0.76719749f, -0.01440001f, -0.56303620f, - -0.67308003f, -0.01440000f, -0.67308003f, - -0.56303614f, -0.01440000f, -0.76719743f, - -0.43888611f, -0.01440000f, -0.84356833f, - -0.30244991f, -0.01440000f, -0.90037251f, - -0.15554780f, -0.01440000f, -0.93578976f, - 0.00000000f, -0.01440000f, -0.94800001f, - -0.96962506f, -0.08838750f, -0.00000000f, - -0.95713621f, -0.08838749f, -0.15909605f, - -0.92091113f, -0.08838750f, -0.30934918f, - -0.86281121f, -0.08838750f, -0.44889757f, - -0.78469825f, -0.08838750f, -0.57587969f, - -0.68843377f, -0.08838749f, -0.68843377f, - -0.57587969f, -0.08838749f, -0.78469819f, - -0.44889760f, -0.08838749f, -0.86281121f, - -0.30934915f, -0.08838749f, -0.92091107f, - -0.15909600f, -0.08838749f, -0.95713627f, - 0.00000000f, -0.08838749f, -0.96962506f, - -0.98600000f, -0.16080001f, -0.00000000f, - -0.97330022f, -0.16080000f, -0.16178288f, - -0.93646342f, -0.16080001f, -0.31457347f, - -0.87738222f, -0.16080000f, -0.45647857f, - -0.79795015f, -0.16080001f, -0.58560514f, - -0.70006001f, -0.16080001f, -0.70006001f, - -0.58560514f, -0.16080000f, -0.79795015f, - -0.45647860f, -0.16080001f, -0.87738228f, - -0.31457344f, -0.16080000f, -0.93646336f, - -0.16178282f, -0.16080000f, -0.97330034f, - 0.00000000f, -0.16080000f, -0.98600000f, - -0.99637496f, -0.23141253f, -0.00000000f, - -0.98354161f, -0.23141250f, -0.16348520f, - -0.94631720f, -0.23141254f, -0.31788349f, - -0.88661432f, -0.23141253f, -0.46128178f, - -0.80634636f, -0.23141254f, -0.59176707f, - -0.70742619f, -0.23141253f, -0.70742619f, - -0.59176701f, -0.23141253f, -0.80634630f, - -0.46128178f, -0.23141253f, -0.88661432f, - -0.31788346f, -0.23141253f, -0.94631708f, - -0.16348514f, -0.23141253f, -0.98354173f, - 0.00000000f, -0.23141253f, -0.99637496f, - -1.00000000f, -0.30000001f, -0.00000000f, - -0.98711991f, -0.29999998f, -0.16407999f, - -0.94976002f, -0.30000004f, -0.31904000f, - -0.88984001f, -0.30000004f, -0.46296000f, - -0.80928004f, -0.30000001f, -0.59392005f, - -0.71000004f, -0.30000001f, -0.71000004f, - -0.59391999f, -0.30000001f, -0.80928004f, - -0.46296003f, -0.30000001f, -0.88984001f, - -0.31904000f, -0.30000001f, -0.94976002f, - -0.16407993f, -0.30000001f, -0.98712003f, - 0.00000000f, -0.30000001f, -1.00000000f, - 1.00000000f, -0.30000001f, -0.00000000f, - 0.98711991f, -0.29999998f, 0.16407999f, - 0.94976002f, -0.30000004f, 0.31904000f, - 0.88984001f, -0.30000004f, 0.46296000f, - 0.80928004f, -0.30000001f, 0.59392005f, - 0.71000004f, -0.30000001f, 0.71000004f, - 0.59391999f, -0.30000001f, 0.80928004f, - 0.46296003f, -0.30000001f, 0.88984001f, - 0.31904000f, -0.30000001f, 0.94976002f, - 0.16407993f, -0.30000001f, 0.98712003f, - 0.00000000f, -0.30000001f, 1.00000000f, - 0.99299991f, -0.36416247f, -0.00000000f, - 0.98021001f, -0.36416242f, 0.16293143f, - 0.94311166f, -0.36416250f, 0.31680670f, - 0.88361102f, -0.36416245f, 0.45971927f, - 0.80361503f, -0.36416247f, 0.58976257f, - 0.70502996f, -0.36416247f, 0.70502996f, - 0.58976251f, -0.36416250f, 0.80361497f, - 0.45971930f, -0.36416247f, 0.88361108f, - 0.31680670f, -0.36416250f, 0.94311166f, - 0.16293137f, -0.36416247f, 0.98021007f, - 0.00000000f, -0.36416247f, 0.99299991f, - 0.97400004f, -0.42180002f, -0.00000001f, - 0.96145481f, -0.42179996f, 0.15981390f, - 0.92506635f, -0.42180005f, 0.31074497f, - 0.86670411f, -0.42180002f, 0.45092306f, - 0.78823876f, -0.42180011f, 0.57847816f, - 0.69154000f, -0.42180008f, 0.69154000f, - 0.57847810f, -0.42180005f, 0.78823876f, - 0.45092303f, -0.42180008f, 0.86670417f, - 0.31074494f, -0.42180008f, 0.92506629f, - 0.15981385f, -0.42180008f, 0.96145493f, - 0.00000000f, -0.42180005f, 0.97400004f, - 0.94600004f, -0.47313750f, -0.00000001f, - 0.93381548f, -0.47313747f, 0.15521967f, - 0.89847302f, -0.47313756f, 0.30181187f, - 0.84178865f, -0.47313750f, 0.43796018f, - 0.76557899f, -0.47313753f, 0.56184840f, - 0.67166001f, -0.47313753f, 0.67166001f, - 0.56184828f, -0.47313753f, 0.76557899f, - 0.43796021f, -0.47313753f, 0.84178865f, - 0.30181184f, -0.47313753f, 0.89847302f, - 0.15521961f, -0.47313753f, 0.93381560f, - 0.00000000f, -0.47313753f, 0.94600004f, - 0.91200000f, -0.51840001f, -0.00000001f, - 0.90025330f, -0.51839995f, 0.14964095f, - 0.86618114f, -0.51840007f, 0.29096451f, - 0.81153411f, -0.51840001f, 0.42221951f, - 0.73806345f, -0.51840007f, 0.54165506f, - 0.64752001f, -0.51840007f, 0.64752001f, - 0.54165506f, -0.51840007f, 0.73806340f, - 0.42221954f, -0.51840007f, 0.81153411f, - 0.29096448f, -0.51840007f, 0.86618114f, - 0.14964090f, -0.51840007f, 0.90025342f, - 0.00000000f, -0.51840007f, 0.91200000f, - 0.87500000f, -0.55781251f, -0.00000001f, - 0.86372989f, -0.55781251f, 0.14356998f, - 0.83104002f, -0.55781251f, 0.27916002f, - 0.77860999f, -0.55781251f, 0.40509003f, - 0.70812005f, -0.55781257f, 0.51968002f, - 0.62125003f, -0.55781251f, 0.62125003f, - 0.51967996f, -0.55781251f, 0.70812005f, - 0.40509003f, -0.55781257f, 0.77860999f, - 0.27915999f, -0.55781251f, 0.83104002f, - 0.14356995f, -0.55781251f, 0.86373001f, - 0.00000000f, -0.55781251f, 0.87500000f, - 0.83800000f, -0.59160000f, -0.00000001f, - 0.82720655f, -0.59159994f, 0.13749902f, - 0.79589891f, -0.59160000f, 0.26735553f, - 0.74568588f, -0.59160000f, 0.38796049f, - 0.67817670f, -0.59160006f, 0.49770495f, - 0.59498000f, -0.59160000f, 0.59497994f, - 0.49770495f, -0.59160000f, 0.67817664f, - 0.38796049f, -0.59160006f, 0.74568594f, - 0.26735550f, -0.59160000f, 0.79589891f, - 0.13749899f, -0.59160000f, 0.82720655f, - 0.00000000f, -0.59160000f, 0.83800000f, - 0.80400008f, -0.61998749f, -0.00000001f, - 0.79364455f, -0.61998743f, 0.13192031f, - 0.76360714f, -0.61998749f, 0.25650817f, - 0.71543139f, -0.61998749f, 0.37221986f, - 0.65066117f, -0.61998749f, 0.47751173f, - 0.57084000f, -0.61998749f, 0.57084000f, - 0.47751170f, -0.61998749f, 0.65066117f, - 0.37221986f, -0.61998749f, 0.71543145f, - 0.25650814f, -0.61998749f, 0.76360714f, - 0.13192026f, -0.61998749f, 0.79364455f, - 0.00000000f, -0.61998749f, 0.80400008f, - 0.77600002f, -0.64320004f, -0.00000001f, - 0.76600504f, -0.64319998f, 0.12732607f, - 0.73701382f, -0.64320010f, 0.24757506f, - 0.69051588f, -0.64320004f, 0.35925698f, - 0.62800133f, -0.64320010f, 0.46088195f, - 0.55096000f, -0.64320004f, 0.55096000f, - 0.46088192f, -0.64320004f, 0.62800133f, - 0.35925698f, -0.64320004f, 0.69051588f, - 0.24757503f, -0.64320004f, 0.73701382f, - 0.12732603f, -0.64320004f, 0.76600516f, - 0.00000000f, -0.64320004f, 0.77600002f, - 0.75699997f, -0.66146249f, -0.00000001f, - 0.74724966f, -0.66146243f, 0.12420854f, - 0.71896833f, -0.66146255f, 0.24151328f, - 0.67360884f, -0.66146243f, 0.35046071f, - 0.61262494f, -0.66146255f, 0.44959745f, - 0.53746998f, -0.66146249f, 0.53746998f, - 0.44959742f, -0.66146249f, 0.61262494f, - 0.35046071f, -0.66146249f, 0.67360890f, - 0.24151327f, -0.66146255f, 0.71896827f, - 0.12420851f, -0.66146249f, 0.74724984f, - 0.00000000f, -0.66146249f, 0.75699997f, - 0.75000000f, -0.67500001f, -0.00000001f, - 0.74033999f, -0.67499995f, 0.12305998f, - 0.71232003f, -0.67500007f, 0.23928000f, - 0.66737998f, -0.67500001f, 0.34721997f, - 0.60696000f, -0.67500007f, 0.44544002f, - 0.53250003f, -0.67500007f, 0.53250003f, - 0.44543999f, -0.67500001f, 0.60696000f, - 0.34722000f, -0.67500001f, 0.66738003f, - 0.23927999f, -0.67500001f, 0.71231997f, - 0.12305996f, -0.67500001f, 0.74033999f, - 0.00000000f, -0.67500001f, 0.75000000f, - 0.00000000f, -0.30000001f, -1.00000000f, - 0.16407999f, -0.29999998f, -0.98711991f, - 0.31904000f, -0.30000004f, -0.94976002f, - 0.46296000f, -0.30000004f, -0.88984001f, - 0.59392005f, -0.30000001f, -0.80928004f, - 0.71000004f, -0.30000001f, -0.71000004f, - 0.80928004f, -0.30000001f, -0.59391999f, - 0.88984001f, -0.30000001f, -0.46296003f, - 0.94976002f, -0.30000001f, -0.31904000f, - 0.98712003f, -0.30000001f, -0.16407993f, - 1.00000000f, -0.30000001f, -0.00000000f, - 0.00000000f, -0.36416247f, -0.99299991f, - 0.16293143f, -0.36416242f, -0.98021001f, - 0.31680670f, -0.36416250f, -0.94311166f, - 0.45971927f, -0.36416245f, -0.88361102f, - 0.58976257f, -0.36416247f, -0.80361503f, - 0.70502996f, -0.36416247f, -0.70502996f, - 0.80361497f, -0.36416250f, -0.58976251f, - 0.88361108f, -0.36416247f, -0.45971930f, - 0.94311166f, -0.36416250f, -0.31680670f, - 0.98021007f, -0.36416247f, -0.16293137f, - 0.99299991f, -0.36416247f, -0.00000000f, - 0.00000000f, -0.42180002f, -0.97400004f, - 0.15981390f, -0.42179996f, -0.96145481f, - 0.31074497f, -0.42180005f, -0.92506635f, - 0.45092306f, -0.42180002f, -0.86670411f, - 0.57847816f, -0.42180005f, -0.78823876f, - 0.69154000f, -0.42180002f, -0.69154000f, - 0.78823876f, -0.42180002f, -0.57847810f, - 0.86670417f, -0.42180002f, -0.45092303f, - 0.92506629f, -0.42180002f, -0.31074494f, - 0.96145493f, -0.42180002f, -0.15981385f, - 0.97400004f, -0.42180002f, -0.00000001f, - 0.00000000f, -0.47313750f, -0.94600004f, - 0.15521967f, -0.47313747f, -0.93381548f, - 0.30181187f, -0.47313756f, -0.89847302f, - 0.43796018f, -0.47313750f, -0.84178865f, - 0.56184840f, -0.47313753f, -0.76557899f, - 0.67166001f, -0.47313750f, -0.67166001f, - 0.76557899f, -0.47313750f, -0.56184828f, - 0.84178865f, -0.47313750f, -0.43796021f, - 0.89847302f, -0.47313750f, -0.30181184f, - 0.93381560f, -0.47313750f, -0.15521961f, - 0.94600004f, -0.47313750f, -0.00000001f, - 0.00000000f, -0.51840001f, -0.91200000f, - 0.14964095f, -0.51839995f, -0.90025330f, - 0.29096451f, -0.51840001f, -0.86618114f, - 0.42221951f, -0.51840001f, -0.81153411f, - 0.54165506f, -0.51840007f, -0.73806345f, - 0.64752001f, -0.51840001f, -0.64752001f, - 0.73806340f, -0.51840001f, -0.54165506f, - 0.81153411f, -0.51840007f, -0.42221954f, - 0.86618114f, -0.51840007f, -0.29096448f, - 0.90025342f, -0.51840001f, -0.14964090f, - 0.91200000f, -0.51840001f, -0.00000001f, - 0.00000000f, -0.55781251f, -0.87500000f, - 0.14356999f, -0.55781251f, -0.86372989f, - 0.27916002f, -0.55781251f, -0.83104002f, - 0.40509003f, -0.55781251f, -0.77860999f, - 0.51968002f, -0.55781257f, -0.70812005f, - 0.62125003f, -0.55781251f, -0.62125003f, - 0.70812005f, -0.55781251f, -0.51967996f, - 0.77860999f, -0.55781257f, -0.40509003f, - 0.83104002f, -0.55781251f, -0.27915999f, - 0.86373001f, -0.55781251f, -0.14356995f, - 0.87500000f, -0.55781251f, -0.00000001f, - 0.00000000f, -0.59160000f, -0.83800000f, - 0.13749902f, -0.59159994f, -0.82720655f, - 0.26735553f, -0.59160000f, -0.79589891f, - 0.38796049f, -0.59160000f, -0.74568588f, - 0.49770495f, -0.59160006f, -0.67817670f, - 0.59497994f, -0.59160000f, -0.59498000f, - 0.67817664f, -0.59160000f, -0.49770495f, - 0.74568594f, -0.59160006f, -0.38796049f, - 0.79589891f, -0.59160000f, -0.26735550f, - 0.82720655f, -0.59160000f, -0.13749899f, - 0.83800000f, -0.59160000f, -0.00000001f, - 0.00000000f, -0.61998749f, -0.80400008f, - 0.13192032f, -0.61998743f, -0.79364455f, - 0.25650817f, -0.61998749f, -0.76360714f, - 0.37221986f, -0.61998749f, -0.71543139f, - 0.47751173f, -0.61998749f, -0.65066117f, - 0.57084000f, -0.61998749f, -0.57084000f, - 0.65066117f, -0.61998749f, -0.47751170f, - 0.71543145f, -0.61998749f, -0.37221986f, - 0.76360714f, -0.61998749f, -0.25650814f, - 0.79364455f, -0.61998749f, -0.13192026f, - 0.80400008f, -0.61998749f, -0.00000001f, - 0.00000000f, -0.64320004f, -0.77600002f, - 0.12732607f, -0.64319998f, -0.76600504f, - 0.24757506f, -0.64320010f, -0.73701382f, - 0.35925698f, -0.64320004f, -0.69051588f, - 0.46088195f, -0.64320010f, -0.62800133f, - 0.55096000f, -0.64320004f, -0.55096000f, - 0.62800133f, -0.64320004f, -0.46088192f, - 0.69051588f, -0.64320004f, -0.35925698f, - 0.73701382f, -0.64320004f, -0.24757503f, - 0.76600516f, -0.64320004f, -0.12732603f, - 0.77600002f, -0.64320004f, -0.00000001f, - 0.00000000f, -0.66146249f, -0.75699997f, - 0.12420855f, -0.66146243f, -0.74724966f, - 0.24151328f, -0.66146255f, -0.71896833f, - 0.35046071f, -0.66146243f, -0.67360884f, - 0.44959745f, -0.66146255f, -0.61262494f, - 0.53746998f, -0.66146249f, -0.53746998f, - 0.61262494f, -0.66146249f, -0.44959742f, - 0.67360890f, -0.66146249f, -0.35046071f, - 0.71896827f, -0.66146255f, -0.24151327f, - 0.74724984f, -0.66146249f, -0.12420852f, - 0.75699997f, -0.66146249f, -0.00000001f, - 0.00000000f, -0.67500001f, -0.75000000f, - 0.12305999f, -0.67499995f, -0.74033999f, - 0.23928000f, -0.67500007f, -0.71232003f, - 0.34721997f, -0.67500001f, -0.66737998f, - 0.44544002f, -0.67500007f, -0.60696000f, - 0.53250003f, -0.67500007f, -0.53250003f, - 0.60696000f, -0.67500001f, -0.44543999f, - 0.66738003f, -0.67500001f, -0.34722000f, - 0.71231997f, -0.67500001f, -0.23927999f, - 0.74033999f, -0.67500001f, -0.12305997f, - 0.75000000f, -0.67500001f, -0.00000001f, - 0.00000000f, -0.30000001f, 1.00000000f, - -0.16407999f, -0.29999998f, 0.98711991f, - -0.31904000f, -0.30000004f, 0.94976002f, - -0.46296000f, -0.30000004f, 0.88984001f, - -0.59392005f, -0.30000001f, 0.80928004f, - -0.71000004f, -0.30000001f, 0.71000004f, - -0.80928004f, -0.30000001f, 0.59391999f, - -0.88984001f, -0.30000001f, 0.46296003f, - -0.94976002f, -0.30000001f, 0.31904000f, - -0.98712003f, -0.30000001f, 0.16407993f, - -1.00000000f, -0.30000001f, -0.00000000f, - 0.00000000f, -0.36416247f, 0.99299991f, - -0.16293143f, -0.36416242f, 0.98021001f, - -0.31680670f, -0.36416250f, 0.94311166f, - -0.45971927f, -0.36416245f, 0.88361102f, - -0.58976257f, -0.36416247f, 0.80361503f, - -0.70502996f, -0.36416247f, 0.70502996f, - -0.80361497f, -0.36416250f, 0.58976251f, - -0.88361108f, -0.36416247f, 0.45971930f, - -0.94311166f, -0.36416250f, 0.31680670f, - -0.98021007f, -0.36416247f, 0.16293137f, - -0.99299991f, -0.36416247f, -0.00000000f, - 0.00000000f, -0.42180005f, 0.97400004f, - -0.15981390f, -0.42179999f, 0.96145481f, - -0.31074497f, -0.42180005f, 0.92506635f, - -0.45092306f, -0.42180002f, 0.86670411f, - -0.57847816f, -0.42180011f, 0.78823876f, - -0.69154000f, -0.42180008f, 0.69154000f, - -0.78823876f, -0.42180002f, 0.57847810f, - -0.86670417f, -0.42180005f, 0.45092303f, - -0.92506629f, -0.42180005f, 0.31074494f, - -0.96145493f, -0.42180002f, 0.15981385f, - -0.97400004f, -0.42180002f, -0.00000001f, - 0.00000000f, -0.47313753f, 0.94600004f, - -0.15521967f, -0.47313747f, 0.93381548f, - -0.30181187f, -0.47313756f, 0.89847302f, - -0.43796018f, -0.47313750f, 0.84178865f, - -0.56184840f, -0.47313753f, 0.76557899f, - -0.67166001f, -0.47313750f, 0.67166001f, - -0.76557899f, -0.47313753f, 0.56184828f, - -0.84178865f, -0.47313753f, 0.43796021f, - -0.89847302f, -0.47313750f, 0.30181184f, - -0.93381560f, -0.47313750f, 0.15521961f, - -0.94600004f, -0.47313750f, -0.00000001f, - 0.00000000f, -0.51840007f, 0.91200000f, - -0.14964095f, -0.51839995f, 0.90025330f, - -0.29096451f, -0.51840007f, 0.86618114f, - -0.42221951f, -0.51840007f, 0.81153411f, - -0.54165506f, -0.51840007f, 0.73806345f, - -0.64752001f, -0.51840007f, 0.64752001f, - -0.73806340f, -0.51840007f, 0.54165506f, - -0.81153411f, -0.51840007f, 0.42221954f, - -0.86618114f, -0.51840007f, 0.29096448f, - -0.90025342f, -0.51840001f, 0.14964090f, - -0.91200000f, -0.51840001f, -0.00000001f, - 0.00000000f, -0.55781251f, 0.87500000f, - -0.14356999f, -0.55781251f, 0.86372989f, - -0.27916002f, -0.55781251f, 0.83104002f, - -0.40509003f, -0.55781251f, 0.77860999f, - -0.51968002f, -0.55781257f, 0.70812005f, - -0.62125003f, -0.55781251f, 0.62125003f, - -0.70812005f, -0.55781251f, 0.51967996f, - -0.77860999f, -0.55781257f, 0.40509003f, - -0.83104002f, -0.55781251f, 0.27915999f, - -0.86373001f, -0.55781251f, 0.14356995f, - -0.87500000f, -0.55781251f, -0.00000001f, - 0.00000000f, -0.59160000f, 0.83800000f, - -0.13749902f, -0.59159994f, 0.82720655f, - -0.26735553f, -0.59160000f, 0.79589891f, - -0.38796049f, -0.59160000f, 0.74568588f, - -0.49770495f, -0.59160006f, 0.67817670f, - -0.59497994f, -0.59160000f, 0.59498000f, - -0.67817664f, -0.59160000f, 0.49770495f, - -0.74568594f, -0.59160006f, 0.38796049f, - -0.79589891f, -0.59160000f, 0.26735550f, - -0.82720655f, -0.59160000f, 0.13749899f, - -0.83800000f, -0.59160000f, -0.00000001f, - 0.00000000f, -0.61998749f, 0.80400008f, - -0.13192032f, -0.61998743f, 0.79364455f, - -0.25650817f, -0.61998749f, 0.76360714f, - -0.37221986f, -0.61998749f, 0.71543139f, - -0.47751173f, -0.61998749f, 0.65066117f, - -0.57084000f, -0.61998749f, 0.57084000f, - -0.65066117f, -0.61998749f, 0.47751170f, - -0.71543145f, -0.61998749f, 0.37221986f, - -0.76360714f, -0.61998749f, 0.25650814f, - -0.79364455f, -0.61998749f, 0.13192026f, - -0.80400008f, -0.61998749f, -0.00000001f, - 0.00000000f, -0.64320004f, 0.77600002f, - -0.12732607f, -0.64319998f, 0.76600504f, - -0.24757506f, -0.64320010f, 0.73701382f, - -0.35925698f, -0.64320004f, 0.69051588f, - -0.46088195f, -0.64320010f, 0.62800133f, - -0.55096000f, -0.64320004f, 0.55096000f, - -0.62800133f, -0.64320004f, 0.46088192f, - -0.69051588f, -0.64320004f, 0.35925698f, - -0.73701382f, -0.64320004f, 0.24757503f, - -0.76600516f, -0.64320004f, 0.12732603f, - -0.77600002f, -0.64320004f, -0.00000001f, - 0.00000000f, -0.66146249f, 0.75699997f, - -0.12420855f, -0.66146243f, 0.74724966f, - -0.24151328f, -0.66146255f, 0.71896833f, - -0.35046071f, -0.66146243f, 0.67360884f, - -0.44959745f, -0.66146255f, 0.61262494f, - -0.53746998f, -0.66146249f, 0.53746998f, - -0.61262494f, -0.66146249f, 0.44959742f, - -0.67360890f, -0.66146249f, 0.35046071f, - -0.71896827f, -0.66146255f, 0.24151327f, - -0.74724984f, -0.66146249f, 0.12420850f, - -0.75699997f, -0.66146249f, -0.00000001f, - 0.00000000f, -0.67500001f, 0.75000000f, - -0.12305999f, -0.67499995f, 0.74033999f, - -0.23928000f, -0.67500007f, 0.71232003f, - -0.34721997f, -0.67500001f, 0.66737998f, - -0.44544002f, -0.67500007f, 0.60696000f, - -0.53250003f, -0.67500007f, 0.53250003f, - -0.60696000f, -0.67500001f, 0.44543999f, - -0.66738003f, -0.67500001f, 0.34722000f, - -0.71231997f, -0.67500001f, 0.23927999f, - -0.74033999f, -0.67500001f, 0.12305995f, - -0.75000000f, -0.67500001f, -0.00000001f, - -1.00000000f, -0.30000001f, -0.00000000f, - -0.98711991f, -0.29999998f, -0.16407999f, - -0.94976002f, -0.30000004f, -0.31904000f, - -0.88984001f, -0.30000004f, -0.46296000f, - -0.80928004f, -0.30000001f, -0.59392005f, - -0.71000004f, -0.30000001f, -0.71000004f, - -0.59391999f, -0.30000001f, -0.80928004f, - -0.46296003f, -0.30000001f, -0.88984001f, - -0.31904000f, -0.30000001f, -0.94976002f, - -0.16407993f, -0.30000001f, -0.98712003f, - 0.00000000f, -0.30000001f, -1.00000000f, - -0.99299991f, -0.36416247f, -0.00000000f, - -0.98021001f, -0.36416242f, -0.16293143f, - -0.94311166f, -0.36416250f, -0.31680670f, - -0.88361102f, -0.36416245f, -0.45971927f, - -0.80361503f, -0.36416247f, -0.58976257f, - -0.70502996f, -0.36416247f, -0.70502996f, - -0.58976251f, -0.36416250f, -0.80361497f, - -0.45971930f, -0.36416247f, -0.88361108f, - -0.31680670f, -0.36416250f, -0.94311166f, - -0.16293137f, -0.36416247f, -0.98021007f, - 0.00000000f, -0.36416247f, -0.99299991f, - -0.97400004f, -0.42180002f, -0.00000001f, - -0.96145481f, -0.42179996f, -0.15981390f, - -0.92506635f, -0.42180005f, -0.31074497f, - -0.86670411f, -0.42180002f, -0.45092306f, - -0.78823876f, -0.42180005f, -0.57847816f, - -0.69154000f, -0.42180002f, -0.69154000f, - -0.57847810f, -0.42180002f, -0.78823876f, - -0.45092303f, -0.42180002f, -0.86670417f, - -0.31074494f, -0.42180002f, -0.92506629f, - -0.15981385f, -0.42180002f, -0.96145493f, - 0.00000000f, -0.42180002f, -0.97400004f, - -0.94600004f, -0.47313750f, -0.00000001f, - -0.93381548f, -0.47313747f, -0.15521967f, - -0.89847302f, -0.47313756f, -0.30181187f, - -0.84178865f, -0.47313750f, -0.43796018f, - -0.76557899f, -0.47313753f, -0.56184840f, - -0.67166001f, -0.47313750f, -0.67166001f, - -0.56184828f, -0.47313750f, -0.76557899f, - -0.43796021f, -0.47313750f, -0.84178865f, - -0.30181184f, -0.47313750f, -0.89847302f, - -0.15521961f, -0.47313750f, -0.93381560f, - 0.00000000f, -0.47313750f, -0.94600004f, - -0.91200000f, -0.51840001f, -0.00000001f, - -0.90025330f, -0.51839995f, -0.14964096f, - -0.86618114f, -0.51840001f, -0.29096451f, - -0.81153411f, -0.51840001f, -0.42221951f, - -0.73806345f, -0.51840007f, -0.54165506f, - -0.64752001f, -0.51840001f, -0.64752001f, - -0.54165506f, -0.51840001f, -0.73806340f, - -0.42221954f, -0.51840007f, -0.81153411f, - -0.29096448f, -0.51840007f, -0.86618114f, - -0.14964090f, -0.51840001f, -0.90025342f, - 0.00000000f, -0.51840001f, -0.91200000f, - -0.87500000f, -0.55781251f, -0.00000001f, - -0.86372989f, -0.55781251f, -0.14357001f, - -0.83104002f, -0.55781251f, -0.27916002f, - -0.77860999f, -0.55781251f, -0.40509003f, - -0.70812005f, -0.55781257f, -0.51968002f, - -0.62125003f, -0.55781251f, -0.62125003f, - -0.51967996f, -0.55781251f, -0.70812005f, - -0.40509003f, -0.55781257f, -0.77860999f, - -0.27915999f, -0.55781251f, -0.83104002f, - -0.14356995f, -0.55781251f, -0.86373001f, - 0.00000000f, -0.55781251f, -0.87500000f, - -0.83800000f, -0.59160000f, -0.00000001f, - -0.82720655f, -0.59159994f, -0.13749903f, - -0.79589891f, -0.59160000f, -0.26735553f, - -0.74568588f, -0.59160000f, -0.38796049f, - -0.67817670f, -0.59160006f, -0.49770495f, - -0.59498000f, -0.59160000f, -0.59497994f, - -0.49770495f, -0.59160000f, -0.67817664f, - -0.38796049f, -0.59160006f, -0.74568594f, - -0.26735550f, -0.59160000f, -0.79589891f, - -0.13749899f, -0.59160000f, -0.82720655f, - 0.00000000f, -0.59160000f, -0.83800000f, - -0.80400008f, -0.61998749f, -0.00000001f, - -0.79364455f, -0.61998743f, -0.13192032f, - -0.76360714f, -0.61998749f, -0.25650817f, - -0.71543139f, -0.61998749f, -0.37221986f, - -0.65066117f, -0.61998749f, -0.47751173f, - -0.57084000f, -0.61998749f, -0.57084000f, - -0.47751170f, -0.61998749f, -0.65066117f, - -0.37221986f, -0.61998749f, -0.71543145f, - -0.25650814f, -0.61998749f, -0.76360714f, - -0.13192026f, -0.61998749f, -0.79364455f, - 0.00000000f, -0.61998749f, -0.80400008f, - -0.77600002f, -0.64320004f, -0.00000001f, - -0.76600504f, -0.64319998f, -0.12732607f, - -0.73701382f, -0.64320010f, -0.24757506f, - -0.69051588f, -0.64320004f, -0.35925698f, - -0.62800133f, -0.64320010f, -0.46088195f, - -0.55096000f, -0.64320004f, -0.55096000f, - -0.46088192f, -0.64320004f, -0.62800133f, - -0.35925698f, -0.64320004f, -0.69051588f, - -0.24757503f, -0.64320004f, -0.73701382f, - -0.12732603f, -0.64320004f, -0.76600516f, - 0.00000000f, -0.64320004f, -0.77600002f, - -0.75699997f, -0.66146249f, -0.00000001f, - -0.74724966f, -0.66146243f, -0.12420855f, - -0.71896833f, -0.66146255f, -0.24151328f, - -0.67360884f, -0.66146243f, -0.35046071f, - -0.61262494f, -0.66146255f, -0.44959745f, - -0.53746998f, -0.66146249f, -0.53746998f, - -0.44959742f, -0.66146249f, -0.61262494f, - -0.35046071f, -0.66146249f, -0.67360890f, - -0.24151327f, -0.66146255f, -0.71896827f, - -0.12420851f, -0.66146249f, -0.74724984f, - 0.00000000f, -0.66146249f, -0.75699997f, - -0.75000000f, -0.67500001f, -0.00000001f, - -0.74033999f, -0.67499995f, -0.12306000f, - -0.71232003f, -0.67500007f, -0.23928000f, - -0.66737998f, -0.67500001f, -0.34721997f, - -0.60696000f, -0.67500007f, -0.44544002f, - -0.53250003f, -0.67500007f, -0.53250003f, - -0.44543999f, -0.67500001f, -0.60696000f, - -0.34722000f, -0.67500001f, -0.66738003f, - -0.23927999f, -0.67500001f, -0.71231997f, - -0.12305996f, -0.67500001f, -0.74033999f, - 0.00000000f, -0.67500001f, -0.75000000f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500017f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.09730000f, 0.82072502f, 0.00000001f, - 0.09605332f, 0.82072490f, 0.01602404f, - 0.09243499f, 0.82072508f, 0.03113591f, - 0.08662736f, 0.82072502f, 0.04515318f, - 0.07881293f, 0.82072508f, 0.05789340f, - 0.06917413f, 0.82072502f, 0.06917413f, - 0.05789339f, 0.82072502f, 0.07881294f, - 0.04515317f, 0.82072508f, 0.08662736f, - 0.03113590f, 0.82072502f, 0.09243499f, - 0.01602403f, 0.82072502f, 0.09605335f, - 0.00000000f, 0.82072502f, 0.09730001f, - 0.15440002f, 0.80880016f, 0.00000001f, - 0.15242170f, 0.80880004f, 0.02542728f, - 0.14667983f, 0.80880022f, 0.04940725f, - 0.13746388f, 0.80880022f, 0.07165039f, - 0.12506345f, 0.80880028f, 0.09186716f, - 0.10976801f, 0.80880016f, 0.10976802f, - 0.09186715f, 0.80880016f, 0.12506345f, - 0.07165038f, 0.80880022f, 0.13746390f, - 0.04940724f, 0.80880022f, 0.14667983f, - 0.02542726f, 0.80880016f, 0.15242171f, - 0.00000000f, 0.80880016f, 0.15440002f, - 0.17909999f, 0.79057503f, 0.00000001f, - 0.17680508f, 0.79057491f, 0.02949390f, - 0.17014435f, 0.79057509f, 0.05730941f, - 0.15945368f, 0.79057509f, 0.08311062f, - 0.14506906f, 0.79057503f, 0.10656159f, - 0.12732637f, 0.79057503f, 0.12732637f, - 0.10656157f, 0.79057503f, 0.14506905f, - 0.08311062f, 0.79057503f, 0.15945369f, - 0.05730940f, 0.79057503f, 0.17014435f, - 0.02949388f, 0.79057503f, 0.17680509f, - 0.00000000f, 0.79057503f, 0.17909999f, - 0.17920001f, 0.76740009f, 0.00000001f, - 0.17690356f, 0.76740003f, 0.02950812f, - 0.17023848f, 0.76740015f, 0.05733787f, - 0.15954098f, 0.76740009f, 0.08315296f, - 0.14514741f, 0.76740015f, 0.10661709f, - 0.12739401f, 0.76740009f, 0.12739401f, - 0.10661709f, 0.76740009f, 0.14514741f, - 0.08315295f, 0.76740009f, 0.15954098f, - 0.05733785f, 0.76740015f, 0.17023847f, - 0.02950810f, 0.76740009f, 0.17690358f, - 0.00000000f, 0.76740009f, 0.17920001f, - 0.16250001f, 0.74062496f, 0.00000001f, - 0.16041712f, 0.74062496f, 0.02675413f, - 0.15437202f, 0.74062502f, 0.05198801f, - 0.14466989f, 0.74062496f, 0.07539638f, - 0.13161601f, 0.74062496f, 0.09667401f, - 0.11551563f, 0.74062496f, 0.11551563f, - 0.09667400f, 0.74062496f, 0.13161600f, - 0.07539637f, 0.74062502f, 0.14466989f, - 0.05198800f, 0.74062502f, 0.15437201f, - 0.02675411f, 0.74062496f, 0.16041712f, - 0.00000000f, 0.74062496f, 0.16250001f, - 0.13680001f, 0.71160007f, 0.00000001f, - 0.13504578f, 0.71160001f, 0.02251614f, - 0.12995483f, 0.71160012f, 0.04375527f, - 0.12178454f, 0.71160007f, 0.06345994f, - 0.11079245f, 0.71160012f, 0.08137268f, - 0.09723600f, 0.71160007f, 0.09723601f, - 0.08137267f, 0.71160007f, 0.11079245f, - 0.06345994f, 0.71160007f, 0.12178455f, - 0.04375526f, 0.71160007f, 0.12995481f, - 0.02251612f, 0.71160007f, 0.13504580f, - 0.00000000f, 0.71160007f, 0.13680001f, - 0.10990001f, 0.68167502f, 0.00000001f, - 0.10848958f, 0.68167496f, 0.01807833f, - 0.10439678f, 0.68167502f, 0.03513508f, - 0.09782913f, 0.68167496f, 0.05096266f, - 0.08899431f, 0.68167502f, 0.06535347f, - 0.07809988f, 0.68167502f, 0.07809989f, - 0.06535345f, 0.68167502f, 0.08899432f, - 0.05096266f, 0.68167502f, 0.09782915f, - 0.03513507f, 0.68167502f, 0.10439678f, - 0.01807831f, 0.68167502f, 0.10848960f, - 0.00000000f, 0.68167502f, 0.10990001f, - 0.08960000f, 0.65219998f, 0.00000001f, - 0.08844854f, 0.65219992f, 0.01472490f, - 0.08510771f, 0.65220004f, 0.02862286f, - 0.07974781f, 0.65219998f, 0.04152356f, - 0.07253914f, 0.65219998f, 0.05325671f, - 0.06365200f, 0.65219998f, 0.06365201f, - 0.05325670f, 0.65219998f, 0.07253915f, - 0.04152355f, 0.65219998f, 0.07974782f, - 0.02862285f, 0.65219998f, 0.08510773f, - 0.01472489f, 0.65219998f, 0.08844855f, - 0.00000000f, 0.65219998f, 0.08960001f, - 0.08370000f, 0.62452501f, 0.00000001f, - 0.08262266f, 0.62452495f, 0.01374006f, - 0.07949751f, 0.62452501f, 0.02671403f, - 0.07448471f, 0.62452501f, 0.03876166f, - 0.06774452f, 0.62452507f, 0.04972278f, - 0.05943713f, 0.62452501f, 0.05943713f, - 0.04972277f, 0.62452501f, 0.06774452f, - 0.03876166f, 0.62452501f, 0.07448472f, - 0.02671402f, 0.62452501f, 0.07949752f, - 0.01374005f, 0.62452501f, 0.08262268f, - 0.00000000f, 0.62452501f, 0.08370001f, - 0.10000000f, 0.60000002f, 0.00000001f, - 0.09871199f, 0.59999996f, 0.01640801f, - 0.09497602f, 0.60000008f, 0.03190401f, - 0.08898400f, 0.60000008f, 0.04629601f, - 0.08092801f, 0.60000002f, 0.05939201f, - 0.07100000f, 0.60000002f, 0.07100001f, - 0.05939200f, 0.60000002f, 0.08092801f, - 0.04629600f, 0.60000002f, 0.08898401f, - 0.03190400f, 0.60000002f, 0.09497601f, - 0.01640799f, 0.60000002f, 0.09871200f, - 0.00000000f, 0.60000002f, 0.10000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500017f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82072502f, -0.09729999f, - 0.01602403f, 0.82072490f, -0.09605332f, - 0.03113590f, 0.82072508f, -0.09243497f, - 0.04515317f, 0.82072502f, -0.08662734f, - 0.05789339f, 0.82072508f, -0.07881292f, - 0.06917413f, 0.82072502f, -0.06917411f, - 0.07881293f, 0.82072502f, -0.05789338f, - 0.08662736f, 0.82072508f, -0.04515316f, - 0.09243498f, 0.82072502f, -0.03113589f, - 0.09605334f, 0.82072502f, -0.01602402f, - 0.09730000f, 0.82072502f, 0.00000001f, - 0.00000000f, 0.80880016f, -0.15440002f, - 0.02542727f, 0.80880004f, -0.15242170f, - 0.04940724f, 0.80880022f, -0.14667983f, - 0.07165038f, 0.80880022f, -0.13746388f, - 0.09186715f, 0.80880028f, -0.12506345f, - 0.10976800f, 0.80880016f, -0.10976801f, - 0.12506345f, 0.80880016f, -0.09186714f, - 0.13746388f, 0.80880022f, -0.07165038f, - 0.14667982f, 0.80880022f, -0.04940723f, - 0.15242171f, 0.80880016f, -0.02542725f, - 0.15440002f, 0.80880016f, 0.00000001f, - 0.00000000f, 0.79057503f, -0.17909999f, - 0.02949389f, 0.79057491f, -0.17680508f, - 0.05730940f, 0.79057509f, -0.17014435f, - 0.08311061f, 0.79057509f, -0.15945368f, - 0.10656158f, 0.79057503f, -0.14506905f, - 0.12732637f, 0.79057503f, -0.12732637f, - 0.14506905f, 0.79057503f, -0.10656157f, - 0.15945369f, 0.79057503f, -0.08311061f, - 0.17014435f, 0.79057503f, -0.05730939f, - 0.17680509f, 0.79057503f, -0.02949387f, - 0.17909999f, 0.79057503f, 0.00000001f, - 0.00000000f, 0.76740009f, -0.17920001f, - 0.02950811f, 0.76740003f, -0.17690356f, - 0.05733786f, 0.76740015f, -0.17023848f, - 0.08315294f, 0.76740009f, -0.15954097f, - 0.10661709f, 0.76740015f, -0.14514740f, - 0.12739401f, 0.76740009f, -0.12739399f, - 0.14514741f, 0.76740009f, -0.10661709f, - 0.15954098f, 0.76740009f, -0.08315295f, - 0.17023847f, 0.76740015f, -0.05733785f, - 0.17690358f, 0.76740009f, -0.02950809f, - 0.17920001f, 0.76740009f, 0.00000001f, - 0.00000000f, 0.74062496f, -0.16250001f, - 0.02675412f, 0.74062496f, -0.16041712f, - 0.05198800f, 0.74062502f, -0.15437202f, - 0.07539637f, 0.74062496f, -0.14466989f, - 0.09667401f, 0.74062496f, -0.13161601f, - 0.11551563f, 0.74062496f, -0.11551563f, - 0.13161600f, 0.74062496f, -0.09667400f, - 0.14466989f, 0.74062502f, -0.07539637f, - 0.15437201f, 0.74062502f, -0.05198799f, - 0.16041712f, 0.74062496f, -0.02675411f, - 0.16250001f, 0.74062496f, 0.00000001f, - 0.00000000f, 0.71160007f, -0.13679999f, - 0.02251613f, 0.71160001f, -0.13504578f, - 0.04375527f, 0.71160012f, -0.12995481f, - 0.06345994f, 0.71160007f, -0.12178454f, - 0.08137268f, 0.71160012f, -0.11079244f, - 0.09723600f, 0.71160007f, -0.09723599f, - 0.11079245f, 0.71160007f, -0.08137266f, - 0.12178455f, 0.71160007f, -0.06345993f, - 0.12995481f, 0.71160007f, -0.04375526f, - 0.13504580f, 0.71160007f, -0.02251611f, - 0.13680001f, 0.71160007f, 0.00000001f, - 0.00000000f, 0.68167502f, -0.10990000f, - 0.01807832f, 0.68167496f, -0.10848958f, - 0.03513507f, 0.68167502f, -0.10439678f, - 0.05096266f, 0.68167496f, -0.09782913f, - 0.06535346f, 0.68167502f, -0.08899431f, - 0.07809988f, 0.68167502f, -0.07809987f, - 0.08899431f, 0.68167502f, -0.06535345f, - 0.09782915f, 0.68167502f, -0.05096265f, - 0.10439678f, 0.68167502f, -0.03513506f, - 0.10848960f, 0.68167502f, -0.01807830f, - 0.10990001f, 0.68167502f, 0.00000001f, - 0.00000000f, 0.65219998f, -0.08960000f, - 0.01472490f, 0.65219992f, -0.08844854f, - 0.02862285f, 0.65220004f, -0.08510771f, - 0.04152355f, 0.65219998f, -0.07974780f, - 0.05325671f, 0.65219998f, -0.07253914f, - 0.06365199f, 0.65219998f, -0.06365199f, - 0.07253914f, 0.65219998f, -0.05325670f, - 0.07974781f, 0.65219998f, -0.04152355f, - 0.08510771f, 0.65219998f, -0.02862284f, - 0.08844854f, 0.65219998f, -0.01472488f, - 0.08960000f, 0.65219998f, 0.00000001f, - 0.00000000f, 0.62452501f, -0.08369999f, - 0.01374006f, 0.62452495f, -0.08262266f, - 0.02671402f, 0.62452501f, -0.07949750f, - 0.03876166f, 0.62452501f, -0.07448471f, - 0.04972277f, 0.62452507f, -0.06774451f, - 0.05943713f, 0.62452501f, -0.05943712f, - 0.06774452f, 0.62452501f, -0.04972276f, - 0.07448471f, 0.62452501f, -0.03876166f, - 0.07949751f, 0.62452501f, -0.02671401f, - 0.08262268f, 0.62452501f, -0.01374004f, - 0.08370000f, 0.62452501f, 0.00000001f, - 0.00000000f, 0.60000002f, -0.09999999f, - 0.01640800f, 0.59999996f, -0.09871199f, - 0.03190400f, 0.60000008f, -0.09497599f, - 0.04629600f, 0.60000008f, -0.08898398f, - 0.05939200f, 0.60000002f, -0.08092800f, - 0.07100000f, 0.60000002f, -0.07099999f, - 0.08092801f, 0.60000002f, -0.05939199f, - 0.08898400f, 0.60000002f, -0.04629600f, - 0.09497601f, 0.60000002f, -0.03190399f, - 0.09871200f, 0.60000002f, -0.01640799f, - 0.10000000f, 0.60000002f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500017f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82072502f, 0.09730001f, - -0.01602403f, 0.82072490f, 0.09605334f, - -0.03113590f, 0.82072508f, 0.09243499f, - -0.04515317f, 0.82072502f, 0.08662736f, - -0.05789339f, 0.82072508f, 0.07881294f, - -0.06917413f, 0.82072502f, 0.06917413f, - -0.07881293f, 0.82072502f, 0.05789340f, - -0.08662736f, 0.82072508f, 0.04515318f, - -0.09243498f, 0.82072502f, 0.03113591f, - -0.09605334f, 0.82072502f, 0.01602404f, - -0.09730000f, 0.82072502f, 0.00000001f, - 0.00000000f, 0.80880016f, 0.15440002f, - -0.02542727f, 0.80880004f, 0.15242170f, - -0.04940724f, 0.80880022f, 0.14667983f, - -0.07165038f, 0.80880022f, 0.13746390f, - -0.09186715f, 0.80880028f, 0.12506345f, - -0.10976800f, 0.80880016f, 0.10976802f, - -0.12506345f, 0.80880016f, 0.09186715f, - -0.13746388f, 0.80880022f, 0.07165039f, - -0.14667982f, 0.80880022f, 0.04940725f, - -0.15242171f, 0.80880016f, 0.02542727f, - -0.15440002f, 0.80880016f, 0.00000001f, - 0.00000000f, 0.79057503f, 0.17909999f, - -0.02949389f, 0.79057491f, 0.17680508f, - -0.05730940f, 0.79057509f, 0.17014435f, - -0.08311061f, 0.79057509f, 0.15945368f, - -0.10656158f, 0.79057503f, 0.14506906f, - -0.12732637f, 0.79057503f, 0.12732637f, - -0.14506905f, 0.79057503f, 0.10656157f, - -0.15945369f, 0.79057503f, 0.08311062f, - -0.17014435f, 0.79057503f, 0.05730941f, - -0.17680509f, 0.79057503f, 0.02949389f, - -0.17909999f, 0.79057503f, 0.00000001f, - 0.00000000f, 0.76740009f, 0.17920001f, - -0.02950811f, 0.76740003f, 0.17690358f, - -0.05733786f, 0.76740015f, 0.17023848f, - -0.08315294f, 0.76740009f, 0.15954098f, - -0.10661709f, 0.76740015f, 0.14514741f, - -0.12739401f, 0.76740009f, 0.12739401f, - -0.14514741f, 0.76740009f, 0.10661709f, - -0.15954098f, 0.76740009f, 0.08315295f, - -0.17023847f, 0.76740015f, 0.05733786f, - -0.17690358f, 0.76740009f, 0.02950811f, - -0.17920001f, 0.76740009f, 0.00000001f, - 0.00000000f, 0.74062496f, 0.16250001f, - -0.02675412f, 0.74062496f, 0.16041712f, - -0.05198800f, 0.74062502f, 0.15437202f, - -0.07539637f, 0.74062496f, 0.14466989f, - -0.09667401f, 0.74062496f, 0.13161601f, - -0.11551563f, 0.74062496f, 0.11551563f, - -0.13161600f, 0.74062496f, 0.09667400f, - -0.14466989f, 0.74062502f, 0.07539638f, - -0.15437201f, 0.74062502f, 0.05198800f, - -0.16041712f, 0.74062496f, 0.02675412f, - -0.16250001f, 0.74062496f, 0.00000001f, - 0.00000000f, 0.71160007f, 0.13680001f, - -0.02251613f, 0.71160001f, 0.13504578f, - -0.04375527f, 0.71160012f, 0.12995483f, - -0.06345994f, 0.71160007f, 0.12178455f, - -0.08137268f, 0.71160012f, 0.11079246f, - -0.09723600f, 0.71160007f, 0.09723601f, - -0.11079245f, 0.71160007f, 0.08137267f, - -0.12178455f, 0.71160007f, 0.06345994f, - -0.12995481f, 0.71160007f, 0.04375527f, - -0.13504580f, 0.71160007f, 0.02251613f, - -0.13680001f, 0.71160007f, 0.00000001f, - 0.00000000f, 0.68167502f, 0.10990001f, - -0.01807832f, 0.68167496f, 0.10848960f, - -0.03513507f, 0.68167502f, 0.10439679f, - -0.05096266f, 0.68167496f, 0.09782915f, - -0.06535346f, 0.68167502f, 0.08899432f, - -0.07809988f, 0.68167502f, 0.07809988f, - -0.08899431f, 0.68167502f, 0.06535346f, - -0.09782915f, 0.68167502f, 0.05096267f, - -0.10439678f, 0.68167502f, 0.03513508f, - -0.10848960f, 0.68167502f, 0.01807832f, - -0.10990001f, 0.68167502f, 0.00000001f, - 0.00000000f, 0.65219998f, 0.08960001f, - -0.01472490f, 0.65219992f, 0.08844855f, - -0.02862285f, 0.65220004f, 0.08510773f, - -0.04152355f, 0.65219998f, 0.07974782f, - -0.05325671f, 0.65219998f, 0.07253915f, - -0.06365199f, 0.65219998f, 0.06365201f, - -0.07253914f, 0.65219998f, 0.05325671f, - -0.07974781f, 0.65219998f, 0.04152356f, - -0.08510771f, 0.65219998f, 0.02862286f, - -0.08844854f, 0.65219998f, 0.01472490f, - -0.08960000f, 0.65219998f, 0.00000001f, - 0.00000000f, 0.62452501f, 0.08370001f, - -0.01374006f, 0.62452495f, 0.08262267f, - -0.02671402f, 0.62452501f, 0.07949752f, - -0.03876166f, 0.62452501f, 0.07448472f, - -0.04972277f, 0.62452507f, 0.06774452f, - -0.05943713f, 0.62452501f, 0.05943713f, - -0.06774452f, 0.62452501f, 0.04972278f, - -0.07448471f, 0.62452501f, 0.03876167f, - -0.07949751f, 0.62452501f, 0.02671402f, - -0.08262268f, 0.62452501f, 0.01374006f, - -0.08370000f, 0.62452501f, 0.00000001f, - 0.00000000f, 0.60000002f, 0.10000001f, - -0.01640800f, 0.59999996f, 0.09871200f, - -0.03190400f, 0.60000008f, 0.09497602f, - -0.04629600f, 0.60000008f, 0.08898401f, - -0.05939200f, 0.60000002f, 0.08092801f, - -0.07100000f, 0.60000002f, 0.07100001f, - -0.08092801f, 0.60000002f, 0.05939201f, - -0.08898400f, 0.60000002f, 0.04629601f, - -0.09497601f, 0.60000002f, 0.03190401f, - -0.09871200f, 0.60000002f, 0.01640800f, - -0.10000000f, 0.60000002f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500017f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500011f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - 0.00000000f, 0.82500005f, 0.00000001f, - -0.09730000f, 0.82072502f, 0.00000001f, - -0.09605332f, 0.82072490f, -0.01602402f, - -0.09243499f, 0.82072508f, -0.03113589f, - -0.08662736f, 0.82072502f, -0.04515316f, - -0.07881293f, 0.82072508f, -0.05789338f, - -0.06917413f, 0.82072502f, -0.06917411f, - -0.05789339f, 0.82072502f, -0.07881292f, - -0.04515317f, 0.82072508f, -0.08662735f, - -0.03113590f, 0.82072502f, -0.09243497f, - -0.01602403f, 0.82072502f, -0.09605333f, - 0.00000000f, 0.82072502f, -0.09729999f, - -0.15440002f, 0.80880016f, 0.00000001f, - -0.15242170f, 0.80880004f, -0.02542726f, - -0.14667983f, 0.80880022f, -0.04940723f, - -0.13746388f, 0.80880022f, -0.07165037f, - -0.12506345f, 0.80880028f, -0.09186714f, - -0.10976801f, 0.80880016f, -0.10976800f, - -0.09186715f, 0.80880016f, -0.12506345f, - -0.07165038f, 0.80880022f, -0.13746388f, - -0.04940724f, 0.80880022f, -0.14667982f, - -0.02542726f, 0.80880016f, -0.15242171f, - 0.00000000f, 0.80880016f, -0.15440002f, - -0.17909999f, 0.79057503f, 0.00000001f, - -0.17680508f, 0.79057491f, -0.02949388f, - -0.17014435f, 0.79057509f, -0.05730940f, - -0.15945368f, 0.79057509f, -0.08311061f, - -0.14506906f, 0.79057503f, -0.10656158f, - -0.12732637f, 0.79057503f, -0.12732637f, - -0.10656157f, 0.79057503f, -0.14506905f, - -0.08311062f, 0.79057503f, -0.15945369f, - -0.05730940f, 0.79057503f, -0.17014435f, - -0.02949388f, 0.79057503f, -0.17680509f, - 0.00000000f, 0.79057503f, -0.17909999f, - -0.17920001f, 0.76740009f, 0.00000001f, - -0.17690356f, 0.76740003f, -0.02950810f, - -0.17023848f, 0.76740015f, -0.05733785f, - -0.15954098f, 0.76740009f, -0.08315294f, - -0.14514741f, 0.76740015f, -0.10661709f, - -0.12739401f, 0.76740009f, -0.12739401f, - -0.10661709f, 0.76740009f, -0.14514740f, - -0.08315295f, 0.76740009f, -0.15954098f, - -0.05733785f, 0.76740015f, -0.17023847f, - -0.02950810f, 0.76740009f, -0.17690358f, - 0.00000000f, 0.76740009f, -0.17920001f, - -0.16250001f, 0.74062496f, 0.00000001f, - -0.16041712f, 0.74062496f, -0.02675412f, - -0.15437202f, 0.74062502f, -0.05198800f, - -0.14466989f, 0.74062496f, -0.07539637f, - -0.13161601f, 0.74062496f, -0.09667400f, - -0.11551563f, 0.74062496f, -0.11551563f, - -0.09667400f, 0.74062496f, -0.13161600f, - -0.07539637f, 0.74062502f, -0.14466989f, - -0.05198800f, 0.74062502f, -0.15437201f, - -0.02675411f, 0.74062496f, -0.16041712f, - 0.00000000f, 0.74062496f, -0.16250001f, - -0.13680001f, 0.71160007f, 0.00000001f, - -0.13504578f, 0.71160001f, -0.02251612f, - -0.12995483f, 0.71160012f, -0.04375526f, - -0.12178454f, 0.71160007f, -0.06345993f, - -0.11079245f, 0.71160012f, -0.08137267f, - -0.09723600f, 0.71160007f, -0.09723599f, - -0.08137267f, 0.71160007f, -0.11079245f, - -0.06345994f, 0.71160007f, -0.12178454f, - -0.04375526f, 0.71160007f, -0.12995481f, - -0.02251612f, 0.71160007f, -0.13504578f, - 0.00000000f, 0.71160007f, -0.13679999f, - -0.10990001f, 0.68167502f, 0.00000001f, - -0.10848958f, 0.68167496f, -0.01807831f, - -0.10439678f, 0.68167502f, -0.03513507f, - -0.09782913f, 0.68167496f, -0.05096265f, - -0.08899431f, 0.68167502f, -0.06535345f, - -0.07809988f, 0.68167502f, -0.07809987f, - -0.06535345f, 0.68167502f, -0.08899430f, - -0.05096266f, 0.68167502f, -0.09782913f, - -0.03513507f, 0.68167502f, -0.10439677f, - -0.01807831f, 0.68167502f, -0.10848959f, - 0.00000000f, 0.68167502f, -0.10990000f, - -0.08960000f, 0.65219998f, 0.00000001f, - -0.08844854f, 0.65219992f, -0.01472489f, - -0.08510771f, 0.65220004f, -0.02862284f, - -0.07974781f, 0.65219998f, -0.04152355f, - -0.07253914f, 0.65219998f, -0.05325670f, - -0.06365200f, 0.65219998f, -0.06365199f, - -0.05325670f, 0.65219998f, -0.07253914f, - -0.04152355f, 0.65219998f, -0.07974781f, - -0.02862285f, 0.65219998f, -0.08510771f, - -0.01472489f, 0.65219998f, -0.08844854f, - 0.00000000f, 0.65219998f, -0.08960000f, - -0.08370000f, 0.62452501f, 0.00000001f, - -0.08262266f, 0.62452495f, -0.01374005f, - -0.07949751f, 0.62452501f, -0.02671401f, - -0.07448471f, 0.62452501f, -0.03876165f, - -0.06774452f, 0.62452507f, -0.04972276f, - -0.05943713f, 0.62452501f, -0.05943712f, - -0.04972277f, 0.62452501f, -0.06774451f, - -0.03876166f, 0.62452501f, -0.07448471f, - -0.02671402f, 0.62452501f, -0.07949750f, - -0.01374005f, 0.62452501f, -0.08262267f, - 0.00000000f, 0.62452501f, -0.08369999f, - -0.10000000f, 0.60000002f, 0.00000001f, - -0.09871199f, 0.59999996f, -0.01640799f, - -0.09497602f, 0.60000008f, -0.03190399f, - -0.08898400f, 0.60000008f, -0.04629599f, - -0.08092801f, 0.60000002f, -0.05939199f, - -0.07100000f, 0.60000002f, -0.07099999f, - -0.05939200f, 0.60000002f, -0.08092800f, - -0.04629600f, 0.60000002f, -0.08898400f, - -0.03190400f, 0.60000002f, -0.09497599f, - -0.01640799f, 0.60000002f, -0.09871200f, - 0.00000000f, 0.60000002f, -0.09999999f, - 0.10000000f, 0.60000002f, 0.00000001f, - 0.09871199f, 0.59999996f, 0.01640801f, - 0.09497602f, 0.60000008f, 0.03190401f, - 0.08898400f, 0.60000008f, 0.04629601f, - 0.08092801f, 0.60000002f, 0.05939201f, - 0.07100000f, 0.60000002f, 0.07100001f, - 0.05939200f, 0.60000002f, 0.08092801f, - 0.04629600f, 0.60000002f, 0.08898401f, - 0.03190400f, 0.60000002f, 0.09497601f, - 0.01640799f, 0.60000002f, 0.09871200f, - 0.00000000f, 0.60000002f, 0.10000001f, - 0.13969998f, 0.57959992f, 0.00000001f, - 0.13790064f, 0.57959986f, 0.02292198f, - 0.13268146f, 0.57959998f, 0.04456990f, - 0.12431064f, 0.57959992f, 0.06467552f, - 0.11305641f, 0.57959998f, 0.08297063f, - 0.09918699f, 0.57959992f, 0.09918701f, - 0.08297062f, 0.57959992f, 0.11305644f, - 0.06467551f, 0.57959998f, 0.12431066f, - 0.04456988f, 0.57959992f, 0.13268149f, - 0.02292197f, 0.57959992f, 0.13790068f, - 0.00000000f, 0.57959992f, 0.13970001f, - 0.19560002f, 0.56280005f, 0.00000001f, - 0.19308068f, 0.56279999f, 0.03209405f, - 0.18577307f, 0.56280011f, 0.06240424f, - 0.17405272f, 0.56280005f, 0.09055499f, - 0.15829518f, 0.56280005f, 0.11617076f, - 0.13887602f, 0.56280005f, 0.13887601f, - 0.11617076f, 0.56280005f, 0.15829518f, - 0.09055499f, 0.56280005f, 0.17405272f, - 0.06240423f, 0.56280005f, 0.18577307f, - 0.03209404f, 0.56280005f, 0.19308069f, - 0.00000000f, 0.56280005f, 0.19560002f, - 0.26289999f, 0.54869998f, 0.00000001f, - 0.25951380f, 0.54869998f, 0.04313663f, - 0.24969190f, 0.54869998f, 0.08387563f, - 0.23393893f, 0.54870003f, 0.12171219f, - 0.21275970f, 0.54869998f, 0.15614158f, - 0.18665901f, 0.54869998f, 0.18665899f, - 0.15614155f, 0.54869998f, 0.21275972f, - 0.12171219f, 0.54869998f, 0.23393893f, - 0.08387562f, 0.54869998f, 0.24969190f, - 0.04313662f, 0.54869998f, 0.25951385f, - 0.00000000f, 0.54869998f, 0.26289999f, - 0.33680001f, 0.53640002f, 0.00000001f, - 0.33246198f, 0.53639996f, 0.05526215f, - 0.31987920f, 0.53640002f, 0.10745268f, - 0.29969811f, 0.53640002f, 0.15592493f, - 0.27256551f, 0.53640002f, 0.20003228f, - 0.23912801f, 0.53640002f, 0.23912801f, - 0.20003226f, 0.53640002f, 0.27256551f, - 0.15592495f, 0.53640008f, 0.29969811f, - 0.10745268f, 0.53640008f, 0.31987917f, - 0.05526213f, 0.53640002f, 0.33246201f, - 0.00000000f, 0.53640002f, 0.33680001f, - 0.41250002f, 0.52499998f, 0.00000001f, - 0.40718701f, 0.52499992f, 0.06768300f, - 0.39177606f, 0.52499998f, 0.13160400f, - 0.36705902f, 0.52499998f, 0.19097100f, - 0.33382803f, 0.52499998f, 0.24499202f, - 0.29287499f, 0.52499998f, 0.29287499f, - 0.24499199f, 0.52499998f, 0.33382803f, - 0.19097102f, 0.52499998f, 0.36705902f, - 0.13160400f, 0.52499998f, 0.39177603f, - 0.06768297f, 0.52499998f, 0.40718701f, - 0.00000000f, 0.52499998f, 0.41250002f, - 0.48519999f, 0.51359999f, 0.00000001f, - 0.47895056f, 0.51359999f, 0.07961162f, - 0.46082360f, 0.51359999f, 0.15479822f, - 0.43175036f, 0.51359999f, 0.22462820f, - 0.39266267f, 0.51360005f, 0.28817001f, - 0.34449199f, 0.51359999f, 0.34449199f, - 0.28816998f, 0.51359999f, 0.39266264f, - 0.22462821f, 0.51359999f, 0.43175036f, - 0.15479821f, 0.51359999f, 0.46082354f, - 0.07961158f, 0.51359999f, 0.47895062f, - 0.00000000f, 0.51359999f, 0.48519999f, - 0.55009997f, 0.50129998f, 0.00000001f, - 0.54301465f, 0.50129992f, 0.09026041f, - 0.52246296f, 0.50129998f, 0.17550392f, - 0.48950094f, 0.50129998f, 0.25467429f, - 0.44518495f, 0.50129998f, 0.32671541f, - 0.39057100f, 0.50129998f, 0.39057100f, - 0.32671538f, 0.50129998f, 0.44518495f, - 0.25467432f, 0.50129998f, 0.48950097f, - 0.17550389f, 0.50129998f, 0.52246296f, - 0.09026037f, 0.50129998f, 0.54301471f, - 0.00000000f, 0.50129998f, 0.55009997f, - 0.60240000f, 0.48720002f, 0.00000001f, - 0.59464109f, 0.48719996f, 0.09884179f, - 0.57213551f, 0.48720005f, 0.19218971f, - 0.53603959f, 0.48719999f, 0.27888709f, - 0.48751029f, 0.48720002f, 0.35777742f, - 0.42770401f, 0.48720002f, 0.42770401f, - 0.35777742f, 0.48720002f, 0.48751026f, - 0.27888709f, 0.48720005f, 0.53603959f, - 0.19218969f, 0.48720002f, 0.57213545f, - 0.09884176f, 0.48720002f, 0.59464109f, - 0.00000000f, 0.48720002f, 0.60240000f, - 0.63730001f, 0.47040004f, 0.00000001f, - 0.62909156f, 0.47039998f, 0.10456818f, - 0.60528207f, 0.47040007f, 0.20332420f, - 0.56709504f, 0.47040001f, 0.29504442f, - 0.51575416f, 0.47040004f, 0.37850523f, - 0.45248300f, 0.47040004f, 0.45248300f, - 0.37850523f, 0.47040004f, 0.51575416f, - 0.29504442f, 0.47040004f, 0.56709504f, - 0.20332420f, 0.47040004f, 0.60528207f, - 0.10456815f, 0.47040004f, 0.62909162f, - 0.00000000f, 0.47040004f, 0.63730001f, - 0.64999998f, 0.45000005f, 0.00000001f, - 0.64162791f, 0.44999996f, 0.10665201f, - 0.61734402f, 0.45000011f, 0.20737600f, - 0.57839590f, 0.45000002f, 0.30092400f, - 0.52603197f, 0.45000008f, 0.38604802f, - 0.46149999f, 0.45000005f, 0.46149999f, - 0.38604796f, 0.45000005f, 0.52603197f, - 0.30092400f, 0.45000008f, 0.57839596f, - 0.20737599f, 0.45000005f, 0.61734402f, - 0.10665196f, 0.45000005f, 0.64162797f, - 0.00000000f, 0.45000005f, 0.64999998f, - 0.00000000f, 0.60000002f, -0.09999999f, - 0.01640800f, 0.59999996f, -0.09871199f, - 0.03190400f, 0.60000008f, -0.09497599f, - 0.04629600f, 0.60000008f, -0.08898398f, - 0.05939200f, 0.60000002f, -0.08092800f, - 0.07100000f, 0.60000002f, -0.07099999f, - 0.08092801f, 0.60000002f, -0.05939199f, - 0.08898400f, 0.60000002f, -0.04629600f, - 0.09497601f, 0.60000002f, -0.03190399f, - 0.09871200f, 0.60000002f, -0.01640799f, - 0.10000000f, 0.60000002f, 0.00000001f, - 0.00000000f, 0.57959992f, -0.13969998f, - 0.02292197f, 0.57959986f, -0.13790064f, - 0.04456988f, 0.57959998f, -0.13268146f, - 0.06467551f, 0.57959992f, -0.12431064f, - 0.08297062f, 0.57959998f, -0.11305641f, - 0.09918699f, 0.57959992f, -0.09918699f, - 0.11305641f, 0.57959992f, -0.08297061f, - 0.12431064f, 0.57959998f, -0.06467551f, - 0.13268146f, 0.57959992f, -0.04456988f, - 0.13790065f, 0.57959992f, -0.02292196f, - 0.13969998f, 0.57959992f, 0.00000001f, - 0.00000000f, 0.56280005f, -0.19560000f, - 0.03209405f, 0.56279999f, -0.19308066f, - 0.06240423f, 0.56280011f, -0.18577306f, - 0.09055499f, 0.56280005f, -0.17405270f, - 0.11617076f, 0.56280005f, -0.15829517f, - 0.13887601f, 0.56280005f, -0.13887601f, - 0.15829518f, 0.56280005f, -0.11617075f, - 0.17405272f, 0.56280005f, -0.09055498f, - 0.18577307f, 0.56280005f, -0.06240422f, - 0.19308069f, 0.56280005f, -0.03209403f, - 0.19560002f, 0.56280005f, 0.00000001f, - 0.00000000f, 0.54869998f, -0.26289999f, - 0.04313663f, 0.54869998f, -0.25951380f, - 0.08387563f, 0.54869998f, -0.24969190f, - 0.12171219f, 0.54870003f, -0.23393893f, - 0.15614158f, 0.54869998f, -0.21275970f, - 0.18665899f, 0.54869998f, -0.18665899f, - 0.21275972f, 0.54869998f, -0.15614155f, - 0.23393893f, 0.54869998f, -0.12171219f, - 0.24969190f, 0.54869998f, -0.08387561f, - 0.25951385f, 0.54869998f, -0.04313661f, - 0.26289999f, 0.54869998f, 0.00000001f, - 0.00000000f, 0.53640002f, -0.33680001f, - 0.05526214f, 0.53639996f, -0.33246198f, - 0.10745268f, 0.53640002f, -0.31987920f, - 0.15592493f, 0.53640002f, -0.29969811f, - 0.20003228f, 0.53640002f, -0.27256551f, - 0.23912801f, 0.53640002f, -0.23912799f, - 0.27256551f, 0.53640002f, -0.20003225f, - 0.29969811f, 0.53640008f, -0.15592495f, - 0.31987917f, 0.53640008f, -0.10745267f, - 0.33246201f, 0.53640002f, -0.05526212f, - 0.33680001f, 0.53640002f, 0.00000001f, - 0.00000000f, 0.52499998f, -0.41250002f, - 0.06768300f, 0.52499992f, -0.40718701f, - 0.13160400f, 0.52499998f, -0.39177606f, - 0.19097100f, 0.52499998f, -0.36705902f, - 0.24499202f, 0.52499998f, -0.33382803f, - 0.29287499f, 0.52499998f, -0.29287499f, - 0.33382803f, 0.52499998f, -0.24499199f, - 0.36705902f, 0.52499998f, -0.19097102f, - 0.39177603f, 0.52499998f, -0.13160400f, - 0.40718701f, 0.52499998f, -0.06768297f, - 0.41250002f, 0.52499998f, 0.00000001f, - 0.00000000f, 0.51359999f, -0.48519999f, - 0.07961161f, 0.51359999f, -0.47895056f, - 0.15479822f, 0.51359999f, -0.46082360f, - 0.22462820f, 0.51359999f, -0.43175036f, - 0.28817001f, 0.51360005f, -0.39266267f, - 0.34449199f, 0.51359999f, -0.34449199f, - 0.39266264f, 0.51359999f, -0.28816998f, - 0.43175036f, 0.51359999f, -0.22462821f, - 0.46082354f, 0.51359999f, -0.15479821f, - 0.47895062f, 0.51359999f, -0.07961158f, - 0.48519999f, 0.51359999f, 0.00000001f, - 0.00000000f, 0.50129998f, -0.55009997f, - 0.09026040f, 0.50129992f, -0.54301465f, - 0.17550392f, 0.50129998f, -0.52246296f, - 0.25467429f, 0.50129998f, -0.48950094f, - 0.32671541f, 0.50129998f, -0.44518495f, - 0.39057100f, 0.50129998f, -0.39057100f, - 0.44518495f, 0.50129998f, -0.32671538f, - 0.48950097f, 0.50129998f, -0.25467432f, - 0.52246296f, 0.50129998f, -0.17550389f, - 0.54301471f, 0.50129998f, -0.09026036f, - 0.55009997f, 0.50129998f, 0.00000001f, - 0.00000000f, 0.48720002f, -0.60240000f, - 0.09884179f, 0.48719996f, -0.59464109f, - 0.19218971f, 0.48720005f, -0.57213551f, - 0.27888709f, 0.48719999f, -0.53603959f, - 0.35777742f, 0.48720002f, -0.48751029f, - 0.42770401f, 0.48720002f, -0.42770401f, - 0.48751026f, 0.48720002f, -0.35777742f, - 0.53603959f, 0.48720005f, -0.27888709f, - 0.57213545f, 0.48720002f, -0.19218969f, - 0.59464109f, 0.48720002f, -0.09884175f, - 0.60240000f, 0.48720002f, 0.00000001f, - 0.00000000f, 0.47040004f, -0.63730001f, - 0.10456818f, 0.47039998f, -0.62909156f, - 0.20332420f, 0.47040007f, -0.60528207f, - 0.29504442f, 0.47040001f, -0.56709504f, - 0.37850523f, 0.47040004f, -0.51575416f, - 0.45248300f, 0.47040004f, -0.45248300f, - 0.51575416f, 0.47040004f, -0.37850523f, - 0.56709504f, 0.47040004f, -0.29504442f, - 0.60528207f, 0.47040004f, -0.20332420f, - 0.62909162f, 0.47040004f, -0.10456815f, - 0.63730001f, 0.47040004f, 0.00000001f, - 0.00000000f, 0.45000005f, -0.64999998f, - 0.10665200f, 0.44999996f, -0.64162791f, - 0.20737600f, 0.45000011f, -0.61734402f, - 0.30092400f, 0.45000002f, -0.57839590f, - 0.38604802f, 0.45000008f, -0.52603197f, - 0.46149999f, 0.45000005f, -0.46149999f, - 0.52603197f, 0.45000005f, -0.38604796f, - 0.57839596f, 0.45000008f, -0.30092400f, - 0.61734402f, 0.45000005f, -0.20737599f, - 0.64162797f, 0.45000005f, -0.10665195f, - 0.64999998f, 0.45000005f, 0.00000001f, - 0.00000000f, 0.60000002f, 0.10000001f, - -0.01640800f, 0.59999996f, 0.09871200f, - -0.03190400f, 0.60000008f, 0.09497602f, - -0.04629600f, 0.60000008f, 0.08898401f, - -0.05939200f, 0.60000002f, 0.08092801f, - -0.07100000f, 0.60000002f, 0.07100001f, - -0.08092801f, 0.60000002f, 0.05939201f, - -0.08898400f, 0.60000002f, 0.04629601f, - -0.09497601f, 0.60000002f, 0.03190401f, - -0.09871200f, 0.60000002f, 0.01640800f, - -0.10000000f, 0.60000002f, 0.00000001f, - 0.00000000f, 0.57959992f, 0.13970001f, - -0.02292197f, 0.57959986f, 0.13790067f, - -0.04456988f, 0.57959998f, 0.13268149f, - -0.06467551f, 0.57959992f, 0.12431065f, - -0.08297062f, 0.57959998f, 0.11305643f, - -0.09918699f, 0.57959992f, 0.09918701f, - -0.11305641f, 0.57959992f, 0.08297063f, - -0.12431064f, 0.57959998f, 0.06467552f, - -0.13268146f, 0.57959992f, 0.04456989f, - -0.13790065f, 0.57959992f, 0.02292197f, - -0.13969998f, 0.57959992f, 0.00000001f, - 0.00000000f, 0.56280005f, 0.19560002f, - -0.03209405f, 0.56279999f, 0.19308068f, - -0.06240423f, 0.56280011f, 0.18577307f, - -0.09055499f, 0.56280005f, 0.17405272f, - -0.11617076f, 0.56280005f, 0.15829518f, - -0.13887601f, 0.56280005f, 0.13887602f, - -0.15829518f, 0.56280005f, 0.11617076f, - -0.17405272f, 0.56280005f, 0.09055499f, - -0.18577307f, 0.56280005f, 0.06240423f, - -0.19308069f, 0.56280005f, 0.03209404f, - -0.19560002f, 0.56280005f, 0.00000001f, - 0.00000000f, 0.54869998f, 0.26289999f, - -0.04313663f, 0.54869998f, 0.25951380f, - -0.08387563f, 0.54869998f, 0.24969190f, - -0.12171219f, 0.54870003f, 0.23393893f, - -0.15614158f, 0.54869998f, 0.21275970f, - -0.18665899f, 0.54869998f, 0.18665901f, - -0.21275972f, 0.54869998f, 0.15614155f, - -0.23393893f, 0.54869998f, 0.12171219f, - -0.24969190f, 0.54869998f, 0.08387562f, - -0.25951385f, 0.54869998f, 0.04313662f, - -0.26289999f, 0.54869998f, 0.00000001f, - 0.00000000f, 0.53640002f, 0.33680001f, - -0.05526214f, 0.53639996f, 0.33246198f, - -0.10745268f, 0.53640002f, 0.31987920f, - -0.15592493f, 0.53640002f, 0.29969811f, - -0.20003228f, 0.53640002f, 0.27256551f, - -0.23912801f, 0.53640002f, 0.23912801f, - -0.27256551f, 0.53640002f, 0.20003226f, - -0.29969811f, 0.53640008f, 0.15592495f, - -0.31987917f, 0.53640008f, 0.10745268f, - -0.33246201f, 0.53640002f, 0.05526213f, - -0.33680001f, 0.53640002f, 0.00000001f, - 0.00000000f, 0.52499998f, 0.41250002f, - -0.06768300f, 0.52499992f, 0.40718701f, - -0.13160400f, 0.52499998f, 0.39177606f, - -0.19097100f, 0.52499998f, 0.36705902f, - -0.24499202f, 0.52499998f, 0.33382803f, - -0.29287499f, 0.52499998f, 0.29287499f, - -0.33382803f, 0.52499998f, 0.24499199f, - -0.36705902f, 0.52499998f, 0.19097102f, - -0.39177603f, 0.52499998f, 0.13160400f, - -0.40718701f, 0.52499998f, 0.06768298f, - -0.41250002f, 0.52499998f, 0.00000001f, - 0.00000000f, 0.51359999f, 0.48519999f, - -0.07961161f, 0.51359999f, 0.47895056f, - -0.15479822f, 0.51359999f, 0.46082360f, - -0.22462820f, 0.51359999f, 0.43175036f, - -0.28817001f, 0.51360005f, 0.39266267f, - -0.34449199f, 0.51359999f, 0.34449199f, - -0.39266264f, 0.51359999f, 0.28816998f, - -0.43175036f, 0.51359999f, 0.22462821f, - -0.46082354f, 0.51359999f, 0.15479821f, - -0.47895062f, 0.51359999f, 0.07961159f, - -0.48519999f, 0.51359999f, 0.00000001f, - 0.00000000f, 0.50129998f, 0.55009997f, - -0.09026040f, 0.50129992f, 0.54301465f, - -0.17550392f, 0.50129998f, 0.52246296f, - -0.25467429f, 0.50129998f, 0.48950094f, - -0.32671541f, 0.50129998f, 0.44518495f, - -0.39057100f, 0.50129998f, 0.39057100f, - -0.44518495f, 0.50129998f, 0.32671538f, - -0.48950097f, 0.50129998f, 0.25467432f, - -0.52246296f, 0.50129998f, 0.17550389f, - -0.54301471f, 0.50129998f, 0.09026038f, - -0.55009997f, 0.50129998f, 0.00000001f, - 0.00000000f, 0.48720002f, 0.60240000f, - -0.09884179f, 0.48719996f, 0.59464109f, - -0.19218971f, 0.48720005f, 0.57213551f, - -0.27888709f, 0.48719999f, 0.53603959f, - -0.35777742f, 0.48720002f, 0.48751029f, - -0.42770401f, 0.48720002f, 0.42770401f, - -0.48751026f, 0.48720002f, 0.35777742f, - -0.53603959f, 0.48720005f, 0.27888709f, - -0.57213545f, 0.48720002f, 0.19218969f, - -0.59464109f, 0.48720002f, 0.09884176f, - -0.60240000f, 0.48720002f, 0.00000001f, - 0.00000000f, 0.47040004f, 0.63730001f, - -0.10456818f, 0.47039998f, 0.62909156f, - -0.20332420f, 0.47040007f, 0.60528207f, - -0.29504442f, 0.47040001f, 0.56709504f, - -0.37850523f, 0.47040004f, 0.51575416f, - -0.45248300f, 0.47040004f, 0.45248300f, - -0.51575416f, 0.47040004f, 0.37850523f, - -0.56709504f, 0.47040004f, 0.29504442f, - -0.60528207f, 0.47040004f, 0.20332420f, - -0.62909162f, 0.47040004f, 0.10456816f, - -0.63730001f, 0.47040004f, 0.00000001f, - 0.00000000f, 0.45000005f, 0.64999998f, - -0.10665200f, 0.44999996f, 0.64162791f, - -0.20737600f, 0.45000011f, 0.61734402f, - -0.30092400f, 0.45000002f, 0.57839590f, - -0.38604802f, 0.45000008f, 0.52603197f, - -0.46149999f, 0.45000005f, 0.46149999f, - -0.52603197f, 0.45000005f, 0.38604796f, - -0.57839596f, 0.45000008f, 0.30092400f, - -0.61734402f, 0.45000005f, 0.20737599f, - -0.64162797f, 0.45000005f, 0.10665197f, - -0.64999998f, 0.45000005f, 0.00000001f, - -0.10000000f, 0.60000002f, 0.00000001f, - -0.09871199f, 0.59999996f, -0.01640799f, - -0.09497602f, 0.60000008f, -0.03190399f, - -0.08898400f, 0.60000008f, -0.04629599f, - -0.08092801f, 0.60000002f, -0.05939199f, - -0.07100000f, 0.60000002f, -0.07099999f, - -0.05939200f, 0.60000002f, -0.08092800f, - -0.04629600f, 0.60000002f, -0.08898400f, - -0.03190400f, 0.60000002f, -0.09497599f, - -0.01640799f, 0.60000002f, -0.09871200f, - 0.00000000f, 0.60000002f, -0.09999999f, - -0.13969998f, 0.57959992f, 0.00000001f, - -0.13790064f, 0.57959986f, -0.02292197f, - -0.13268146f, 0.57959998f, -0.04456988f, - -0.12431064f, 0.57959992f, -0.06467550f, - -0.11305641f, 0.57959998f, -0.08297062f, - -0.09918699f, 0.57959992f, -0.09918699f, - -0.08297062f, 0.57959992f, -0.11305641f, - -0.06467551f, 0.57959998f, -0.12431063f, - -0.04456988f, 0.57959992f, -0.13268146f, - -0.02292197f, 0.57959992f, -0.13790065f, - 0.00000000f, 0.57959992f, -0.13969998f, - -0.19560002f, 0.56280005f, 0.00000001f, - -0.19308068f, 0.56279999f, -0.03209404f, - -0.18577307f, 0.56280011f, -0.06240422f, - -0.17405272f, 0.56280005f, -0.09055497f, - -0.15829518f, 0.56280005f, -0.11617076f, - -0.13887602f, 0.56280005f, -0.13887601f, - -0.11617076f, 0.56280005f, -0.15829517f, - -0.09055499f, 0.56280005f, -0.17405272f, - -0.06240423f, 0.56280005f, -0.18577306f, - -0.03209404f, 0.56280005f, -0.19308066f, - 0.00000000f, 0.56280005f, -0.19560000f, - -0.26289999f, 0.54869998f, 0.00000001f, - -0.25951380f, 0.54869998f, -0.04313662f, - -0.24969190f, 0.54869998f, -0.08387562f, - -0.23393893f, 0.54870003f, -0.12171219f, - -0.21275970f, 0.54869998f, -0.15614156f, - -0.18665901f, 0.54869998f, -0.18665899f, - -0.15614155f, 0.54869998f, -0.21275972f, - -0.12171219f, 0.54869998f, -0.23393893f, - -0.08387562f, 0.54869998f, -0.24969190f, - -0.04313662f, 0.54869998f, -0.25951385f, - 0.00000000f, 0.54869998f, -0.26289999f, - -0.33680001f, 0.53640002f, 0.00000001f, - -0.33246198f, 0.53639996f, -0.05526214f, - -0.31987920f, 0.53640002f, -0.10745268f, - -0.29969811f, 0.53640002f, -0.15592493f, - -0.27256551f, 0.53640002f, -0.20003226f, - -0.23912801f, 0.53640002f, -0.23912801f, - -0.20003226f, 0.53640002f, -0.27256551f, - -0.15592495f, 0.53640008f, -0.29969811f, - -0.10745268f, 0.53640008f, -0.31987917f, - -0.05526213f, 0.53640002f, -0.33246201f, - 0.00000000f, 0.53640002f, -0.33680001f, - -0.41250002f, 0.52499998f, 0.00000001f, - -0.40718701f, 0.52499992f, -0.06768300f, - -0.39177606f, 0.52499998f, -0.13160400f, - -0.36705902f, 0.52499998f, -0.19097100f, - -0.33382803f, 0.52499998f, -0.24499202f, - -0.29287499f, 0.52499998f, -0.29287499f, - -0.24499199f, 0.52499998f, -0.33382803f, - -0.19097102f, 0.52499998f, -0.36705902f, - -0.13160400f, 0.52499998f, -0.39177603f, - -0.06768297f, 0.52499998f, -0.40718701f, - 0.00000000f, 0.52499998f, -0.41250002f, - -0.48519999f, 0.51359999f, 0.00000001f, - -0.47895056f, 0.51359999f, -0.07961161f, - -0.46082360f, 0.51359999f, -0.15479822f, - -0.43175036f, 0.51359999f, -0.22462820f, - -0.39266267f, 0.51360005f, -0.28817001f, - -0.34449199f, 0.51359999f, -0.34449199f, - -0.28816998f, 0.51359999f, -0.39266264f, - -0.22462821f, 0.51359999f, -0.43175036f, - -0.15479821f, 0.51359999f, -0.46082354f, - -0.07961158f, 0.51359999f, -0.47895062f, - 0.00000000f, 0.51359999f, -0.48519999f, - -0.55009997f, 0.50129998f, 0.00000001f, - -0.54301465f, 0.50129992f, -0.09026039f, - -0.52246296f, 0.50129998f, -0.17550392f, - -0.48950094f, 0.50129998f, -0.25467429f, - -0.44518495f, 0.50129998f, -0.32671541f, - -0.39057100f, 0.50129998f, -0.39057100f, - -0.32671538f, 0.50129998f, -0.44518495f, - -0.25467432f, 0.50129998f, -0.48950097f, - -0.17550389f, 0.50129998f, -0.52246296f, - -0.09026037f, 0.50129998f, -0.54301471f, - 0.00000000f, 0.50129998f, -0.55009997f, - -0.60240000f, 0.48720002f, 0.00000001f, - -0.59464109f, 0.48719996f, -0.09884178f, - -0.57213551f, 0.48720005f, -0.19218971f, - -0.53603959f, 0.48719999f, -0.27888709f, - -0.48751029f, 0.48720002f, -0.35777742f, - -0.42770401f, 0.48720002f, -0.42770401f, - -0.35777742f, 0.48720002f, -0.48751026f, - -0.27888709f, 0.48720005f, -0.53603959f, - -0.19218969f, 0.48720002f, -0.57213545f, - -0.09884176f, 0.48720002f, -0.59464109f, - 0.00000000f, 0.48720002f, -0.60240000f, - -0.63730001f, 0.47040004f, 0.00000001f, - -0.62909156f, 0.47039998f, -0.10456817f, - -0.60528207f, 0.47040007f, -0.20332420f, - -0.56709504f, 0.47040001f, -0.29504442f, - -0.51575416f, 0.47040004f, -0.37850523f, - -0.45248300f, 0.47040004f, -0.45248300f, - -0.37850523f, 0.47040004f, -0.51575416f, - -0.29504442f, 0.47040004f, -0.56709504f, - -0.20332420f, 0.47040004f, -0.60528207f, - -0.10456815f, 0.47040004f, -0.62909162f, - 0.00000000f, 0.47040004f, -0.63730001f, - -0.64999998f, 0.45000005f, 0.00000001f, - -0.64162791f, 0.44999996f, -0.10665199f, - -0.61734402f, 0.45000011f, -0.20737600f, - -0.57839590f, 0.45000002f, -0.30092400f, - -0.52603197f, 0.45000008f, -0.38604802f, - -0.46149999f, 0.45000005f, -0.46149999f, - -0.38604796f, 0.45000005f, -0.52603197f, - -0.30092400f, 0.45000008f, -0.57839596f, - -0.20737599f, 0.45000005f, -0.61734402f, - -0.10665196f, 0.45000005f, -0.64162797f, - 0.00000000f, 0.45000005f, -0.64999998f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.74891251f, 0.19413748f, - 0.03185407f, -0.74891245f, 0.19163698f, - 0.06193763f, -0.74891251f, 0.18438403f, - 0.08987789f, -0.74891245f, 0.17275129f, - 0.11530213f, -0.74891257f, 0.15711159f, - 0.13783762f, -0.74891251f, 0.13783762f, - 0.15711159f, -0.74891251f, 0.11530213f, - 0.17275131f, -0.74891257f, 0.08987789f, - 0.18438402f, -0.74891257f, 0.06193761f, - 0.19163698f, -0.74891251f, 0.03185406f, - 0.19413748f, -0.74891251f, -0.00000001f, - 0.00000000f, -0.74580008f, 0.35160002f, - 0.05769053f, -0.74579996f, 0.34707141f, - 0.11217448f, -0.74580014f, 0.33393562f, - 0.16277674f, -0.74580008f, 0.31286776f, - 0.20882230f, -0.74580008f, 0.28454286f, - 0.24963601f, -0.74580008f, 0.24963601f, - 0.28454286f, -0.74580008f, 0.20882228f, - 0.31286776f, -0.74580008f, 0.16277674f, - 0.33393565f, -0.74580008f, 0.11217446f, - 0.34707141f, -0.74580002f, 0.05769050f, - 0.35160002f, -0.74580008f, -0.00000001f, - 0.00000000f, -0.74088752f, 0.47621247f, - 0.07813694f, -0.74088746f, 0.47007880f, - 0.15193085f, -0.74088758f, 0.45228758f, - 0.22046733f, -0.74088752f, 0.42375290f, - 0.28283215f, -0.74088758f, 0.38538927f, - 0.33811086f, -0.74088752f, 0.33811086f, - 0.38538924f, -0.74088752f, 0.28283212f, - 0.42375290f, -0.74088752f, 0.22046733f, - 0.45228755f, -0.74088752f, 0.15193082f, - 0.47007886f, -0.74088752f, 0.07813691f, - 0.47621247f, -0.74088752f, -0.00000001f, - 0.00000000f, -0.73440003f, 0.57179999f, - 0.09382094f, -0.73439997f, 0.56443512f, - 0.18242709f, -0.73440009f, 0.54307282f, - 0.26472056f, -0.73440003f, 0.50881052f, - 0.33960345f, -0.73440003f, 0.46274635f, - 0.40597799f, -0.73440003f, 0.40597799f, - 0.46274632f, -0.73440009f, 0.33960345f, - 0.50881052f, -0.73440003f, 0.26472053f, - 0.54307282f, -0.73440003f, 0.18242708f, - 0.56443524f, -0.73440003f, 0.09382091f, - 0.57179999f, -0.73440003f, -0.00000001f, - 0.00000000f, -0.72656250f, 0.64218748f, - 0.10537013f, -0.72656244f, 0.63391608f, - 0.20488352f, -0.72656256f, 0.60992402f, - 0.29730710f, -0.72656256f, 0.57144409f, - 0.38140801f, -0.72656256f, 0.51970953f, - 0.45595312f, -0.72656250f, 0.45595312f, - 0.51970953f, -0.72656250f, 0.38140798f, - 0.57144415f, -0.72656250f, 0.29730713f, - 0.60992396f, -0.72656250f, 0.20488349f, - 0.63391614f, -0.72656250f, 0.10537008f, - 0.64218748f, -0.72656250f, -0.00000001f, - 0.00000000f, -0.71759999f, 0.69119996f, - 0.11341208f, -0.71759993f, 0.68229729f, - 0.22052045f, -0.71760005f, 0.65647405f, - 0.31999791f, -0.71759999f, 0.61505735f, - 0.41051748f, -0.71759999f, 0.55937433f, - 0.49075195f, -0.71759999f, 0.49075198f, - 0.55937433f, -0.71759999f, 0.41051745f, - 0.61505735f, -0.71759999f, 0.31999797f, - 0.65647411f, -0.71759999f, 0.22052044f, - 0.68229735f, -0.71759999f, 0.11341204f, - 0.69119996f, -0.71759999f, -0.00000001f, - 0.00000000f, -0.70773757f, 0.72266257f, - 0.11857446f, -0.70773745f, 0.71335465f, - 0.23055826f, -0.70773757f, 0.68635601f, - 0.33456385f, -0.70773745f, 0.64305401f, - 0.42920375f, -0.70773751f, 0.58483636f, - 0.51309043f, -0.70773751f, 0.51309037f, - 0.58483636f, -0.70773751f, 0.42920372f, - 0.64305407f, -0.70773757f, 0.33456385f, - 0.68635601f, -0.70773751f, 0.23055825f, - 0.71335471f, -0.70773751f, 0.11857441f, - 0.72266257f, -0.70773751f, -0.00000001f, - 0.00000000f, -0.69720000f, 0.74039996f, - 0.12148482f, -0.69719994f, 0.73086351f, - 0.23621722f, -0.69720006f, 0.70320231f, - 0.34277558f, -0.69720000f, 0.65883750f, - 0.43973836f, -0.69720006f, 0.59919089f, - 0.52568400f, -0.69719994f, 0.52568400f, - 0.59919089f, -0.69720006f, 0.43973833f, - 0.65883750f, -0.69720000f, 0.34277558f, - 0.70320225f, -0.69720006f, 0.23621720f, - 0.73086363f, -0.69720000f, 0.12148478f, - 0.74039996f, -0.69720000f, -0.00000001f, - 0.00000000f, -0.68621248f, 0.74823749f, - 0.12277080f, -0.68621248f, 0.73860013f, - 0.23871772f, -0.68621254f, 0.71064609f, - 0.34640405f, -0.68621248f, 0.66581166f, - 0.44439322f, -0.68621248f, 0.60553366f, - 0.53124863f, -0.68621248f, 0.53124863f, - 0.60553366f, -0.68621248f, 0.44439319f, - 0.66581166f, -0.68621254f, 0.34640405f, - 0.71064603f, -0.68621254f, 0.23871769f, - 0.73860019f, -0.68621248f, 0.12277076f, - 0.74823749f, -0.68621248f, -0.00000001f, - 0.00000000f, -0.67500001f, 0.75000000f, - 0.12305999f, -0.67499995f, 0.74033999f, - 0.23928000f, -0.67500007f, 0.71232003f, - 0.34721997f, -0.67500001f, 0.66737998f, - 0.44544002f, -0.67500007f, 0.60696000f, - 0.53250003f, -0.67500007f, 0.53250003f, - 0.60696000f, -0.67500001f, 0.44543999f, - 0.66738003f, -0.67500001f, 0.34722000f, - 0.71231997f, -0.67500001f, 0.23927999f, - 0.74033999f, -0.67500001f, 0.12305995f, - 0.75000000f, -0.67500001f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.19413748f, -0.74891251f, -0.00000001f, - 0.19163698f, -0.74891245f, -0.03185408f, - 0.18438403f, -0.74891251f, -0.06193763f, - 0.17275129f, -0.74891245f, -0.08987790f, - 0.15711159f, -0.74891257f, -0.11530215f, - 0.13783762f, -0.74891251f, -0.13783762f, - 0.11530213f, -0.74891251f, -0.15711159f, - 0.08987789f, -0.74891257f, -0.17275131f, - 0.06193762f, -0.74891257f, -0.18438402f, - 0.03185407f, -0.74891251f, -0.19163698f, - 0.00000000f, -0.74891251f, -0.19413748f, - 0.35160002f, -0.74580008f, -0.00000001f, - 0.34707141f, -0.74579996f, -0.05769053f, - 0.33393562f, -0.74580014f, -0.11217449f, - 0.31286776f, -0.74580008f, -0.16277674f, - 0.28454286f, -0.74580008f, -0.20882230f, - 0.24963601f, -0.74580008f, -0.24963601f, - 0.20882228f, -0.74580008f, -0.28454286f, - 0.16277674f, -0.74580008f, -0.31286776f, - 0.11217447f, -0.74580008f, -0.33393565f, - 0.05769051f, -0.74580002f, -0.34707141f, - 0.00000000f, -0.74580008f, -0.35160002f, - 0.47621247f, -0.74088752f, -0.00000001f, - 0.47007880f, -0.74088746f, -0.07813694f, - 0.45228758f, -0.74088758f, -0.15193085f, - 0.42375290f, -0.74088752f, -0.22046733f, - 0.38538927f, -0.74088758f, -0.28283215f, - 0.33811086f, -0.74088752f, -0.33811086f, - 0.28283212f, -0.74088752f, -0.38538924f, - 0.22046733f, -0.74088752f, -0.42375290f, - 0.15193082f, -0.74088752f, -0.45228755f, - 0.07813691f, -0.74088752f, -0.47007886f, - 0.00000000f, -0.74088752f, -0.47621247f, - 0.57179999f, -0.73440003f, -0.00000001f, - 0.56443512f, -0.73439997f, -0.09382095f, - 0.54307282f, -0.73440009f, -0.18242709f, - 0.50881052f, -0.73440003f, -0.26472056f, - 0.46274635f, -0.73440003f, -0.33960345f, - 0.40597799f, -0.73440003f, -0.40597799f, - 0.33960345f, -0.73440009f, -0.46274632f, - 0.26472053f, -0.73440003f, -0.50881052f, - 0.18242708f, -0.73440003f, -0.54307282f, - 0.09382091f, -0.73440003f, -0.56443524f, - 0.00000000f, -0.73440003f, -0.57179999f, - 0.64218748f, -0.72656250f, -0.00000001f, - 0.63391608f, -0.72656244f, -0.10537013f, - 0.60992402f, -0.72656256f, -0.20488352f, - 0.57144409f, -0.72656256f, -0.29730710f, - 0.51970953f, -0.72656256f, -0.38140801f, - 0.45595312f, -0.72656250f, -0.45595312f, - 0.38140798f, -0.72656250f, -0.51970953f, - 0.29730713f, -0.72656250f, -0.57144415f, - 0.20488349f, -0.72656250f, -0.60992396f, - 0.10537009f, -0.72656250f, -0.63391614f, - 0.00000000f, -0.72656250f, -0.64218748f, - 0.69119996f, -0.71759999f, -0.00000001f, - 0.68229729f, -0.71759993f, -0.11341209f, - 0.65647405f, -0.71760005f, -0.22052045f, - 0.61505735f, -0.71759999f, -0.31999791f, - 0.55937433f, -0.71759999f, -0.41051748f, - 0.49075198f, -0.71759999f, -0.49075195f, - 0.41051745f, -0.71759999f, -0.55937433f, - 0.31999797f, -0.71759999f, -0.61505735f, - 0.22052044f, -0.71759999f, -0.65647411f, - 0.11341204f, -0.71759999f, -0.68229735f, - 0.00000000f, -0.71759999f, -0.69119996f, - 0.72266257f, -0.70773751f, -0.00000001f, - 0.71335465f, -0.70773745f, -0.11857446f, - 0.68635601f, -0.70773757f, -0.23055826f, - 0.64305401f, -0.70773745f, -0.33456385f, - 0.58483636f, -0.70773751f, -0.42920375f, - 0.51309037f, -0.70773751f, -0.51309043f, - 0.42920372f, -0.70773751f, -0.58483636f, - 0.33456385f, -0.70773751f, -0.64305407f, - 0.23055825f, -0.70773751f, -0.68635601f, - 0.11857442f, -0.70773751f, -0.71335471f, - 0.00000000f, -0.70773751f, -0.72266257f, - 0.74039996f, -0.69720000f, -0.00000001f, - 0.73086351f, -0.69719994f, -0.12148483f, - 0.70320231f, -0.69720006f, -0.23621722f, - 0.65883750f, -0.69720000f, -0.34277558f, - 0.59919089f, -0.69720006f, -0.43973836f, - 0.52568400f, -0.69719994f, -0.52568400f, - 0.43973833f, -0.69720006f, -0.59919089f, - 0.34277558f, -0.69720000f, -0.65883750f, - 0.23621720f, -0.69720006f, -0.70320225f, - 0.12148479f, -0.69720000f, -0.73086363f, - 0.00000000f, -0.69720000f, -0.74039996f, - 0.74823749f, -0.68621248f, -0.00000001f, - 0.73860013f, -0.68621248f, -0.12277081f, - 0.71064609f, -0.68621254f, -0.23871772f, - 0.66581166f, -0.68621248f, -0.34640405f, - 0.60553366f, -0.68621248f, -0.44439322f, - 0.53124863f, -0.68621248f, -0.53124863f, - 0.44439319f, -0.68621248f, -0.60553366f, - 0.34640405f, -0.68621254f, -0.66581166f, - 0.23871769f, -0.68621254f, -0.71064603f, - 0.12277076f, -0.68621248f, -0.73860019f, - 0.00000000f, -0.68621248f, -0.74823749f, - 0.75000000f, -0.67500001f, -0.00000001f, - 0.74033999f, -0.67499995f, -0.12306000f, - 0.71232003f, -0.67500007f, -0.23928000f, - 0.66737998f, -0.67500001f, -0.34721997f, - 0.60696000f, -0.67500007f, -0.44544002f, - 0.53250003f, -0.67500007f, -0.53250003f, - 0.44543999f, -0.67500001f, -0.60696000f, - 0.34722000f, -0.67500001f, -0.66738003f, - 0.23927999f, -0.67500001f, -0.71231997f, - 0.12305996f, -0.67500001f, -0.74033999f, - 0.00000000f, -0.67500001f, -0.75000000f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - -0.19413748f, -0.74891251f, -0.00000001f, - -0.19163698f, -0.74891245f, 0.03185407f, - -0.18438403f, -0.74891251f, 0.06193762f, - -0.17275129f, -0.74891245f, 0.08987788f, - -0.15711159f, -0.74891257f, 0.11530213f, - -0.13783762f, -0.74891251f, 0.13783762f, - -0.11530213f, -0.74891251f, 0.15711159f, - -0.08987789f, -0.74891257f, 0.17275131f, - -0.06193762f, -0.74891257f, 0.18438402f, - -0.03185407f, -0.74891251f, 0.19163698f, - 0.00000000f, -0.74891251f, 0.19413748f, - -0.35160002f, -0.74580008f, -0.00000001f, - -0.34707141f, -0.74579996f, 0.05769052f, - -0.33393562f, -0.74580014f, 0.11217447f, - -0.31286776f, -0.74580008f, 0.16277674f, - -0.28454286f, -0.74580008f, 0.20882230f, - -0.24963601f, -0.74580008f, 0.24963601f, - -0.20882228f, -0.74580008f, 0.28454286f, - -0.16277674f, -0.74580008f, 0.31286776f, - -0.11217447f, -0.74580008f, 0.33393565f, - -0.05769051f, -0.74580002f, 0.34707141f, - 0.00000000f, -0.74580008f, 0.35160002f, - -0.47621247f, -0.74088752f, -0.00000001f, - -0.47007880f, -0.74088746f, 0.07813693f, - -0.45228758f, -0.74088758f, 0.15193084f, - -0.42375290f, -0.74088752f, 0.22046733f, - -0.38538927f, -0.74088758f, 0.28283215f, - -0.33811086f, -0.74088752f, 0.33811086f, - -0.28283212f, -0.74088752f, 0.38538924f, - -0.22046733f, -0.74088752f, 0.42375290f, - -0.15193082f, -0.74088752f, 0.45228755f, - -0.07813691f, -0.74088752f, 0.47007886f, - 0.00000000f, -0.74088752f, 0.47621247f, - -0.57179999f, -0.73440003f, -0.00000001f, - -0.56443512f, -0.73439997f, 0.09382094f, - -0.54307282f, -0.73440009f, 0.18242709f, - -0.50881052f, -0.73440003f, 0.26472056f, - -0.46274635f, -0.73440003f, 0.33960345f, - -0.40597799f, -0.73440003f, 0.40597799f, - -0.33960345f, -0.73440009f, 0.46274632f, - -0.26472053f, -0.73440003f, 0.50881052f, - -0.18242708f, -0.73440003f, 0.54307282f, - -0.09382091f, -0.73440003f, 0.56443524f, - 0.00000000f, -0.73440003f, 0.57179999f, - -0.64218748f, -0.72656250f, -0.00000001f, - -0.63391608f, -0.72656244f, 0.10537011f, - -0.60992402f, -0.72656256f, 0.20488352f, - -0.57144409f, -0.72656256f, 0.29730710f, - -0.51970953f, -0.72656256f, 0.38140801f, - -0.45595312f, -0.72656250f, 0.45595312f, - -0.38140798f, -0.72656250f, 0.51970953f, - -0.29730713f, -0.72656250f, 0.57144415f, - -0.20488349f, -0.72656250f, 0.60992396f, - -0.10537009f, -0.72656250f, 0.63391614f, - 0.00000000f, -0.72656250f, 0.64218748f, - -0.69119996f, -0.71759999f, -0.00000001f, - -0.68229729f, -0.71759993f, 0.11341207f, - -0.65647405f, -0.71760005f, 0.22052045f, - -0.61505735f, -0.71759999f, 0.31999791f, - -0.55937433f, -0.71759999f, 0.41051748f, - -0.49075198f, -0.71759999f, 0.49075195f, - -0.41051745f, -0.71759999f, 0.55937433f, - -0.31999797f, -0.71759999f, 0.61505735f, - -0.22052044f, -0.71759999f, 0.65647411f, - -0.11341204f, -0.71759999f, 0.68229735f, - 0.00000000f, -0.71759999f, 0.69119996f, - -0.72266257f, -0.70773751f, -0.00000001f, - -0.71335465f, -0.70773745f, 0.11857444f, - -0.68635601f, -0.70773757f, 0.23055826f, - -0.64305401f, -0.70773751f, 0.33456385f, - -0.58483636f, -0.70773751f, 0.42920375f, - -0.51309037f, -0.70773751f, 0.51309043f, - -0.42920372f, -0.70773751f, 0.58483636f, - -0.33456385f, -0.70773757f, 0.64305407f, - -0.23055825f, -0.70773757f, 0.68635601f, - -0.11857442f, -0.70773757f, 0.71335471f, - 0.00000000f, -0.70773757f, 0.72266257f, - -0.74039996f, -0.69720000f, -0.00000001f, - -0.73086351f, -0.69719994f, 0.12148482f, - -0.70320231f, -0.69720006f, 0.23621722f, - -0.65883750f, -0.69720000f, 0.34277558f, - -0.59919089f, -0.69720006f, 0.43973836f, - -0.52568400f, -0.69719994f, 0.52568400f, - -0.43973833f, -0.69720006f, 0.59919089f, - -0.34277558f, -0.69720000f, 0.65883750f, - -0.23621720f, -0.69720006f, 0.70320225f, - -0.12148479f, -0.69720000f, 0.73086363f, - 0.00000000f, -0.69720000f, 0.74039996f, - -0.74823749f, -0.68621248f, -0.00000001f, - -0.73860013f, -0.68621248f, 0.12277079f, - -0.71064609f, -0.68621254f, 0.23871772f, - -0.66581166f, -0.68621248f, 0.34640405f, - -0.60553366f, -0.68621248f, 0.44439322f, - -0.53124863f, -0.68621248f, 0.53124863f, - -0.44439319f, -0.68621248f, 0.60553366f, - -0.34640405f, -0.68621254f, 0.66581166f, - -0.23871769f, -0.68621254f, 0.71064603f, - -0.12277076f, -0.68621248f, 0.73860019f, - 0.00000000f, -0.68621248f, 0.74823749f, - -0.75000000f, -0.67500001f, -0.00000001f, - -0.74033999f, -0.67499995f, 0.12305998f, - -0.71232003f, -0.67500007f, 0.23928000f, - -0.66737998f, -0.67500001f, 0.34721997f, - -0.60696000f, -0.67500007f, 0.44544002f, - -0.53250003f, -0.67500007f, 0.53250003f, - -0.44543999f, -0.67500001f, 0.60696000f, - -0.34722000f, -0.67500001f, 0.66738003f, - -0.23927999f, -0.67500001f, 0.71231997f, - -0.12305996f, -0.67500001f, 0.74033999f, - 0.00000000f, -0.67500001f, 0.75000000f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000006f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.75000000f, -0.00000001f, - 0.00000000f, -0.74891251f, -0.19413748f, - -0.03185407f, -0.74891245f, -0.19163698f, - -0.06193763f, -0.74891251f, -0.18438403f, - -0.08987789f, -0.74891245f, -0.17275129f, - -0.11530213f, -0.74891257f, -0.15711159f, - -0.13783762f, -0.74891251f, -0.13783762f, - -0.15711159f, -0.74891251f, -0.11530213f, - -0.17275131f, -0.74891257f, -0.08987790f, - -0.18438402f, -0.74891257f, -0.06193763f, - -0.19163698f, -0.74891251f, -0.03185407f, - -0.19413748f, -0.74891251f, -0.00000001f, - 0.00000000f, -0.74580008f, -0.35160002f, - -0.05769053f, -0.74579996f, -0.34707141f, - -0.11217448f, -0.74580014f, -0.33393562f, - -0.16277674f, -0.74580008f, -0.31286776f, - -0.20882230f, -0.74580008f, -0.28454286f, - -0.24963601f, -0.74580008f, -0.24963601f, - -0.28454286f, -0.74580008f, -0.20882228f, - -0.31286776f, -0.74580008f, -0.16277674f, - -0.33393565f, -0.74580008f, -0.11217447f, - -0.34707141f, -0.74580002f, -0.05769052f, - -0.35160002f, -0.74580008f, -0.00000001f, - 0.00000000f, -0.74088752f, -0.47621247f, - -0.07813694f, -0.74088746f, -0.47007880f, - -0.15193085f, -0.74088758f, -0.45228758f, - -0.22046733f, -0.74088752f, -0.42375290f, - -0.28283215f, -0.74088758f, -0.38538927f, - -0.33811086f, -0.74088752f, -0.33811086f, - -0.38538924f, -0.74088752f, -0.28283212f, - -0.42375290f, -0.74088752f, -0.22046733f, - -0.45228755f, -0.74088752f, -0.15193082f, - -0.47007886f, -0.74088752f, -0.07813692f, - -0.47621247f, -0.74088752f, -0.00000001f, - 0.00000000f, -0.73440003f, -0.57179999f, - -0.09382094f, -0.73439997f, -0.56443512f, - -0.18242709f, -0.73440009f, -0.54307282f, - -0.26472056f, -0.73440003f, -0.50881052f, - -0.33960345f, -0.73440003f, -0.46274635f, - -0.40597799f, -0.73440003f, -0.40597799f, - -0.46274632f, -0.73440009f, -0.33960345f, - -0.50881052f, -0.73440003f, -0.26472053f, - -0.54307282f, -0.73440003f, -0.18242708f, - -0.56443524f, -0.73440003f, -0.09382092f, - -0.57179999f, -0.73440003f, -0.00000001f, - 0.00000000f, -0.72656250f, -0.64218748f, - -0.10537013f, -0.72656244f, -0.63391608f, - -0.20488352f, -0.72656256f, -0.60992402f, - -0.29730710f, -0.72656256f, -0.57144409f, - -0.38140801f, -0.72656256f, -0.51970953f, - -0.45595312f, -0.72656250f, -0.45595312f, - -0.51970953f, -0.72656250f, -0.38140798f, - -0.57144415f, -0.72656250f, -0.29730713f, - -0.60992396f, -0.72656250f, -0.20488349f, - -0.63391614f, -0.72656250f, -0.10537010f, - -0.64218748f, -0.72656250f, -0.00000001f, - 0.00000000f, -0.71759999f, -0.69119996f, - -0.11341208f, -0.71759993f, -0.68229729f, - -0.22052045f, -0.71760005f, -0.65647405f, - -0.31999791f, -0.71759999f, -0.61505735f, - -0.41051748f, -0.71759999f, -0.55937433f, - -0.49075195f, -0.71759999f, -0.49075198f, - -0.55937433f, -0.71759999f, -0.41051745f, - -0.61505735f, -0.71759999f, -0.31999797f, - -0.65647411f, -0.71759999f, -0.22052044f, - -0.68229735f, -0.71759999f, -0.11341205f, - -0.69119996f, -0.71759999f, -0.00000001f, - 0.00000000f, -0.70773751f, -0.72266257f, - -0.11857446f, -0.70773745f, -0.71335465f, - -0.23055826f, -0.70773757f, -0.68635601f, - -0.33456385f, -0.70773745f, -0.64305401f, - -0.42920375f, -0.70773751f, -0.58483636f, - -0.51309043f, -0.70773751f, -0.51309037f, - -0.58483636f, -0.70773751f, -0.42920372f, - -0.64305407f, -0.70773751f, -0.33456385f, - -0.68635601f, -0.70773751f, -0.23055825f, - -0.71335471f, -0.70773751f, -0.11857443f, - -0.72266257f, -0.70773751f, -0.00000001f, - 0.00000000f, -0.69720000f, -0.74039996f, - -0.12148482f, -0.69719994f, -0.73086351f, - -0.23621722f, -0.69720006f, -0.70320231f, - -0.34277558f, -0.69720000f, -0.65883750f, - -0.43973836f, -0.69720006f, -0.59919089f, - -0.52568400f, -0.69719994f, -0.52568400f, - -0.59919089f, -0.69720006f, -0.43973833f, - -0.65883750f, -0.69720000f, -0.34277558f, - -0.70320225f, -0.69720006f, -0.23621720f, - -0.73086363f, -0.69720000f, -0.12148479f, - -0.74039996f, -0.69720000f, -0.00000001f, - 0.00000000f, -0.68621248f, -0.74823749f, - -0.12277080f, -0.68621248f, -0.73860013f, - -0.23871772f, -0.68621254f, -0.71064609f, - -0.34640405f, -0.68621248f, -0.66581166f, - -0.44439322f, -0.68621248f, -0.60553366f, - -0.53124863f, -0.68621248f, -0.53124863f, - -0.60553366f, -0.68621248f, -0.44439319f, - -0.66581166f, -0.68621254f, -0.34640405f, - -0.71064603f, -0.68621254f, -0.23871769f, - -0.73860019f, -0.68621248f, -0.12277077f, - -0.74823749f, -0.68621248f, -0.00000001f, - 0.00000000f, -0.67500001f, -0.75000000f, - -0.12305999f, -0.67499995f, -0.74033999f, - -0.23928000f, -0.67500007f, -0.71232003f, - -0.34721997f, -0.67500001f, -0.66737998f, - -0.44544002f, -0.67500007f, -0.60696000f, - -0.53250003f, -0.67500007f, -0.53250003f, - -0.60696000f, -0.67500001f, -0.44543999f, - -0.66738003f, -0.67500001f, -0.34722000f, - -0.71231997f, -0.67500001f, -0.23927999f, - -0.74033999f, -0.67500001f, -0.12305997f, - -0.75000000f, -0.67500001f, -0.00000001f, - -0.80000001f, 0.26250005f, 0.00000000f, - -0.79859996f, 0.26565003f, 0.04050000f, - -0.79480010f, 0.27420005f, 0.07200000f, - -0.78920001f, 0.28680006f, 0.09450001f, - -0.78240001f, 0.30210006f, 0.10800001f, - -0.77499998f, 0.31875002f, 0.11250000f, - -0.76760000f, 0.33540002f, 0.10800000f, - -0.76080006f, 0.35070002f, 0.09450001f, - -0.75519997f, 0.36330000f, 0.07200000f, - -0.75139999f, 0.37185001f, 0.04049999f, - -0.75000000f, 0.37500000f, 0.00000000f, - -0.90044993f, 0.26238751f, 0.00000000f, - -0.90022725f, 0.26553434f, 0.04050000f, - -0.89962322f, 0.27407584f, 0.07200000f, - -0.89873272f, 0.28666320f, 0.09449999f, - -0.89765161f, 0.30194792f, 0.10800000f, - -0.89647496f, 0.31858125f, 0.11250000f, - -0.89529836f, 0.33521461f, 0.10800000f, - -0.89421713f, 0.35049930f, 0.09449999f, - -0.89332676f, 0.36308670f, 0.07200000f, - -0.89272249f, 0.37162814f, 0.04049999f, - -0.89249992f, 0.37477499f, 0.00000000f, - -0.99160004f, 0.26160005f, 0.00000000f, - -0.99239522f, 0.26472485f, 0.04050001f, - -0.99455369f, 0.27320647f, 0.07200002f, - -0.99773449f, 0.28570563f, 0.09450001f, - -1.00159693f, 0.30088326f, 0.10800002f, - -1.00580013f, 0.31740004f, 0.11250001f, - -1.01000333f, 0.33391684f, 0.10800001f, - -1.01386571f, 0.34909445f, 0.09450001f, - -1.01704645f, 0.36159366f, 0.07200001f, - -1.01920485f, 0.37007523f, 0.04050000f, - -1.02000010f, 0.37320003f, 0.00000000f, - -1.07315004f, 0.25946254f, 0.00000000f, - -1.07481182f, 0.26252747f, 0.04050001f, - -1.07932246f, 0.27084666f, 0.07200002f, - -1.08596969f, 0.28310645f, 0.09450001f, - -1.09404123f, 0.29799330f, 0.10800002f, - -1.10282505f, 0.31419379f, 0.11250001f, - -1.11160886f, 0.33039424f, 0.10800001f, - -1.11968040f, 0.34528112f, 0.09450001f, - -1.12632775f, 0.35754091f, 0.07200001f, - -1.13083827f, 0.36586004f, 0.04050000f, - -1.13250005f, 0.36892501f, 0.00000000f, - -1.14480007f, 0.25530005f, 0.00000000f, - -1.14718556f, 0.25824845f, 0.04050000f, - -1.15366089f, 0.26625127f, 0.07200000f, - -1.16320336f, 0.27804485f, 0.09450001f, - -1.17479050f, 0.29236567f, 0.10800001f, - -1.18740010f, 0.30795002f, 0.11250000f, - -1.20000958f, 0.32353443f, 0.10800000f, - -1.21159685f, 0.33785522f, 0.09450001f, - -1.22113919f, 0.34964880f, 0.07200000f, - -1.22761440f, 0.35765159f, 0.04049999f, - -1.23000002f, 0.36059999f, 0.00000000f, - -1.20625007f, 0.24843754f, 0.00000000f, - -1.20922494f, 0.25119376f, 0.04050000f, - -1.21730018f, 0.25867507f, 0.07200000f, - -1.22920001f, 0.26970002f, 0.09450001f, - -1.24365008f, 0.28308752f, 0.10800001f, - -1.25937510f, 0.29765627f, 0.11250000f, - -1.27509999f, 0.31222504f, 0.10800000f, - -1.28955007f, 0.32561252f, 0.09450001f, - -1.30145001f, 0.33663750f, 0.07200000f, - -1.30952501f, 0.34411874f, 0.04049999f, - -1.31250000f, 0.34687501f, 0.00000000f, - -1.25720000f, 0.23820004f, 0.00000000f, - -1.26063836f, 0.24066961f, 0.04050000f, - -1.26997125f, 0.24737285f, 0.07200000f, - -1.28372490f, 0.25725123f, 0.09450001f, - -1.30042577f, 0.26924643f, 0.10800001f, - -1.31860006f, 0.28230003f, 0.11250000f, - -1.33677435f, 0.29535359f, 0.10800000f, - -1.35347521f, 0.30734879f, 0.09450001f, - -1.36722875f, 0.31722721f, 0.07200000f, - -1.37656152f, 0.32393038f, 0.04049999f, - -1.38000000f, 0.32639998f, 0.00000000f, - -1.29735005f, 0.22391254f, 0.00000000f, - -1.30113411f, 0.22598207f, 0.04050000f, - -1.31140578f, 0.23159945f, 0.07200000f, - -1.32654238f, 0.23987763f, 0.09450001f, - -1.34492302f, 0.24992974f, 0.10800001f, - -1.36492503f, 0.26086879f, 0.11250000f, - -1.38492727f, 0.27180785f, 0.10800000f, - -1.40330780f, 0.28185993f, 0.09450001f, - -1.41844463f, 0.29013813f, 0.07200000f, - -1.42871594f, 0.29575545f, 0.04049999f, - -1.43250012f, 0.29782501f, 0.00000000f, - -1.32640004f, 0.20490001f, 0.00000000f, - -1.33042073f, 0.20643719f, 0.04050000f, - -1.34133446f, 0.21060961f, 0.07200000f, - -1.35741770f, 0.21675842f, 0.09450001f, - -1.37694728f, 0.22422481f, 0.10800001f, - -1.39820004f, 0.23234999f, 0.11250000f, - -1.41945279f, 0.24047519f, 0.10800000f, - -1.43898249f, 0.24794158f, 0.09450001f, - -1.45506573f, 0.25409040f, 0.07200000f, - -1.46597922f, 0.25826281f, 0.04049999f, - -1.47000003f, 0.25979999f, 0.00000000f, - -1.34404993f, 0.18048748f, 0.00000000f, - -1.34820640f, 0.18134111f, 0.04050000f, - -1.35948884f, 0.18365818f, 0.07200000f, - -1.37611520f, 0.18707278f, 0.09450001f, - -1.39630449f, 0.19121909f, 0.10800001f, - -1.41827500f, 0.19573122f, 0.11250000f, - -1.44024563f, 0.20024337f, 0.10800000f, - -1.46043491f, 0.20438966f, 0.09450001f, - -1.47706127f, 0.20780426f, 0.07200000f, - -1.48834348f, 0.21012132f, 0.04049999f, - -1.49250007f, 0.21097496f, 0.00000000f, - -1.35000002f, 0.14999998f, 0.00000000f, - -1.35419989f, 0.14999996f, 0.04050000f, - -1.36559999f, 0.14999999f, 0.07200000f, - -1.38239992f, 0.14999998f, 0.09450001f, - -1.40280008f, 0.14999999f, 0.10800001f, - -1.42499995f, 0.14999998f, 0.11250000f, - -1.44719994f, 0.14999998f, 0.10800000f, - -1.46760011f, 0.14999998f, 0.09450001f, - -1.48440003f, 0.14999998f, 0.07200000f, - -1.49580002f, 0.14999998f, 0.04049999f, - -1.50000000f, 0.14999998f, 0.00000000f, - -0.75000000f, 0.37500000f, 0.00000000f, - -0.75139999f, 0.37184998f, -0.04050000f, - -0.75520003f, 0.36330003f, -0.07200000f, - -0.76080000f, 0.35070002f, -0.09450001f, - -0.76760006f, 0.33540004f, -0.10800001f, - -0.77500004f, 0.31875002f, -0.11250000f, - -0.78240001f, 0.30210003f, -0.10800000f, - -0.78920001f, 0.28680006f, -0.09450001f, - -0.79480004f, 0.27420002f, -0.07200000f, - -0.79860002f, 0.26565003f, -0.04049999f, - -0.80000001f, 0.26250005f, 0.00000000f, - -0.89249992f, 0.37477499f, 0.00000000f, - -0.89272243f, 0.37162811f, -0.04049999f, - -0.89332676f, 0.36308670f, -0.07200000f, - -0.89421707f, 0.35049930f, -0.09449999f, - -0.89529842f, 0.33521461f, -0.10800000f, - -0.89647490f, 0.31858125f, -0.11250000f, - -0.89765155f, 0.30194789f, -0.10800000f, - -0.89873278f, 0.28666323f, -0.09449999f, - -0.89962316f, 0.27407581f, -0.07200000f, - -0.90022731f, 0.26553437f, -0.04049998f, - -0.90044993f, 0.26238751f, 0.00000000f, - -1.02000010f, 0.37320003f, 0.00000000f, - -1.01920474f, 0.37007520f, -0.04050000f, - -1.01704657f, 0.36159366f, -0.07200001f, - -1.01386571f, 0.34909445f, -0.09450001f, - -1.01000333f, 0.33391684f, -0.10800002f, - -1.00580001f, 0.31740004f, -0.11250001f, - -1.00159681f, 0.30088323f, -0.10800001f, - -0.99773443f, 0.28570566f, -0.09450001f, - -0.99455369f, 0.27320647f, -0.07200001f, - -0.99239522f, 0.26472485f, -0.04049999f, - -0.99160004f, 0.26160005f, 0.00000000f, - -1.13250005f, 0.36892501f, 0.00000000f, - -1.13083816f, 0.36586002f, -0.04050000f, - -1.12632775f, 0.35754091f, -0.07200001f, - -1.11968040f, 0.34528109f, -0.09450001f, - -1.11160886f, 0.33039424f, -0.10800002f, - -1.10282505f, 0.31419379f, -0.11250001f, - -1.09404123f, 0.29799333f, -0.10800001f, - -1.08596969f, 0.28310645f, -0.09450001f, - -1.07932246f, 0.27084661f, -0.07200001f, - -1.07481182f, 0.26252750f, -0.04049999f, - -1.07315004f, 0.25946254f, 0.00000000f, - -1.23000002f, 0.36059999f, 0.00000000f, - -1.22761440f, 0.35765156f, -0.04050000f, - -1.22113931f, 0.34964883f, -0.07200000f, - -1.21159685f, 0.33785522f, -0.09450001f, - -1.20000970f, 0.32353443f, -0.10800001f, - -1.18740010f, 0.30795002f, -0.11250000f, - -1.17479038f, 0.29236564f, -0.10800000f, - -1.16320324f, 0.27804482f, -0.09450001f, - -1.15366089f, 0.26625124f, -0.07200000f, - -1.14718568f, 0.25824845f, -0.04049999f, - -1.14480007f, 0.25530005f, 0.00000000f, - -1.31250000f, 0.34687501f, 0.00000000f, - -1.30952489f, 0.34411871f, -0.04050000f, - -1.30145013f, 0.33663750f, -0.07200000f, - -1.28955019f, 0.32561252f, -0.09450001f, - -1.27510011f, 0.31222504f, -0.10800001f, - -1.25937498f, 0.29765630f, -0.11250000f, - -1.24365008f, 0.28308752f, -0.10800000f, - -1.22920012f, 0.26970005f, -0.09450001f, - -1.21730018f, 0.25867504f, -0.07200000f, - -1.20922506f, 0.25119379f, -0.04049999f, - -1.20625007f, 0.24843754f, 0.00000000f, - -1.38000000f, 0.32639998f, 0.00000000f, - -1.37656140f, 0.32393035f, -0.04050000f, - -1.36722875f, 0.31722721f, -0.07200000f, - -1.35347521f, 0.30734879f, -0.09450001f, - -1.33677447f, 0.29535362f, -0.10800001f, - -1.31860006f, 0.28230000f, -0.11250000f, - -1.30042553f, 0.26924643f, -0.10800000f, - -1.28372478f, 0.25725123f, -0.09450001f, - -1.26997125f, 0.24737284f, -0.07200000f, - -1.26063836f, 0.24066964f, -0.04049999f, - -1.25720000f, 0.23820004f, 0.00000000f, - -1.43250012f, 0.29782501f, 0.00000000f, - -1.42871583f, 0.29575542f, -0.04050000f, - -1.41844463f, 0.29013813f, -0.07200000f, - -1.40330768f, 0.28185993f, -0.09450001f, - -1.38492751f, 0.27180785f, -0.10800001f, - -1.36492515f, 0.26086876f, -0.11250000f, - -1.34492302f, 0.24992973f, -0.10800000f, - -1.32654250f, 0.23987764f, -0.09450001f, - -1.31140566f, 0.23159944f, -0.07200000f, - -1.30113423f, 0.22598210f, -0.04049999f, - -1.29735005f, 0.22391254f, 0.00000000f, - -1.47000003f, 0.25979999f, 0.00000000f, - -1.46597922f, 0.25826275f, -0.04050000f, - -1.45506561f, 0.25409040f, -0.07200000f, - -1.43898249f, 0.24794158f, -0.09450001f, - -1.41945291f, 0.24047521f, -0.10800001f, - -1.39820004f, 0.23234999f, -0.11250000f, - -1.37694728f, 0.22422481f, -0.10800000f, - -1.35741770f, 0.21675842f, -0.09450001f, - -1.34133446f, 0.21060961f, -0.07200000f, - -1.33042085f, 0.20643722f, -0.04049999f, - -1.32640004f, 0.20490001f, 0.00000000f, - -1.49250007f, 0.21097496f, 0.00000000f, - -1.48834324f, 0.21012127f, -0.04050000f, - -1.47706139f, 0.20780428f, -0.07200000f, - -1.46043479f, 0.20438966f, -0.09450001f, - -1.44024563f, 0.20024338f, -0.10800001f, - -1.41827488f, 0.19573122f, -0.11250000f, - -1.39630437f, 0.19121908f, -0.10800000f, - -1.37611520f, 0.18707278f, -0.09450001f, - -1.35948884f, 0.18365818f, -0.07200000f, - -1.34820652f, 0.18134113f, -0.04049999f, - -1.34404993f, 0.18048748f, 0.00000000f, - -1.50000000f, 0.14999998f, 0.00000000f, - -1.49580002f, 0.14999996f, -0.04050000f, - -1.48440015f, 0.14999999f, -0.07200000f, - -1.46759999f, 0.14999998f, -0.09450001f, - -1.44720006f, 0.14999999f, -0.10800001f, - -1.42500007f, 0.14999998f, -0.11250000f, - -1.40280008f, 0.14999998f, -0.10800000f, - -1.38240004f, 0.14999998f, -0.09450001f, - -1.36559999f, 0.14999998f, -0.07200000f, - -1.35420001f, 0.14999998f, -0.04049999f, - -1.35000002f, 0.14999998f, 0.00000000f, - -1.35000002f, 0.14999998f, 0.00000000f, - -1.35419989f, 0.14999996f, 0.04050000f, - -1.36559999f, 0.14999999f, 0.07200000f, - -1.38239992f, 0.14999998f, 0.09450001f, - -1.40280008f, 0.14999999f, 0.10800001f, - -1.42499995f, 0.14999998f, 0.11250000f, - -1.44719994f, 0.14999998f, 0.10800000f, - -1.46760011f, 0.14999998f, 0.09450001f, - -1.48440003f, 0.14999998f, 0.07200000f, - -1.49580002f, 0.14999998f, 0.04049999f, - -1.50000000f, 0.14999998f, 0.00000000f, - -1.34694993f, 0.11309998f, 0.00000000f, - -1.35108757f, 0.11225944f, 0.04049999f, - -1.36231863f, 0.10997803f, 0.07200000f, - -1.37886941f, 0.10661592f, 0.09449999f, - -1.39896679f, 0.10253337f, 0.10800000f, - -1.42083752f, 0.09809060f, 0.11250000f, - -1.44270813f, 0.09364782f, 0.10800000f, - -1.46280551f, 0.08956527f, 0.09449999f, - -1.47935629f, 0.08620317f, 0.07200000f, - -1.49058723f, 0.08392174f, 0.04049999f, - -1.49472487f, 0.08308122f, 0.00000000f, - -1.33760011f, 0.07080000f, 0.00000000f, - -1.34155357f, 0.06930479f, 0.04050000f, - -1.35228503f, 0.06524640f, 0.07200002f, - -1.36809933f, 0.05926559f, 0.09450001f, - -1.38730252f, 0.05200320f, 0.10800002f, - -1.40820003f, 0.04410000f, 0.11250001f, - -1.42909765f, 0.03619679f, 0.10800001f, - -1.44830084f, 0.02893440f, 0.09450001f, - -1.46411526f, 0.02295359f, 0.07200001f, - -1.47484648f, 0.01889519f, 0.04049999f, - -1.47880006f, 0.01739999f, 0.00000000f, - -1.32164991f, 0.02445000f, 0.00000000f, - -1.32530177f, 0.02245132f, 0.04050000f, - -1.33521414f, 0.01702635f, 0.07200002f, - -1.34982169f, 0.00903165f, 0.09450001f, - -1.36755967f, -0.00067620f, 0.10800002f, - -1.38686240f, -0.01124063f, 0.11250001f, - -1.40616536f, -0.02180506f, 0.10800001f, - -1.42390323f, -0.03151290f, 0.09450001f, - -1.43851089f, -0.03950761f, 0.07200001f, - -1.44842303f, -0.04493258f, 0.04049999f, - -1.45207500f, -0.04693126f, -0.00000000f, - -1.29880011f, -0.02460000f, -0.00000000f, - -1.30203676f, -0.02698559f, 0.04050000f, - -1.31082261f, -0.03346080f, 0.07200000f, - -1.32376969f, -0.04300320f, 0.09450001f, - -1.33949125f, -0.05459040f, 0.10800001f, - -1.35660005f, -0.06720001f, 0.11250000f, - -1.37370884f, -0.07980961f, 0.10800000f, - -1.38943052f, -0.09139681f, 0.09450001f, - -1.40237761f, -0.10093921f, 0.07200000f, - -1.41116321f, -0.10741441f, 0.04049999f, - -1.41439998f, -0.10980001f, -0.00000000f, - -1.26874995f, -0.07500000f, -0.00000000f, - -1.27146244f, -0.07769062f, 0.04050000f, - -1.27882504f, -0.08499375f, 0.07200000f, - -1.28967500f, -0.09575625f, 0.09450001f, - -1.30285001f, -0.10882500f, 0.10800001f, - -1.31718755f, -0.12304687f, 0.11250000f, - -1.33152497f, -0.13726875f, 0.10800000f, - -1.34470010f, -0.15033749f, 0.09450001f, - -1.35555005f, -0.16110000f, 0.07200000f, - -1.36291242f, -0.16840312f, 0.04049999f, - -1.36562502f, -0.17109375f, -0.00000000f, - -1.23119998f, -0.12540001f, -0.00000000f, - -1.23328304f, -0.12834840f, 0.04050000f, - -1.23893762f, -0.13635120f, 0.07200000f, - -1.24727035f, -0.14814480f, 0.09450001f, - -1.25738895f, -0.16246562f, 0.10800001f, - -1.26839995f, -0.17805001f, 0.11250000f, - -1.27941120f, -0.19363439f, 0.10800000f, - -1.28952956f, -0.20795521f, 0.09450001f, - -1.29786241f, -0.21974881f, 0.07200000f, - -1.30351675f, -0.22775160f, 0.04049999f, - -1.30559993f, -0.23070000f, -0.00000000f, - -1.18585014f, -0.17445001f, -0.00000000f, - -1.18720317f, -0.17764355f, 0.04050000f, - -1.19087601f, -0.18631189f, 0.07200000f, - -1.19628823f, -0.19908616f, 0.09450001f, - -1.20286059f, -0.21459784f, 0.10800001f, - -1.21001256f, -0.23147814f, 0.11250000f, - -1.21716475f, -0.24835847f, 0.10800000f, - -1.22373688f, -0.26387012f, 0.09450001f, - -1.22914934f, -0.27664441f, 0.07200000f, - -1.23282194f, -0.28531271f, 0.04049999f, - -1.23417509f, -0.28850627f, -0.00000000f, - -1.13240004f, -0.22080001f, -0.00000000f, - -1.13292634f, -0.22426079f, 0.04050000f, - -1.13435543f, -0.23365441f, 0.07200000f, - -1.13646090f, -0.24749762f, 0.09450001f, - -1.13901782f, -0.26430723f, 0.10800001f, - -1.14180005f, -0.28260002f, 0.11250000f, - -1.14458251f, -0.30089283f, 0.10800000f, - -1.14713919f, -0.31770241f, 0.09450001f, - -1.14924490f, -0.33154562f, 0.07200000f, - -1.15067363f, -0.34093922f, 0.04049999f, - -1.15120006f, -0.34440002f, -0.00000000f, - -1.07054996f, -0.26310003f, -0.00000000f, - -1.07015729f, -0.26688471f, 0.04050000f, - -1.06909144f, -0.27715757f, 0.07200000f, - -1.06752050f, -0.29229647f, 0.09450001f, - -1.06561327f, -0.31067947f, 0.10800001f, - -1.06353748f, -0.33068439f, 0.11250000f, - -1.06146181f, -0.35068941f, 0.10800000f, - -1.05955434f, -0.36907232f, 0.09450001f, - -1.05798364f, -0.38421124f, 0.07200000f, - -1.05691767f, -0.39448404f, 0.04049999f, - -1.05652499f, -0.39826876f, -0.00000000f, - -1.00000000f, -0.30000001f, -0.00000000f, - -0.99859989f, -0.30419996f, 0.04050000f, - -0.99480003f, -0.31560001f, 0.07200000f, - -0.98920000f, -0.33240002f, 0.09450001f, - -0.98240000f, -0.35280001f, 0.10800001f, - -0.97499996f, -0.37500000f, 0.11250000f, - -0.96759999f, -0.39720002f, 0.10800000f, - -0.96080005f, -0.41759998f, 0.09450001f, - -0.95520002f, -0.43440002f, 0.07200000f, - -0.95139992f, -0.44580001f, 0.04049999f, - -0.94999999f, -0.44999999f, -0.00000001f, - -1.50000000f, 0.14999998f, 0.00000000f, - -1.49580002f, 0.14999996f, -0.04050000f, - -1.48440015f, 0.14999999f, -0.07200000f, - -1.46759999f, 0.14999998f, -0.09450001f, - -1.44720006f, 0.14999999f, -0.10800001f, - -1.42500007f, 0.14999998f, -0.11250000f, - -1.40280008f, 0.14999998f, -0.10800000f, - -1.38240004f, 0.14999998f, -0.09450001f, - -1.36559999f, 0.14999998f, -0.07200000f, - -1.35420001f, 0.14999998f, -0.04049999f, - -1.35000002f, 0.14999998f, 0.00000000f, - -1.49472487f, 0.08308122f, 0.00000000f, - -1.49058712f, 0.08392174f, -0.04049999f, - -1.47935617f, 0.08620317f, -0.07200000f, - -1.46280551f, 0.08956527f, -0.09449999f, - -1.44270813f, 0.09364782f, -0.10800000f, - -1.42083728f, 0.09809060f, -0.11250000f, - -1.39896679f, 0.10253337f, -0.10800000f, - -1.37886930f, 0.10661593f, -0.09449999f, - -1.36231852f, 0.10997803f, -0.07200000f, - -1.35108757f, 0.11225945f, -0.04049999f, - -1.34694993f, 0.11309998f, 0.00000000f, - -1.47880006f, 0.01739999f, 0.00000000f, - -1.47484636f, 0.01889519f, -0.04050000f, - -1.46411538f, 0.02295360f, -0.07200002f, - -1.44830084f, 0.02893439f, -0.09450001f, - -1.42909777f, 0.03619680f, -0.10800002f, - -1.40820003f, 0.04409999f, -0.11250001f, - -1.38730240f, 0.05200320f, -0.10800001f, - -1.36809933f, 0.05926560f, -0.09450001f, - -1.35228491f, 0.06524640f, -0.07200001f, - -1.34155369f, 0.06930479f, -0.04049999f, - -1.33760011f, 0.07080000f, 0.00000000f, - -1.45207500f, -0.04693126f, -0.00000000f, - -1.44842303f, -0.04493257f, -0.04050000f, - -1.43851078f, -0.03950761f, -0.07200002f, - -1.42390323f, -0.03151290f, -0.09450001f, - -1.40616548f, -0.02180506f, -0.10800002f, - -1.38686240f, -0.01124063f, -0.11250001f, - -1.36755955f, -0.00067620f, -0.10800001f, - -1.34982181f, 0.00903165f, -0.09450001f, - -1.33521414f, 0.01702635f, -0.07200001f, - -1.32530189f, 0.02245133f, -0.04049999f, - -1.32164991f, 0.02445000f, 0.00000000f, - -1.41439998f, -0.10980001f, -0.00000000f, - -1.41116297f, -0.10741439f, -0.04050000f, - -1.40237772f, -0.10093922f, -0.07200000f, - -1.38943040f, -0.09139680f, -0.09450001f, - -1.37370884f, -0.07980961f, -0.10800001f, - -1.35660017f, -0.06720000f, -0.11250000f, - -1.33949125f, -0.05459040f, -0.10800000f, - -1.32376981f, -0.04300320f, -0.09450001f, - -1.31082249f, -0.03346080f, -0.07200000f, - -1.30203688f, -0.02698559f, -0.04049999f, - -1.29880011f, -0.02460000f, -0.00000000f, - -1.36562502f, -0.17109375f, -0.00000000f, - -1.36291230f, -0.16840309f, -0.04050000f, - -1.35555005f, -0.16110000f, -0.07200000f, - -1.34469998f, -0.15033749f, -0.09450001f, - -1.33152509f, -0.13726877f, -0.10800001f, - -1.31718755f, -0.12304687f, -0.11250000f, - -1.30285001f, -0.10882499f, -0.10800000f, - -1.28967500f, -0.09575625f, -0.09450001f, - -1.27882504f, -0.08499375f, -0.07200000f, - -1.27146244f, -0.07769062f, -0.04049999f, - -1.26874995f, -0.07500000f, -0.00000000f, - -1.30559993f, -0.23070000f, -0.00000000f, - -1.30351651f, -0.22775158f, -0.04050000f, - -1.29786241f, -0.21974881f, -0.07200000f, - -1.28952956f, -0.20795520f, -0.09450001f, - -1.27941132f, -0.19363441f, -0.10800001f, - -1.26839995f, -0.17805001f, -0.11250000f, - -1.25738883f, -0.16246560f, -0.10800000f, - -1.24727035f, -0.14814481f, -0.09450001f, - -1.23893762f, -0.13635120f, -0.07200000f, - -1.23328316f, -0.12834841f, -0.04049999f, - -1.23119998f, -0.12540001f, -0.00000000f, - -1.23417509f, -0.28850627f, -0.00000000f, - -1.23282194f, -0.28531265f, -0.04050000f, - -1.22914934f, -0.27664444f, -0.07200000f, - -1.22373676f, -0.26387009f, -0.09450001f, - -1.21716475f, -0.24835847f, -0.10800001f, - -1.21001267f, -0.23147814f, -0.11250000f, - -1.20286047f, -0.21459781f, -0.10800000f, - -1.19628835f, -0.19908617f, -0.09450001f, - -1.19087601f, -0.18631187f, -0.07200000f, - -1.18720317f, -0.17764360f, -0.04049999f, - -1.18585014f, -0.17445001f, -0.00000000f, - -1.15120006f, -0.34440002f, -0.00000000f, - -1.15067351f, -0.34093919f, -0.04050000f, - -1.14924490f, -0.33154565f, -0.07200001f, - -1.14713919f, -0.31770241f, -0.09450001f, - -1.14458263f, -0.30089283f, -0.10800001f, - -1.14180017f, -0.28259999f, -0.11250000f, - -1.13901758f, -0.26430720f, -0.10800000f, - -1.13646090f, -0.24749762f, -0.09450001f, - -1.13435531f, -0.23365441f, -0.07200000f, - -1.13292646f, -0.22426081f, -0.04049999f, - -1.13240004f, -0.22080001f, -0.00000000f, - -1.05652499f, -0.39826876f, -0.00000000f, - -1.05691755f, -0.39448401f, -0.04050000f, - -1.05798364f, -0.38421121f, -0.07200001f, - -1.05955434f, -0.36907232f, -0.09450001f, - -1.06146181f, -0.35068938f, -0.10800001f, - -1.06353748f, -0.33068442f, -0.11250000f, - -1.06561315f, -0.31067941f, -0.10800000f, - -1.06752062f, -0.29229647f, -0.09450001f, - -1.06909132f, -0.27715760f, -0.07200000f, - -1.07015729f, -0.26688474f, -0.04049999f, - -1.07054996f, -0.26310003f, -0.00000000f, - -0.94999999f, -0.44999999f, -0.00000001f, - -0.95139986f, -0.44579995f, -0.04050000f, - -0.95520008f, -0.43440005f, -0.07200001f, - -0.96079999f, -0.41760001f, -0.09450001f, - -0.96759999f, -0.39719999f, -0.10800001f, - -0.97500002f, -0.37500000f, -0.11250000f, - -0.98240000f, -0.35280001f, -0.10800000f, - -0.98920006f, -0.33240002f, -0.09450001f, - -0.99480003f, -0.31560001f, -0.07200000f, - -0.99860001f, -0.30419999f, -0.04049999f, - -1.00000000f, -0.30000001f, -0.00000000f, - 0.85000002f, -0.03750002f, -0.00000000f, - 0.84999996f, -0.04905002f, 0.08910000f, - 0.85000008f, -0.08040002f, 0.15840001f, - 0.85000002f, -0.12660003f, 0.20790000f, - 0.85000008f, -0.18270002f, 0.23760001f, - 0.85000002f, -0.24375001f, 0.24750000f, - 0.85000002f, -0.30480003f, 0.23760000f, - 0.85000002f, -0.36089998f, 0.20790002f, - 0.85000002f, -0.40710002f, 0.15840001f, - 0.85000002f, -0.43845001f, 0.08909997f, - 0.85000002f, -0.44999999f, -0.00000001f, - 0.96794993f, -0.02790002f, -0.00000000f, - 0.96969706f, -0.03838952f, 0.08755019f, - 0.97443962f, -0.06686102f, 0.15564480f, - 0.98142833f, -0.10881902f, 0.20428377f, - 0.98991477f, -0.15976802f, 0.23346718f, - 0.99914992f, -0.21521249f, 0.24319497f, - 1.00838506f, -0.27065700f, 0.23346716f, - 1.01687145f, -0.32160598f, 0.20428379f, - 1.02386022f, -0.36356401f, 0.15564479f, - 1.02860272f, -0.39203548f, 0.08755016f, - 1.03034985f, -0.40252498f, -0.00000000f, - 1.05560005f, -0.00120003f, -0.00000000f, - 1.05848956f, -0.01044003f, 0.08334360f, - 1.06633294f, -0.03552003f, 0.14816642f, - 1.07789123f, -0.07248003f, 0.19446841f, - 1.09192657f, -0.11736003f, 0.22224963f, - 1.10720015f, -0.16620001f, 0.23151001f, - 1.12247372f, -0.21504003f, 0.22224963f, - 1.13650894f, -0.25992000f, 0.19446844f, - 1.14806736f, -0.29688001f, 0.14816642f, - 1.15591049f, -0.32196000f, 0.08334358f, - 1.15880013f, -0.33120000f, -0.00000000f, - 1.11864996f, 0.03944998f, 0.00000000f, - 1.12222838f, 0.03158548f, 0.07714440f, - 1.13194120f, 0.01023899f, 0.13714561f, - 1.14625478f, -0.02121901f, 0.18000358f, - 1.16363573f, -0.05941800f, 0.20571840f, - 1.18255007f, -0.10098749f, 0.21428999f, - 1.20146441f, -0.14255700f, 0.20571840f, - 1.21884537f, -0.18075597f, 0.18000360f, - 1.23315883f, -0.21221398f, 0.13714559f, - 1.24287164f, -0.23356047f, 0.07714437f, - 1.24645007f, -0.24142496f, -0.00000000f, - 1.16280007f, 0.09089998f, 0.00000000f, - 1.16676486f, 0.08447397f, 0.06961680f, - 1.17752659f, 0.06703199f, 0.12376321f, - 1.19338572f, 0.04132799f, 0.16243920f, - 1.21264338f, 0.01011599f, 0.18564481f, - 1.23360014f, -0.02385001f, 0.19338000f, - 1.25455689f, -0.05781601f, 0.18564481f, - 1.27381444f, -0.08902800f, 0.16243921f, - 1.28967381f, -0.11473200f, 0.12376320f, - 1.30043530f, -0.13217400f, 0.06961678f, - 1.30440009f, -0.13859999f, -0.00000000f, - 1.19375002f, 0.14999998f, 0.00000000f, - 1.19794989f, 0.14501247f, 0.06142500f, - 1.20935011f, 0.13147499f, 0.10920001f, - 1.22614992f, 0.11152498f, 0.14332500f, - 1.24654996f, 0.08730000f, 0.16380000f, - 1.26874995f, 0.06093749f, 0.17062500f, - 1.29094982f, 0.03457499f, 0.16380000f, - 1.31134987f, 0.01035001f, 0.14332500f, - 1.32814991f, -0.00959999f, 0.10920000f, - 1.33954990f, -0.02313749f, 0.06142498f, - 1.34374988f, -0.02812499f, -0.00000000f, - 1.21719992f, 0.21360001f, 0.00000000f, - 1.22163498f, 0.20998798f, 0.05323320f, - 1.23367357f, 0.20018403f, 0.09463681f, - 1.25141430f, 0.18573602f, 0.12421080f, - 1.27295685f, 0.16819203f, 0.14195521f, - 1.29639995f, 0.14910004f, 0.14787000f, - 1.31984317f, 0.13000804f, 0.14195520f, - 1.34138560f, 0.11246406f, 0.12421081f, - 1.35912633f, 0.09801605f, 0.09463680f, - 1.37116480f, 0.08821206f, 0.05323318f, - 1.37559998f, 0.08460006f, 0.00000000f, - 1.23885000f, 0.27855000f, 0.00000000f, - 1.24367154f, 0.27618748f, 0.04570561f, - 1.25675893f, 0.26977503f, 0.08125442f, - 1.27604520f, 0.26032501f, 0.10664641f, - 1.29946446f, 0.24885003f, 0.12188162f, - 1.32495010f, 0.23636252f, 0.12696001f, - 1.35043573f, 0.22387503f, 0.12188161f, - 1.37385488f, 0.21240003f, 0.10664642f, - 1.39314127f, 0.20295003f, 0.08125441f, - 1.40622854f, 0.19653754f, 0.04570559f, - 1.41105008f, 0.19417503f, 0.00000000f, - 1.26440001f, 0.34170002f, 0.00000000f, - 1.26991034f, 0.34039798f, 0.03950640f, - 1.28486729f, 0.33686405f, 0.07023361f, - 1.30690885f, 0.33165601f, 0.09218160f, - 1.33367372f, 0.32533202f, 0.10535040f, - 1.36280000f, 0.31845003f, 0.10974000f, - 1.39192641f, 0.31156802f, 0.10535040f, - 1.41869128f, 0.30524403f, 0.09218161f, - 1.44073272f, 0.30003607f, 0.07023360f, - 1.45568967f, 0.29650205f, 0.03950639f, - 1.46120000f, 0.29520005f, 0.00000000f, - 1.29955006f, 0.39990005f, 0.00000000f, - 1.30620289f, 0.39940652f, 0.03529980f, - 1.32426059f, 0.39806706f, 0.06275520f, - 1.35087168f, 0.39609307f, 0.08236619f, - 1.38318527f, 0.39369607f, 0.09413280f, - 1.41835010f, 0.39108756f, 0.09805499f, - 1.45351493f, 0.38847905f, 0.09413280f, - 1.48582840f, 0.38608208f, 0.08236620f, - 1.51243973f, 0.38410807f, 0.06275519f, - 1.53049719f, 0.38276857f, 0.03529979f, - 1.53715003f, 0.38227507f, 0.00000000f, - 1.35000002f, 0.45000005f, 0.00000001f, - 1.35839975f, 0.44999996f, 0.03375000f, - 1.38120008f, 0.45000011f, 0.06000001f, - 1.41480005f, 0.45000002f, 0.07875000f, - 1.45560014f, 0.45000008f, 0.09000000f, - 1.50000000f, 0.45000005f, 0.09375000f, - 1.54439998f, 0.45000005f, 0.09000000f, - 1.58520007f, 0.45000008f, 0.07875000f, - 1.61880004f, 0.45000005f, 0.06000000f, - 1.64159989f, 0.45000005f, 0.03374999f, - 1.64999998f, 0.45000005f, 0.00000001f, - 0.85000002f, -0.44999999f, -0.00000001f, - 0.84999996f, -0.43844995f, -0.08910000f, - 0.85000008f, -0.40710002f, -0.15840001f, - 0.85000002f, -0.36089998f, -0.20790000f, - 0.85000008f, -0.30480000f, -0.23760001f, - 0.85000002f, -0.24375001f, -0.24750000f, - 0.85000002f, -0.18269999f, -0.23760000f, - 0.85000002f, -0.12660003f, -0.20790002f, - 0.85000002f, -0.08040002f, -0.15840001f, - 0.85000002f, -0.04905001f, -0.08909997f, - 0.85000002f, -0.03750002f, -0.00000000f, - 1.03034985f, -0.40252498f, -0.00000000f, - 1.02860260f, -0.39203545f, -0.08755019f, - 1.02386034f, -0.36356398f, -0.15564480f, - 1.01687145f, -0.32160601f, -0.20428377f, - 1.00838506f, -0.27065703f, -0.23346718f, - 0.99914992f, -0.21521249f, -0.24319497f, - 0.98991477f, -0.15976799f, -0.23346716f, - 0.98142833f, -0.10881902f, -0.20428379f, - 0.97443956f, -0.06686102f, -0.15564479f, - 0.96969712f, -0.03838951f, -0.08755016f, - 0.96794993f, -0.02790002f, -0.00000000f, - 1.15880013f, -0.33120000f, -0.00000000f, - 1.15591037f, -0.32195994f, -0.08334360f, - 1.14806736f, -0.29688004f, -0.14816642f, - 1.13650882f, -0.25992000f, -0.19446841f, - 1.12247384f, -0.21504001f, -0.22224963f, - 1.10720003f, -0.16620003f, -0.23151001f, - 1.09192646f, -0.11736001f, -0.22224963f, - 1.07789123f, -0.07248002f, -0.19446844f, - 1.06633282f, -0.03552002f, -0.14816642f, - 1.05848956f, -0.01044002f, -0.08334358f, - 1.05560005f, -0.00120003f, -0.00000000f, - 1.24645007f, -0.24142496f, -0.00000000f, - 1.24287152f, -0.23356044f, -0.07714440f, - 1.23315895f, -0.21221398f, -0.13714561f, - 1.21884525f, -0.18075597f, -0.18000358f, - 1.20146453f, -0.14255700f, -0.20571840f, - 1.18254995f, -0.10098749f, -0.21428999f, - 1.16363561f, -0.05941799f, -0.20571840f, - 1.14625478f, -0.02121901f, -0.18000360f, - 1.13194120f, 0.01023899f, -0.13714559f, - 1.12222838f, 0.03158549f, -0.07714437f, - 1.11864996f, 0.03944998f, 0.00000000f, - 1.30440009f, -0.13859999f, -0.00000000f, - 1.30043507f, -0.13217399f, -0.06961680f, - 1.28967369f, -0.11473200f, -0.12376321f, - 1.27381444f, -0.08902799f, -0.16243920f, - 1.25455701f, -0.05781601f, -0.18564481f, - 1.23360002f, -0.02385001f, -0.19338000f, - 1.21264338f, 0.01011600f, -0.18564481f, - 1.19338572f, 0.04132798f, -0.16243921f, - 1.17752647f, 0.06703199f, -0.12376320f, - 1.16676486f, 0.08447399f, -0.06961678f, - 1.16280007f, 0.09089998f, 0.00000000f, - 1.34374988f, -0.02812499f, -0.00000000f, - 1.33954978f, -0.02313748f, -0.06142500f, - 1.32814991f, -0.00959999f, -0.10920001f, - 1.31134987f, 0.01035001f, -0.14332500f, - 1.29095006f, 0.03457500f, -0.16380000f, - 1.26874995f, 0.06093749f, -0.17062500f, - 1.24654996f, 0.08730000f, -0.16380000f, - 1.22615004f, 0.11152498f, -0.14332500f, - 1.20935011f, 0.13147499f, -0.10920000f, - 1.19795001f, 0.14501248f, -0.06142498f, - 1.19375002f, 0.14999998f, 0.00000000f, - 1.37559998f, 0.08460006f, 0.00000000f, - 1.37116480f, 0.08821206f, -0.05323320f, - 1.35912645f, 0.09801605f, -0.09463680f, - 1.34138560f, 0.11246406f, -0.12421079f, - 1.31984317f, 0.13000806f, -0.14195520f, - 1.29639995f, 0.14910004f, -0.14786999f, - 1.27295685f, 0.16819203f, -0.14195520f, - 1.25141430f, 0.18573603f, -0.12421080f, - 1.23367357f, 0.20018402f, -0.09463680f, - 1.22163510f, 0.20998801f, -0.05323318f, - 1.21719992f, 0.21360001f, 0.00000000f, - 1.41105008f, 0.19417503f, 0.00000000f, - 1.40622830f, 0.19653751f, -0.04570560f, - 1.39314139f, 0.20295003f, -0.08125441f, - 1.37385488f, 0.21240002f, -0.10664640f, - 1.35043585f, 0.22387503f, -0.12188162f, - 1.32494998f, 0.23636252f, -0.12696001f, - 1.29946434f, 0.24885002f, -0.12188160f, - 1.27604532f, 0.26032501f, -0.10664640f, - 1.25675893f, 0.26977503f, -0.08125440f, - 1.24367166f, 0.27618751f, -0.04570558f, - 1.23885000f, 0.27855000f, 0.00000000f, - 1.46120000f, 0.29520005f, 0.00000000f, - 1.45568943f, 0.29650205f, -0.03950639f, - 1.44073284f, 0.30003604f, -0.07023360f, - 1.41869116f, 0.30524403f, -0.09218159f, - 1.39192653f, 0.31156805f, -0.10535039f, - 1.36280012f, 0.31845003f, -0.10973999f, - 1.33367360f, 0.32533202f, -0.10535039f, - 1.30690885f, 0.33165604f, -0.09218159f, - 1.28486729f, 0.33686402f, -0.07023359f, - 1.26991045f, 0.34039801f, -0.03950638f, - 1.26440001f, 0.34170002f, 0.00000000f, - 1.53715003f, 0.38227507f, 0.00000000f, - 1.53049695f, 0.38276854f, -0.03529979f, - 1.51243961f, 0.38410810f, -0.06275519f, - 1.48582840f, 0.38608205f, -0.08236619f, - 1.45351493f, 0.38847908f, -0.09413280f, - 1.41835010f, 0.39108753f, -0.09805499f, - 1.38318527f, 0.39369607f, -0.09413280f, - 1.35087168f, 0.39609307f, -0.08236620f, - 1.32426047f, 0.39806706f, -0.06275519f, - 1.30620289f, 0.39940655f, -0.03529978f, - 1.29955006f, 0.39990005f, 0.00000000f, - 1.64999998f, 0.45000005f, 0.00000001f, - 1.64159989f, 0.44999996f, -0.03374999f, - 1.61880016f, 0.45000011f, -0.05999999f, - 1.58519995f, 0.45000002f, -0.07874999f, - 1.54440010f, 0.45000008f, -0.09000000f, - 1.50000000f, 0.45000005f, -0.09374999f, - 1.45560002f, 0.45000005f, -0.08999999f, - 1.41480005f, 0.45000008f, -0.07875000f, - 1.38120008f, 0.45000005f, -0.05999999f, - 1.35839999f, 0.45000005f, -0.03374998f, - 1.35000002f, 0.45000005f, 0.00000001f, - 1.35000002f, 0.45000005f, 0.00000001f, - 1.35839975f, 0.44999996f, 0.03375000f, - 1.38120008f, 0.45000011f, 0.06000001f, - 1.41480005f, 0.45000002f, 0.07875000f, - 1.45560014f, 0.45000008f, 0.09000000f, - 1.50000000f, 0.45000005f, 0.09375000f, - 1.54439998f, 0.45000005f, 0.09000000f, - 1.58520007f, 0.45000008f, 0.07875000f, - 1.61880004f, 0.45000005f, 0.06000000f, - 1.64159989f, 0.45000005f, 0.03374999f, - 1.64999998f, 0.45000005f, 0.00000001f, - 1.36489987f, 0.46012494f, 0.00000001f, - 1.37370336f, 0.46020287f, 0.03337200f, - 1.39759886f, 0.46041453f, 0.05932800f, - 1.43281305f, 0.46072635f, 0.07786799f, - 1.47557306f, 0.46110505f, 0.08899199f, - 1.52210617f, 0.46151716f, 0.09269999f, - 1.56863928f, 0.46192923f, 0.08899198f, - 1.61139929f, 0.46230793f, 0.07786799f, - 1.64661360f, 0.46261978f, 0.05932799f, - 1.67050874f, 0.46283138f, 0.03337199f, - 1.67931235f, 0.46290934f, 0.00000001f, - 1.37919998f, 0.46800002f, 0.00000001f, - 1.38818228f, 0.46815118f, 0.03234600f, - 1.41256332f, 0.46856162f, 0.05750401f, - 1.44849277f, 0.46916643f, 0.07547401f, - 1.49212170f, 0.46990088f, 0.08625601f, - 1.53960001f, 0.47070009f, 0.08985001f, - 1.58707845f, 0.47149926f, 0.08625601f, - 1.63070726f, 0.47223371f, 0.07547401f, - 1.66663694f, 0.47283852f, 0.05750401f, - 1.69101763f, 0.47324890f, 0.03234600f, - 1.70000005f, 0.47340012f, 0.00000001f, - 1.39230001f, 0.47362497f, 0.00000001f, - 1.40126371f, 0.47383994f, 0.03083400f, - 1.42559445f, 0.47442356f, 0.05481601f, - 1.46144974f, 0.47528344f, 0.07194600f, - 1.50498855f, 0.47632772f, 0.08222401f, - 1.55236876f, 0.47746408f, 0.08565000f, - 1.59974909f, 0.47860044f, 0.08222400f, - 1.64328790f, 0.47964469f, 0.07194600f, - 1.67914319f, 0.48050463f, 0.05481600f, - 1.70347357f, 0.48108816f, 0.03083399f, - 1.71243751f, 0.48130316f, 0.00000001f, - 1.40359998f, 0.47700000f, 0.00000001f, - 1.41237509f, 0.47726458f, 0.02899800f, - 1.43619370f, 0.47798279f, 0.05155201f, - 1.47129452f, 0.47904122f, 0.06766201f, - 1.51391697f, 0.48032647f, 0.07732801f, - 1.56030011f, 0.48172504f, 0.08055001f, - 1.60668325f, 0.48312366f, 0.07732800f, - 1.64930582f, 0.48440886f, 0.06766201f, - 1.68440676f, 0.48546728f, 0.05155201f, - 1.70822501f, 0.48618549f, 0.02899799f, - 1.71700025f, 0.48645008f, 0.00000001f, - 1.41249990f, 0.47812498f, 0.00000001f, - 1.42094362f, 0.47842023f, 0.02700000f, - 1.44386256f, 0.47922191f, 0.04800001f, - 1.47763753f, 0.48040313f, 0.06300000f, - 1.51865005f, 0.48183754f, 0.07200000f, - 1.56328130f, 0.48339847f, 0.07500000f, - 1.60791266f, 0.48495942f, 0.07200000f, - 1.64892507f, 0.48639381f, 0.06300000f, - 1.68270016f, 0.48757505f, 0.04800000f, - 1.70561898f, 0.48837662f, 0.02700000f, - 1.71406269f, 0.48867193f, 0.00000001f, - 1.41839993f, 0.47700000f, 0.00000001f, - 1.42639649f, 0.47730237f, 0.02500200f, - 1.44810247f, 0.47812322f, 0.04444801f, - 1.48008955f, 0.47933280f, 0.05833800f, - 1.51893127f, 0.48080164f, 0.06667200f, - 1.56120014f, 0.48240003f, 0.06945001f, - 1.60346889f, 0.48399845f, 0.06667200f, - 1.64231050f, 0.48546726f, 0.05833801f, - 1.67429769f, 0.48667687f, 0.04444801f, - 1.69600332f, 0.48749766f, 0.02500200f, - 1.70400012f, 0.48780006f, 0.00000001f, - 1.42070007f, 0.47362500f, 0.00000001f, - 1.42816150f, 0.47390610f, 0.02316600f, - 1.44841480f, 0.47466925f, 0.04118401f, - 1.47826135f, 0.47579375f, 0.05405401f, - 1.51450372f, 0.47715935f, 0.06177600f, - 1.55394375f, 0.47864535f, 0.06435001f, - 1.59338403f, 0.48013136f, 0.06177600f, - 1.62962627f, 0.48149687f, 0.05405401f, - 1.65947294f, 0.48262146f, 0.04118400f, - 1.67972589f, 0.48338455f, 0.02316600f, - 1.68718755f, 0.48366567f, 0.00000001f, - 1.41880012f, 0.46799999f, 0.00000001f, - 1.42566562f, 0.46822673f, 0.02165400f, - 1.44430101f, 0.46884245f, 0.03849601f, - 1.47176325f, 0.46974963f, 0.05052601f, - 1.50511050f, 0.47085124f, 0.05774401f, - 1.54139996f, 0.47205001f, 0.06015000f, - 1.57768965f, 0.47324884f, 0.05774400f, - 1.61103690f, 0.47435045f, 0.05052601f, - 1.63849926f, 0.47525764f, 0.03849601f, - 1.65713453f, 0.47587326f, 0.02165400f, - 1.66400003f, 0.47610006f, 0.00000001f, - 1.41209996f, 0.46012503f, 0.00000001f, - 1.41833580f, 0.46025965f, 0.02062801f, - 1.43526208f, 0.46062523f, 0.03667201f, - 1.46020591f, 0.46116382f, 0.04813201f, - 1.49049485f, 0.46181795f, 0.05500801f, - 1.52345622f, 0.46252972f, 0.05730001f, - 1.55641770f, 0.46324152f, 0.05500801f, - 1.58670676f, 0.46389559f, 0.04813201f, - 1.61165047f, 0.46443427f, 0.03667201f, - 1.62857664f, 0.46479973f, 0.02062800f, - 1.63481259f, 0.46493441f, 0.00000001f, - 1.39999998f, 0.45000005f, 0.00000001f, - 1.40559983f, 0.44999996f, 0.02025001f, - 1.42079997f, 0.45000011f, 0.03600001f, - 1.44319999f, 0.45000002f, 0.04725001f, - 1.47040009f, 0.45000008f, 0.05400001f, - 1.50000000f, 0.45000005f, 0.05625001f, - 1.52960002f, 0.45000005f, 0.05400001f, - 1.55680001f, 0.45000008f, 0.04725001f, - 1.57920003f, 0.45000005f, 0.03600001f, - 1.59440005f, 0.45000005f, 0.02025000f, - 1.60000002f, 0.45000005f, 0.00000001f, - 1.64999998f, 0.45000005f, 0.00000001f, - 1.64159989f, 0.44999996f, -0.03374999f, - 1.61880016f, 0.45000011f, -0.05999999f, - 1.58519995f, 0.45000002f, -0.07874999f, - 1.54440010f, 0.45000008f, -0.09000000f, - 1.50000000f, 0.45000005f, -0.09374999f, - 1.45560002f, 0.45000005f, -0.08999999f, - 1.41480005f, 0.45000008f, -0.07875000f, - 1.38120008f, 0.45000005f, -0.05999999f, - 1.35839999f, 0.45000005f, -0.03374998f, - 1.35000002f, 0.45000005f, 0.00000001f, - 1.67931235f, 0.46290934f, 0.00000001f, - 1.67050874f, 0.46283132f, -0.03337199f, - 1.64661360f, 0.46261978f, -0.05932799f, - 1.61139941f, 0.46230793f, -0.07786798f, - 1.56863928f, 0.46192926f, -0.08899198f, - 1.52210605f, 0.46151716f, -0.09269998f, - 1.47557306f, 0.46110505f, -0.08899198f, - 1.43281293f, 0.46072638f, -0.07786798f, - 1.39759874f, 0.46041453f, -0.05932799f, - 1.37370336f, 0.46020290f, -0.03337198f, - 1.36489987f, 0.46012494f, 0.00000001f, - 1.70000005f, 0.47340012f, 0.00000001f, - 1.69101751f, 0.47324887f, -0.03234600f, - 1.66663706f, 0.47283855f, -0.05750400f, - 1.63070726f, 0.47223368f, -0.07547399f, - 1.58707845f, 0.47149929f, -0.08625600f, - 1.53960001f, 0.47070006f, -0.08985000f, - 1.49212158f, 0.46990088f, -0.08625600f, - 1.44849288f, 0.46916646f, -0.07547400f, - 1.41256320f, 0.46856165f, -0.05750399f, - 1.38818240f, 0.46815124f, -0.03234598f, - 1.37919998f, 0.46800002f, 0.00000001f, - 1.71243751f, 0.48130316f, 0.00000001f, - 1.70347345f, 0.48108810f, -0.03083399f, - 1.67914343f, 0.48050466f, -0.05481599f, - 1.64328778f, 0.47964469f, -0.07194599f, - 1.59974921f, 0.47860047f, -0.08222400f, - 1.55236864f, 0.47746405f, -0.08564999f, - 1.50498843f, 0.47632769f, -0.08222400f, - 1.46144986f, 0.47528344f, -0.07194600f, - 1.42559433f, 0.47442353f, -0.05481599f, - 1.40126395f, 0.47383997f, -0.03083398f, - 1.39230001f, 0.47362497f, 0.00000001f, - 1.71700025f, 0.48645008f, 0.00000001f, - 1.70822489f, 0.48618543f, -0.02899799f, - 1.68440676f, 0.48546731f, -0.05155200f, - 1.64930582f, 0.48440889f, -0.06766199f, - 1.60668337f, 0.48312369f, -0.07732800f, - 1.56030011f, 0.48172504f, -0.08055000f, - 1.51391685f, 0.48032641f, -0.07732800f, - 1.47129452f, 0.47904122f, -0.06766200f, - 1.43619370f, 0.47798282f, -0.05155200f, - 1.41237521f, 0.47726461f, -0.02899799f, - 1.40359998f, 0.47700000f, 0.00000001f, - 1.71406269f, 0.48867193f, 0.00000001f, - 1.70561886f, 0.48837656f, -0.02699999f, - 1.68270016f, 0.48757505f, -0.04800000f, - 1.64892519f, 0.48639381f, -0.06299999f, - 1.60791278f, 0.48495948f, -0.07200000f, - 1.56328130f, 0.48339844f, -0.07500000f, - 1.51865005f, 0.48183751f, -0.07200000f, - 1.47763753f, 0.48040313f, -0.06299999f, - 1.44386244f, 0.47922188f, -0.04799999f, - 1.42094362f, 0.47842029f, -0.02699998f, - 1.41249990f, 0.47812498f, 0.00000001f, - 1.70400012f, 0.48780006f, 0.00000001f, - 1.69600320f, 0.48749760f, -0.02500199f, - 1.67429769f, 0.48667687f, -0.04444800f, - 1.64231050f, 0.48546728f, -0.05833799f, - 1.60346901f, 0.48399848f, -0.06667200f, - 1.56120002f, 0.48240003f, -0.06944999f, - 1.51893127f, 0.48080158f, -0.06667199f, - 1.48008966f, 0.47933280f, -0.05833799f, - 1.44810236f, 0.47812319f, -0.04444799f, - 1.42639661f, 0.47730240f, -0.02500199f, - 1.41839993f, 0.47700000f, 0.00000001f, - 1.68718755f, 0.48366567f, 0.00000001f, - 1.67972589f, 0.48338449f, -0.02316599f, - 1.65947306f, 0.48262149f, -0.04118400f, - 1.62962627f, 0.48149690f, -0.05405399f, - 1.59338415f, 0.48013139f, -0.06177600f, - 1.55394387f, 0.47864535f, -0.06434999f, - 1.51450372f, 0.47715932f, -0.06177600f, - 1.47826147f, 0.47579378f, -0.05405399f, - 1.44841480f, 0.47466925f, -0.04118399f, - 1.42816162f, 0.47390613f, -0.02316599f, - 1.42070007f, 0.47362500f, 0.00000001f, - 1.66400003f, 0.47610006f, 0.00000001f, - 1.65713418f, 0.47587320f, -0.02165399f, - 1.63849938f, 0.47525769f, -0.03849600f, - 1.61103702f, 0.47435045f, -0.05052599f, - 1.57768977f, 0.47324887f, -0.05774400f, - 1.54140007f, 0.47205001f, -0.06015000f, - 1.50511050f, 0.47085121f, -0.05774400f, - 1.47176337f, 0.46974963f, -0.05052600f, - 1.44430089f, 0.46884239f, -0.03849599f, - 1.42566574f, 0.46822679f, -0.02165399f, - 1.41880012f, 0.46799999f, 0.00000001f, - 1.63481259f, 0.46493441f, 0.00000001f, - 1.62857652f, 0.46479967f, -0.02062799f, - 1.61165059f, 0.46443427f, -0.03667200f, - 1.58670664f, 0.46389559f, -0.04813199f, - 1.55641782f, 0.46324155f, -0.05500800f, - 1.52345634f, 0.46252972f, -0.05730000f, - 1.49049485f, 0.46181795f, -0.05500799f, - 1.46020591f, 0.46116385f, -0.04813200f, - 1.43526220f, 0.46062523f, -0.03667200f, - 1.41833591f, 0.46025968f, -0.02062799f, - 1.41209996f, 0.46012503f, 0.00000001f, - 1.60000002f, 0.45000005f, 0.00000001f, - 1.59439981f, 0.44999996f, -0.02024999f, - 1.57920015f, 0.45000011f, -0.03600000f, - 1.55680001f, 0.45000002f, -0.04725000f, - 1.52960002f, 0.45000008f, -0.05400000f, - 1.50000000f, 0.45000005f, -0.05625000f, - 1.47039998f, 0.45000005f, -0.05400000f, - 1.44320011f, 0.45000008f, -0.04725000f, - 1.42079997f, 0.45000005f, -0.03599999f, - 1.40559995f, 0.45000005f, -0.02024999f, - 1.39999998f, 0.45000005f, 0.00000001f, - }; - - std::vector<uint32_t> m_teapotIndices = - { - 0, 1, 11, 11, 1, 12, - 1, 2, 12, 12, 2, 13, - 2, 3, 13, 13, 3, 14, - 3, 4, 14, 14, 4, 15, - 4, 5, 15, 15, 5, 16, - 5, 6, 16, 16, 6, 17, - 6, 7, 17, 17, 7, 18, - 7, 8, 18, 18, 8, 19, - 8, 9, 19, 19, 9, 20, - 9, 10, 20, 20, 10, 21, - 11, 12, 22, 22, 12, 23, - 12, 13, 23, 23, 13, 24, - 13, 14, 24, 24, 14, 25, - 14, 15, 25, 25, 15, 26, - 15, 16, 26, 26, 16, 27, - 16, 17, 27, 27, 17, 28, - 17, 18, 28, 28, 18, 29, - 18, 19, 29, 29, 19, 30, - 19, 20, 30, 30, 20, 31, - 20, 21, 31, 31, 21, 32, - 22, 23, 33, 33, 23, 34, - 23, 24, 34, 34, 24, 35, - 24, 25, 35, 35, 25, 36, - 25, 26, 36, 36, 26, 37, - 26, 27, 37, 37, 27, 38, - 27, 28, 38, 38, 28, 39, - 28, 29, 39, 39, 29, 40, - 29, 30, 40, 40, 30, 41, - 30, 31, 41, 41, 31, 42, - 31, 32, 42, 42, 32, 43, - 33, 34, 44, 44, 34, 45, - 34, 35, 45, 45, 35, 46, - 35, 36, 46, 46, 36, 47, - 36, 37, 47, 47, 37, 48, - 37, 38, 48, 48, 38, 49, - 38, 39, 49, 49, 39, 50, - 39, 40, 50, 50, 40, 51, - 40, 41, 51, 51, 41, 52, - 41, 42, 52, 52, 42, 53, - 42, 43, 53, 53, 43, 54, - 44, 45, 55, 55, 45, 56, - 45, 46, 56, 56, 46, 57, - 46, 47, 57, 57, 47, 58, - 47, 48, 58, 58, 48, 59, - 48, 49, 59, 59, 49, 60, - 49, 50, 60, 60, 50, 61, - 50, 51, 61, 61, 51, 62, - 51, 52, 62, 62, 52, 63, - 52, 53, 63, 63, 53, 64, - 53, 54, 64, 64, 54, 65, - 55, 56, 66, 66, 56, 67, - 56, 57, 67, 67, 57, 68, - 57, 58, 68, 68, 58, 69, - 58, 59, 69, 69, 59, 70, - 59, 60, 70, 70, 60, 71, - 60, 61, 71, 71, 61, 72, - 61, 62, 72, 72, 62, 73, - 62, 63, 73, 73, 63, 74, - 63, 64, 74, 74, 64, 75, - 64, 65, 75, 75, 65, 76, - 66, 67, 77, 77, 67, 78, - 67, 68, 78, 78, 68, 79, - 68, 69, 79, 79, 69, 80, - 69, 70, 80, 80, 70, 81, - 70, 71, 81, 81, 71, 82, - 71, 72, 82, 82, 72, 83, - 72, 73, 83, 83, 73, 84, - 73, 74, 84, 84, 74, 85, - 74, 75, 85, 85, 75, 86, - 75, 76, 86, 86, 76, 87, - 77, 78, 88, 88, 78, 89, - 78, 79, 89, 89, 79, 90, - 79, 80, 90, 90, 80, 91, - 80, 81, 91, 91, 81, 92, - 81, 82, 92, 92, 82, 93, - 82, 83, 93, 93, 83, 94, - 83, 84, 94, 94, 84, 95, - 84, 85, 95, 95, 85, 96, - 85, 86, 96, 96, 86, 97, - 86, 87, 97, 97, 87, 98, - 88, 89, 99, 99, 89, 100, - 89, 90, 100, 100, 90, 101, - 90, 91, 101, 101, 91, 102, - 91, 92, 102, 102, 92, 103, - 92, 93, 103, 103, 93, 104, - 93, 94, 104, 104, 94, 105, - 94, 95, 105, 105, 95, 106, - 95, 96, 106, 106, 96, 107, - 96, 97, 107, 107, 97, 108, - 97, 98, 108, 108, 98, 109, - 99, 100, 110, 110, 100, 111, - 100, 101, 111, 111, 101, 112, - 101, 102, 112, 112, 102, 113, - 102, 103, 113, 113, 103, 114, - 103, 104, 114, 114, 104, 115, - 104, 105, 115, 115, 105, 116, - 105, 106, 116, 116, 106, 117, - 106, 107, 117, 117, 107, 118, - 107, 108, 118, 118, 108, 119, - 108, 109, 119, 119, 109, 120, - 121, 122, 132, 132, 122, 133, - 122, 123, 133, 133, 123, 134, - 123, 124, 134, 134, 124, 135, - 124, 125, 135, 135, 125, 136, - 125, 126, 136, 136, 126, 137, - 126, 127, 137, 137, 127, 138, - 127, 128, 138, 138, 128, 139, - 128, 129, 139, 139, 129, 140, - 129, 130, 140, 140, 130, 141, - 130, 131, 141, 141, 131, 142, - 132, 133, 143, 143, 133, 144, - 133, 134, 144, 144, 134, 145, - 134, 135, 145, 145, 135, 146, - 135, 136, 146, 146, 136, 147, - 136, 137, 147, 147, 137, 148, - 137, 138, 148, 148, 138, 149, - 138, 139, 149, 149, 139, 150, - 139, 140, 150, 150, 140, 151, - 140, 141, 151, 151, 141, 152, - 141, 142, 152, 152, 142, 153, - 143, 144, 154, 154, 144, 155, - 144, 145, 155, 155, 145, 156, - 145, 146, 156, 156, 146, 157, - 146, 147, 157, 157, 147, 158, - 147, 148, 158, 158, 148, 159, - 148, 149, 159, 159, 149, 160, - 149, 150, 160, 160, 150, 161, - 150, 151, 161, 161, 151, 162, - 151, 152, 162, 162, 152, 163, - 152, 153, 163, 163, 153, 164, - 154, 155, 165, 165, 155, 166, - 155, 156, 166, 166, 156, 167, - 156, 157, 167, 167, 157, 168, - 157, 158, 168, 168, 158, 169, - 158, 159, 169, 169, 159, 170, - 159, 160, 170, 170, 160, 171, - 160, 161, 171, 171, 161, 172, - 161, 162, 172, 172, 162, 173, - 162, 163, 173, 173, 163, 174, - 163, 164, 174, 174, 164, 175, - 165, 166, 176, 176, 166, 177, - 166, 167, 177, 177, 167, 178, - 167, 168, 178, 178, 168, 179, - 168, 169, 179, 179, 169, 180, - 169, 170, 180, 180, 170, 181, - 170, 171, 181, 181, 171, 182, - 171, 172, 182, 182, 172, 183, - 172, 173, 183, 183, 173, 184, - 173, 174, 184, 184, 174, 185, - 174, 175, 185, 185, 175, 186, - 176, 177, 187, 187, 177, 188, - 177, 178, 188, 188, 178, 189, - 178, 179, 189, 189, 179, 190, - 179, 180, 190, 190, 180, 191, - 180, 181, 191, 191, 181, 192, - 181, 182, 192, 192, 182, 193, - 182, 183, 193, 193, 183, 194, - 183, 184, 194, 194, 184, 195, - 184, 185, 195, 195, 185, 196, - 185, 186, 196, 196, 186, 197, - 187, 188, 198, 198, 188, 199, - 188, 189, 199, 199, 189, 200, - 189, 190, 200, 200, 190, 201, - 190, 191, 201, 201, 191, 202, - 191, 192, 202, 202, 192, 203, - 192, 193, 203, 203, 193, 204, - 193, 194, 204, 204, 194, 205, - 194, 195, 205, 205, 195, 206, - 195, 196, 206, 206, 196, 207, - 196, 197, 207, 207, 197, 208, - 198, 199, 209, 209, 199, 210, - 199, 200, 210, 210, 200, 211, - 200, 201, 211, 211, 201, 212, - 201, 202, 212, 212, 202, 213, - 202, 203, 213, 213, 203, 214, - 203, 204, 214, 214, 204, 215, - 204, 205, 215, 215, 205, 216, - 205, 206, 216, 216, 206, 217, - 206, 207, 217, 217, 207, 218, - 207, 208, 218, 218, 208, 219, - 209, 210, 220, 220, 210, 221, - 210, 211, 221, 221, 211, 222, - 211, 212, 222, 222, 212, 223, - 212, 213, 223, 223, 213, 224, - 213, 214, 224, 224, 214, 225, - 214, 215, 225, 225, 215, 226, - 215, 216, 226, 226, 216, 227, - 216, 217, 227, 227, 217, 228, - 217, 218, 228, 228, 218, 229, - 218, 219, 229, 229, 219, 230, - 220, 221, 231, 231, 221, 232, - 221, 222, 232, 232, 222, 233, - 222, 223, 233, 233, 223, 234, - 223, 224, 234, 234, 224, 235, - 224, 225, 235, 235, 225, 236, - 225, 226, 236, 236, 226, 237, - 226, 227, 237, 237, 227, 238, - 227, 228, 238, 238, 228, 239, - 228, 229, 239, 239, 229, 240, - 229, 230, 240, 240, 230, 241, - 242, 243, 253, 253, 243, 254, - 243, 244, 254, 254, 244, 255, - 244, 245, 255, 255, 245, 256, - 245, 246, 256, 256, 246, 257, - 246, 247, 257, 257, 247, 258, - 247, 248, 258, 258, 248, 259, - 248, 249, 259, 259, 249, 260, - 249, 250, 260, 260, 250, 261, - 250, 251, 261, 261, 251, 262, - 251, 252, 262, 262, 252, 263, - 253, 254, 264, 264, 254, 265, - 254, 255, 265, 265, 255, 266, - 255, 256, 266, 266, 256, 267, - 256, 257, 267, 267, 257, 268, - 257, 258, 268, 268, 258, 269, - 258, 259, 269, 269, 259, 270, - 259, 260, 270, 270, 260, 271, - 260, 261, 271, 271, 261, 272, - 261, 262, 272, 272, 262, 273, - 262, 263, 273, 273, 263, 274, - 264, 265, 275, 275, 265, 276, - 265, 266, 276, 276, 266, 277, - 266, 267, 277, 277, 267, 278, - 267, 268, 278, 278, 268, 279, - 268, 269, 279, 279, 269, 280, - 269, 270, 280, 280, 270, 281, - 270, 271, 281, 281, 271, 282, - 271, 272, 282, 282, 272, 283, - 272, 273, 283, 283, 273, 284, - 273, 274, 284, 284, 274, 285, - 275, 276, 286, 286, 276, 287, - 276, 277, 287, 287, 277, 288, - 277, 278, 288, 288, 278, 289, - 278, 279, 289, 289, 279, 290, - 279, 280, 290, 290, 280, 291, - 280, 281, 291, 291, 281, 292, - 281, 282, 292, 292, 282, 293, - 282, 283, 293, 293, 283, 294, - 283, 284, 294, 294, 284, 295, - 284, 285, 295, 295, 285, 296, - 286, 287, 297, 297, 287, 298, - 287, 288, 298, 298, 288, 299, - 288, 289, 299, 299, 289, 300, - 289, 290, 300, 300, 290, 301, - 290, 291, 301, 301, 291, 302, - 291, 292, 302, 302, 292, 303, - 292, 293, 303, 303, 293, 304, - 293, 294, 304, 304, 294, 305, - 294, 295, 305, 305, 295, 306, - 295, 296, 306, 306, 296, 307, - 297, 298, 308, 308, 298, 309, - 298, 299, 309, 309, 299, 310, - 299, 300, 310, 310, 300, 311, - 300, 301, 311, 311, 301, 312, - 301, 302, 312, 312, 302, 313, - 302, 303, 313, 313, 303, 314, - 303, 304, 314, 314, 304, 315, - 304, 305, 315, 315, 305, 316, - 305, 306, 316, 316, 306, 317, - 306, 307, 317, 317, 307, 318, - 308, 309, 319, 319, 309, 320, - 309, 310, 320, 320, 310, 321, - 310, 311, 321, 321, 311, 322, - 311, 312, 322, 322, 312, 323, - 312, 313, 323, 323, 313, 324, - 313, 314, 324, 324, 314, 325, - 314, 315, 325, 325, 315, 326, - 315, 316, 326, 326, 316, 327, - 316, 317, 327, 327, 317, 328, - 317, 318, 328, 328, 318, 329, - 319, 320, 330, 330, 320, 331, - 320, 321, 331, 331, 321, 332, - 321, 322, 332, 332, 322, 333, - 322, 323, 333, 333, 323, 334, - 323, 324, 334, 334, 324, 335, - 324, 325, 335, 335, 325, 336, - 325, 326, 336, 336, 326, 337, - 326, 327, 337, 337, 327, 338, - 327, 328, 338, 338, 328, 339, - 328, 329, 339, 339, 329, 340, - 330, 331, 341, 341, 331, 342, - 331, 332, 342, 342, 332, 343, - 332, 333, 343, 343, 333, 344, - 333, 334, 344, 344, 334, 345, - 334, 335, 345, 345, 335, 346, - 335, 336, 346, 346, 336, 347, - 336, 337, 347, 347, 337, 348, - 337, 338, 348, 348, 338, 349, - 338, 339, 349, 349, 339, 350, - 339, 340, 350, 350, 340, 351, - 341, 342, 352, 352, 342, 353, - 342, 343, 353, 353, 343, 354, - 343, 344, 354, 354, 344, 355, - 344, 345, 355, 355, 345, 356, - 345, 346, 356, 356, 346, 357, - 346, 347, 357, 357, 347, 358, - 347, 348, 358, 358, 348, 359, - 348, 349, 359, 359, 349, 360, - 349, 350, 360, 360, 350, 361, - 350, 351, 361, 361, 351, 362, - 363, 364, 374, 374, 364, 375, - 364, 365, 375, 375, 365, 376, - 365, 366, 376, 376, 366, 377, - 366, 367, 377, 377, 367, 378, - 367, 368, 378, 378, 368, 379, - 368, 369, 379, 379, 369, 380, - 369, 370, 380, 380, 370, 381, - 370, 371, 381, 381, 371, 382, - 371, 372, 382, 382, 372, 383, - 372, 373, 383, 383, 373, 384, - 374, 375, 385, 385, 375, 386, - 375, 376, 386, 386, 376, 387, - 376, 377, 387, 387, 377, 388, - 377, 378, 388, 388, 378, 389, - 378, 379, 389, 389, 379, 390, - 379, 380, 390, 390, 380, 391, - 380, 381, 391, 391, 381, 392, - 381, 382, 392, 392, 382, 393, - 382, 383, 393, 393, 383, 394, - 383, 384, 394, 394, 384, 395, - 385, 386, 396, 396, 386, 397, - 386, 387, 397, 397, 387, 398, - 387, 388, 398, 398, 388, 399, - 388, 389, 399, 399, 389, 400, - 389, 390, 400, 400, 390, 401, - 390, 391, 401, 401, 391, 402, - 391, 392, 402, 402, 392, 403, - 392, 393, 403, 403, 393, 404, - 393, 394, 404, 404, 394, 405, - 394, 395, 405, 405, 395, 406, - 396, 397, 407, 407, 397, 408, - 397, 398, 408, 408, 398, 409, - 398, 399, 409, 409, 399, 410, - 399, 400, 410, 410, 400, 411, - 400, 401, 411, 411, 401, 412, - 401, 402, 412, 412, 402, 413, - 402, 403, 413, 413, 403, 414, - 403, 404, 414, 414, 404, 415, - 404, 405, 415, 415, 405, 416, - 405, 406, 416, 416, 406, 417, - 407, 408, 418, 418, 408, 419, - 408, 409, 419, 419, 409, 420, - 409, 410, 420, 420, 410, 421, - 410, 411, 421, 421, 411, 422, - 411, 412, 422, 422, 412, 423, - 412, 413, 423, 423, 413, 424, - 413, 414, 424, 424, 414, 425, - 414, 415, 425, 425, 415, 426, - 415, 416, 426, 426, 416, 427, - 416, 417, 427, 427, 417, 428, - 418, 419, 429, 429, 419, 430, - 419, 420, 430, 430, 420, 431, - 420, 421, 431, 431, 421, 432, - 421, 422, 432, 432, 422, 433, - 422, 423, 433, 433, 423, 434, - 423, 424, 434, 434, 424, 435, - 424, 425, 435, 435, 425, 436, - 425, 426, 436, 436, 426, 437, - 426, 427, 437, 437, 427, 438, - 427, 428, 438, 438, 428, 439, - 429, 430, 440, 440, 430, 441, - 430, 431, 441, 441, 431, 442, - 431, 432, 442, 442, 432, 443, - 432, 433, 443, 443, 433, 444, - 433, 434, 444, 444, 434, 445, - 434, 435, 445, 445, 435, 446, - 435, 436, 446, 446, 436, 447, - 436, 437, 447, 447, 437, 448, - 437, 438, 448, 448, 438, 449, - 438, 439, 449, 449, 439, 450, - 440, 441, 451, 451, 441, 452, - 441, 442, 452, 452, 442, 453, - 442, 443, 453, 453, 443, 454, - 443, 444, 454, 454, 444, 455, - 444, 445, 455, 455, 445, 456, - 445, 446, 456, 456, 446, 457, - 446, 447, 457, 457, 447, 458, - 447, 448, 458, 458, 448, 459, - 448, 449, 459, 459, 449, 460, - 449, 450, 460, 460, 450, 461, - 451, 452, 462, 462, 452, 463, - 452, 453, 463, 463, 453, 464, - 453, 454, 464, 464, 454, 465, - 454, 455, 465, 465, 455, 466, - 455, 456, 466, 466, 456, 467, - 456, 457, 467, 467, 457, 468, - 457, 458, 468, 468, 458, 469, - 458, 459, 469, 469, 459, 470, - 459, 460, 470, 470, 460, 471, - 460, 461, 471, 471, 461, 472, - 462, 463, 473, 473, 463, 474, - 463, 464, 474, 474, 464, 475, - 464, 465, 475, 475, 465, 476, - 465, 466, 476, 476, 466, 477, - 466, 467, 477, 477, 467, 478, - 467, 468, 478, 478, 468, 479, - 468, 469, 479, 479, 469, 480, - 469, 470, 480, 480, 470, 481, - 470, 471, 481, 481, 471, 482, - 471, 472, 482, 482, 472, 483, - 484, 485, 495, 495, 485, 496, - 485, 486, 496, 496, 486, 497, - 486, 487, 497, 497, 487, 498, - 487, 488, 498, 498, 488, 499, - 488, 489, 499, 499, 489, 500, - 489, 490, 500, 500, 490, 501, - 490, 491, 501, 501, 491, 502, - 491, 492, 502, 502, 492, 503, - 492, 493, 503, 503, 493, 504, - 493, 494, 504, 504, 494, 505, - 495, 496, 506, 506, 496, 507, - 496, 497, 507, 507, 497, 508, - 497, 498, 508, 508, 498, 509, - 498, 499, 509, 509, 499, 510, - 499, 500, 510, 510, 500, 511, - 500, 501, 511, 511, 501, 512, - 501, 502, 512, 512, 502, 513, - 502, 503, 513, 513, 503, 514, - 503, 504, 514, 514, 504, 515, - 504, 505, 515, 515, 505, 516, - 506, 507, 517, 517, 507, 518, - 507, 508, 518, 518, 508, 519, - 508, 509, 519, 519, 509, 520, - 509, 510, 520, 520, 510, 521, - 510, 511, 521, 521, 511, 522, - 511, 512, 522, 522, 512, 523, - 512, 513, 523, 523, 513, 524, - 513, 514, 524, 524, 514, 525, - 514, 515, 525, 525, 515, 526, - 515, 516, 526, 526, 516, 527, - 517, 518, 528, 528, 518, 529, - 518, 519, 529, 529, 519, 530, - 519, 520, 530, 530, 520, 531, - 520, 521, 531, 531, 521, 532, - 521, 522, 532, 532, 522, 533, - 522, 523, 533, 533, 523, 534, - 523, 524, 534, 534, 524, 535, - 524, 525, 535, 535, 525, 536, - 525, 526, 536, 536, 526, 537, - 526, 527, 537, 537, 527, 538, - 528, 529, 539, 539, 529, 540, - 529, 530, 540, 540, 530, 541, - 530, 531, 541, 541, 531, 542, - 531, 532, 542, 542, 532, 543, - 532, 533, 543, 543, 533, 544, - 533, 534, 544, 544, 534, 545, - 534, 535, 545, 545, 535, 546, - 535, 536, 546, 546, 536, 547, - 536, 537, 547, 547, 537, 548, - 537, 538, 548, 548, 538, 549, - 539, 540, 550, 550, 540, 551, - 540, 541, 551, 551, 541, 552, - 541, 542, 552, 552, 542, 553, - 542, 543, 553, 553, 543, 554, - 543, 544, 554, 554, 544, 555, - 544, 545, 555, 555, 545, 556, - 545, 546, 556, 556, 546, 557, - 546, 547, 557, 557, 547, 558, - 547, 548, 558, 558, 548, 559, - 548, 549, 559, 559, 549, 560, - 550, 551, 561, 561, 551, 562, - 551, 552, 562, 562, 552, 563, - 552, 553, 563, 563, 553, 564, - 553, 554, 564, 564, 554, 565, - 554, 555, 565, 565, 555, 566, - 555, 556, 566, 566, 556, 567, - 556, 557, 567, 567, 557, 568, - 557, 558, 568, 568, 558, 569, - 558, 559, 569, 569, 559, 570, - 559, 560, 570, 570, 560, 571, - 561, 562, 572, 572, 562, 573, - 562, 563, 573, 573, 563, 574, - 563, 564, 574, 574, 564, 575, - 564, 565, 575, 575, 565, 576, - 565, 566, 576, 576, 566, 577, - 566, 567, 577, 577, 567, 578, - 567, 568, 578, 578, 568, 579, - 568, 569, 579, 579, 569, 580, - 569, 570, 580, 580, 570, 581, - 570, 571, 581, 581, 571, 582, - 572, 573, 583, 583, 573, 584, - 573, 574, 584, 584, 574, 585, - 574, 575, 585, 585, 575, 586, - 575, 576, 586, 586, 576, 587, - 576, 577, 587, 587, 577, 588, - 577, 578, 588, 588, 578, 589, - 578, 579, 589, 589, 579, 590, - 579, 580, 590, 590, 580, 591, - 580, 581, 591, 591, 581, 592, - 581, 582, 592, 592, 582, 593, - 583, 584, 594, 594, 584, 595, - 584, 585, 595, 595, 585, 596, - 585, 586, 596, 596, 586, 597, - 586, 587, 597, 597, 587, 598, - 587, 588, 598, 598, 588, 599, - 588, 589, 599, 599, 589, 600, - 589, 590, 600, 600, 590, 601, - 590, 591, 601, 601, 591, 602, - 591, 592, 602, 602, 592, 603, - 592, 593, 603, 603, 593, 604, - 605, 606, 616, 616, 606, 617, - 606, 607, 617, 617, 607, 618, - 607, 608, 618, 618, 608, 619, - 608, 609, 619, 619, 609, 620, - 609, 610, 620, 620, 610, 621, - 610, 611, 621, 621, 611, 622, - 611, 612, 622, 622, 612, 623, - 612, 613, 623, 623, 613, 624, - 613, 614, 624, 624, 614, 625, - 614, 615, 625, 625, 615, 626, - 616, 617, 627, 627, 617, 628, - 617, 618, 628, 628, 618, 629, - 618, 619, 629, 629, 619, 630, - 619, 620, 630, 630, 620, 631, - 620, 621, 631, 631, 621, 632, - 621, 622, 632, 632, 622, 633, - 622, 623, 633, 633, 623, 634, - 623, 624, 634, 634, 624, 635, - 624, 625, 635, 635, 625, 636, - 625, 626, 636, 636, 626, 637, - 627, 628, 638, 638, 628, 639, - 628, 629, 639, 639, 629, 640, - 629, 630, 640, 640, 630, 641, - 630, 631, 641, 641, 631, 642, - 631, 632, 642, 642, 632, 643, - 632, 633, 643, 643, 633, 644, - 633, 634, 644, 644, 634, 645, - 634, 635, 645, 645, 635, 646, - 635, 636, 646, 646, 636, 647, - 636, 637, 647, 647, 637, 648, - 638, 639, 649, 649, 639, 650, - 639, 640, 650, 650, 640, 651, - 640, 641, 651, 651, 641, 652, - 641, 642, 652, 652, 642, 653, - 642, 643, 653, 653, 643, 654, - 643, 644, 654, 654, 644, 655, - 644, 645, 655, 655, 645, 656, - 645, 646, 656, 656, 646, 657, - 646, 647, 657, 657, 647, 658, - 647, 648, 658, 658, 648, 659, - 649, 650, 660, 660, 650, 661, - 650, 651, 661, 661, 651, 662, - 651, 652, 662, 662, 652, 663, - 652, 653, 663, 663, 653, 664, - 653, 654, 664, 664, 654, 665, - 654, 655, 665, 665, 655, 666, - 655, 656, 666, 666, 656, 667, - 656, 657, 667, 667, 657, 668, - 657, 658, 668, 668, 658, 669, - 658, 659, 669, 669, 659, 670, - 660, 661, 671, 671, 661, 672, - 661, 662, 672, 672, 662, 673, - 662, 663, 673, 673, 663, 674, - 663, 664, 674, 674, 664, 675, - 664, 665, 675, 675, 665, 676, - 665, 666, 676, 676, 666, 677, - 666, 667, 677, 677, 667, 678, - 667, 668, 678, 678, 668, 679, - 668, 669, 679, 679, 669, 680, - 669, 670, 680, 680, 670, 681, - 671, 672, 682, 682, 672, 683, - 672, 673, 683, 683, 673, 684, - 673, 674, 684, 684, 674, 685, - 674, 675, 685, 685, 675, 686, - 675, 676, 686, 686, 676, 687, - 676, 677, 687, 687, 677, 688, - 677, 678, 688, 688, 678, 689, - 678, 679, 689, 689, 679, 690, - 679, 680, 690, 690, 680, 691, - 680, 681, 691, 691, 681, 692, - 682, 683, 693, 693, 683, 694, - 683, 684, 694, 694, 684, 695, - 684, 685, 695, 695, 685, 696, - 685, 686, 696, 696, 686, 697, - 686, 687, 697, 697, 687, 698, - 687, 688, 698, 698, 688, 699, - 688, 689, 699, 699, 689, 700, - 689, 690, 700, 700, 690, 701, - 690, 691, 701, 701, 691, 702, - 691, 692, 702, 702, 692, 703, - 693, 694, 704, 704, 694, 705, - 694, 695, 705, 705, 695, 706, - 695, 696, 706, 706, 696, 707, - 696, 697, 707, 707, 697, 708, - 697, 698, 708, 708, 698, 709, - 698, 699, 709, 709, 699, 710, - 699, 700, 710, 710, 700, 711, - 700, 701, 711, 711, 701, 712, - 701, 702, 712, 712, 702, 713, - 702, 703, 713, 713, 703, 714, - 704, 705, 715, 715, 705, 716, - 705, 706, 716, 716, 706, 717, - 706, 707, 717, 717, 707, 718, - 707, 708, 718, 718, 708, 719, - 708, 709, 719, 719, 709, 720, - 709, 710, 720, 720, 710, 721, - 710, 711, 721, 721, 711, 722, - 711, 712, 722, 722, 712, 723, - 712, 713, 723, 723, 713, 724, - 713, 714, 724, 724, 714, 725, - 726, 727, 737, 737, 727, 738, - 727, 728, 738, 738, 728, 739, - 728, 729, 739, 739, 729, 740, - 729, 730, 740, 740, 730, 741, - 730, 731, 741, 741, 731, 742, - 731, 732, 742, 742, 732, 743, - 732, 733, 743, 743, 733, 744, - 733, 734, 744, 744, 734, 745, - 734, 735, 745, 745, 735, 746, - 735, 736, 746, 746, 736, 747, - 737, 738, 748, 748, 738, 749, - 738, 739, 749, 749, 739, 750, - 739, 740, 750, 750, 740, 751, - 740, 741, 751, 751, 741, 752, - 741, 742, 752, 752, 742, 753, - 742, 743, 753, 753, 743, 754, - 743, 744, 754, 754, 744, 755, - 744, 745, 755, 755, 745, 756, - 745, 746, 756, 756, 746, 757, - 746, 747, 757, 757, 747, 758, - 748, 749, 759, 759, 749, 760, - 749, 750, 760, 760, 750, 761, - 750, 751, 761, 761, 751, 762, - 751, 752, 762, 762, 752, 763, - 752, 753, 763, 763, 753, 764, - 753, 754, 764, 764, 754, 765, - 754, 755, 765, 765, 755, 766, - 755, 756, 766, 766, 756, 767, - 756, 757, 767, 767, 757, 768, - 757, 758, 768, 768, 758, 769, - 759, 760, 770, 770, 760, 771, - 760, 761, 771, 771, 761, 772, - 761, 762, 772, 772, 762, 773, - 762, 763, 773, 773, 763, 774, - 763, 764, 774, 774, 764, 775, - 764, 765, 775, 775, 765, 776, - 765, 766, 776, 776, 766, 777, - 766, 767, 777, 777, 767, 778, - 767, 768, 778, 778, 768, 779, - 768, 769, 779, 779, 769, 780, - 770, 771, 781, 781, 771, 782, - 771, 772, 782, 782, 772, 783, - 772, 773, 783, 783, 773, 784, - 773, 774, 784, 784, 774, 785, - 774, 775, 785, 785, 775, 786, - 775, 776, 786, 786, 776, 787, - 776, 777, 787, 787, 777, 788, - 777, 778, 788, 788, 778, 789, - 778, 779, 789, 789, 779, 790, - 779, 780, 790, 790, 780, 791, - 781, 782, 792, 792, 782, 793, - 782, 783, 793, 793, 783, 794, - 783, 784, 794, 794, 784, 795, - 784, 785, 795, 795, 785, 796, - 785, 786, 796, 796, 786, 797, - 786, 787, 797, 797, 787, 798, - 787, 788, 798, 798, 788, 799, - 788, 789, 799, 799, 789, 800, - 789, 790, 800, 800, 790, 801, - 790, 791, 801, 801, 791, 802, - 792, 793, 803, 803, 793, 804, - 793, 794, 804, 804, 794, 805, - 794, 795, 805, 805, 795, 806, - 795, 796, 806, 806, 796, 807, - 796, 797, 807, 807, 797, 808, - 797, 798, 808, 808, 798, 809, - 798, 799, 809, 809, 799, 810, - 799, 800, 810, 810, 800, 811, - 800, 801, 811, 811, 801, 812, - 801, 802, 812, 812, 802, 813, - 803, 804, 814, 814, 804, 815, - 804, 805, 815, 815, 805, 816, - 805, 806, 816, 816, 806, 817, - 806, 807, 817, 817, 807, 818, - 807, 808, 818, 818, 808, 819, - 808, 809, 819, 819, 809, 820, - 809, 810, 820, 820, 810, 821, - 810, 811, 821, 821, 811, 822, - 811, 812, 822, 822, 812, 823, - 812, 813, 823, 823, 813, 824, - 814, 815, 825, 825, 815, 826, - 815, 816, 826, 826, 816, 827, - 816, 817, 827, 827, 817, 828, - 817, 818, 828, 828, 818, 829, - 818, 819, 829, 829, 819, 830, - 819, 820, 830, 830, 820, 831, - 820, 821, 831, 831, 821, 832, - 821, 822, 832, 832, 822, 833, - 822, 823, 833, 833, 823, 834, - 823, 824, 834, 834, 824, 835, - 825, 826, 836, 836, 826, 837, - 826, 827, 837, 837, 827, 838, - 827, 828, 838, 838, 828, 839, - 828, 829, 839, 839, 829, 840, - 829, 830, 840, 840, 830, 841, - 830, 831, 841, 841, 831, 842, - 831, 832, 842, 842, 832, 843, - 832, 833, 843, 843, 833, 844, - 833, 834, 844, 844, 834, 845, - 834, 835, 845, 845, 835, 846, - 847, 848, 858, 858, 848, 859, - 848, 849, 859, 859, 849, 860, - 849, 850, 860, 860, 850, 861, - 850, 851, 861, 861, 851, 862, - 851, 852, 862, 862, 852, 863, - 852, 853, 863, 863, 853, 864, - 853, 854, 864, 864, 854, 865, - 854, 855, 865, 865, 855, 866, - 855, 856, 866, 866, 856, 867, - 856, 857, 867, 867, 857, 868, - 858, 859, 869, 869, 859, 870, - 859, 860, 870, 870, 860, 871, - 860, 861, 871, 871, 861, 872, - 861, 862, 872, 872, 862, 873, - 862, 863, 873, 873, 863, 874, - 863, 864, 874, 874, 864, 875, - 864, 865, 875, 875, 865, 876, - 865, 866, 876, 876, 866, 877, - 866, 867, 877, 877, 867, 878, - 867, 868, 878, 878, 868, 879, - 869, 870, 880, 880, 870, 881, - 870, 871, 881, 881, 871, 882, - 871, 872, 882, 882, 872, 883, - 872, 873, 883, 883, 873, 884, - 873, 874, 884, 884, 874, 885, - 874, 875, 885, 885, 875, 886, - 875, 876, 886, 886, 876, 887, - 876, 877, 887, 887, 877, 888, - 877, 878, 888, 888, 878, 889, - 878, 879, 889, 889, 879, 890, - 880, 881, 891, 891, 881, 892, - 881, 882, 892, 892, 882, 893, - 882, 883, 893, 893, 883, 894, - 883, 884, 894, 894, 884, 895, - 884, 885, 895, 895, 885, 896, - 885, 886, 896, 896, 886, 897, - 886, 887, 897, 897, 887, 898, - 887, 888, 898, 898, 888, 899, - 888, 889, 899, 899, 889, 900, - 889, 890, 900, 900, 890, 901, - 891, 892, 902, 902, 892, 903, - 892, 893, 903, 903, 893, 904, - 893, 894, 904, 904, 894, 905, - 894, 895, 905, 905, 895, 906, - 895, 896, 906, 906, 896, 907, - 896, 897, 907, 907, 897, 908, - 897, 898, 908, 908, 898, 909, - 898, 899, 909, 909, 899, 910, - 899, 900, 910, 910, 900, 911, - 900, 901, 911, 911, 901, 912, - 902, 903, 913, 913, 903, 914, - 903, 904, 914, 914, 904, 915, - 904, 905, 915, 915, 905, 916, - 905, 906, 916, 916, 906, 917, - 906, 907, 917, 917, 907, 918, - 907, 908, 918, 918, 908, 919, - 908, 909, 919, 919, 909, 920, - 909, 910, 920, 920, 910, 921, - 910, 911, 921, 921, 911, 922, - 911, 912, 922, 922, 912, 923, - 913, 914, 924, 924, 914, 925, - 914, 915, 925, 925, 915, 926, - 915, 916, 926, 926, 916, 927, - 916, 917, 927, 927, 917, 928, - 917, 918, 928, 928, 918, 929, - 918, 919, 929, 929, 919, 930, - 919, 920, 930, 930, 920, 931, - 920, 921, 931, 931, 921, 932, - 921, 922, 932, 932, 922, 933, - 922, 923, 933, 933, 923, 934, - 924, 925, 935, 935, 925, 936, - 925, 926, 936, 936, 926, 937, - 926, 927, 937, 937, 927, 938, - 927, 928, 938, 938, 928, 939, - 928, 929, 939, 939, 929, 940, - 929, 930, 940, 940, 930, 941, - 930, 931, 941, 941, 931, 942, - 931, 932, 942, 942, 932, 943, - 932, 933, 943, 943, 933, 944, - 933, 934, 944, 944, 934, 945, - 935, 936, 946, 946, 936, 947, - 936, 937, 947, 947, 937, 948, - 937, 938, 948, 948, 938, 949, - 938, 939, 949, 949, 939, 950, - 939, 940, 950, 950, 940, 951, - 940, 941, 951, 951, 941, 952, - 941, 942, 952, 952, 942, 953, - 942, 943, 953, 953, 943, 954, - 943, 944, 954, 954, 944, 955, - 944, 945, 955, 955, 945, 956, - 946, 947, 957, 957, 947, 958, - 947, 948, 958, 958, 948, 959, - 948, 949, 959, 959, 949, 960, - 949, 950, 960, 960, 950, 961, - 950, 951, 961, 961, 951, 962, - 951, 952, 962, 962, 952, 963, - 952, 953, 963, 963, 953, 964, - 953, 954, 964, 964, 954, 965, - 954, 955, 965, 965, 955, 966, - 955, 956, 966, 966, 956, 967, - 968, 969, 979, 979, 969, 980, - 969, 970, 980, 980, 970, 981, - 970, 971, 981, 981, 971, 982, - 971, 972, 982, 982, 972, 983, - 972, 973, 983, 983, 973, 984, - 973, 974, 984, 984, 974, 985, - 974, 975, 985, 985, 975, 986, - 975, 976, 986, 986, 976, 987, - 976, 977, 987, 987, 977, 988, - 977, 978, 988, 988, 978, 989, - 979, 980, 990, 990, 980, 991, - 980, 981, 991, 991, 981, 992, - 981, 982, 992, 992, 982, 993, - 982, 983, 993, 993, 983, 994, - 983, 984, 994, 994, 984, 995, - 984, 985, 995, 995, 985, 996, - 985, 986, 996, 996, 986, 997, - 986, 987, 997, 997, 987, 998, - 987, 988, 998, 998, 988, 999, - 988, 989, 999, 999, 989, 1000, - 990, 991, 1001, 1001, 991, 1002, - 991, 992, 1002, 1002, 992, 1003, - 992, 993, 1003, 1003, 993, 1004, - 993, 994, 1004, 1004, 994, 1005, - 994, 995, 1005, 1005, 995, 1006, - 995, 996, 1006, 1006, 996, 1007, - 996, 997, 1007, 1007, 997, 1008, - 997, 998, 1008, 1008, 998, 1009, - 998, 999, 1009, 1009, 999, 1010, - 999, 1000, 1010, 1010, 1000, 1011, - 1001, 1002, 1012, 1012, 1002, 1013, - 1002, 1003, 1013, 1013, 1003, 1014, - 1003, 1004, 1014, 1014, 1004, 1015, - 1004, 1005, 1015, 1015, 1005, 1016, - 1005, 1006, 1016, 1016, 1006, 1017, - 1006, 1007, 1017, 1017, 1007, 1018, - 1007, 1008, 1018, 1018, 1008, 1019, - 1008, 1009, 1019, 1019, 1009, 1020, - 1009, 1010, 1020, 1020, 1010, 1021, - 1010, 1011, 1021, 1021, 1011, 1022, - 1012, 1013, 1023, 1023, 1013, 1024, - 1013, 1014, 1024, 1024, 1014, 1025, - 1014, 1015, 1025, 1025, 1015, 1026, - 1015, 1016, 1026, 1026, 1016, 1027, - 1016, 1017, 1027, 1027, 1017, 1028, - 1017, 1018, 1028, 1028, 1018, 1029, - 1018, 1019, 1029, 1029, 1019, 1030, - 1019, 1020, 1030, 1030, 1020, 1031, - 1020, 1021, 1031, 1031, 1021, 1032, - 1021, 1022, 1032, 1032, 1022, 1033, - 1023, 1024, 1034, 1034, 1024, 1035, - 1024, 1025, 1035, 1035, 1025, 1036, - 1025, 1026, 1036, 1036, 1026, 1037, - 1026, 1027, 1037, 1037, 1027, 1038, - 1027, 1028, 1038, 1038, 1028, 1039, - 1028, 1029, 1039, 1039, 1029, 1040, - 1029, 1030, 1040, 1040, 1030, 1041, - 1030, 1031, 1041, 1041, 1031, 1042, - 1031, 1032, 1042, 1042, 1032, 1043, - 1032, 1033, 1043, 1043, 1033, 1044, - 1034, 1035, 1045, 1045, 1035, 1046, - 1035, 1036, 1046, 1046, 1036, 1047, - 1036, 1037, 1047, 1047, 1037, 1048, - 1037, 1038, 1048, 1048, 1038, 1049, - 1038, 1039, 1049, 1049, 1039, 1050, - 1039, 1040, 1050, 1050, 1040, 1051, - 1040, 1041, 1051, 1051, 1041, 1052, - 1041, 1042, 1052, 1052, 1042, 1053, - 1042, 1043, 1053, 1053, 1043, 1054, - 1043, 1044, 1054, 1054, 1044, 1055, - 1045, 1046, 1056, 1056, 1046, 1057, - 1046, 1047, 1057, 1057, 1047, 1058, - 1047, 1048, 1058, 1058, 1048, 1059, - 1048, 1049, 1059, 1059, 1049, 1060, - 1049, 1050, 1060, 1060, 1050, 1061, - 1050, 1051, 1061, 1061, 1051, 1062, - 1051, 1052, 1062, 1062, 1052, 1063, - 1052, 1053, 1063, 1063, 1053, 1064, - 1053, 1054, 1064, 1064, 1054, 1065, - 1054, 1055, 1065, 1065, 1055, 1066, - 1056, 1057, 1067, 1067, 1057, 1068, - 1057, 1058, 1068, 1068, 1058, 1069, - 1058, 1059, 1069, 1069, 1059, 1070, - 1059, 1060, 1070, 1070, 1060, 1071, - 1060, 1061, 1071, 1071, 1061, 1072, - 1061, 1062, 1072, 1072, 1062, 1073, - 1062, 1063, 1073, 1073, 1063, 1074, - 1063, 1064, 1074, 1074, 1064, 1075, - 1064, 1065, 1075, 1075, 1065, 1076, - 1065, 1066, 1076, 1076, 1066, 1077, - 1067, 1068, 1078, 1078, 1068, 1079, - 1068, 1069, 1079, 1079, 1069, 1080, - 1069, 1070, 1080, 1080, 1070, 1081, - 1070, 1071, 1081, 1081, 1071, 1082, - 1071, 1072, 1082, 1082, 1072, 1083, - 1072, 1073, 1083, 1083, 1073, 1084, - 1073, 1074, 1084, 1084, 1074, 1085, - 1074, 1075, 1085, 1085, 1075, 1086, - 1075, 1076, 1086, 1086, 1076, 1087, - 1076, 1077, 1087, 1087, 1077, 1088, - 1089, 1090, 1100, 1100, 1090, 1101, - 1090, 1091, 1101, 1101, 1091, 1102, - 1091, 1092, 1102, 1102, 1092, 1103, - 1092, 1093, 1103, 1103, 1093, 1104, - 1093, 1094, 1104, 1104, 1094, 1105, - 1094, 1095, 1105, 1105, 1095, 1106, - 1095, 1096, 1106, 1106, 1096, 1107, - 1096, 1097, 1107, 1107, 1097, 1108, - 1097, 1098, 1108, 1108, 1098, 1109, - 1098, 1099, 1109, 1109, 1099, 1110, - 1100, 1101, 1111, 1111, 1101, 1112, - 1101, 1102, 1112, 1112, 1102, 1113, - 1102, 1103, 1113, 1113, 1103, 1114, - 1103, 1104, 1114, 1114, 1104, 1115, - 1104, 1105, 1115, 1115, 1105, 1116, - 1105, 1106, 1116, 1116, 1106, 1117, - 1106, 1107, 1117, 1117, 1107, 1118, - 1107, 1108, 1118, 1118, 1108, 1119, - 1108, 1109, 1119, 1119, 1109, 1120, - 1109, 1110, 1120, 1120, 1110, 1121, - 1111, 1112, 1122, 1122, 1112, 1123, - 1112, 1113, 1123, 1123, 1113, 1124, - 1113, 1114, 1124, 1124, 1114, 1125, - 1114, 1115, 1125, 1125, 1115, 1126, - 1115, 1116, 1126, 1126, 1116, 1127, - 1116, 1117, 1127, 1127, 1117, 1128, - 1117, 1118, 1128, 1128, 1118, 1129, - 1118, 1119, 1129, 1129, 1119, 1130, - 1119, 1120, 1130, 1130, 1120, 1131, - 1120, 1121, 1131, 1131, 1121, 1132, - 1122, 1123, 1133, 1133, 1123, 1134, - 1123, 1124, 1134, 1134, 1124, 1135, - 1124, 1125, 1135, 1135, 1125, 1136, - 1125, 1126, 1136, 1136, 1126, 1137, - 1126, 1127, 1137, 1137, 1127, 1138, - 1127, 1128, 1138, 1138, 1128, 1139, - 1128, 1129, 1139, 1139, 1129, 1140, - 1129, 1130, 1140, 1140, 1130, 1141, - 1130, 1131, 1141, 1141, 1131, 1142, - 1131, 1132, 1142, 1142, 1132, 1143, - 1133, 1134, 1144, 1144, 1134, 1145, - 1134, 1135, 1145, 1145, 1135, 1146, - 1135, 1136, 1146, 1146, 1136, 1147, - 1136, 1137, 1147, 1147, 1137, 1148, - 1137, 1138, 1148, 1148, 1138, 1149, - 1138, 1139, 1149, 1149, 1139, 1150, - 1139, 1140, 1150, 1150, 1140, 1151, - 1140, 1141, 1151, 1151, 1141, 1152, - 1141, 1142, 1152, 1152, 1142, 1153, - 1142, 1143, 1153, 1153, 1143, 1154, - 1144, 1145, 1155, 1155, 1145, 1156, - 1145, 1146, 1156, 1156, 1146, 1157, - 1146, 1147, 1157, 1157, 1147, 1158, - 1147, 1148, 1158, 1158, 1148, 1159, - 1148, 1149, 1159, 1159, 1149, 1160, - 1149, 1150, 1160, 1160, 1150, 1161, - 1150, 1151, 1161, 1161, 1151, 1162, - 1151, 1152, 1162, 1162, 1152, 1163, - 1152, 1153, 1163, 1163, 1153, 1164, - 1153, 1154, 1164, 1164, 1154, 1165, - 1155, 1156, 1166, 1166, 1156, 1167, - 1156, 1157, 1167, 1167, 1157, 1168, - 1157, 1158, 1168, 1168, 1158, 1169, - 1158, 1159, 1169, 1169, 1159, 1170, - 1159, 1160, 1170, 1170, 1160, 1171, - 1160, 1161, 1171, 1171, 1161, 1172, - 1161, 1162, 1172, 1172, 1162, 1173, - 1162, 1163, 1173, 1173, 1163, 1174, - 1163, 1164, 1174, 1174, 1164, 1175, - 1164, 1165, 1175, 1175, 1165, 1176, - 1166, 1167, 1177, 1177, 1167, 1178, - 1167, 1168, 1178, 1178, 1168, 1179, - 1168, 1169, 1179, 1179, 1169, 1180, - 1169, 1170, 1180, 1180, 1170, 1181, - 1170, 1171, 1181, 1181, 1171, 1182, - 1171, 1172, 1182, 1182, 1172, 1183, - 1172, 1173, 1183, 1183, 1173, 1184, - 1173, 1174, 1184, 1184, 1174, 1185, - 1174, 1175, 1185, 1185, 1175, 1186, - 1175, 1176, 1186, 1186, 1176, 1187, - 1177, 1178, 1188, 1188, 1178, 1189, - 1178, 1179, 1189, 1189, 1179, 1190, - 1179, 1180, 1190, 1190, 1180, 1191, - 1180, 1181, 1191, 1191, 1181, 1192, - 1181, 1182, 1192, 1192, 1182, 1193, - 1182, 1183, 1193, 1193, 1183, 1194, - 1183, 1184, 1194, 1194, 1184, 1195, - 1184, 1185, 1195, 1195, 1185, 1196, - 1185, 1186, 1196, 1196, 1186, 1197, - 1186, 1187, 1197, 1197, 1187, 1198, - 1188, 1189, 1199, 1199, 1189, 1200, - 1189, 1190, 1200, 1200, 1190, 1201, - 1190, 1191, 1201, 1201, 1191, 1202, - 1191, 1192, 1202, 1202, 1192, 1203, - 1192, 1193, 1203, 1203, 1193, 1204, - 1193, 1194, 1204, 1204, 1194, 1205, - 1194, 1195, 1205, 1205, 1195, 1206, - 1195, 1196, 1206, 1206, 1196, 1207, - 1196, 1197, 1207, 1207, 1197, 1208, - 1197, 1198, 1208, 1208, 1198, 1209, - 1210, 1211, 1221, 1221, 1211, 1222, - 1211, 1212, 1222, 1222, 1212, 1223, - 1212, 1213, 1223, 1223, 1213, 1224, - 1213, 1214, 1224, 1224, 1214, 1225, - 1214, 1215, 1225, 1225, 1215, 1226, - 1215, 1216, 1226, 1226, 1216, 1227, - 1216, 1217, 1227, 1227, 1217, 1228, - 1217, 1218, 1228, 1228, 1218, 1229, - 1218, 1219, 1229, 1229, 1219, 1230, - 1219, 1220, 1230, 1230, 1220, 1231, - 1221, 1222, 1232, 1232, 1222, 1233, - 1222, 1223, 1233, 1233, 1223, 1234, - 1223, 1224, 1234, 1234, 1224, 1235, - 1224, 1225, 1235, 1235, 1225, 1236, - 1225, 1226, 1236, 1236, 1226, 1237, - 1226, 1227, 1237, 1237, 1227, 1238, - 1227, 1228, 1238, 1238, 1228, 1239, - 1228, 1229, 1239, 1239, 1229, 1240, - 1229, 1230, 1240, 1240, 1230, 1241, - 1230, 1231, 1241, 1241, 1231, 1242, - 1232, 1233, 1243, 1243, 1233, 1244, - 1233, 1234, 1244, 1244, 1234, 1245, - 1234, 1235, 1245, 1245, 1235, 1246, - 1235, 1236, 1246, 1246, 1236, 1247, - 1236, 1237, 1247, 1247, 1237, 1248, - 1237, 1238, 1248, 1248, 1238, 1249, - 1238, 1239, 1249, 1249, 1239, 1250, - 1239, 1240, 1250, 1250, 1240, 1251, - 1240, 1241, 1251, 1251, 1241, 1252, - 1241, 1242, 1252, 1252, 1242, 1253, - 1243, 1244, 1254, 1254, 1244, 1255, - 1244, 1245, 1255, 1255, 1245, 1256, - 1245, 1246, 1256, 1256, 1246, 1257, - 1246, 1247, 1257, 1257, 1247, 1258, - 1247, 1248, 1258, 1258, 1248, 1259, - 1248, 1249, 1259, 1259, 1249, 1260, - 1249, 1250, 1260, 1260, 1250, 1261, - 1250, 1251, 1261, 1261, 1251, 1262, - 1251, 1252, 1262, 1262, 1252, 1263, - 1252, 1253, 1263, 1263, 1253, 1264, - 1254, 1255, 1265, 1265, 1255, 1266, - 1255, 1256, 1266, 1266, 1256, 1267, - 1256, 1257, 1267, 1267, 1257, 1268, - 1257, 1258, 1268, 1268, 1258, 1269, - 1258, 1259, 1269, 1269, 1259, 1270, - 1259, 1260, 1270, 1270, 1260, 1271, - 1260, 1261, 1271, 1271, 1261, 1272, - 1261, 1262, 1272, 1272, 1262, 1273, - 1262, 1263, 1273, 1273, 1263, 1274, - 1263, 1264, 1274, 1274, 1264, 1275, - 1265, 1266, 1276, 1276, 1266, 1277, - 1266, 1267, 1277, 1277, 1267, 1278, - 1267, 1268, 1278, 1278, 1268, 1279, - 1268, 1269, 1279, 1279, 1269, 1280, - 1269, 1270, 1280, 1280, 1270, 1281, - 1270, 1271, 1281, 1281, 1271, 1282, - 1271, 1272, 1282, 1282, 1272, 1283, - 1272, 1273, 1283, 1283, 1273, 1284, - 1273, 1274, 1284, 1284, 1274, 1285, - 1274, 1275, 1285, 1285, 1275, 1286, - 1276, 1277, 1287, 1287, 1277, 1288, - 1277, 1278, 1288, 1288, 1278, 1289, - 1278, 1279, 1289, 1289, 1279, 1290, - 1279, 1280, 1290, 1290, 1280, 1291, - 1280, 1281, 1291, 1291, 1281, 1292, - 1281, 1282, 1292, 1292, 1282, 1293, - 1282, 1283, 1293, 1293, 1283, 1294, - 1283, 1284, 1294, 1294, 1284, 1295, - 1284, 1285, 1295, 1295, 1285, 1296, - 1285, 1286, 1296, 1296, 1286, 1297, - 1287, 1288, 1298, 1298, 1288, 1299, - 1288, 1289, 1299, 1299, 1289, 1300, - 1289, 1290, 1300, 1300, 1290, 1301, - 1290, 1291, 1301, 1301, 1291, 1302, - 1291, 1292, 1302, 1302, 1292, 1303, - 1292, 1293, 1303, 1303, 1293, 1304, - 1293, 1294, 1304, 1304, 1294, 1305, - 1294, 1295, 1305, 1305, 1295, 1306, - 1295, 1296, 1306, 1306, 1296, 1307, - 1296, 1297, 1307, 1307, 1297, 1308, - 1298, 1299, 1309, 1309, 1299, 1310, - 1299, 1300, 1310, 1310, 1300, 1311, - 1300, 1301, 1311, 1311, 1301, 1312, - 1301, 1302, 1312, 1312, 1302, 1313, - 1302, 1303, 1313, 1313, 1303, 1314, - 1303, 1304, 1314, 1314, 1304, 1315, - 1304, 1305, 1315, 1315, 1305, 1316, - 1305, 1306, 1316, 1316, 1306, 1317, - 1306, 1307, 1317, 1317, 1307, 1318, - 1307, 1308, 1318, 1318, 1308, 1319, - 1309, 1310, 1320, 1320, 1310, 1321, - 1310, 1311, 1321, 1321, 1311, 1322, - 1311, 1312, 1322, 1322, 1312, 1323, - 1312, 1313, 1323, 1323, 1313, 1324, - 1313, 1314, 1324, 1324, 1314, 1325, - 1314, 1315, 1325, 1325, 1315, 1326, - 1315, 1316, 1326, 1326, 1316, 1327, - 1316, 1317, 1327, 1327, 1317, 1328, - 1317, 1318, 1328, 1328, 1318, 1329, - 1318, 1319, 1329, 1329, 1319, 1330, - 1331, 1332, 1342, 1342, 1332, 1343, - 1332, 1333, 1343, 1343, 1333, 1344, - 1333, 1334, 1344, 1344, 1334, 1345, - 1334, 1335, 1345, 1345, 1335, 1346, - 1335, 1336, 1346, 1346, 1336, 1347, - 1336, 1337, 1347, 1347, 1337, 1348, - 1337, 1338, 1348, 1348, 1338, 1349, - 1338, 1339, 1349, 1349, 1339, 1350, - 1339, 1340, 1350, 1350, 1340, 1351, - 1340, 1341, 1351, 1351, 1341, 1352, - 1342, 1343, 1353, 1353, 1343, 1354, - 1343, 1344, 1354, 1354, 1344, 1355, - 1344, 1345, 1355, 1355, 1345, 1356, - 1345, 1346, 1356, 1356, 1346, 1357, - 1346, 1347, 1357, 1357, 1347, 1358, - 1347, 1348, 1358, 1358, 1348, 1359, - 1348, 1349, 1359, 1359, 1349, 1360, - 1349, 1350, 1360, 1360, 1350, 1361, - 1350, 1351, 1361, 1361, 1351, 1362, - 1351, 1352, 1362, 1362, 1352, 1363, - 1353, 1354, 1364, 1364, 1354, 1365, - 1354, 1355, 1365, 1365, 1355, 1366, - 1355, 1356, 1366, 1366, 1356, 1367, - 1356, 1357, 1367, 1367, 1357, 1368, - 1357, 1358, 1368, 1368, 1358, 1369, - 1358, 1359, 1369, 1369, 1359, 1370, - 1359, 1360, 1370, 1370, 1360, 1371, - 1360, 1361, 1371, 1371, 1361, 1372, - 1361, 1362, 1372, 1372, 1362, 1373, - 1362, 1363, 1373, 1373, 1363, 1374, - 1364, 1365, 1375, 1375, 1365, 1376, - 1365, 1366, 1376, 1376, 1366, 1377, - 1366, 1367, 1377, 1377, 1367, 1378, - 1367, 1368, 1378, 1378, 1368, 1379, - 1368, 1369, 1379, 1379, 1369, 1380, - 1369, 1370, 1380, 1380, 1370, 1381, - 1370, 1371, 1381, 1381, 1371, 1382, - 1371, 1372, 1382, 1382, 1372, 1383, - 1372, 1373, 1383, 1383, 1373, 1384, - 1373, 1374, 1384, 1384, 1374, 1385, - 1375, 1376, 1386, 1386, 1376, 1387, - 1376, 1377, 1387, 1387, 1377, 1388, - 1377, 1378, 1388, 1388, 1378, 1389, - 1378, 1379, 1389, 1389, 1379, 1390, - 1379, 1380, 1390, 1390, 1380, 1391, - 1380, 1381, 1391, 1391, 1381, 1392, - 1381, 1382, 1392, 1392, 1382, 1393, - 1382, 1383, 1393, 1393, 1383, 1394, - 1383, 1384, 1394, 1394, 1384, 1395, - 1384, 1385, 1395, 1395, 1385, 1396, - 1386, 1387, 1397, 1397, 1387, 1398, - 1387, 1388, 1398, 1398, 1388, 1399, - 1388, 1389, 1399, 1399, 1389, 1400, - 1389, 1390, 1400, 1400, 1390, 1401, - 1390, 1391, 1401, 1401, 1391, 1402, - 1391, 1392, 1402, 1402, 1392, 1403, - 1392, 1393, 1403, 1403, 1393, 1404, - 1393, 1394, 1404, 1404, 1394, 1405, - 1394, 1395, 1405, 1405, 1395, 1406, - 1395, 1396, 1406, 1406, 1396, 1407, - 1397, 1398, 1408, 1408, 1398, 1409, - 1398, 1399, 1409, 1409, 1399, 1410, - 1399, 1400, 1410, 1410, 1400, 1411, - 1400, 1401, 1411, 1411, 1401, 1412, - 1401, 1402, 1412, 1412, 1402, 1413, - 1402, 1403, 1413, 1413, 1403, 1414, - 1403, 1404, 1414, 1414, 1404, 1415, - 1404, 1405, 1415, 1415, 1405, 1416, - 1405, 1406, 1416, 1416, 1406, 1417, - 1406, 1407, 1417, 1417, 1407, 1418, - 1408, 1409, 1419, 1419, 1409, 1420, - 1409, 1410, 1420, 1420, 1410, 1421, - 1410, 1411, 1421, 1421, 1411, 1422, - 1411, 1412, 1422, 1422, 1412, 1423, - 1412, 1413, 1423, 1423, 1413, 1424, - 1413, 1414, 1424, 1424, 1414, 1425, - 1414, 1415, 1425, 1425, 1415, 1426, - 1415, 1416, 1426, 1426, 1416, 1427, - 1416, 1417, 1427, 1427, 1417, 1428, - 1417, 1418, 1428, 1428, 1418, 1429, - 1419, 1420, 1430, 1430, 1420, 1431, - 1420, 1421, 1431, 1431, 1421, 1432, - 1421, 1422, 1432, 1432, 1422, 1433, - 1422, 1423, 1433, 1433, 1423, 1434, - 1423, 1424, 1434, 1434, 1424, 1435, - 1424, 1425, 1435, 1435, 1425, 1436, - 1425, 1426, 1436, 1436, 1426, 1437, - 1426, 1427, 1437, 1437, 1427, 1438, - 1427, 1428, 1438, 1438, 1428, 1439, - 1428, 1429, 1439, 1439, 1429, 1440, - 1430, 1431, 1441, 1441, 1431, 1442, - 1431, 1432, 1442, 1442, 1432, 1443, - 1432, 1433, 1443, 1443, 1433, 1444, - 1433, 1434, 1444, 1444, 1434, 1445, - 1434, 1435, 1445, 1445, 1435, 1446, - 1435, 1436, 1446, 1446, 1436, 1447, - 1436, 1437, 1447, 1447, 1437, 1448, - 1437, 1438, 1448, 1448, 1438, 1449, - 1438, 1439, 1449, 1449, 1439, 1450, - 1439, 1440, 1450, 1450, 1440, 1451, - 1452, 1453, 1463, 1463, 1453, 1464, - 1453, 1454, 1464, 1464, 1454, 1465, - 1454, 1455, 1465, 1465, 1455, 1466, - 1455, 1456, 1466, 1466, 1456, 1467, - 1456, 1457, 1467, 1467, 1457, 1468, - 1457, 1458, 1468, 1468, 1458, 1469, - 1458, 1459, 1469, 1469, 1459, 1470, - 1459, 1460, 1470, 1470, 1460, 1471, - 1460, 1461, 1471, 1471, 1461, 1472, - 1461, 1462, 1472, 1472, 1462, 1473, - 1463, 1464, 1474, 1474, 1464, 1475, - 1464, 1465, 1475, 1475, 1465, 1476, - 1465, 1466, 1476, 1476, 1466, 1477, - 1466, 1467, 1477, 1477, 1467, 1478, - 1467, 1468, 1478, 1478, 1468, 1479, - 1468, 1469, 1479, 1479, 1469, 1480, - 1469, 1470, 1480, 1480, 1470, 1481, - 1470, 1471, 1481, 1481, 1471, 1482, - 1471, 1472, 1482, 1482, 1472, 1483, - 1472, 1473, 1483, 1483, 1473, 1484, - 1474, 1475, 1485, 1485, 1475, 1486, - 1475, 1476, 1486, 1486, 1476, 1487, - 1476, 1477, 1487, 1487, 1477, 1488, - 1477, 1478, 1488, 1488, 1478, 1489, - 1478, 1479, 1489, 1489, 1479, 1490, - 1479, 1480, 1490, 1490, 1480, 1491, - 1480, 1481, 1491, 1491, 1481, 1492, - 1481, 1482, 1492, 1492, 1482, 1493, - 1482, 1483, 1493, 1493, 1483, 1494, - 1483, 1484, 1494, 1494, 1484, 1495, - 1485, 1486, 1496, 1496, 1486, 1497, - 1486, 1487, 1497, 1497, 1487, 1498, - 1487, 1488, 1498, 1498, 1488, 1499, - 1488, 1489, 1499, 1499, 1489, 1500, - 1489, 1490, 1500, 1500, 1490, 1501, - 1490, 1491, 1501, 1501, 1491, 1502, - 1491, 1492, 1502, 1502, 1492, 1503, - 1492, 1493, 1503, 1503, 1493, 1504, - 1493, 1494, 1504, 1504, 1494, 1505, - 1494, 1495, 1505, 1505, 1495, 1506, - 1496, 1497, 1507, 1507, 1497, 1508, - 1497, 1498, 1508, 1508, 1498, 1509, - 1498, 1499, 1509, 1509, 1499, 1510, - 1499, 1500, 1510, 1510, 1500, 1511, - 1500, 1501, 1511, 1511, 1501, 1512, - 1501, 1502, 1512, 1512, 1502, 1513, - 1502, 1503, 1513, 1513, 1503, 1514, - 1503, 1504, 1514, 1514, 1504, 1515, - 1504, 1505, 1515, 1515, 1505, 1516, - 1505, 1506, 1516, 1516, 1506, 1517, - 1507, 1508, 1518, 1518, 1508, 1519, - 1508, 1509, 1519, 1519, 1509, 1520, - 1509, 1510, 1520, 1520, 1510, 1521, - 1510, 1511, 1521, 1521, 1511, 1522, - 1511, 1512, 1522, 1522, 1512, 1523, - 1512, 1513, 1523, 1523, 1513, 1524, - 1513, 1514, 1524, 1524, 1514, 1525, - 1514, 1515, 1525, 1525, 1515, 1526, - 1515, 1516, 1526, 1526, 1516, 1527, - 1516, 1517, 1527, 1527, 1517, 1528, - 1518, 1519, 1529, 1529, 1519, 1530, - 1519, 1520, 1530, 1530, 1520, 1531, - 1520, 1521, 1531, 1531, 1521, 1532, - 1521, 1522, 1532, 1532, 1522, 1533, - 1522, 1523, 1533, 1533, 1523, 1534, - 1523, 1524, 1534, 1534, 1524, 1535, - 1524, 1525, 1535, 1535, 1525, 1536, - 1525, 1526, 1536, 1536, 1526, 1537, - 1526, 1527, 1537, 1537, 1527, 1538, - 1527, 1528, 1538, 1538, 1528, 1539, - 1529, 1530, 1540, 1540, 1530, 1541, - 1530, 1531, 1541, 1541, 1531, 1542, - 1531, 1532, 1542, 1542, 1532, 1543, - 1532, 1533, 1543, 1543, 1533, 1544, - 1533, 1534, 1544, 1544, 1534, 1545, - 1534, 1535, 1545, 1545, 1535, 1546, - 1535, 1536, 1546, 1546, 1536, 1547, - 1536, 1537, 1547, 1547, 1537, 1548, - 1537, 1538, 1548, 1548, 1538, 1549, - 1538, 1539, 1549, 1549, 1539, 1550, - 1540, 1541, 1551, 1551, 1541, 1552, - 1541, 1542, 1552, 1552, 1542, 1553, - 1542, 1543, 1553, 1553, 1543, 1554, - 1543, 1544, 1554, 1554, 1544, 1555, - 1544, 1545, 1555, 1555, 1545, 1556, - 1545, 1546, 1556, 1556, 1546, 1557, - 1546, 1547, 1557, 1557, 1547, 1558, - 1547, 1548, 1558, 1558, 1548, 1559, - 1548, 1549, 1559, 1559, 1549, 1560, - 1549, 1550, 1560, 1560, 1550, 1561, - 1551, 1552, 1562, 1562, 1552, 1563, - 1552, 1553, 1563, 1563, 1553, 1564, - 1553, 1554, 1564, 1564, 1554, 1565, - 1554, 1555, 1565, 1565, 1555, 1566, - 1555, 1556, 1566, 1566, 1556, 1567, - 1556, 1557, 1567, 1567, 1557, 1568, - 1557, 1558, 1568, 1568, 1558, 1569, - 1558, 1559, 1569, 1569, 1559, 1570, - 1559, 1560, 1570, 1570, 1560, 1571, - 1560, 1561, 1571, 1571, 1561, 1572, - 1573, 1574, 1584, 1584, 1574, 1585, - 1574, 1575, 1585, 1585, 1575, 1586, - 1575, 1576, 1586, 1586, 1576, 1587, - 1576, 1577, 1587, 1587, 1577, 1588, - 1577, 1578, 1588, 1588, 1578, 1589, - 1578, 1579, 1589, 1589, 1579, 1590, - 1579, 1580, 1590, 1590, 1580, 1591, - 1580, 1581, 1591, 1591, 1581, 1592, - 1581, 1582, 1592, 1592, 1582, 1593, - 1582, 1583, 1593, 1593, 1583, 1594, - 1584, 1585, 1595, 1595, 1585, 1596, - 1585, 1586, 1596, 1596, 1586, 1597, - 1586, 1587, 1597, 1597, 1587, 1598, - 1587, 1588, 1598, 1598, 1588, 1599, - 1588, 1589, 1599, 1599, 1589, 1600, - 1589, 1590, 1600, 1600, 1590, 1601, - 1590, 1591, 1601, 1601, 1591, 1602, - 1591, 1592, 1602, 1602, 1592, 1603, - 1592, 1593, 1603, 1603, 1593, 1604, - 1593, 1594, 1604, 1604, 1594, 1605, - 1595, 1596, 1606, 1606, 1596, 1607, - 1596, 1597, 1607, 1607, 1597, 1608, - 1597, 1598, 1608, 1608, 1598, 1609, - 1598, 1599, 1609, 1609, 1599, 1610, - 1599, 1600, 1610, 1610, 1600, 1611, - 1600, 1601, 1611, 1611, 1601, 1612, - 1601, 1602, 1612, 1612, 1602, 1613, - 1602, 1603, 1613, 1613, 1603, 1614, - 1603, 1604, 1614, 1614, 1604, 1615, - 1604, 1605, 1615, 1615, 1605, 1616, - 1606, 1607, 1617, 1617, 1607, 1618, - 1607, 1608, 1618, 1618, 1608, 1619, - 1608, 1609, 1619, 1619, 1609, 1620, - 1609, 1610, 1620, 1620, 1610, 1621, - 1610, 1611, 1621, 1621, 1611, 1622, - 1611, 1612, 1622, 1622, 1612, 1623, - 1612, 1613, 1623, 1623, 1613, 1624, - 1613, 1614, 1624, 1624, 1614, 1625, - 1614, 1615, 1625, 1625, 1615, 1626, - 1615, 1616, 1626, 1626, 1616, 1627, - 1617, 1618, 1628, 1628, 1618, 1629, - 1618, 1619, 1629, 1629, 1619, 1630, - 1619, 1620, 1630, 1630, 1620, 1631, - 1620, 1621, 1631, 1631, 1621, 1632, - 1621, 1622, 1632, 1632, 1622, 1633, - 1622, 1623, 1633, 1633, 1623, 1634, - 1623, 1624, 1634, 1634, 1624, 1635, - 1624, 1625, 1635, 1635, 1625, 1636, - 1625, 1626, 1636, 1636, 1626, 1637, - 1626, 1627, 1637, 1637, 1627, 1638, - 1628, 1629, 1639, 1639, 1629, 1640, - 1629, 1630, 1640, 1640, 1630, 1641, - 1630, 1631, 1641, 1641, 1631, 1642, - 1631, 1632, 1642, 1642, 1632, 1643, - 1632, 1633, 1643, 1643, 1633, 1644, - 1633, 1634, 1644, 1644, 1634, 1645, - 1634, 1635, 1645, 1645, 1635, 1646, - 1635, 1636, 1646, 1646, 1636, 1647, - 1636, 1637, 1647, 1647, 1637, 1648, - 1637, 1638, 1648, 1648, 1638, 1649, - 1639, 1640, 1650, 1650, 1640, 1651, - 1640, 1641, 1651, 1651, 1641, 1652, - 1641, 1642, 1652, 1652, 1642, 1653, - 1642, 1643, 1653, 1653, 1643, 1654, - 1643, 1644, 1654, 1654, 1644, 1655, - 1644, 1645, 1655, 1655, 1645, 1656, - 1645, 1646, 1656, 1656, 1646, 1657, - 1646, 1647, 1657, 1657, 1647, 1658, - 1647, 1648, 1658, 1658, 1648, 1659, - 1648, 1649, 1659, 1659, 1649, 1660, - 1650, 1651, 1661, 1661, 1651, 1662, - 1651, 1652, 1662, 1662, 1652, 1663, - 1652, 1653, 1663, 1663, 1653, 1664, - 1653, 1654, 1664, 1664, 1654, 1665, - 1654, 1655, 1665, 1665, 1655, 1666, - 1655, 1656, 1666, 1666, 1656, 1667, - 1656, 1657, 1667, 1667, 1657, 1668, - 1657, 1658, 1668, 1668, 1658, 1669, - 1658, 1659, 1669, 1669, 1659, 1670, - 1659, 1660, 1670, 1670, 1660, 1671, - 1661, 1662, 1672, 1672, 1662, 1673, - 1662, 1663, 1673, 1673, 1663, 1674, - 1663, 1664, 1674, 1674, 1664, 1675, - 1664, 1665, 1675, 1675, 1665, 1676, - 1665, 1666, 1676, 1676, 1666, 1677, - 1666, 1667, 1677, 1677, 1667, 1678, - 1667, 1668, 1678, 1678, 1668, 1679, - 1668, 1669, 1679, 1679, 1669, 1680, - 1669, 1670, 1680, 1680, 1670, 1681, - 1670, 1671, 1681, 1681, 1671, 1682, - 1672, 1673, 1683, 1683, 1673, 1684, - 1673, 1674, 1684, 1684, 1674, 1685, - 1674, 1675, 1685, 1685, 1675, 1686, - 1675, 1676, 1686, 1686, 1676, 1687, - 1676, 1677, 1687, 1687, 1677, 1688, - 1677, 1678, 1688, 1688, 1678, 1689, - 1678, 1679, 1689, 1689, 1679, 1690, - 1679, 1680, 1690, 1690, 1680, 1691, - 1680, 1681, 1691, 1691, 1681, 1692, - 1681, 1682, 1692, 1692, 1682, 1693, - 1694, 1695, 1705, 1705, 1695, 1706, - 1695, 1696, 1706, 1706, 1696, 1707, - 1696, 1697, 1707, 1707, 1697, 1708, - 1697, 1698, 1708, 1708, 1698, 1709, - 1698, 1699, 1709, 1709, 1699, 1710, - 1699, 1700, 1710, 1710, 1700, 1711, - 1700, 1701, 1711, 1711, 1701, 1712, - 1701, 1702, 1712, 1712, 1702, 1713, - 1702, 1703, 1713, 1713, 1703, 1714, - 1703, 1704, 1714, 1714, 1704, 1715, - 1705, 1706, 1716, 1716, 1706, 1717, - 1706, 1707, 1717, 1717, 1707, 1718, - 1707, 1708, 1718, 1718, 1708, 1719, - 1708, 1709, 1719, 1719, 1709, 1720, - 1709, 1710, 1720, 1720, 1710, 1721, - 1710, 1711, 1721, 1721, 1711, 1722, - 1711, 1712, 1722, 1722, 1712, 1723, - 1712, 1713, 1723, 1723, 1713, 1724, - 1713, 1714, 1724, 1724, 1714, 1725, - 1714, 1715, 1725, 1725, 1715, 1726, - 1716, 1717, 1727, 1727, 1717, 1728, - 1717, 1718, 1728, 1728, 1718, 1729, - 1718, 1719, 1729, 1729, 1719, 1730, - 1719, 1720, 1730, 1730, 1720, 1731, - 1720, 1721, 1731, 1731, 1721, 1732, - 1721, 1722, 1732, 1732, 1722, 1733, - 1722, 1723, 1733, 1733, 1723, 1734, - 1723, 1724, 1734, 1734, 1724, 1735, - 1724, 1725, 1735, 1735, 1725, 1736, - 1725, 1726, 1736, 1736, 1726, 1737, - 1727, 1728, 1738, 1738, 1728, 1739, - 1728, 1729, 1739, 1739, 1729, 1740, - 1729, 1730, 1740, 1740, 1730, 1741, - 1730, 1731, 1741, 1741, 1731, 1742, - 1731, 1732, 1742, 1742, 1732, 1743, - 1732, 1733, 1743, 1743, 1733, 1744, - 1733, 1734, 1744, 1744, 1734, 1745, - 1734, 1735, 1745, 1745, 1735, 1746, - 1735, 1736, 1746, 1746, 1736, 1747, - 1736, 1737, 1747, 1747, 1737, 1748, - 1738, 1739, 1749, 1749, 1739, 1750, - 1739, 1740, 1750, 1750, 1740, 1751, - 1740, 1741, 1751, 1751, 1741, 1752, - 1741, 1742, 1752, 1752, 1742, 1753, - 1742, 1743, 1753, 1753, 1743, 1754, - 1743, 1744, 1754, 1754, 1744, 1755, - 1744, 1745, 1755, 1755, 1745, 1756, - 1745, 1746, 1756, 1756, 1746, 1757, - 1746, 1747, 1757, 1757, 1747, 1758, - 1747, 1748, 1758, 1758, 1748, 1759, - 1749, 1750, 1760, 1760, 1750, 1761, - 1750, 1751, 1761, 1761, 1751, 1762, - 1751, 1752, 1762, 1762, 1752, 1763, - 1752, 1753, 1763, 1763, 1753, 1764, - 1753, 1754, 1764, 1764, 1754, 1765, - 1754, 1755, 1765, 1765, 1755, 1766, - 1755, 1756, 1766, 1766, 1756, 1767, - 1756, 1757, 1767, 1767, 1757, 1768, - 1757, 1758, 1768, 1768, 1758, 1769, - 1758, 1759, 1769, 1769, 1759, 1770, - 1760, 1761, 1771, 1771, 1761, 1772, - 1761, 1762, 1772, 1772, 1762, 1773, - 1762, 1763, 1773, 1773, 1763, 1774, - 1763, 1764, 1774, 1774, 1764, 1775, - 1764, 1765, 1775, 1775, 1765, 1776, - 1765, 1766, 1776, 1776, 1766, 1777, - 1766, 1767, 1777, 1777, 1767, 1778, - 1767, 1768, 1778, 1778, 1768, 1779, - 1768, 1769, 1779, 1779, 1769, 1780, - 1769, 1770, 1780, 1780, 1770, 1781, - 1771, 1772, 1782, 1782, 1772, 1783, - 1772, 1773, 1783, 1783, 1773, 1784, - 1773, 1774, 1784, 1784, 1774, 1785, - 1774, 1775, 1785, 1785, 1775, 1786, - 1775, 1776, 1786, 1786, 1776, 1787, - 1776, 1777, 1787, 1787, 1777, 1788, - 1777, 1778, 1788, 1788, 1778, 1789, - 1778, 1779, 1789, 1789, 1779, 1790, - 1779, 1780, 1790, 1790, 1780, 1791, - 1780, 1781, 1791, 1791, 1781, 1792, - 1782, 1783, 1793, 1793, 1783, 1794, - 1783, 1784, 1794, 1794, 1784, 1795, - 1784, 1785, 1795, 1795, 1785, 1796, - 1785, 1786, 1796, 1796, 1786, 1797, - 1786, 1787, 1797, 1797, 1787, 1798, - 1787, 1788, 1798, 1798, 1788, 1799, - 1788, 1789, 1799, 1799, 1789, 1800, - 1789, 1790, 1800, 1800, 1790, 1801, - 1790, 1791, 1801, 1801, 1791, 1802, - 1791, 1792, 1802, 1802, 1792, 1803, - 1793, 1794, 1804, 1804, 1794, 1805, - 1794, 1795, 1805, 1805, 1795, 1806, - 1795, 1796, 1806, 1806, 1796, 1807, - 1796, 1797, 1807, 1807, 1797, 1808, - 1797, 1798, 1808, 1808, 1798, 1809, - 1798, 1799, 1809, 1809, 1799, 1810, - 1799, 1800, 1810, 1810, 1800, 1811, - 1800, 1801, 1811, 1811, 1801, 1812, - 1801, 1802, 1812, 1812, 1802, 1813, - 1802, 1803, 1813, 1813, 1803, 1814, - 1815, 1816, 1826, 1826, 1816, 1827, - 1816, 1817, 1827, 1827, 1817, 1828, - 1817, 1818, 1828, 1828, 1818, 1829, - 1818, 1819, 1829, 1829, 1819, 1830, - 1819, 1820, 1830, 1830, 1820, 1831, - 1820, 1821, 1831, 1831, 1821, 1832, - 1821, 1822, 1832, 1832, 1822, 1833, - 1822, 1823, 1833, 1833, 1823, 1834, - 1823, 1824, 1834, 1834, 1824, 1835, - 1824, 1825, 1835, 1835, 1825, 1836, - 1826, 1827, 1837, 1837, 1827, 1838, - 1827, 1828, 1838, 1838, 1828, 1839, - 1828, 1829, 1839, 1839, 1829, 1840, - 1829, 1830, 1840, 1840, 1830, 1841, - 1830, 1831, 1841, 1841, 1831, 1842, - 1831, 1832, 1842, 1842, 1832, 1843, - 1832, 1833, 1843, 1843, 1833, 1844, - 1833, 1834, 1844, 1844, 1834, 1845, - 1834, 1835, 1845, 1845, 1835, 1846, - 1835, 1836, 1846, 1846, 1836, 1847, - 1837, 1838, 1848, 1848, 1838, 1849, - 1838, 1839, 1849, 1849, 1839, 1850, - 1839, 1840, 1850, 1850, 1840, 1851, - 1840, 1841, 1851, 1851, 1841, 1852, - 1841, 1842, 1852, 1852, 1842, 1853, - 1842, 1843, 1853, 1853, 1843, 1854, - 1843, 1844, 1854, 1854, 1844, 1855, - 1844, 1845, 1855, 1855, 1845, 1856, - 1845, 1846, 1856, 1856, 1846, 1857, - 1846, 1847, 1857, 1857, 1847, 1858, - 1848, 1849, 1859, 1859, 1849, 1860, - 1849, 1850, 1860, 1860, 1850, 1861, - 1850, 1851, 1861, 1861, 1851, 1862, - 1851, 1852, 1862, 1862, 1852, 1863, - 1852, 1853, 1863, 1863, 1853, 1864, - 1853, 1854, 1864, 1864, 1854, 1865, - 1854, 1855, 1865, 1865, 1855, 1866, - 1855, 1856, 1866, 1866, 1856, 1867, - 1856, 1857, 1867, 1867, 1857, 1868, - 1857, 1858, 1868, 1868, 1858, 1869, - 1859, 1860, 1870, 1870, 1860, 1871, - 1860, 1861, 1871, 1871, 1861, 1872, - 1861, 1862, 1872, 1872, 1862, 1873, - 1862, 1863, 1873, 1873, 1863, 1874, - 1863, 1864, 1874, 1874, 1864, 1875, - 1864, 1865, 1875, 1875, 1865, 1876, - 1865, 1866, 1876, 1876, 1866, 1877, - 1866, 1867, 1877, 1877, 1867, 1878, - 1867, 1868, 1878, 1878, 1868, 1879, - 1868, 1869, 1879, 1879, 1869, 1880, - 1870, 1871, 1881, 1881, 1871, 1882, - 1871, 1872, 1882, 1882, 1872, 1883, - 1872, 1873, 1883, 1883, 1873, 1884, - 1873, 1874, 1884, 1884, 1874, 1885, - 1874, 1875, 1885, 1885, 1875, 1886, - 1875, 1876, 1886, 1886, 1876, 1887, - 1876, 1877, 1887, 1887, 1877, 1888, - 1877, 1878, 1888, 1888, 1878, 1889, - 1878, 1879, 1889, 1889, 1879, 1890, - 1879, 1880, 1890, 1890, 1880, 1891, - 1881, 1882, 1892, 1892, 1882, 1893, - 1882, 1883, 1893, 1893, 1883, 1894, - 1883, 1884, 1894, 1894, 1884, 1895, - 1884, 1885, 1895, 1895, 1885, 1896, - 1885, 1886, 1896, 1896, 1886, 1897, - 1886, 1887, 1897, 1897, 1887, 1898, - 1887, 1888, 1898, 1898, 1888, 1899, - 1888, 1889, 1899, 1899, 1889, 1900, - 1889, 1890, 1900, 1900, 1890, 1901, - 1890, 1891, 1901, 1901, 1891, 1902, - 1892, 1893, 1903, 1903, 1893, 1904, - 1893, 1894, 1904, 1904, 1894, 1905, - 1894, 1895, 1905, 1905, 1895, 1906, - 1895, 1896, 1906, 1906, 1896, 1907, - 1896, 1897, 1907, 1907, 1897, 1908, - 1897, 1898, 1908, 1908, 1898, 1909, - 1898, 1899, 1909, 1909, 1899, 1910, - 1899, 1900, 1910, 1910, 1900, 1911, - 1900, 1901, 1911, 1911, 1901, 1912, - 1901, 1902, 1912, 1912, 1902, 1913, - 1903, 1904, 1914, 1914, 1904, 1915, - 1904, 1905, 1915, 1915, 1905, 1916, - 1905, 1906, 1916, 1916, 1906, 1917, - 1906, 1907, 1917, 1917, 1907, 1918, - 1907, 1908, 1918, 1918, 1908, 1919, - 1908, 1909, 1919, 1919, 1909, 1920, - 1909, 1910, 1920, 1920, 1910, 1921, - 1910, 1911, 1921, 1921, 1911, 1922, - 1911, 1912, 1922, 1922, 1912, 1923, - 1912, 1913, 1923, 1923, 1913, 1924, - 1914, 1915, 1925, 1925, 1915, 1926, - 1915, 1916, 1926, 1926, 1916, 1927, - 1916, 1917, 1927, 1927, 1917, 1928, - 1917, 1918, 1928, 1928, 1918, 1929, - 1918, 1919, 1929, 1929, 1919, 1930, - 1919, 1920, 1930, 1930, 1920, 1931, - 1920, 1921, 1931, 1931, 1921, 1932, - 1921, 1922, 1932, 1932, 1922, 1933, - 1922, 1923, 1933, 1933, 1923, 1934, - 1923, 1924, 1934, 1934, 1924, 1935, - 1936, 1937, 1947, 1947, 1937, 1948, - 1937, 1938, 1948, 1948, 1938, 1949, - 1938, 1939, 1949, 1949, 1939, 1950, - 1939, 1940, 1950, 1950, 1940, 1951, - 1940, 1941, 1951, 1951, 1941, 1952, - 1941, 1942, 1952, 1952, 1942, 1953, - 1942, 1943, 1953, 1953, 1943, 1954, - 1943, 1944, 1954, 1954, 1944, 1955, - 1944, 1945, 1955, 1955, 1945, 1956, - 1945, 1946, 1956, 1956, 1946, 1957, - 1947, 1948, 1958, 1958, 1948, 1959, - 1948, 1949, 1959, 1959, 1949, 1960, - 1949, 1950, 1960, 1960, 1950, 1961, - 1950, 1951, 1961, 1961, 1951, 1962, - 1951, 1952, 1962, 1962, 1952, 1963, - 1952, 1953, 1963, 1963, 1953, 1964, - 1953, 1954, 1964, 1964, 1954, 1965, - 1954, 1955, 1965, 1965, 1955, 1966, - 1955, 1956, 1966, 1966, 1956, 1967, - 1956, 1957, 1967, 1967, 1957, 1968, - 1958, 1959, 1969, 1969, 1959, 1970, - 1959, 1960, 1970, 1970, 1960, 1971, - 1960, 1961, 1971, 1971, 1961, 1972, - 1961, 1962, 1972, 1972, 1962, 1973, - 1962, 1963, 1973, 1973, 1963, 1974, - 1963, 1964, 1974, 1974, 1964, 1975, - 1964, 1965, 1975, 1975, 1965, 1976, - 1965, 1966, 1976, 1976, 1966, 1977, - 1966, 1967, 1977, 1977, 1967, 1978, - 1967, 1968, 1978, 1978, 1968, 1979, - 1969, 1970, 1980, 1980, 1970, 1981, - 1970, 1971, 1981, 1981, 1971, 1982, - 1971, 1972, 1982, 1982, 1972, 1983, - 1972, 1973, 1983, 1983, 1973, 1984, - 1973, 1974, 1984, 1984, 1974, 1985, - 1974, 1975, 1985, 1985, 1975, 1986, - 1975, 1976, 1986, 1986, 1976, 1987, - 1976, 1977, 1987, 1987, 1977, 1988, - 1977, 1978, 1988, 1988, 1978, 1989, - 1978, 1979, 1989, 1989, 1979, 1990, - 1980, 1981, 1991, 1991, 1981, 1992, - 1981, 1982, 1992, 1992, 1982, 1993, - 1982, 1983, 1993, 1993, 1983, 1994, - 1983, 1984, 1994, 1994, 1984, 1995, - 1984, 1985, 1995, 1995, 1985, 1996, - 1985, 1986, 1996, 1996, 1986, 1997, - 1986, 1987, 1997, 1997, 1987, 1998, - 1987, 1988, 1998, 1998, 1988, 1999, - 1988, 1989, 1999, 1999, 1989, 2000, - 1989, 1990, 2000, 2000, 1990, 2001, - 1991, 1992, 2002, 2002, 1992, 2003, - 1992, 1993, 2003, 2003, 1993, 2004, - 1993, 1994, 2004, 2004, 1994, 2005, - 1994, 1995, 2005, 2005, 1995, 2006, - 1995, 1996, 2006, 2006, 1996, 2007, - 1996, 1997, 2007, 2007, 1997, 2008, - 1997, 1998, 2008, 2008, 1998, 2009, - 1998, 1999, 2009, 2009, 1999, 2010, - 1999, 2000, 2010, 2010, 2000, 2011, - 2000, 2001, 2011, 2011, 2001, 2012, - 2002, 2003, 2013, 2013, 2003, 2014, - 2003, 2004, 2014, 2014, 2004, 2015, - 2004, 2005, 2015, 2015, 2005, 2016, - 2005, 2006, 2016, 2016, 2006, 2017, - 2006, 2007, 2017, 2017, 2007, 2018, - 2007, 2008, 2018, 2018, 2008, 2019, - 2008, 2009, 2019, 2019, 2009, 2020, - 2009, 2010, 2020, 2020, 2010, 2021, - 2010, 2011, 2021, 2021, 2011, 2022, - 2011, 2012, 2022, 2022, 2012, 2023, - 2013, 2014, 2024, 2024, 2014, 2025, - 2014, 2015, 2025, 2025, 2015, 2026, - 2015, 2016, 2026, 2026, 2016, 2027, - 2016, 2017, 2027, 2027, 2017, 2028, - 2017, 2018, 2028, 2028, 2018, 2029, - 2018, 2019, 2029, 2029, 2019, 2030, - 2019, 2020, 2030, 2030, 2020, 2031, - 2020, 2021, 2031, 2031, 2021, 2032, - 2021, 2022, 2032, 2032, 2022, 2033, - 2022, 2023, 2033, 2033, 2023, 2034, - 2024, 2025, 2035, 2035, 2025, 2036, - 2025, 2026, 2036, 2036, 2026, 2037, - 2026, 2027, 2037, 2037, 2027, 2038, - 2027, 2028, 2038, 2038, 2028, 2039, - 2028, 2029, 2039, 2039, 2029, 2040, - 2029, 2030, 2040, 2040, 2030, 2041, - 2030, 2031, 2041, 2041, 2031, 2042, - 2031, 2032, 2042, 2042, 2032, 2043, - 2032, 2033, 2043, 2043, 2033, 2044, - 2033, 2034, 2044, 2044, 2034, 2045, - 2035, 2036, 2046, 2046, 2036, 2047, - 2036, 2037, 2047, 2047, 2037, 2048, - 2037, 2038, 2048, 2048, 2038, 2049, - 2038, 2039, 2049, 2049, 2039, 2050, - 2039, 2040, 2050, 2050, 2040, 2051, - 2040, 2041, 2051, 2051, 2041, 2052, - 2041, 2042, 2052, 2052, 2042, 2053, - 2042, 2043, 2053, 2053, 2043, 2054, - 2043, 2044, 2054, 2054, 2044, 2055, - 2044, 2045, 2055, 2055, 2045, 2056, - 2057, 2058, 2068, 2068, 2058, 2069, - 2058, 2059, 2069, 2069, 2059, 2070, - 2059, 2060, 2070, 2070, 2060, 2071, - 2060, 2061, 2071, 2071, 2061, 2072, - 2061, 2062, 2072, 2072, 2062, 2073, - 2062, 2063, 2073, 2073, 2063, 2074, - 2063, 2064, 2074, 2074, 2064, 2075, - 2064, 2065, 2075, 2075, 2065, 2076, - 2065, 2066, 2076, 2076, 2066, 2077, - 2066, 2067, 2077, 2077, 2067, 2078, - 2068, 2069, 2079, 2079, 2069, 2080, - 2069, 2070, 2080, 2080, 2070, 2081, - 2070, 2071, 2081, 2081, 2071, 2082, - 2071, 2072, 2082, 2082, 2072, 2083, - 2072, 2073, 2083, 2083, 2073, 2084, - 2073, 2074, 2084, 2084, 2074, 2085, - 2074, 2075, 2085, 2085, 2075, 2086, - 2075, 2076, 2086, 2086, 2076, 2087, - 2076, 2077, 2087, 2087, 2077, 2088, - 2077, 2078, 2088, 2088, 2078, 2089, - 2079, 2080, 2090, 2090, 2080, 2091, - 2080, 2081, 2091, 2091, 2081, 2092, - 2081, 2082, 2092, 2092, 2082, 2093, - 2082, 2083, 2093, 2093, 2083, 2094, - 2083, 2084, 2094, 2094, 2084, 2095, - 2084, 2085, 2095, 2095, 2085, 2096, - 2085, 2086, 2096, 2096, 2086, 2097, - 2086, 2087, 2097, 2097, 2087, 2098, - 2087, 2088, 2098, 2098, 2088, 2099, - 2088, 2089, 2099, 2099, 2089, 2100, - 2090, 2091, 2101, 2101, 2091, 2102, - 2091, 2092, 2102, 2102, 2092, 2103, - 2092, 2093, 2103, 2103, 2093, 2104, - 2093, 2094, 2104, 2104, 2094, 2105, - 2094, 2095, 2105, 2105, 2095, 2106, - 2095, 2096, 2106, 2106, 2096, 2107, - 2096, 2097, 2107, 2107, 2097, 2108, - 2097, 2098, 2108, 2108, 2098, 2109, - 2098, 2099, 2109, 2109, 2099, 2110, - 2099, 2100, 2110, 2110, 2100, 2111, - 2101, 2102, 2112, 2112, 2102, 2113, - 2102, 2103, 2113, 2113, 2103, 2114, - 2103, 2104, 2114, 2114, 2104, 2115, - 2104, 2105, 2115, 2115, 2105, 2116, - 2105, 2106, 2116, 2116, 2106, 2117, - 2106, 2107, 2117, 2117, 2107, 2118, - 2107, 2108, 2118, 2118, 2108, 2119, - 2108, 2109, 2119, 2119, 2109, 2120, - 2109, 2110, 2120, 2120, 2110, 2121, - 2110, 2111, 2121, 2121, 2111, 2122, - 2112, 2113, 2123, 2123, 2113, 2124, - 2113, 2114, 2124, 2124, 2114, 2125, - 2114, 2115, 2125, 2125, 2115, 2126, - 2115, 2116, 2126, 2126, 2116, 2127, - 2116, 2117, 2127, 2127, 2117, 2128, - 2117, 2118, 2128, 2128, 2118, 2129, - 2118, 2119, 2129, 2129, 2119, 2130, - 2119, 2120, 2130, 2130, 2120, 2131, - 2120, 2121, 2131, 2131, 2121, 2132, - 2121, 2122, 2132, 2132, 2122, 2133, - 2123, 2124, 2134, 2134, 2124, 2135, - 2124, 2125, 2135, 2135, 2125, 2136, - 2125, 2126, 2136, 2136, 2126, 2137, - 2126, 2127, 2137, 2137, 2127, 2138, - 2127, 2128, 2138, 2138, 2128, 2139, - 2128, 2129, 2139, 2139, 2129, 2140, - 2129, 2130, 2140, 2140, 2130, 2141, - 2130, 2131, 2141, 2141, 2131, 2142, - 2131, 2132, 2142, 2142, 2132, 2143, - 2132, 2133, 2143, 2143, 2133, 2144, - 2134, 2135, 2145, 2145, 2135, 2146, - 2135, 2136, 2146, 2146, 2136, 2147, - 2136, 2137, 2147, 2147, 2137, 2148, - 2137, 2138, 2148, 2148, 2138, 2149, - 2138, 2139, 2149, 2149, 2139, 2150, - 2139, 2140, 2150, 2150, 2140, 2151, - 2140, 2141, 2151, 2151, 2141, 2152, - 2141, 2142, 2152, 2152, 2142, 2153, - 2142, 2143, 2153, 2153, 2143, 2154, - 2143, 2144, 2154, 2154, 2144, 2155, - 2145, 2146, 2156, 2156, 2146, 2157, - 2146, 2147, 2157, 2157, 2147, 2158, - 2147, 2148, 2158, 2158, 2148, 2159, - 2148, 2149, 2159, 2159, 2149, 2160, - 2149, 2150, 2160, 2160, 2150, 2161, - 2150, 2151, 2161, 2161, 2151, 2162, - 2151, 2152, 2162, 2162, 2152, 2163, - 2152, 2153, 2163, 2163, 2153, 2164, - 2153, 2154, 2164, 2164, 2154, 2165, - 2154, 2155, 2165, 2165, 2155, 2166, - 2156, 2157, 2167, 2167, 2157, 2168, - 2157, 2158, 2168, 2168, 2158, 2169, - 2158, 2159, 2169, 2169, 2159, 2170, - 2159, 2160, 2170, 2170, 2160, 2171, - 2160, 2161, 2171, 2171, 2161, 2172, - 2161, 2162, 2172, 2172, 2162, 2173, - 2162, 2163, 2173, 2173, 2163, 2174, - 2163, 2164, 2174, 2174, 2164, 2175, - 2164, 2165, 2175, 2175, 2165, 2176, - 2165, 2166, 2176, 2176, 2166, 2177, - 2178, 2179, 2189, 2189, 2179, 2190, - 2179, 2180, 2190, 2190, 2180, 2191, - 2180, 2181, 2191, 2191, 2181, 2192, - 2181, 2182, 2192, 2192, 2182, 2193, - 2182, 2183, 2193, 2193, 2183, 2194, - 2183, 2184, 2194, 2194, 2184, 2195, - 2184, 2185, 2195, 2195, 2185, 2196, - 2185, 2186, 2196, 2196, 2186, 2197, - 2186, 2187, 2197, 2197, 2187, 2198, - 2187, 2188, 2198, 2198, 2188, 2199, - 2189, 2190, 2200, 2200, 2190, 2201, - 2190, 2191, 2201, 2201, 2191, 2202, - 2191, 2192, 2202, 2202, 2192, 2203, - 2192, 2193, 2203, 2203, 2193, 2204, - 2193, 2194, 2204, 2204, 2194, 2205, - 2194, 2195, 2205, 2205, 2195, 2206, - 2195, 2196, 2206, 2206, 2196, 2207, - 2196, 2197, 2207, 2207, 2197, 2208, - 2197, 2198, 2208, 2208, 2198, 2209, - 2198, 2199, 2209, 2209, 2199, 2210, - 2200, 2201, 2211, 2211, 2201, 2212, - 2201, 2202, 2212, 2212, 2202, 2213, - 2202, 2203, 2213, 2213, 2203, 2214, - 2203, 2204, 2214, 2214, 2204, 2215, - 2204, 2205, 2215, 2215, 2205, 2216, - 2205, 2206, 2216, 2216, 2206, 2217, - 2206, 2207, 2217, 2217, 2207, 2218, - 2207, 2208, 2218, 2218, 2208, 2219, - 2208, 2209, 2219, 2219, 2209, 2220, - 2209, 2210, 2220, 2220, 2210, 2221, - 2211, 2212, 2222, 2222, 2212, 2223, - 2212, 2213, 2223, 2223, 2213, 2224, - 2213, 2214, 2224, 2224, 2214, 2225, - 2214, 2215, 2225, 2225, 2215, 2226, - 2215, 2216, 2226, 2226, 2216, 2227, - 2216, 2217, 2227, 2227, 2217, 2228, - 2217, 2218, 2228, 2228, 2218, 2229, - 2218, 2219, 2229, 2229, 2219, 2230, - 2219, 2220, 2230, 2230, 2220, 2231, - 2220, 2221, 2231, 2231, 2221, 2232, - 2222, 2223, 2233, 2233, 2223, 2234, - 2223, 2224, 2234, 2234, 2224, 2235, - 2224, 2225, 2235, 2235, 2225, 2236, - 2225, 2226, 2236, 2236, 2226, 2237, - 2226, 2227, 2237, 2237, 2227, 2238, - 2227, 2228, 2238, 2238, 2228, 2239, - 2228, 2229, 2239, 2239, 2229, 2240, - 2229, 2230, 2240, 2240, 2230, 2241, - 2230, 2231, 2241, 2241, 2231, 2242, - 2231, 2232, 2242, 2242, 2232, 2243, - 2233, 2234, 2244, 2244, 2234, 2245, - 2234, 2235, 2245, 2245, 2235, 2246, - 2235, 2236, 2246, 2246, 2236, 2247, - 2236, 2237, 2247, 2247, 2237, 2248, - 2237, 2238, 2248, 2248, 2238, 2249, - 2238, 2239, 2249, 2249, 2239, 2250, - 2239, 2240, 2250, 2250, 2240, 2251, - 2240, 2241, 2251, 2251, 2241, 2252, - 2241, 2242, 2252, 2252, 2242, 2253, - 2242, 2243, 2253, 2253, 2243, 2254, - 2244, 2245, 2255, 2255, 2245, 2256, - 2245, 2246, 2256, 2256, 2246, 2257, - 2246, 2247, 2257, 2257, 2247, 2258, - 2247, 2248, 2258, 2258, 2248, 2259, - 2248, 2249, 2259, 2259, 2249, 2260, - 2249, 2250, 2260, 2260, 2250, 2261, - 2250, 2251, 2261, 2261, 2251, 2262, - 2251, 2252, 2262, 2262, 2252, 2263, - 2252, 2253, 2263, 2263, 2253, 2264, - 2253, 2254, 2264, 2264, 2254, 2265, - 2255, 2256, 2266, 2266, 2256, 2267, - 2256, 2257, 2267, 2267, 2257, 2268, - 2257, 2258, 2268, 2268, 2258, 2269, - 2258, 2259, 2269, 2269, 2259, 2270, - 2259, 2260, 2270, 2270, 2260, 2271, - 2260, 2261, 2271, 2271, 2261, 2272, - 2261, 2262, 2272, 2272, 2262, 2273, - 2262, 2263, 2273, 2273, 2263, 2274, - 2263, 2264, 2274, 2274, 2264, 2275, - 2264, 2265, 2275, 2275, 2265, 2276, - 2266, 2267, 2277, 2277, 2267, 2278, - 2267, 2268, 2278, 2278, 2268, 2279, - 2268, 2269, 2279, 2279, 2269, 2280, - 2269, 2270, 2280, 2280, 2270, 2281, - 2270, 2271, 2281, 2281, 2271, 2282, - 2271, 2272, 2282, 2282, 2272, 2283, - 2272, 2273, 2283, 2283, 2273, 2284, - 2273, 2274, 2284, 2284, 2274, 2285, - 2274, 2275, 2285, 2285, 2275, 2286, - 2275, 2276, 2286, 2286, 2276, 2287, - 2277, 2278, 2288, 2288, 2278, 2289, - 2278, 2279, 2289, 2289, 2279, 2290, - 2279, 2280, 2290, 2290, 2280, 2291, - 2280, 2281, 2291, 2291, 2281, 2292, - 2281, 2282, 2292, 2292, 2282, 2293, - 2282, 2283, 2293, 2293, 2283, 2294, - 2283, 2284, 2294, 2294, 2284, 2295, - 2284, 2285, 2295, 2295, 2285, 2296, - 2285, 2286, 2296, 2296, 2286, 2297, - 2286, 2287, 2297, 2297, 2287, 2298, - 2299, 2300, 2310, 2310, 2300, 2311, - 2300, 2301, 2311, 2311, 2301, 2312, - 2301, 2302, 2312, 2312, 2302, 2313, - 2302, 2303, 2313, 2313, 2303, 2314, - 2303, 2304, 2314, 2314, 2304, 2315, - 2304, 2305, 2315, 2315, 2305, 2316, - 2305, 2306, 2316, 2316, 2306, 2317, - 2306, 2307, 2317, 2317, 2307, 2318, - 2307, 2308, 2318, 2318, 2308, 2319, - 2308, 2309, 2319, 2319, 2309, 2320, - 2310, 2311, 2321, 2321, 2311, 2322, - 2311, 2312, 2322, 2322, 2312, 2323, - 2312, 2313, 2323, 2323, 2313, 2324, - 2313, 2314, 2324, 2324, 2314, 2325, - 2314, 2315, 2325, 2325, 2315, 2326, - 2315, 2316, 2326, 2326, 2316, 2327, - 2316, 2317, 2327, 2327, 2317, 2328, - 2317, 2318, 2328, 2328, 2318, 2329, - 2318, 2319, 2329, 2329, 2319, 2330, - 2319, 2320, 2330, 2330, 2320, 2331, - 2321, 2322, 2332, 2332, 2322, 2333, - 2322, 2323, 2333, 2333, 2323, 2334, - 2323, 2324, 2334, 2334, 2324, 2335, - 2324, 2325, 2335, 2335, 2325, 2336, - 2325, 2326, 2336, 2336, 2326, 2337, - 2326, 2327, 2337, 2337, 2327, 2338, - 2327, 2328, 2338, 2338, 2328, 2339, - 2328, 2329, 2339, 2339, 2329, 2340, - 2329, 2330, 2340, 2340, 2330, 2341, - 2330, 2331, 2341, 2341, 2331, 2342, - 2332, 2333, 2343, 2343, 2333, 2344, - 2333, 2334, 2344, 2344, 2334, 2345, - 2334, 2335, 2345, 2345, 2335, 2346, - 2335, 2336, 2346, 2346, 2336, 2347, - 2336, 2337, 2347, 2347, 2337, 2348, - 2337, 2338, 2348, 2348, 2338, 2349, - 2338, 2339, 2349, 2349, 2339, 2350, - 2339, 2340, 2350, 2350, 2340, 2351, - 2340, 2341, 2351, 2351, 2341, 2352, - 2341, 2342, 2352, 2352, 2342, 2353, - 2343, 2344, 2354, 2354, 2344, 2355, - 2344, 2345, 2355, 2355, 2345, 2356, - 2345, 2346, 2356, 2356, 2346, 2357, - 2346, 2347, 2357, 2357, 2347, 2358, - 2347, 2348, 2358, 2358, 2348, 2359, - 2348, 2349, 2359, 2359, 2349, 2360, - 2349, 2350, 2360, 2360, 2350, 2361, - 2350, 2351, 2361, 2361, 2351, 2362, - 2351, 2352, 2362, 2362, 2352, 2363, - 2352, 2353, 2363, 2363, 2353, 2364, - 2354, 2355, 2365, 2365, 2355, 2366, - 2355, 2356, 2366, 2366, 2356, 2367, - 2356, 2357, 2367, 2367, 2357, 2368, - 2357, 2358, 2368, 2368, 2358, 2369, - 2358, 2359, 2369, 2369, 2359, 2370, - 2359, 2360, 2370, 2370, 2360, 2371, - 2360, 2361, 2371, 2371, 2361, 2372, - 2361, 2362, 2372, 2372, 2362, 2373, - 2362, 2363, 2373, 2373, 2363, 2374, - 2363, 2364, 2374, 2374, 2364, 2375, - 2365, 2366, 2376, 2376, 2366, 2377, - 2366, 2367, 2377, 2377, 2367, 2378, - 2367, 2368, 2378, 2378, 2368, 2379, - 2368, 2369, 2379, 2379, 2369, 2380, - 2369, 2370, 2380, 2380, 2370, 2381, - 2370, 2371, 2381, 2381, 2371, 2382, - 2371, 2372, 2382, 2382, 2372, 2383, - 2372, 2373, 2383, 2383, 2373, 2384, - 2373, 2374, 2384, 2384, 2374, 2385, - 2374, 2375, 2385, 2385, 2375, 2386, - 2376, 2377, 2387, 2387, 2377, 2388, - 2377, 2378, 2388, 2388, 2378, 2389, - 2378, 2379, 2389, 2389, 2379, 2390, - 2379, 2380, 2390, 2390, 2380, 2391, - 2380, 2381, 2391, 2391, 2381, 2392, - 2381, 2382, 2392, 2392, 2382, 2393, - 2382, 2383, 2393, 2393, 2383, 2394, - 2383, 2384, 2394, 2394, 2384, 2395, - 2384, 2385, 2395, 2395, 2385, 2396, - 2385, 2386, 2396, 2396, 2386, 2397, - 2387, 2388, 2398, 2398, 2388, 2399, - 2388, 2389, 2399, 2399, 2389, 2400, - 2389, 2390, 2400, 2400, 2390, 2401, - 2390, 2391, 2401, 2401, 2391, 2402, - 2391, 2392, 2402, 2402, 2392, 2403, - 2392, 2393, 2403, 2403, 2393, 2404, - 2393, 2394, 2404, 2404, 2394, 2405, - 2394, 2395, 2405, 2405, 2395, 2406, - 2395, 2396, 2406, 2406, 2396, 2407, - 2396, 2397, 2407, 2407, 2397, 2408, - 2398, 2399, 2409, 2409, 2399, 2410, - 2399, 2400, 2410, 2410, 2400, 2411, - 2400, 2401, 2411, 2411, 2401, 2412, - 2401, 2402, 2412, 2412, 2402, 2413, - 2402, 2403, 2413, 2413, 2403, 2414, - 2403, 2404, 2414, 2414, 2404, 2415, - 2404, 2405, 2415, 2415, 2405, 2416, - 2405, 2406, 2416, 2416, 2406, 2417, - 2406, 2407, 2417, 2417, 2407, 2418, - 2407, 2408, 2418, 2418, 2408, 2419, - 2420, 2421, 2431, 2431, 2421, 2432, - 2421, 2422, 2432, 2432, 2422, 2433, - 2422, 2423, 2433, 2433, 2423, 2434, - 2423, 2424, 2434, 2434, 2424, 2435, - 2424, 2425, 2435, 2435, 2425, 2436, - 2425, 2426, 2436, 2436, 2426, 2437, - 2426, 2427, 2437, 2437, 2427, 2438, - 2427, 2428, 2438, 2438, 2428, 2439, - 2428, 2429, 2439, 2439, 2429, 2440, - 2429, 2430, 2440, 2440, 2430, 2441, - 2431, 2432, 2442, 2442, 2432, 2443, - 2432, 2433, 2443, 2443, 2433, 2444, - 2433, 2434, 2444, 2444, 2434, 2445, - 2434, 2435, 2445, 2445, 2435, 2446, - 2435, 2436, 2446, 2446, 2436, 2447, - 2436, 2437, 2447, 2447, 2437, 2448, - 2437, 2438, 2448, 2448, 2438, 2449, - 2438, 2439, 2449, 2449, 2439, 2450, - 2439, 2440, 2450, 2450, 2440, 2451, - 2440, 2441, 2451, 2451, 2441, 2452, - 2442, 2443, 2453, 2453, 2443, 2454, - 2443, 2444, 2454, 2454, 2444, 2455, - 2444, 2445, 2455, 2455, 2445, 2456, - 2445, 2446, 2456, 2456, 2446, 2457, - 2446, 2447, 2457, 2457, 2447, 2458, - 2447, 2448, 2458, 2458, 2448, 2459, - 2448, 2449, 2459, 2459, 2449, 2460, - 2449, 2450, 2460, 2460, 2450, 2461, - 2450, 2451, 2461, 2461, 2451, 2462, - 2451, 2452, 2462, 2462, 2452, 2463, - 2453, 2454, 2464, 2464, 2454, 2465, - 2454, 2455, 2465, 2465, 2455, 2466, - 2455, 2456, 2466, 2466, 2456, 2467, - 2456, 2457, 2467, 2467, 2457, 2468, - 2457, 2458, 2468, 2468, 2458, 2469, - 2458, 2459, 2469, 2469, 2459, 2470, - 2459, 2460, 2470, 2470, 2460, 2471, - 2460, 2461, 2471, 2471, 2461, 2472, - 2461, 2462, 2472, 2472, 2462, 2473, - 2462, 2463, 2473, 2473, 2463, 2474, - 2464, 2465, 2475, 2475, 2465, 2476, - 2465, 2466, 2476, 2476, 2466, 2477, - 2466, 2467, 2477, 2477, 2467, 2478, - 2467, 2468, 2478, 2478, 2468, 2479, - 2468, 2469, 2479, 2479, 2469, 2480, - 2469, 2470, 2480, 2480, 2470, 2481, - 2470, 2471, 2481, 2481, 2471, 2482, - 2471, 2472, 2482, 2482, 2472, 2483, - 2472, 2473, 2483, 2483, 2473, 2484, - 2473, 2474, 2484, 2484, 2474, 2485, - 2475, 2476, 2486, 2486, 2476, 2487, - 2476, 2477, 2487, 2487, 2477, 2488, - 2477, 2478, 2488, 2488, 2478, 2489, - 2478, 2479, 2489, 2489, 2479, 2490, - 2479, 2480, 2490, 2490, 2480, 2491, - 2480, 2481, 2491, 2491, 2481, 2492, - 2481, 2482, 2492, 2492, 2482, 2493, - 2482, 2483, 2493, 2493, 2483, 2494, - 2483, 2484, 2494, 2494, 2484, 2495, - 2484, 2485, 2495, 2495, 2485, 2496, - 2486, 2487, 2497, 2497, 2487, 2498, - 2487, 2488, 2498, 2498, 2488, 2499, - 2488, 2489, 2499, 2499, 2489, 2500, - 2489, 2490, 2500, 2500, 2490, 2501, - 2490, 2491, 2501, 2501, 2491, 2502, - 2491, 2492, 2502, 2502, 2492, 2503, - 2492, 2493, 2503, 2503, 2493, 2504, - 2493, 2494, 2504, 2504, 2494, 2505, - 2494, 2495, 2505, 2505, 2495, 2506, - 2495, 2496, 2506, 2506, 2496, 2507, - 2497, 2498, 2508, 2508, 2498, 2509, - 2498, 2499, 2509, 2509, 2499, 2510, - 2499, 2500, 2510, 2510, 2500, 2511, - 2500, 2501, 2511, 2511, 2501, 2512, - 2501, 2502, 2512, 2512, 2502, 2513, - 2502, 2503, 2513, 2513, 2503, 2514, - 2503, 2504, 2514, 2514, 2504, 2515, - 2504, 2505, 2515, 2515, 2505, 2516, - 2505, 2506, 2516, 2516, 2506, 2517, - 2506, 2507, 2517, 2517, 2507, 2518, - 2508, 2509, 2519, 2519, 2509, 2520, - 2509, 2510, 2520, 2520, 2510, 2521, - 2510, 2511, 2521, 2521, 2511, 2522, - 2511, 2512, 2522, 2522, 2512, 2523, - 2512, 2513, 2523, 2523, 2513, 2524, - 2513, 2514, 2524, 2524, 2514, 2525, - 2514, 2515, 2525, 2525, 2515, 2526, - 2515, 2516, 2526, 2526, 2516, 2527, - 2516, 2517, 2527, 2527, 2517, 2528, - 2517, 2518, 2528, 2528, 2518, 2529, - 2519, 2520, 2530, 2530, 2520, 2531, - 2520, 2521, 2531, 2531, 2521, 2532, - 2521, 2522, 2532, 2532, 2522, 2533, - 2522, 2523, 2533, 2533, 2523, 2534, - 2523, 2524, 2534, 2534, 2524, 2535, - 2524, 2525, 2535, 2535, 2525, 2536, - 2525, 2526, 2536, 2536, 2526, 2537, - 2526, 2527, 2537, 2537, 2527, 2538, - 2527, 2528, 2538, 2538, 2528, 2539, - 2528, 2529, 2539, 2539, 2529, 2540, - 2541, 2542, 2552, 2552, 2542, 2553, - 2542, 2543, 2553, 2553, 2543, 2554, - 2543, 2544, 2554, 2554, 2544, 2555, - 2544, 2545, 2555, 2555, 2545, 2556, - 2545, 2546, 2556, 2556, 2546, 2557, - 2546, 2547, 2557, 2557, 2547, 2558, - 2547, 2548, 2558, 2558, 2548, 2559, - 2548, 2549, 2559, 2559, 2549, 2560, - 2549, 2550, 2560, 2560, 2550, 2561, - 2550, 2551, 2561, 2561, 2551, 2562, - 2552, 2553, 2563, 2563, 2553, 2564, - 2553, 2554, 2564, 2564, 2554, 2565, - 2554, 2555, 2565, 2565, 2555, 2566, - 2555, 2556, 2566, 2566, 2556, 2567, - 2556, 2557, 2567, 2567, 2557, 2568, - 2557, 2558, 2568, 2568, 2558, 2569, - 2558, 2559, 2569, 2569, 2559, 2570, - 2559, 2560, 2570, 2570, 2560, 2571, - 2560, 2561, 2571, 2571, 2561, 2572, - 2561, 2562, 2572, 2572, 2562, 2573, - 2563, 2564, 2574, 2574, 2564, 2575, - 2564, 2565, 2575, 2575, 2565, 2576, - 2565, 2566, 2576, 2576, 2566, 2577, - 2566, 2567, 2577, 2577, 2567, 2578, - 2567, 2568, 2578, 2578, 2568, 2579, - 2568, 2569, 2579, 2579, 2569, 2580, - 2569, 2570, 2580, 2580, 2570, 2581, - 2570, 2571, 2581, 2581, 2571, 2582, - 2571, 2572, 2582, 2582, 2572, 2583, - 2572, 2573, 2583, 2583, 2573, 2584, - 2574, 2575, 2585, 2585, 2575, 2586, - 2575, 2576, 2586, 2586, 2576, 2587, - 2576, 2577, 2587, 2587, 2577, 2588, - 2577, 2578, 2588, 2588, 2578, 2589, - 2578, 2579, 2589, 2589, 2579, 2590, - 2579, 2580, 2590, 2590, 2580, 2591, - 2580, 2581, 2591, 2591, 2581, 2592, - 2581, 2582, 2592, 2592, 2582, 2593, - 2582, 2583, 2593, 2593, 2583, 2594, - 2583, 2584, 2594, 2594, 2584, 2595, - 2585, 2586, 2596, 2596, 2586, 2597, - 2586, 2587, 2597, 2597, 2587, 2598, - 2587, 2588, 2598, 2598, 2588, 2599, - 2588, 2589, 2599, 2599, 2589, 2600, - 2589, 2590, 2600, 2600, 2590, 2601, - 2590, 2591, 2601, 2601, 2591, 2602, - 2591, 2592, 2602, 2602, 2592, 2603, - 2592, 2593, 2603, 2603, 2593, 2604, - 2593, 2594, 2604, 2604, 2594, 2605, - 2594, 2595, 2605, 2605, 2595, 2606, - 2596, 2597, 2607, 2607, 2597, 2608, - 2597, 2598, 2608, 2608, 2598, 2609, - 2598, 2599, 2609, 2609, 2599, 2610, - 2599, 2600, 2610, 2610, 2600, 2611, - 2600, 2601, 2611, 2611, 2601, 2612, - 2601, 2602, 2612, 2612, 2602, 2613, - 2602, 2603, 2613, 2613, 2603, 2614, - 2603, 2604, 2614, 2614, 2604, 2615, - 2604, 2605, 2615, 2615, 2605, 2616, - 2605, 2606, 2616, 2616, 2606, 2617, - 2607, 2608, 2618, 2618, 2608, 2619, - 2608, 2609, 2619, 2619, 2609, 2620, - 2609, 2610, 2620, 2620, 2610, 2621, - 2610, 2611, 2621, 2621, 2611, 2622, - 2611, 2612, 2622, 2622, 2612, 2623, - 2612, 2613, 2623, 2623, 2613, 2624, - 2613, 2614, 2624, 2624, 2614, 2625, - 2614, 2615, 2625, 2625, 2615, 2626, - 2615, 2616, 2626, 2626, 2616, 2627, - 2616, 2617, 2627, 2627, 2617, 2628, - 2618, 2619, 2629, 2629, 2619, 2630, - 2619, 2620, 2630, 2630, 2620, 2631, - 2620, 2621, 2631, 2631, 2621, 2632, - 2621, 2622, 2632, 2632, 2622, 2633, - 2622, 2623, 2633, 2633, 2623, 2634, - 2623, 2624, 2634, 2634, 2624, 2635, - 2624, 2625, 2635, 2635, 2625, 2636, - 2625, 2626, 2636, 2636, 2626, 2637, - 2626, 2627, 2637, 2637, 2627, 2638, - 2627, 2628, 2638, 2638, 2628, 2639, - 2629, 2630, 2640, 2640, 2630, 2641, - 2630, 2631, 2641, 2641, 2631, 2642, - 2631, 2632, 2642, 2642, 2632, 2643, - 2632, 2633, 2643, 2643, 2633, 2644, - 2633, 2634, 2644, 2644, 2634, 2645, - 2634, 2635, 2645, 2645, 2635, 2646, - 2635, 2636, 2646, 2646, 2636, 2647, - 2636, 2637, 2647, 2647, 2637, 2648, - 2637, 2638, 2648, 2648, 2638, 2649, - 2638, 2639, 2649, 2649, 2639, 2650, - 2640, 2641, 2651, 2651, 2641, 2652, - 2641, 2642, 2652, 2652, 2642, 2653, - 2642, 2643, 2653, 2653, 2643, 2654, - 2643, 2644, 2654, 2654, 2644, 2655, - 2644, 2645, 2655, 2655, 2645, 2656, - 2645, 2646, 2656, 2656, 2646, 2657, - 2646, 2647, 2657, 2657, 2647, 2658, - 2647, 2648, 2658, 2658, 2648, 2659, - 2648, 2649, 2659, 2659, 2649, 2660, - 2649, 2650, 2660, 2660, 2650, 2661, - 2662, 2663, 2673, 2673, 2663, 2674, - 2663, 2664, 2674, 2674, 2664, 2675, - 2664, 2665, 2675, 2675, 2665, 2676, - 2665, 2666, 2676, 2676, 2666, 2677, - 2666, 2667, 2677, 2677, 2667, 2678, - 2667, 2668, 2678, 2678, 2668, 2679, - 2668, 2669, 2679, 2679, 2669, 2680, - 2669, 2670, 2680, 2680, 2670, 2681, - 2670, 2671, 2681, 2681, 2671, 2682, - 2671, 2672, 2682, 2682, 2672, 2683, - 2673, 2674, 2684, 2684, 2674, 2685, - 2674, 2675, 2685, 2685, 2675, 2686, - 2675, 2676, 2686, 2686, 2676, 2687, - 2676, 2677, 2687, 2687, 2677, 2688, - 2677, 2678, 2688, 2688, 2678, 2689, - 2678, 2679, 2689, 2689, 2679, 2690, - 2679, 2680, 2690, 2690, 2680, 2691, - 2680, 2681, 2691, 2691, 2681, 2692, - 2681, 2682, 2692, 2692, 2682, 2693, - 2682, 2683, 2693, 2693, 2683, 2694, - 2684, 2685, 2695, 2695, 2685, 2696, - 2685, 2686, 2696, 2696, 2686, 2697, - 2686, 2687, 2697, 2697, 2687, 2698, - 2687, 2688, 2698, 2698, 2688, 2699, - 2688, 2689, 2699, 2699, 2689, 2700, - 2689, 2690, 2700, 2700, 2690, 2701, - 2690, 2691, 2701, 2701, 2691, 2702, - 2691, 2692, 2702, 2702, 2692, 2703, - 2692, 2693, 2703, 2703, 2693, 2704, - 2693, 2694, 2704, 2704, 2694, 2705, - 2695, 2696, 2706, 2706, 2696, 2707, - 2696, 2697, 2707, 2707, 2697, 2708, - 2697, 2698, 2708, 2708, 2698, 2709, - 2698, 2699, 2709, 2709, 2699, 2710, - 2699, 2700, 2710, 2710, 2700, 2711, - 2700, 2701, 2711, 2711, 2701, 2712, - 2701, 2702, 2712, 2712, 2702, 2713, - 2702, 2703, 2713, 2713, 2703, 2714, - 2703, 2704, 2714, 2714, 2704, 2715, - 2704, 2705, 2715, 2715, 2705, 2716, - 2706, 2707, 2717, 2717, 2707, 2718, - 2707, 2708, 2718, 2718, 2708, 2719, - 2708, 2709, 2719, 2719, 2709, 2720, - 2709, 2710, 2720, 2720, 2710, 2721, - 2710, 2711, 2721, 2721, 2711, 2722, - 2711, 2712, 2722, 2722, 2712, 2723, - 2712, 2713, 2723, 2723, 2713, 2724, - 2713, 2714, 2724, 2724, 2714, 2725, - 2714, 2715, 2725, 2725, 2715, 2726, - 2715, 2716, 2726, 2726, 2716, 2727, - 2717, 2718, 2728, 2728, 2718, 2729, - 2718, 2719, 2729, 2729, 2719, 2730, - 2719, 2720, 2730, 2730, 2720, 2731, - 2720, 2721, 2731, 2731, 2721, 2732, - 2721, 2722, 2732, 2732, 2722, 2733, - 2722, 2723, 2733, 2733, 2723, 2734, - 2723, 2724, 2734, 2734, 2724, 2735, - 2724, 2725, 2735, 2735, 2725, 2736, - 2725, 2726, 2736, 2736, 2726, 2737, - 2726, 2727, 2737, 2737, 2727, 2738, - 2728, 2729, 2739, 2739, 2729, 2740, - 2729, 2730, 2740, 2740, 2730, 2741, - 2730, 2731, 2741, 2741, 2731, 2742, - 2731, 2732, 2742, 2742, 2732, 2743, - 2732, 2733, 2743, 2743, 2733, 2744, - 2733, 2734, 2744, 2744, 2734, 2745, - 2734, 2735, 2745, 2745, 2735, 2746, - 2735, 2736, 2746, 2746, 2736, 2747, - 2736, 2737, 2747, 2747, 2737, 2748, - 2737, 2738, 2748, 2748, 2738, 2749, - 2739, 2740, 2750, 2750, 2740, 2751, - 2740, 2741, 2751, 2751, 2741, 2752, - 2741, 2742, 2752, 2752, 2742, 2753, - 2742, 2743, 2753, 2753, 2743, 2754, - 2743, 2744, 2754, 2754, 2744, 2755, - 2744, 2745, 2755, 2755, 2745, 2756, - 2745, 2746, 2756, 2756, 2746, 2757, - 2746, 2747, 2757, 2757, 2747, 2758, - 2747, 2748, 2758, 2758, 2748, 2759, - 2748, 2749, 2759, 2759, 2749, 2760, - 2750, 2751, 2761, 2761, 2751, 2762, - 2751, 2752, 2762, 2762, 2752, 2763, - 2752, 2753, 2763, 2763, 2753, 2764, - 2753, 2754, 2764, 2764, 2754, 2765, - 2754, 2755, 2765, 2765, 2755, 2766, - 2755, 2756, 2766, 2766, 2756, 2767, - 2756, 2757, 2767, 2767, 2757, 2768, - 2757, 2758, 2768, 2768, 2758, 2769, - 2758, 2759, 2769, 2769, 2759, 2770, - 2759, 2760, 2770, 2770, 2760, 2771, - 2761, 2762, 2772, 2772, 2762, 2773, - 2762, 2763, 2773, 2773, 2763, 2774, - 2763, 2764, 2774, 2774, 2764, 2775, - 2764, 2765, 2775, 2775, 2765, 2776, - 2765, 2766, 2776, 2776, 2766, 2777, - 2766, 2767, 2777, 2777, 2767, 2778, - 2767, 2768, 2778, 2778, 2768, 2779, - 2768, 2769, 2779, 2779, 2769, 2780, - 2769, 2770, 2780, 2780, 2770, 2781, - 2770, 2771, 2781, 2781, 2771, 2782, - 2783, 2784, 2794, 2794, 2784, 2795, - 2784, 2785, 2795, 2795, 2785, 2796, - 2785, 2786, 2796, 2796, 2786, 2797, - 2786, 2787, 2797, 2797, 2787, 2798, - 2787, 2788, 2798, 2798, 2788, 2799, - 2788, 2789, 2799, 2799, 2789, 2800, - 2789, 2790, 2800, 2800, 2790, 2801, - 2790, 2791, 2801, 2801, 2791, 2802, - 2791, 2792, 2802, 2802, 2792, 2803, - 2792, 2793, 2803, 2803, 2793, 2804, - 2794, 2795, 2805, 2805, 2795, 2806, - 2795, 2796, 2806, 2806, 2796, 2807, - 2796, 2797, 2807, 2807, 2797, 2808, - 2797, 2798, 2808, 2808, 2798, 2809, - 2798, 2799, 2809, 2809, 2799, 2810, - 2799, 2800, 2810, 2810, 2800, 2811, - 2800, 2801, 2811, 2811, 2801, 2812, - 2801, 2802, 2812, 2812, 2802, 2813, - 2802, 2803, 2813, 2813, 2803, 2814, - 2803, 2804, 2814, 2814, 2804, 2815, - 2805, 2806, 2816, 2816, 2806, 2817, - 2806, 2807, 2817, 2817, 2807, 2818, - 2807, 2808, 2818, 2818, 2808, 2819, - 2808, 2809, 2819, 2819, 2809, 2820, - 2809, 2810, 2820, 2820, 2810, 2821, - 2810, 2811, 2821, 2821, 2811, 2822, - 2811, 2812, 2822, 2822, 2812, 2823, - 2812, 2813, 2823, 2823, 2813, 2824, - 2813, 2814, 2824, 2824, 2814, 2825, - 2814, 2815, 2825, 2825, 2815, 2826, - 2816, 2817, 2827, 2827, 2817, 2828, - 2817, 2818, 2828, 2828, 2818, 2829, - 2818, 2819, 2829, 2829, 2819, 2830, - 2819, 2820, 2830, 2830, 2820, 2831, - 2820, 2821, 2831, 2831, 2821, 2832, - 2821, 2822, 2832, 2832, 2822, 2833, - 2822, 2823, 2833, 2833, 2823, 2834, - 2823, 2824, 2834, 2834, 2824, 2835, - 2824, 2825, 2835, 2835, 2825, 2836, - 2825, 2826, 2836, 2836, 2826, 2837, - 2827, 2828, 2838, 2838, 2828, 2839, - 2828, 2829, 2839, 2839, 2829, 2840, - 2829, 2830, 2840, 2840, 2830, 2841, - 2830, 2831, 2841, 2841, 2831, 2842, - 2831, 2832, 2842, 2842, 2832, 2843, - 2832, 2833, 2843, 2843, 2833, 2844, - 2833, 2834, 2844, 2844, 2834, 2845, - 2834, 2835, 2845, 2845, 2835, 2846, - 2835, 2836, 2846, 2846, 2836, 2847, - 2836, 2837, 2847, 2847, 2837, 2848, - 2838, 2839, 2849, 2849, 2839, 2850, - 2839, 2840, 2850, 2850, 2840, 2851, - 2840, 2841, 2851, 2851, 2841, 2852, - 2841, 2842, 2852, 2852, 2842, 2853, - 2842, 2843, 2853, 2853, 2843, 2854, - 2843, 2844, 2854, 2854, 2844, 2855, - 2844, 2845, 2855, 2855, 2845, 2856, - 2845, 2846, 2856, 2856, 2846, 2857, - 2846, 2847, 2857, 2857, 2847, 2858, - 2847, 2848, 2858, 2858, 2848, 2859, - 2849, 2850, 2860, 2860, 2850, 2861, - 2850, 2851, 2861, 2861, 2851, 2862, - 2851, 2852, 2862, 2862, 2852, 2863, - 2852, 2853, 2863, 2863, 2853, 2864, - 2853, 2854, 2864, 2864, 2854, 2865, - 2854, 2855, 2865, 2865, 2855, 2866, - 2855, 2856, 2866, 2866, 2856, 2867, - 2856, 2857, 2867, 2867, 2857, 2868, - 2857, 2858, 2868, 2868, 2858, 2869, - 2858, 2859, 2869, 2869, 2859, 2870, - 2860, 2861, 2871, 2871, 2861, 2872, - 2861, 2862, 2872, 2872, 2862, 2873, - 2862, 2863, 2873, 2873, 2863, 2874, - 2863, 2864, 2874, 2874, 2864, 2875, - 2864, 2865, 2875, 2875, 2865, 2876, - 2865, 2866, 2876, 2876, 2866, 2877, - 2866, 2867, 2877, 2877, 2867, 2878, - 2867, 2868, 2878, 2878, 2868, 2879, - 2868, 2869, 2879, 2879, 2869, 2880, - 2869, 2870, 2880, 2880, 2870, 2881, - 2871, 2872, 2882, 2882, 2872, 2883, - 2872, 2873, 2883, 2883, 2873, 2884, - 2873, 2874, 2884, 2884, 2874, 2885, - 2874, 2875, 2885, 2885, 2875, 2886, - 2875, 2876, 2886, 2886, 2876, 2887, - 2876, 2877, 2887, 2887, 2877, 2888, - 2877, 2878, 2888, 2888, 2878, 2889, - 2878, 2879, 2889, 2889, 2879, 2890, - 2879, 2880, 2890, 2890, 2880, 2891, - 2880, 2881, 2891, 2891, 2881, 2892, - 2882, 2883, 2893, 2893, 2883, 2894, - 2883, 2884, 2894, 2894, 2884, 2895, - 2884, 2885, 2895, 2895, 2885, 2896, - 2885, 2886, 2896, 2896, 2886, 2897, - 2886, 2887, 2897, 2897, 2887, 2898, - 2887, 2888, 2898, 2898, 2888, 2899, - 2888, 2889, 2899, 2899, 2889, 2900, - 2889, 2890, 2900, 2900, 2890, 2901, - 2890, 2891, 2901, 2901, 2891, 2902, - 2891, 2892, 2902, 2902, 2892, 2903, - 2904, 2905, 2915, 2915, 2905, 2916, - 2905, 2906, 2916, 2916, 2906, 2917, - 2906, 2907, 2917, 2917, 2907, 2918, - 2907, 2908, 2918, 2918, 2908, 2919, - 2908, 2909, 2919, 2919, 2909, 2920, - 2909, 2910, 2920, 2920, 2910, 2921, - 2910, 2911, 2921, 2921, 2911, 2922, - 2911, 2912, 2922, 2922, 2912, 2923, - 2912, 2913, 2923, 2923, 2913, 2924, - 2913, 2914, 2924, 2924, 2914, 2925, - 2915, 2916, 2926, 2926, 2916, 2927, - 2916, 2917, 2927, 2927, 2917, 2928, - 2917, 2918, 2928, 2928, 2918, 2929, - 2918, 2919, 2929, 2929, 2919, 2930, - 2919, 2920, 2930, 2930, 2920, 2931, - 2920, 2921, 2931, 2931, 2921, 2932, - 2921, 2922, 2932, 2932, 2922, 2933, - 2922, 2923, 2933, 2933, 2923, 2934, - 2923, 2924, 2934, 2934, 2924, 2935, - 2924, 2925, 2935, 2935, 2925, 2936, - 2926, 2927, 2937, 2937, 2927, 2938, - 2927, 2928, 2938, 2938, 2928, 2939, - 2928, 2929, 2939, 2939, 2929, 2940, - 2929, 2930, 2940, 2940, 2930, 2941, - 2930, 2931, 2941, 2941, 2931, 2942, - 2931, 2932, 2942, 2942, 2932, 2943, - 2932, 2933, 2943, 2943, 2933, 2944, - 2933, 2934, 2944, 2944, 2934, 2945, - 2934, 2935, 2945, 2945, 2935, 2946, - 2935, 2936, 2946, 2946, 2936, 2947, - 2937, 2938, 2948, 2948, 2938, 2949, - 2938, 2939, 2949, 2949, 2939, 2950, - 2939, 2940, 2950, 2950, 2940, 2951, - 2940, 2941, 2951, 2951, 2941, 2952, - 2941, 2942, 2952, 2952, 2942, 2953, - 2942, 2943, 2953, 2953, 2943, 2954, - 2943, 2944, 2954, 2954, 2944, 2955, - 2944, 2945, 2955, 2955, 2945, 2956, - 2945, 2946, 2956, 2956, 2946, 2957, - 2946, 2947, 2957, 2957, 2947, 2958, - 2948, 2949, 2959, 2959, 2949, 2960, - 2949, 2950, 2960, 2960, 2950, 2961, - 2950, 2951, 2961, 2961, 2951, 2962, - 2951, 2952, 2962, 2962, 2952, 2963, - 2952, 2953, 2963, 2963, 2953, 2964, - 2953, 2954, 2964, 2964, 2954, 2965, - 2954, 2955, 2965, 2965, 2955, 2966, - 2955, 2956, 2966, 2966, 2956, 2967, - 2956, 2957, 2967, 2967, 2957, 2968, - 2957, 2958, 2968, 2968, 2958, 2969, - 2959, 2960, 2970, 2970, 2960, 2971, - 2960, 2961, 2971, 2971, 2961, 2972, - 2961, 2962, 2972, 2972, 2962, 2973, - 2962, 2963, 2973, 2973, 2963, 2974, - 2963, 2964, 2974, 2974, 2964, 2975, - 2964, 2965, 2975, 2975, 2965, 2976, - 2965, 2966, 2976, 2976, 2966, 2977, - 2966, 2967, 2977, 2977, 2967, 2978, - 2967, 2968, 2978, 2978, 2968, 2979, - 2968, 2969, 2979, 2979, 2969, 2980, - 2970, 2971, 2981, 2981, 2971, 2982, - 2971, 2972, 2982, 2982, 2972, 2983, - 2972, 2973, 2983, 2983, 2973, 2984, - 2973, 2974, 2984, 2984, 2974, 2985, - 2974, 2975, 2985, 2985, 2975, 2986, - 2975, 2976, 2986, 2986, 2976, 2987, - 2976, 2977, 2987, 2987, 2977, 2988, - 2977, 2978, 2988, 2988, 2978, 2989, - 2978, 2979, 2989, 2989, 2979, 2990, - 2979, 2980, 2990, 2990, 2980, 2991, - 2981, 2982, 2992, 2992, 2982, 2993, - 2982, 2983, 2993, 2993, 2983, 2994, - 2983, 2984, 2994, 2994, 2984, 2995, - 2984, 2985, 2995, 2995, 2985, 2996, - 2985, 2986, 2996, 2996, 2986, 2997, - 2986, 2987, 2997, 2997, 2987, 2998, - 2987, 2988, 2998, 2998, 2988, 2999, - 2988, 2989, 2999, 2999, 2989, 3000, - 2989, 2990, 3000, 3000, 2990, 3001, - 2990, 2991, 3001, 3001, 2991, 3002, - 2992, 2993, 3003, 3003, 2993, 3004, - 2993, 2994, 3004, 3004, 2994, 3005, - 2994, 2995, 3005, 3005, 2995, 3006, - 2995, 2996, 3006, 3006, 2996, 3007, - 2996, 2997, 3007, 3007, 2997, 3008, - 2997, 2998, 3008, 3008, 2998, 3009, - 2998, 2999, 3009, 3009, 2999, 3010, - 2999, 3000, 3010, 3010, 3000, 3011, - 3000, 3001, 3011, 3011, 3001, 3012, - 3001, 3002, 3012, 3012, 3002, 3013, - 3003, 3004, 3014, 3014, 3004, 3015, - 3004, 3005, 3015, 3015, 3005, 3016, - 3005, 3006, 3016, 3016, 3006, 3017, - 3006, 3007, 3017, 3017, 3007, 3018, - 3007, 3008, 3018, 3018, 3008, 3019, - 3008, 3009, 3019, 3019, 3009, 3020, - 3009, 3010, 3020, 3020, 3010, 3021, - 3010, 3011, 3021, 3021, 3011, 3022, - 3011, 3012, 3022, 3022, 3012, 3023, - 3012, 3013, 3023, 3023, 3013, 3024, - 3025, 3026, 3036, 3036, 3026, 3037, - 3026, 3027, 3037, 3037, 3027, 3038, - 3027, 3028, 3038, 3038, 3028, 3039, - 3028, 3029, 3039, 3039, 3029, 3040, - 3029, 3030, 3040, 3040, 3030, 3041, - 3030, 3031, 3041, 3041, 3031, 3042, - 3031, 3032, 3042, 3042, 3032, 3043, - 3032, 3033, 3043, 3043, 3033, 3044, - 3033, 3034, 3044, 3044, 3034, 3045, - 3034, 3035, 3045, 3045, 3035, 3046, - 3036, 3037, 3047, 3047, 3037, 3048, - 3037, 3038, 3048, 3048, 3038, 3049, - 3038, 3039, 3049, 3049, 3039, 3050, - 3039, 3040, 3050, 3050, 3040, 3051, - 3040, 3041, 3051, 3051, 3041, 3052, - 3041, 3042, 3052, 3052, 3042, 3053, - 3042, 3043, 3053, 3053, 3043, 3054, - 3043, 3044, 3054, 3054, 3044, 3055, - 3044, 3045, 3055, 3055, 3045, 3056, - 3045, 3046, 3056, 3056, 3046, 3057, - 3047, 3048, 3058, 3058, 3048, 3059, - 3048, 3049, 3059, 3059, 3049, 3060, - 3049, 3050, 3060, 3060, 3050, 3061, - 3050, 3051, 3061, 3061, 3051, 3062, - 3051, 3052, 3062, 3062, 3052, 3063, - 3052, 3053, 3063, 3063, 3053, 3064, - 3053, 3054, 3064, 3064, 3054, 3065, - 3054, 3055, 3065, 3065, 3055, 3066, - 3055, 3056, 3066, 3066, 3056, 3067, - 3056, 3057, 3067, 3067, 3057, 3068, - 3058, 3059, 3069, 3069, 3059, 3070, - 3059, 3060, 3070, 3070, 3060, 3071, - 3060, 3061, 3071, 3071, 3061, 3072, - 3061, 3062, 3072, 3072, 3062, 3073, - 3062, 3063, 3073, 3073, 3063, 3074, - 3063, 3064, 3074, 3074, 3064, 3075, - 3064, 3065, 3075, 3075, 3065, 3076, - 3065, 3066, 3076, 3076, 3066, 3077, - 3066, 3067, 3077, 3077, 3067, 3078, - 3067, 3068, 3078, 3078, 3068, 3079, - 3069, 3070, 3080, 3080, 3070, 3081, - 3070, 3071, 3081, 3081, 3071, 3082, - 3071, 3072, 3082, 3082, 3072, 3083, - 3072, 3073, 3083, 3083, 3073, 3084, - 3073, 3074, 3084, 3084, 3074, 3085, - 3074, 3075, 3085, 3085, 3075, 3086, - 3075, 3076, 3086, 3086, 3076, 3087, - 3076, 3077, 3087, 3087, 3077, 3088, - 3077, 3078, 3088, 3088, 3078, 3089, - 3078, 3079, 3089, 3089, 3079, 3090, - 3080, 3081, 3091, 3091, 3081, 3092, - 3081, 3082, 3092, 3092, 3082, 3093, - 3082, 3083, 3093, 3093, 3083, 3094, - 3083, 3084, 3094, 3094, 3084, 3095, - 3084, 3085, 3095, 3095, 3085, 3096, - 3085, 3086, 3096, 3096, 3086, 3097, - 3086, 3087, 3097, 3097, 3087, 3098, - 3087, 3088, 3098, 3098, 3088, 3099, - 3088, 3089, 3099, 3099, 3089, 3100, - 3089, 3090, 3100, 3100, 3090, 3101, - 3091, 3092, 3102, 3102, 3092, 3103, - 3092, 3093, 3103, 3103, 3093, 3104, - 3093, 3094, 3104, 3104, 3094, 3105, - 3094, 3095, 3105, 3105, 3095, 3106, - 3095, 3096, 3106, 3106, 3096, 3107, - 3096, 3097, 3107, 3107, 3097, 3108, - 3097, 3098, 3108, 3108, 3098, 3109, - 3098, 3099, 3109, 3109, 3099, 3110, - 3099, 3100, 3110, 3110, 3100, 3111, - 3100, 3101, 3111, 3111, 3101, 3112, - 3102, 3103, 3113, 3113, 3103, 3114, - 3103, 3104, 3114, 3114, 3104, 3115, - 3104, 3105, 3115, 3115, 3105, 3116, - 3105, 3106, 3116, 3116, 3106, 3117, - 3106, 3107, 3117, 3117, 3107, 3118, - 3107, 3108, 3118, 3118, 3108, 3119, - 3108, 3109, 3119, 3119, 3109, 3120, - 3109, 3110, 3120, 3120, 3110, 3121, - 3110, 3111, 3121, 3121, 3111, 3122, - 3111, 3112, 3122, 3122, 3112, 3123, - 3113, 3114, 3124, 3124, 3114, 3125, - 3114, 3115, 3125, 3125, 3115, 3126, - 3115, 3116, 3126, 3126, 3116, 3127, - 3116, 3117, 3127, 3127, 3117, 3128, - 3117, 3118, 3128, 3128, 3118, 3129, - 3118, 3119, 3129, 3129, 3119, 3130, - 3119, 3120, 3130, 3130, 3120, 3131, - 3120, 3121, 3131, 3131, 3121, 3132, - 3121, 3122, 3132, 3132, 3122, 3133, - 3122, 3123, 3133, 3133, 3123, 3134, - 3124, 3125, 3135, 3135, 3125, 3136, - 3125, 3126, 3136, 3136, 3126, 3137, - 3126, 3127, 3137, 3137, 3127, 3138, - 3127, 3128, 3138, 3138, 3128, 3139, - 3128, 3129, 3139, 3139, 3129, 3140, - 3129, 3130, 3140, 3140, 3130, 3141, - 3130, 3131, 3141, 3141, 3131, 3142, - 3131, 3132, 3142, 3142, 3132, 3143, - 3132, 3133, 3143, 3143, 3133, 3144, - 3133, 3134, 3144, 3144, 3134, 3145, - 3146, 3147, 3157, 3157, 3147, 3158, - 3147, 3148, 3158, 3158, 3148, 3159, - 3148, 3149, 3159, 3159, 3149, 3160, - 3149, 3150, 3160, 3160, 3150, 3161, - 3150, 3151, 3161, 3161, 3151, 3162, - 3151, 3152, 3162, 3162, 3152, 3163, - 3152, 3153, 3163, 3163, 3153, 3164, - 3153, 3154, 3164, 3164, 3154, 3165, - 3154, 3155, 3165, 3165, 3155, 3166, - 3155, 3156, 3166, 3166, 3156, 3167, - 3157, 3158, 3168, 3168, 3158, 3169, - 3158, 3159, 3169, 3169, 3159, 3170, - 3159, 3160, 3170, 3170, 3160, 3171, - 3160, 3161, 3171, 3171, 3161, 3172, - 3161, 3162, 3172, 3172, 3162, 3173, - 3162, 3163, 3173, 3173, 3163, 3174, - 3163, 3164, 3174, 3174, 3164, 3175, - 3164, 3165, 3175, 3175, 3165, 3176, - 3165, 3166, 3176, 3176, 3166, 3177, - 3166, 3167, 3177, 3177, 3167, 3178, - 3168, 3169, 3179, 3179, 3169, 3180, - 3169, 3170, 3180, 3180, 3170, 3181, - 3170, 3171, 3181, 3181, 3171, 3182, - 3171, 3172, 3182, 3182, 3172, 3183, - 3172, 3173, 3183, 3183, 3173, 3184, - 3173, 3174, 3184, 3184, 3174, 3185, - 3174, 3175, 3185, 3185, 3175, 3186, - 3175, 3176, 3186, 3186, 3176, 3187, - 3176, 3177, 3187, 3187, 3177, 3188, - 3177, 3178, 3188, 3188, 3178, 3189, - 3179, 3180, 3190, 3190, 3180, 3191, - 3180, 3181, 3191, 3191, 3181, 3192, - 3181, 3182, 3192, 3192, 3182, 3193, - 3182, 3183, 3193, 3193, 3183, 3194, - 3183, 3184, 3194, 3194, 3184, 3195, - 3184, 3185, 3195, 3195, 3185, 3196, - 3185, 3186, 3196, 3196, 3186, 3197, - 3186, 3187, 3197, 3197, 3187, 3198, - 3187, 3188, 3198, 3198, 3188, 3199, - 3188, 3189, 3199, 3199, 3189, 3200, - 3190, 3191, 3201, 3201, 3191, 3202, - 3191, 3192, 3202, 3202, 3192, 3203, - 3192, 3193, 3203, 3203, 3193, 3204, - 3193, 3194, 3204, 3204, 3194, 3205, - 3194, 3195, 3205, 3205, 3195, 3206, - 3195, 3196, 3206, 3206, 3196, 3207, - 3196, 3197, 3207, 3207, 3197, 3208, - 3197, 3198, 3208, 3208, 3198, 3209, - 3198, 3199, 3209, 3209, 3199, 3210, - 3199, 3200, 3210, 3210, 3200, 3211, - 3201, 3202, 3212, 3212, 3202, 3213, - 3202, 3203, 3213, 3213, 3203, 3214, - 3203, 3204, 3214, 3214, 3204, 3215, - 3204, 3205, 3215, 3215, 3205, 3216, - 3205, 3206, 3216, 3216, 3206, 3217, - 3206, 3207, 3217, 3217, 3207, 3218, - 3207, 3208, 3218, 3218, 3208, 3219, - 3208, 3209, 3219, 3219, 3209, 3220, - 3209, 3210, 3220, 3220, 3210, 3221, - 3210, 3211, 3221, 3221, 3211, 3222, - 3212, 3213, 3223, 3223, 3213, 3224, - 3213, 3214, 3224, 3224, 3214, 3225, - 3214, 3215, 3225, 3225, 3215, 3226, - 3215, 3216, 3226, 3226, 3216, 3227, - 3216, 3217, 3227, 3227, 3217, 3228, - 3217, 3218, 3228, 3228, 3218, 3229, - 3218, 3219, 3229, 3229, 3219, 3230, - 3219, 3220, 3230, 3230, 3220, 3231, - 3220, 3221, 3231, 3231, 3221, 3232, - 3221, 3222, 3232, 3232, 3222, 3233, - 3223, 3224, 3234, 3234, 3224, 3235, - 3224, 3225, 3235, 3235, 3225, 3236, - 3225, 3226, 3236, 3236, 3226, 3237, - 3226, 3227, 3237, 3237, 3227, 3238, - 3227, 3228, 3238, 3238, 3228, 3239, - 3228, 3229, 3239, 3239, 3229, 3240, - 3229, 3230, 3240, 3240, 3230, 3241, - 3230, 3231, 3241, 3241, 3231, 3242, - 3231, 3232, 3242, 3242, 3232, 3243, - 3232, 3233, 3243, 3243, 3233, 3244, - 3234, 3235, 3245, 3245, 3235, 3246, - 3235, 3236, 3246, 3246, 3236, 3247, - 3236, 3237, 3247, 3247, 3237, 3248, - 3237, 3238, 3248, 3248, 3238, 3249, - 3238, 3239, 3249, 3249, 3239, 3250, - 3239, 3240, 3250, 3250, 3240, 3251, - 3240, 3241, 3251, 3251, 3241, 3252, - 3241, 3242, 3252, 3252, 3242, 3253, - 3242, 3243, 3253, 3253, 3243, 3254, - 3243, 3244, 3254, 3254, 3244, 3255, - 3245, 3246, 3256, 3256, 3246, 3257, - 3246, 3247, 3257, 3257, 3247, 3258, - 3247, 3248, 3258, 3258, 3248, 3259, - 3248, 3249, 3259, 3259, 3249, 3260, - 3249, 3250, 3260, 3260, 3250, 3261, - 3250, 3251, 3261, 3261, 3251, 3262, - 3251, 3252, 3262, 3262, 3252, 3263, - 3252, 3253, 3263, 3263, 3253, 3264, - 3253, 3254, 3264, 3264, 3254, 3265, - 3254, 3255, 3265, 3265, 3255, 3266, - 3267, 3268, 3278, 3278, 3268, 3279, - 3268, 3269, 3279, 3279, 3269, 3280, - 3269, 3270, 3280, 3280, 3270, 3281, - 3270, 3271, 3281, 3281, 3271, 3282, - 3271, 3272, 3282, 3282, 3272, 3283, - 3272, 3273, 3283, 3283, 3273, 3284, - 3273, 3274, 3284, 3284, 3274, 3285, - 3274, 3275, 3285, 3285, 3275, 3286, - 3275, 3276, 3286, 3286, 3276, 3287, - 3276, 3277, 3287, 3287, 3277, 3288, - 3278, 3279, 3289, 3289, 3279, 3290, - 3279, 3280, 3290, 3290, 3280, 3291, - 3280, 3281, 3291, 3291, 3281, 3292, - 3281, 3282, 3292, 3292, 3282, 3293, - 3282, 3283, 3293, 3293, 3283, 3294, - 3283, 3284, 3294, 3294, 3284, 3295, - 3284, 3285, 3295, 3295, 3285, 3296, - 3285, 3286, 3296, 3296, 3286, 3297, - 3286, 3287, 3297, 3297, 3287, 3298, - 3287, 3288, 3298, 3298, 3288, 3299, - 3289, 3290, 3300, 3300, 3290, 3301, - 3290, 3291, 3301, 3301, 3291, 3302, - 3291, 3292, 3302, 3302, 3292, 3303, - 3292, 3293, 3303, 3303, 3293, 3304, - 3293, 3294, 3304, 3304, 3294, 3305, - 3294, 3295, 3305, 3305, 3295, 3306, - 3295, 3296, 3306, 3306, 3296, 3307, - 3296, 3297, 3307, 3307, 3297, 3308, - 3297, 3298, 3308, 3308, 3298, 3309, - 3298, 3299, 3309, 3309, 3299, 3310, - 3300, 3301, 3311, 3311, 3301, 3312, - 3301, 3302, 3312, 3312, 3302, 3313, - 3302, 3303, 3313, 3313, 3303, 3314, - 3303, 3304, 3314, 3314, 3304, 3315, - 3304, 3305, 3315, 3315, 3305, 3316, - 3305, 3306, 3316, 3316, 3306, 3317, - 3306, 3307, 3317, 3317, 3307, 3318, - 3307, 3308, 3318, 3318, 3308, 3319, - 3308, 3309, 3319, 3319, 3309, 3320, - 3309, 3310, 3320, 3320, 3310, 3321, - 3311, 3312, 3322, 3322, 3312, 3323, - 3312, 3313, 3323, 3323, 3313, 3324, - 3313, 3314, 3324, 3324, 3314, 3325, - 3314, 3315, 3325, 3325, 3315, 3326, - 3315, 3316, 3326, 3326, 3316, 3327, - 3316, 3317, 3327, 3327, 3317, 3328, - 3317, 3318, 3328, 3328, 3318, 3329, - 3318, 3319, 3329, 3329, 3319, 3330, - 3319, 3320, 3330, 3330, 3320, 3331, - 3320, 3321, 3331, 3331, 3321, 3332, - 3322, 3323, 3333, 3333, 3323, 3334, - 3323, 3324, 3334, 3334, 3324, 3335, - 3324, 3325, 3335, 3335, 3325, 3336, - 3325, 3326, 3336, 3336, 3326, 3337, - 3326, 3327, 3337, 3337, 3327, 3338, - 3327, 3328, 3338, 3338, 3328, 3339, - 3328, 3329, 3339, 3339, 3329, 3340, - 3329, 3330, 3340, 3340, 3330, 3341, - 3330, 3331, 3341, 3341, 3331, 3342, - 3331, 3332, 3342, 3342, 3332, 3343, - 3333, 3334, 3344, 3344, 3334, 3345, - 3334, 3335, 3345, 3345, 3335, 3346, - 3335, 3336, 3346, 3346, 3336, 3347, - 3336, 3337, 3347, 3347, 3337, 3348, - 3337, 3338, 3348, 3348, 3338, 3349, - 3338, 3339, 3349, 3349, 3339, 3350, - 3339, 3340, 3350, 3350, 3340, 3351, - 3340, 3341, 3351, 3351, 3341, 3352, - 3341, 3342, 3352, 3352, 3342, 3353, - 3342, 3343, 3353, 3353, 3343, 3354, - 3344, 3345, 3355, 3355, 3345, 3356, - 3345, 3346, 3356, 3356, 3346, 3357, - 3346, 3347, 3357, 3357, 3347, 3358, - 3347, 3348, 3358, 3358, 3348, 3359, - 3348, 3349, 3359, 3359, 3349, 3360, - 3349, 3350, 3360, 3360, 3350, 3361, - 3350, 3351, 3361, 3361, 3351, 3362, - 3351, 3352, 3362, 3362, 3352, 3363, - 3352, 3353, 3363, 3363, 3353, 3364, - 3353, 3354, 3364, 3364, 3354, 3365, - 3355, 3356, 3366, 3366, 3356, 3367, - 3356, 3357, 3367, 3367, 3357, 3368, - 3357, 3358, 3368, 3368, 3358, 3369, - 3358, 3359, 3369, 3369, 3359, 3370, - 3359, 3360, 3370, 3370, 3360, 3371, - 3360, 3361, 3371, 3371, 3361, 3372, - 3361, 3362, 3372, 3372, 3362, 3373, - 3362, 3363, 3373, 3373, 3363, 3374, - 3363, 3364, 3374, 3374, 3364, 3375, - 3364, 3365, 3375, 3375, 3365, 3376, - 3366, 3367, 3377, 3377, 3367, 3378, - 3367, 3368, 3378, 3378, 3368, 3379, - 3368, 3369, 3379, 3379, 3369, 3380, - 3369, 3370, 3380, 3380, 3370, 3381, - 3370, 3371, 3381, 3381, 3371, 3382, - 3371, 3372, 3382, 3382, 3372, 3383, - 3372, 3373, 3383, 3383, 3373, 3384, - 3373, 3374, 3384, 3384, 3374, 3385, - 3374, 3375, 3385, 3385, 3375, 3386, - 3375, 3376, 3386, 3386, 3376, 3387, - 3388, 3389, 3399, 3399, 3389, 3400, - 3389, 3390, 3400, 3400, 3390, 3401, - 3390, 3391, 3401, 3401, 3391, 3402, - 3391, 3392, 3402, 3402, 3392, 3403, - 3392, 3393, 3403, 3403, 3393, 3404, - 3393, 3394, 3404, 3404, 3394, 3405, - 3394, 3395, 3405, 3405, 3395, 3406, - 3395, 3396, 3406, 3406, 3396, 3407, - 3396, 3397, 3407, 3407, 3397, 3408, - 3397, 3398, 3408, 3408, 3398, 3409, - 3399, 3400, 3410, 3410, 3400, 3411, - 3400, 3401, 3411, 3411, 3401, 3412, - 3401, 3402, 3412, 3412, 3402, 3413, - 3402, 3403, 3413, 3413, 3403, 3414, - 3403, 3404, 3414, 3414, 3404, 3415, - 3404, 3405, 3415, 3415, 3405, 3416, - 3405, 3406, 3416, 3416, 3406, 3417, - 3406, 3407, 3417, 3417, 3407, 3418, - 3407, 3408, 3418, 3418, 3408, 3419, - 3408, 3409, 3419, 3419, 3409, 3420, - 3410, 3411, 3421, 3421, 3411, 3422, - 3411, 3412, 3422, 3422, 3412, 3423, - 3412, 3413, 3423, 3423, 3413, 3424, - 3413, 3414, 3424, 3424, 3414, 3425, - 3414, 3415, 3425, 3425, 3415, 3426, - 3415, 3416, 3426, 3426, 3416, 3427, - 3416, 3417, 3427, 3427, 3417, 3428, - 3417, 3418, 3428, 3428, 3418, 3429, - 3418, 3419, 3429, 3429, 3419, 3430, - 3419, 3420, 3430, 3430, 3420, 3431, - 3421, 3422, 3432, 3432, 3422, 3433, - 3422, 3423, 3433, 3433, 3423, 3434, - 3423, 3424, 3434, 3434, 3424, 3435, - 3424, 3425, 3435, 3435, 3425, 3436, - 3425, 3426, 3436, 3436, 3426, 3437, - 3426, 3427, 3437, 3437, 3427, 3438, - 3427, 3428, 3438, 3438, 3428, 3439, - 3428, 3429, 3439, 3439, 3429, 3440, - 3429, 3430, 3440, 3440, 3430, 3441, - 3430, 3431, 3441, 3441, 3431, 3442, - 3432, 3433, 3443, 3443, 3433, 3444, - 3433, 3434, 3444, 3444, 3434, 3445, - 3434, 3435, 3445, 3445, 3435, 3446, - 3435, 3436, 3446, 3446, 3436, 3447, - 3436, 3437, 3447, 3447, 3437, 3448, - 3437, 3438, 3448, 3448, 3438, 3449, - 3438, 3439, 3449, 3449, 3439, 3450, - 3439, 3440, 3450, 3450, 3440, 3451, - 3440, 3441, 3451, 3451, 3441, 3452, - 3441, 3442, 3452, 3452, 3442, 3453, - 3443, 3444, 3454, 3454, 3444, 3455, - 3444, 3445, 3455, 3455, 3445, 3456, - 3445, 3446, 3456, 3456, 3446, 3457, - 3446, 3447, 3457, 3457, 3447, 3458, - 3447, 3448, 3458, 3458, 3448, 3459, - 3448, 3449, 3459, 3459, 3449, 3460, - 3449, 3450, 3460, 3460, 3450, 3461, - 3450, 3451, 3461, 3461, 3451, 3462, - 3451, 3452, 3462, 3462, 3452, 3463, - 3452, 3453, 3463, 3463, 3453, 3464, - 3454, 3455, 3465, 3465, 3455, 3466, - 3455, 3456, 3466, 3466, 3456, 3467, - 3456, 3457, 3467, 3467, 3457, 3468, - 3457, 3458, 3468, 3468, 3458, 3469, - 3458, 3459, 3469, 3469, 3459, 3470, - 3459, 3460, 3470, 3470, 3460, 3471, - 3460, 3461, 3471, 3471, 3461, 3472, - 3461, 3462, 3472, 3472, 3462, 3473, - 3462, 3463, 3473, 3473, 3463, 3474, - 3463, 3464, 3474, 3474, 3464, 3475, - 3465, 3466, 3476, 3476, 3466, 3477, - 3466, 3467, 3477, 3477, 3467, 3478, - 3467, 3468, 3478, 3478, 3468, 3479, - 3468, 3469, 3479, 3479, 3469, 3480, - 3469, 3470, 3480, 3480, 3470, 3481, - 3470, 3471, 3481, 3481, 3471, 3482, - 3471, 3472, 3482, 3482, 3472, 3483, - 3472, 3473, 3483, 3483, 3473, 3484, - 3473, 3474, 3484, 3484, 3474, 3485, - 3474, 3475, 3485, 3485, 3475, 3486, - 3476, 3477, 3487, 3487, 3477, 3488, - 3477, 3478, 3488, 3488, 3478, 3489, - 3478, 3479, 3489, 3489, 3479, 3490, - 3479, 3480, 3490, 3490, 3480, 3491, - 3480, 3481, 3491, 3491, 3481, 3492, - 3481, 3482, 3492, 3492, 3482, 3493, - 3482, 3483, 3493, 3493, 3483, 3494, - 3483, 3484, 3494, 3494, 3484, 3495, - 3484, 3485, 3495, 3495, 3485, 3496, - 3485, 3486, 3496, 3496, 3486, 3497, - 3487, 3488, 3498, 3498, 3488, 3499, - 3488, 3489, 3499, 3499, 3489, 3500, - 3489, 3490, 3500, 3500, 3490, 3501, - 3490, 3491, 3501, 3501, 3491, 3502, - 3491, 3492, 3502, 3502, 3492, 3503, - 3492, 3493, 3503, 3503, 3493, 3504, - 3493, 3494, 3504, 3504, 3494, 3505, - 3494, 3495, 3505, 3505, 3495, 3506, - 3495, 3496, 3506, 3506, 3496, 3507, - 3496, 3497, 3507, 3507, 3497, 3508, - 3509, 3510, 3520, 3520, 3510, 3521, - 3510, 3511, 3521, 3521, 3511, 3522, - 3511, 3512, 3522, 3522, 3512, 3523, - 3512, 3513, 3523, 3523, 3513, 3524, - 3513, 3514, 3524, 3524, 3514, 3525, - 3514, 3515, 3525, 3525, 3515, 3526, - 3515, 3516, 3526, 3526, 3516, 3527, - 3516, 3517, 3527, 3527, 3517, 3528, - 3517, 3518, 3528, 3528, 3518, 3529, - 3518, 3519, 3529, 3529, 3519, 3530, - 3520, 3521, 3531, 3531, 3521, 3532, - 3521, 3522, 3532, 3532, 3522, 3533, - 3522, 3523, 3533, 3533, 3523, 3534, - 3523, 3524, 3534, 3534, 3524, 3535, - 3524, 3525, 3535, 3535, 3525, 3536, - 3525, 3526, 3536, 3536, 3526, 3537, - 3526, 3527, 3537, 3537, 3527, 3538, - 3527, 3528, 3538, 3538, 3528, 3539, - 3528, 3529, 3539, 3539, 3529, 3540, - 3529, 3530, 3540, 3540, 3530, 3541, - 3531, 3532, 3542, 3542, 3532, 3543, - 3532, 3533, 3543, 3543, 3533, 3544, - 3533, 3534, 3544, 3544, 3534, 3545, - 3534, 3535, 3545, 3545, 3535, 3546, - 3535, 3536, 3546, 3546, 3536, 3547, - 3536, 3537, 3547, 3547, 3537, 3548, - 3537, 3538, 3548, 3548, 3538, 3549, - 3538, 3539, 3549, 3549, 3539, 3550, - 3539, 3540, 3550, 3550, 3540, 3551, - 3540, 3541, 3551, 3551, 3541, 3552, - 3542, 3543, 3553, 3553, 3543, 3554, - 3543, 3544, 3554, 3554, 3544, 3555, - 3544, 3545, 3555, 3555, 3545, 3556, - 3545, 3546, 3556, 3556, 3546, 3557, - 3546, 3547, 3557, 3557, 3547, 3558, - 3547, 3548, 3558, 3558, 3548, 3559, - 3548, 3549, 3559, 3559, 3549, 3560, - 3549, 3550, 3560, 3560, 3550, 3561, - 3550, 3551, 3561, 3561, 3551, 3562, - 3551, 3552, 3562, 3562, 3552, 3563, - 3553, 3554, 3564, 3564, 3554, 3565, - 3554, 3555, 3565, 3565, 3555, 3566, - 3555, 3556, 3566, 3566, 3556, 3567, - 3556, 3557, 3567, 3567, 3557, 3568, - 3557, 3558, 3568, 3568, 3558, 3569, - 3558, 3559, 3569, 3569, 3559, 3570, - 3559, 3560, 3570, 3570, 3560, 3571, - 3560, 3561, 3571, 3571, 3561, 3572, - 3561, 3562, 3572, 3572, 3562, 3573, - 3562, 3563, 3573, 3573, 3563, 3574, - 3564, 3565, 3575, 3575, 3565, 3576, - 3565, 3566, 3576, 3576, 3566, 3577, - 3566, 3567, 3577, 3577, 3567, 3578, - 3567, 3568, 3578, 3578, 3568, 3579, - 3568, 3569, 3579, 3579, 3569, 3580, - 3569, 3570, 3580, 3580, 3570, 3581, - 3570, 3571, 3581, 3581, 3571, 3582, - 3571, 3572, 3582, 3582, 3572, 3583, - 3572, 3573, 3583, 3583, 3573, 3584, - 3573, 3574, 3584, 3584, 3574, 3585, - 3575, 3576, 3586, 3586, 3576, 3587, - 3576, 3577, 3587, 3587, 3577, 3588, - 3577, 3578, 3588, 3588, 3578, 3589, - 3578, 3579, 3589, 3589, 3579, 3590, - 3579, 3580, 3590, 3590, 3580, 3591, - 3580, 3581, 3591, 3591, 3581, 3592, - 3581, 3582, 3592, 3592, 3582, 3593, - 3582, 3583, 3593, 3593, 3583, 3594, - 3583, 3584, 3594, 3594, 3584, 3595, - 3584, 3585, 3595, 3595, 3585, 3596, - 3586, 3587, 3597, 3597, 3587, 3598, - 3587, 3588, 3598, 3598, 3588, 3599, - 3588, 3589, 3599, 3599, 3589, 3600, - 3589, 3590, 3600, 3600, 3590, 3601, - 3590, 3591, 3601, 3601, 3591, 3602, - 3591, 3592, 3602, 3602, 3592, 3603, - 3592, 3593, 3603, 3603, 3593, 3604, - 3593, 3594, 3604, 3604, 3594, 3605, - 3594, 3595, 3605, 3605, 3595, 3606, - 3595, 3596, 3606, 3606, 3596, 3607, - 3597, 3598, 3608, 3608, 3598, 3609, - 3598, 3599, 3609, 3609, 3599, 3610, - 3599, 3600, 3610, 3610, 3600, 3611, - 3600, 3601, 3611, 3611, 3601, 3612, - 3601, 3602, 3612, 3612, 3602, 3613, - 3602, 3603, 3613, 3613, 3603, 3614, - 3603, 3604, 3614, 3614, 3604, 3615, - 3604, 3605, 3615, 3615, 3605, 3616, - 3605, 3606, 3616, 3616, 3606, 3617, - 3606, 3607, 3617, 3617, 3607, 3618, - 3608, 3609, 3619, 3619, 3609, 3620, - 3609, 3610, 3620, 3620, 3610, 3621, - 3610, 3611, 3621, 3621, 3611, 3622, - 3611, 3612, 3622, 3622, 3612, 3623, - 3612, 3613, 3623, 3623, 3613, 3624, - 3613, 3614, 3624, 3624, 3614, 3625, - 3614, 3615, 3625, 3625, 3615, 3626, - 3615, 3616, 3626, 3626, 3616, 3627, - 3616, 3617, 3627, 3627, 3617, 3628, - 3617, 3618, 3628, 3628, 3618, 3629, - 3630, 3631, 3641, 3641, 3631, 3642, - 3631, 3632, 3642, 3642, 3632, 3643, - 3632, 3633, 3643, 3643, 3633, 3644, - 3633, 3634, 3644, 3644, 3634, 3645, - 3634, 3635, 3645, 3645, 3635, 3646, - 3635, 3636, 3646, 3646, 3636, 3647, - 3636, 3637, 3647, 3647, 3637, 3648, - 3637, 3638, 3648, 3648, 3638, 3649, - 3638, 3639, 3649, 3649, 3639, 3650, - 3639, 3640, 3650, 3650, 3640, 3651, - 3641, 3642, 3652, 3652, 3642, 3653, - 3642, 3643, 3653, 3653, 3643, 3654, - 3643, 3644, 3654, 3654, 3644, 3655, - 3644, 3645, 3655, 3655, 3645, 3656, - 3645, 3646, 3656, 3656, 3646, 3657, - 3646, 3647, 3657, 3657, 3647, 3658, - 3647, 3648, 3658, 3658, 3648, 3659, - 3648, 3649, 3659, 3659, 3649, 3660, - 3649, 3650, 3660, 3660, 3650, 3661, - 3650, 3651, 3661, 3661, 3651, 3662, - 3652, 3653, 3663, 3663, 3653, 3664, - 3653, 3654, 3664, 3664, 3654, 3665, - 3654, 3655, 3665, 3665, 3655, 3666, - 3655, 3656, 3666, 3666, 3656, 3667, - 3656, 3657, 3667, 3667, 3657, 3668, - 3657, 3658, 3668, 3668, 3658, 3669, - 3658, 3659, 3669, 3669, 3659, 3670, - 3659, 3660, 3670, 3670, 3660, 3671, - 3660, 3661, 3671, 3671, 3661, 3672, - 3661, 3662, 3672, 3672, 3662, 3673, - 3663, 3664, 3674, 3674, 3664, 3675, - 3664, 3665, 3675, 3675, 3665, 3676, - 3665, 3666, 3676, 3676, 3666, 3677, - 3666, 3667, 3677, 3677, 3667, 3678, - 3667, 3668, 3678, 3678, 3668, 3679, - 3668, 3669, 3679, 3679, 3669, 3680, - 3669, 3670, 3680, 3680, 3670, 3681, - 3670, 3671, 3681, 3681, 3671, 3682, - 3671, 3672, 3682, 3682, 3672, 3683, - 3672, 3673, 3683, 3683, 3673, 3684, - 3674, 3675, 3685, 3685, 3675, 3686, - 3675, 3676, 3686, 3686, 3676, 3687, - 3676, 3677, 3687, 3687, 3677, 3688, - 3677, 3678, 3688, 3688, 3678, 3689, - 3678, 3679, 3689, 3689, 3679, 3690, - 3679, 3680, 3690, 3690, 3680, 3691, - 3680, 3681, 3691, 3691, 3681, 3692, - 3681, 3682, 3692, 3692, 3682, 3693, - 3682, 3683, 3693, 3693, 3683, 3694, - 3683, 3684, 3694, 3694, 3684, 3695, - 3685, 3686, 3696, 3696, 3686, 3697, - 3686, 3687, 3697, 3697, 3687, 3698, - 3687, 3688, 3698, 3698, 3688, 3699, - 3688, 3689, 3699, 3699, 3689, 3700, - 3689, 3690, 3700, 3700, 3690, 3701, - 3690, 3691, 3701, 3701, 3691, 3702, - 3691, 3692, 3702, 3702, 3692, 3703, - 3692, 3693, 3703, 3703, 3693, 3704, - 3693, 3694, 3704, 3704, 3694, 3705, - 3694, 3695, 3705, 3705, 3695, 3706, - 3696, 3697, 3707, 3707, 3697, 3708, - 3697, 3698, 3708, 3708, 3698, 3709, - 3698, 3699, 3709, 3709, 3699, 3710, - 3699, 3700, 3710, 3710, 3700, 3711, - 3700, 3701, 3711, 3711, 3701, 3712, - 3701, 3702, 3712, 3712, 3702, 3713, - 3702, 3703, 3713, 3713, 3703, 3714, - 3703, 3704, 3714, 3714, 3704, 3715, - 3704, 3705, 3715, 3715, 3705, 3716, - 3705, 3706, 3716, 3716, 3706, 3717, - 3707, 3708, 3718, 3718, 3708, 3719, - 3708, 3709, 3719, 3719, 3709, 3720, - 3709, 3710, 3720, 3720, 3710, 3721, - 3710, 3711, 3721, 3721, 3711, 3722, - 3711, 3712, 3722, 3722, 3712, 3723, - 3712, 3713, 3723, 3723, 3713, 3724, - 3713, 3714, 3724, 3724, 3714, 3725, - 3714, 3715, 3725, 3725, 3715, 3726, - 3715, 3716, 3726, 3726, 3716, 3727, - 3716, 3717, 3727, 3727, 3717, 3728, - 3718, 3719, 3729, 3729, 3719, 3730, - 3719, 3720, 3730, 3730, 3720, 3731, - 3720, 3721, 3731, 3731, 3721, 3732, - 3721, 3722, 3732, 3732, 3722, 3733, - 3722, 3723, 3733, 3733, 3723, 3734, - 3723, 3724, 3734, 3734, 3724, 3735, - 3724, 3725, 3735, 3735, 3725, 3736, - 3725, 3726, 3736, 3736, 3726, 3737, - 3726, 3727, 3737, 3737, 3727, 3738, - 3727, 3728, 3738, 3738, 3728, 3739, - 3729, 3730, 3740, 3740, 3730, 3741, - 3730, 3731, 3741, 3741, 3731, 3742, - 3731, 3732, 3742, 3742, 3732, 3743, - 3732, 3733, 3743, 3743, 3733, 3744, - 3733, 3734, 3744, 3744, 3734, 3745, - 3734, 3735, 3745, 3745, 3735, 3746, - 3735, 3736, 3746, 3746, 3736, 3747, - 3736, 3737, 3747, 3747, 3737, 3748, - 3737, 3738, 3748, 3748, 3738, 3749, - 3738, 3739, 3749, 3749, 3739, 3750, - 3751, 3752, 3762, 3762, 3752, 3763, - 3752, 3753, 3763, 3763, 3753, 3764, - 3753, 3754, 3764, 3764, 3754, 3765, - 3754, 3755, 3765, 3765, 3755, 3766, - 3755, 3756, 3766, 3766, 3756, 3767, - 3756, 3757, 3767, 3767, 3757, 3768, - 3757, 3758, 3768, 3768, 3758, 3769, - 3758, 3759, 3769, 3769, 3759, 3770, - 3759, 3760, 3770, 3770, 3760, 3771, - 3760, 3761, 3771, 3771, 3761, 3772, - 3762, 3763, 3773, 3773, 3763, 3774, - 3763, 3764, 3774, 3774, 3764, 3775, - 3764, 3765, 3775, 3775, 3765, 3776, - 3765, 3766, 3776, 3776, 3766, 3777, - 3766, 3767, 3777, 3777, 3767, 3778, - 3767, 3768, 3778, 3778, 3768, 3779, - 3768, 3769, 3779, 3779, 3769, 3780, - 3769, 3770, 3780, 3780, 3770, 3781, - 3770, 3771, 3781, 3781, 3771, 3782, - 3771, 3772, 3782, 3782, 3772, 3783, - 3773, 3774, 3784, 3784, 3774, 3785, - 3774, 3775, 3785, 3785, 3775, 3786, - 3775, 3776, 3786, 3786, 3776, 3787, - 3776, 3777, 3787, 3787, 3777, 3788, - 3777, 3778, 3788, 3788, 3778, 3789, - 3778, 3779, 3789, 3789, 3779, 3790, - 3779, 3780, 3790, 3790, 3780, 3791, - 3780, 3781, 3791, 3791, 3781, 3792, - 3781, 3782, 3792, 3792, 3782, 3793, - 3782, 3783, 3793, 3793, 3783, 3794, - 3784, 3785, 3795, 3795, 3785, 3796, - 3785, 3786, 3796, 3796, 3786, 3797, - 3786, 3787, 3797, 3797, 3787, 3798, - 3787, 3788, 3798, 3798, 3788, 3799, - 3788, 3789, 3799, 3799, 3789, 3800, - 3789, 3790, 3800, 3800, 3790, 3801, - 3790, 3791, 3801, 3801, 3791, 3802, - 3791, 3792, 3802, 3802, 3792, 3803, - 3792, 3793, 3803, 3803, 3793, 3804, - 3793, 3794, 3804, 3804, 3794, 3805, - 3795, 3796, 3806, 3806, 3796, 3807, - 3796, 3797, 3807, 3807, 3797, 3808, - 3797, 3798, 3808, 3808, 3798, 3809, - 3798, 3799, 3809, 3809, 3799, 3810, - 3799, 3800, 3810, 3810, 3800, 3811, - 3800, 3801, 3811, 3811, 3801, 3812, - 3801, 3802, 3812, 3812, 3802, 3813, - 3802, 3803, 3813, 3813, 3803, 3814, - 3803, 3804, 3814, 3814, 3804, 3815, - 3804, 3805, 3815, 3815, 3805, 3816, - 3806, 3807, 3817, 3817, 3807, 3818, - 3807, 3808, 3818, 3818, 3808, 3819, - 3808, 3809, 3819, 3819, 3809, 3820, - 3809, 3810, 3820, 3820, 3810, 3821, - 3810, 3811, 3821, 3821, 3811, 3822, - 3811, 3812, 3822, 3822, 3812, 3823, - 3812, 3813, 3823, 3823, 3813, 3824, - 3813, 3814, 3824, 3824, 3814, 3825, - 3814, 3815, 3825, 3825, 3815, 3826, - 3815, 3816, 3826, 3826, 3816, 3827, - 3817, 3818, 3828, 3828, 3818, 3829, - 3818, 3819, 3829, 3829, 3819, 3830, - 3819, 3820, 3830, 3830, 3820, 3831, - 3820, 3821, 3831, 3831, 3821, 3832, - 3821, 3822, 3832, 3832, 3822, 3833, - 3822, 3823, 3833, 3833, 3823, 3834, - 3823, 3824, 3834, 3834, 3824, 3835, - 3824, 3825, 3835, 3835, 3825, 3836, - 3825, 3826, 3836, 3836, 3826, 3837, - 3826, 3827, 3837, 3837, 3827, 3838, - 3828, 3829, 3839, 3839, 3829, 3840, - 3829, 3830, 3840, 3840, 3830, 3841, - 3830, 3831, 3841, 3841, 3831, 3842, - 3831, 3832, 3842, 3842, 3832, 3843, - 3832, 3833, 3843, 3843, 3833, 3844, - 3833, 3834, 3844, 3844, 3834, 3845, - 3834, 3835, 3845, 3845, 3835, 3846, - 3835, 3836, 3846, 3846, 3836, 3847, - 3836, 3837, 3847, 3847, 3837, 3848, - 3837, 3838, 3848, 3848, 3838, 3849, - 3839, 3840, 3850, 3850, 3840, 3851, - 3840, 3841, 3851, 3851, 3841, 3852, - 3841, 3842, 3852, 3852, 3842, 3853, - 3842, 3843, 3853, 3853, 3843, 3854, - 3843, 3844, 3854, 3854, 3844, 3855, - 3844, 3845, 3855, 3855, 3845, 3856, - 3845, 3846, 3856, 3856, 3846, 3857, - 3846, 3847, 3857, 3857, 3847, 3858, - 3847, 3848, 3858, 3858, 3848, 3859, - 3848, 3849, 3859, 3859, 3849, 3860, - 3850, 3851, 3861, 3861, 3851, 3862, - 3851, 3852, 3862, 3862, 3852, 3863, - 3852, 3853, 3863, 3863, 3853, 3864, - 3853, 3854, 3864, 3864, 3854, 3865, - 3854, 3855, 3865, 3865, 3855, 3866, - 3855, 3856, 3866, 3866, 3856, 3867, - 3856, 3857, 3867, 3867, 3857, 3868, - 3857, 3858, 3868, 3868, 3858, 3869, - 3858, 3859, 3869, 3869, 3859, 3870, - 3859, 3860, 3870, 3870, 3860, 3871, - }; - -}; diff --git a/projects/saf_r/.gitignore b/projects/saf_r/.gitignore deleted file mode 100644 index ff3dff30031efafa24269a9ac0ef93f64f63ded1..0000000000000000000000000000000000000000 --- a/projects/saf_r/.gitignore +++ /dev/null @@ -1 +0,0 @@ -saf_r \ No newline at end of file diff --git a/projects/saf_r/CMakeLists.txt b/projects/saf_r/CMakeLists.txt deleted file mode 100644 index ca315a2d294c792615ad7bc18ec55f132103c270..0000000000000000000000000000000000000000 --- a/projects/saf_r/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(saf_r) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(saf_r src/main.cpp "src/safrScene.hpp") - -# including headers of dependencies and the VkCV framework -target_include_directories(saf_r SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(saf_r vkcv vkcv_testing vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/saf_r/shaders/raytracing.comp b/projects/saf_r/shaders/raytracing.comp deleted file mode 100644 index a7c6b92a646e5c2f753946f74fe7ab78aea44fe6..0000000000000000000000000000000000000000 --- a/projects/saf_r/shaders/raytracing.comp +++ /dev/null @@ -1,292 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable - -// defines constants -const float pi = 3.1415926535897932384626433832795; -const float hitBias = 0.01; // used to offset hits to avoid self intersection - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -//structs of materials, lights, spheres and intersection for use in compute shader -struct Material { - vec3 albedo; - vec3 diffuseColor; - float specularExponent; - float refractiveIndex; -}; - -struct Light{ - vec3 position; - float intensity; -}; - -struct Sphere{ - vec3 center; - float radius; - Material material; -}; - -struct Intersection{ - bool hit; - vec3 pos; - vec3 N; - Material material; -}; - - -//incoming light data -layout(std430, binding = 0) coherent buffer lights{ - Light inLights[]; -}; - -// incoming sphere data -layout(std430, binding = 1) coherent buffer spheres{ - Sphere inSpheres[]; -}; - -// output store image as swapchain input -layout(set=0, binding = 2, rgba8) uniform image2D outImage; - -// incoming constants, because size of dynamic arrays cannot be computed on gpu -layout( push_constant ) uniform constants{ - mat4 viewToWorld; - int lightCount; - int sphereCount; -}; - -/* -* safrReflect computes the new reflected or refracted ray depending on the material -* @param vec3: raydirection vector -* @param vec3: normalvector on which should be reflected or refracted -* @param float: degree of refraction. In case of simple reflection it is 1.0 -* @return vec3: new ray that is the result of the reflection or refraction -*/ -vec3 safrReflect(vec3 V, vec3 N, float refractIndex){ - if(refractIndex != 1.0){ - // Snell's law - float cosi = - max(-1.f, min(1.f, dot(V,N))); - float etai = 1; - float etat = refractIndex; - vec3 n = N; - float swap; - if(cosi < 0){ - cosi = -cosi; - n = -N; - swap = etai; - etai = etat; - etat = swap; - } - float eta = etai / etat; - float k = 1 - eta * eta * (1 - cosi * cosi); - if(k < 0){ - return vec3(0,0,0); - } else { - return V * eta + n * (eta * cosi - sqrt(k)); - } - }else{ - return reflect(V, N); - } -} - -/* -* the rayIntersect function checks, if a ray from the raytracer passes through the sphere, hits the sphere or passes by the the sphere -* @param vec3: origin of ray -* @param vec3: direction of ray -* @param float: distance of the ray to the sphere (out because there are no references in shaders) -* @return bool: if ray interesects sphere or not (out because there are no references in shaders) -*/ - -bool rayIntersect(const vec3 origin, const vec3 dir, out float t0, const int id){ - vec3 L = inSpheres[id].center - origin; - float tca = dot(L, dir); - float d2 = dot(L, L) - tca * tca; - if (d2 > inSpheres[id].radius * inSpheres[id].radius){ - return false; - } - float thc = float(sqrt(inSpheres[id].radius * inSpheres[id].radius - d2)); - t0 = tca - thc; - float t1 = tca + thc; - if (t0 < 0) { - t0 = t1; - } - if (t0 < 0){ - return false; - } - return true; -} - -/* -* sceneIntersect iterates over whole scene (over every single object) to check for intersections -* @param vec3: Origin of the ray -* @param vec3: direction of the ray -* @return: Intersection struct with hit(bool) position, normal and material of sphere -*/ - -Intersection sceneIntersect(const vec3 rayOrigin, const vec3 rayDirection) { - //distance if spheres will be rendered - float min_d = 1.0 / 0.0; // lets start with something big - - Intersection intersection; - intersection.hit = false; - - //go over every sphere, check if sphere is hit by ray, save if hit is near enough into intersection struct - for (int i = 0; i < sphereCount; i++) { - float d; - if (rayIntersect(rayOrigin, rayDirection, d, i)) { - - intersection.hit = true; - - if(d < min_d){ - min_d = d; - intersection.pos = rayOrigin + rayDirection * d; - intersection.N = normalize(intersection.pos - inSpheres[i].center); - intersection.material = inSpheres[i].material; - } - } - } - - float checkerboard_dist = min_d; - if (abs(rayDirection.y)>1e-3) { - float d = -(rayOrigin.y + 4) / rayDirection.y; // the checkerboard plane has equation y = -4 - vec3 pt = rayOrigin + rayDirection * d; - if (d > 0 && abs(pt.x) < 10 && pt.z<-10 && pt.z>-30 && d < min_d) { - checkerboard_dist = d; - intersection.hit = true; - intersection.pos = pt; - intersection.N = vec3(0, 1, 0); - intersection.material = inSpheres[0].material; - } - } - return intersection; -} - -/* -* biasHitPosition computes the new hitposition with respect to the raydirection and a bias -* @param vec3: Hit Position -* @param vec3: direction of ray -* @param vec3: N(ormal) -* @return vec3: new Hit position depending on hitBias (used to offset hits to avoid self intersection) -*/ -vec3 biasHitPosition(vec3 hitPos, vec3 rayDirection, vec3 N){ - return hitPos + sign(dot(rayDirection, N)) * N * hitBias; -} - -/* -* computeHitLighting iterates over all lights to compute the color for every ray -* @param Intersection: struct with all the data of the intersection -* @param vec3: Raydirection -* @param float: material albedo of the intersection -* @return colour/shadows of sphere with illumination -*/ -vec3 computeHitLighting(Intersection intersection, vec3 V, out float outReflectionThroughput){ - - float lightIntensityDiffuse = 0; - float lightIntensitySpecular = 0; - - //iterate over every light source to compute sphere colours/shadows - for (int i = 0; i < lightCount; i++) { - - //compute normal + distance between light and intersection - vec3 L = normalize(inLights[i].position - intersection.pos); - float d = distance(inLights[i].position, intersection.pos); - - //compute shadows - vec3 shadowOrigin = biasHitPosition(intersection.pos, L, intersection.N); - Intersection shadowIntersection = sceneIntersect(shadowOrigin, L); - bool isShadowed = false; - if(shadowIntersection.hit){ - isShadowed = distance(shadowIntersection.pos, shadowOrigin) < d; - } - if(isShadowed){ - continue; - } - - lightIntensityDiffuse += inLights[i].intensity * max(0.f, dot(L, intersection.N)); - lightIntensitySpecular += pow(max(0.f, dot(safrReflect(V, intersection.N, intersection.material.refractiveIndex), L)), intersection.material.specularExponent) * inLights[i].intensity; - } - - outReflectionThroughput = intersection.material.albedo[2]; - return intersection.material.diffuseColor * lightIntensityDiffuse * intersection.material.albedo[0] + lightIntensitySpecular * intersection.material.albedo[1]; -} - -/* -* castRay throws a ray out of the initial origin with respect to the initial direction checks for intersection and refelction -* @param vec3: initial origin of ray -* @param vec3: initial direction of ray -* @param int: max depth o ray reflection -* @return s -*/ - -vec3 castRay(const vec3 initialOrigin, const vec3 initialDirection, int max_depth) { - - vec3 skyColor = vec3(0.2, 0.7, 0.8); - vec3 rayOrigin = initialOrigin; - vec3 rayDirection = initialDirection; - - float reflectionThroughput = 1; - vec3 color = vec3(0); - - //iterate to max depth of reflections - for(int i = 0; i < max_depth; i++){ - - Intersection intersection = sceneIntersect(rayOrigin, rayDirection); - - vec3 hitColor; - float hitReflectionThroughput; - - if(intersection.hit){ - hitColor = computeHitLighting(intersection, rayDirection, hitReflectionThroughput); - }else{ - hitColor = skyColor; - } - - color += hitColor * reflectionThroughput; - reflectionThroughput *= hitReflectionThroughput; - - //if there is no intersection of a ray with a sphere, break out of the loop - if(!intersection.hit){ - break; - } - - //compute new direction and origin of the reflected ray - rayDirection = normalize(safrReflect(rayDirection, intersection.N, intersection.material.refractiveIndex)); - rayOrigin = biasHitPosition(intersection.pos, rayDirection, intersection.N); - } - - return color; -} - -/* -* computeDirection transforms the pixel coords to worldspace coords -* @param ivec2: pixel coordinates -* @return vec3: world coordinates -*/ -vec3 computeDirection(ivec2 coord){ - - ivec2 outImageRes = imageSize(outImage); - float fovDegree = 45; - float fov = fovDegree * pi / 180; - - vec2 uv = coord / vec2(outImageRes); - vec2 ndc = 2 * uv - 1; - - float tanFovHalf = tan(fov / 2.f); - float aspectRatio = outImageRes.x / float(outImageRes.y); - float x = ndc.x * tanFovHalf * aspectRatio; - float y = -ndc.y * tanFovHalf; - - vec3 directionViewSpace = normalize(vec3(x, y, 1)); - vec3 directionWorldSpace = mat3(viewToWorld) * directionViewSpace; - return directionWorldSpace; -} - -// the main function -void main(){ - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - int max_depth = 4; - vec3 direction = computeDirection(coord); - vec3 cameraPos = viewToWorld[3].xyz; - vec3 color = castRay(cameraPos, direction, max_depth); - - imageStore(outImage, coord, vec4(color, 0.f)); -} \ No newline at end of file diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp deleted file mode 100644 index 35b4737d9645f2ecd379fd8b41f72cf040173f4f..0000000000000000000000000000000000000000 --- a/projects/saf_r/src/main.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <vkcv/Buffer.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> - -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -#include <cmath> -#include <vector> -#include <cstring> -#include <GLFW/glfw3.h> - -#include "safrScene.hpp" - -void createQuadraticLightCluster(std::vector<safrScene::Light>& lights, int countPerDimension, float dimension, float height, float intensity) { - float distance = dimension/countPerDimension; - - for(int x = 0; x <= countPerDimension; x++) { - for (int z = 0; z <= countPerDimension; z++) { - lights.push_back(safrScene::Light(glm::vec3(x * distance, height, z * distance), - float (intensity/countPerDimension) / 10.f) // Divide by 10, because intensity is busting O.o - ); - } - } - -} - -int main(int argc, const char** argv) { - const std::string applicationName = "SAF_R"; - - //window creation - const int windowWidth = 800; - const int windowHeight = 600; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { "VK_KHR_swapchain" } - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - - std::string shaderPathCompute = "shaders/raytracing.comp"; - - //creating the shader programs - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram computeShaderProgram; - - compiler.compile(vkcv::ShaderStage::COMPUTE, shaderPathCompute, [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - computeShaderProgram.addShader(shaderStage, path); - }); - - vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - const vkcv::DescriptorBindings& computeDescriptorBindings = computeShaderProgram.getReflectedDescriptors().at(0); - - vkcv::DescriptorSetLayoutHandle computeDescriptorSetLayout = core.createDescriptorSetLayout(computeDescriptorBindings); - vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeDescriptorSetLayout); - - const std::vector<vkcv::VertexAttachment> computeVertexAttachments = computeShaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> computeBindings; - for (size_t i = 0; i < computeVertexAttachments.size(); i++) { - computeBindings.push_back(vkcv::createVertexBinding(i, { computeVertexAttachments[i] })); - } - const vkcv::VertexLayout computeLayout { computeBindings }; - - /* - * create the scene - */ - - //materials for the spheres - std::vector<safrScene::Material> materials; - safrScene::Material ivory(glm::vec4(0.6, 0.3, 0.1, 0.0), glm::vec3(0.4, 0.4, 0.3), 50., 1.0); - safrScene::Material red_rubber(glm::vec4(0.9, 0.1, 0.0, 0.0), glm::vec3(0.3, 0.1, 0.1), 10., 1.0); - safrScene::Material mirror( glm::vec4(0.0, 10.0, 0.8, 0.0), glm::vec3(1.0, 1.0, 1.0), 1425., 1.0); - safrScene::Material glass( glm::vec4(0.0, 10.0, 0.8, 0.0), glm::vec3(1.0, 1.0, 1.0), 1425., 1.5); - - materials.push_back(ivory); - materials.push_back(red_rubber); - materials.push_back(mirror); - - //spheres for the scene - std::vector<safrScene::Sphere> spheres; - spheres.push_back(safrScene::Sphere(glm::vec3(-3, 0, -16), 2, ivory)); - //spheres.push_back(safrScene::Sphere(glm::vec3(-1.0, -1.5, 12), 2, mirror)); - spheres.push_back(safrScene::Sphere(glm::vec3(-1.0, -1.5, -12), 2, glass)); - spheres.push_back(safrScene::Sphere(glm::vec3( 1.5, -0.5, -18), 3, red_rubber)); - spheres.push_back(safrScene::Sphere(glm::vec3( 7, 5, -18), 4, mirror)); - - //lights for the scene - std::vector<safrScene::Light> lights; - /* - lights.push_back(safrScene::Light(glm::vec3(-20, 20, 20), 1.5)); - lights.push_back(safrScene::Light(glm::vec3(30, 50, -25), 1.8)); - lights.push_back(safrScene::Light(glm::vec3(30, 20, 30), 1.7)); - */ - createQuadraticLightCluster(lights, 10, 2.5f, 20, 1.5f); - - vkcv::SamplerHandle sampler = vkcv::samplerLinear(core); - - //create Buffer for compute shader - vkcv::Buffer<safrScene::Light> lightsBuffer = vkcv::buffer<safrScene::Light>( - core, - vkcv::BufferType::STORAGE, - lights.size() - ); - lightsBuffer.fill(lights); - - vkcv::Buffer<safrScene::Sphere> sphereBuffer = vkcv::buffer<safrScene::Sphere>( - core, - vkcv::BufferType::STORAGE, - spheres.size() - ); - sphereBuffer.fill(spheres); - - vkcv::DescriptorWrites computeWrites; - computeWrites.writeStorageBuffer( - 0, lightsBuffer.getHandle() - ).writeStorageBuffer( - 1, sphereBuffer.getHandle() - ); - - core.writeDescriptorSet(computeDescriptorSet, computeWrites); - - auto safrIndexBuffer = vkcv::buffer<uint16_t>(core, vkcv::BufferType::INDEX, 3); - uint16_t indices[3] = { 0, 1, 2 }; - safrIndexBuffer.fill(&indices[0], sizeof(indices)); - - vkcv::PassHandle safrPass = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined } - ); - - if (!safrPass) { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - - vkcv::ComputePipelineHandle computePipeline = core.createComputePipeline( - vkcv::ComputePipelineConfig( - computeShaderProgram, - { computeDescriptorSetLayout } - ) - ); - - if (!computePipeline) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - //create the camera - vkcv::camera::CameraManager cameraManager(window); - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(0, 0, 2)); - - cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0.0f, 0.0f, 0.0f)); - cameraManager.getCamera(camHandle1).setCenter(glm::vec3(0.0f, 0.0f, -1.0f)); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - //adjust light position - /* - 639a53157e7d3936caf7c3e40379159cbcf4c89e - lights[0].position.x += std::cos(time * 3.0f) * 2.5f; - lights[1].position.z += std::cos(time * 2.5f) * 3.0f; - lights[2].position.y += std::cos(time * 1.5f) * 4.0f; - lightsBuffer.fill(lights); - */ - - spheres[0].center.y += std::cos(t * 0.5f * 3.141f) * 0.25f; - spheres[1].center.x += std::cos(t * 2.f) * 0.25f; - spheres[1].center.z += std::cos(t * 2.f + 0.5f * 3.141f) * 0.25f; - sphereBuffer.fill(spheres); - - //update camera - cameraManager.update(dt); - glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - glm::mat4 proj = cameraManager.getActiveCamera().getProjection(); - - //create pushconstants for render - vkcv::PushConstants pushConstants(sizeof(glm::mat4) * 2); - pushConstants.appendDrawcall(std::array<glm::mat4, 2>{ mvp, proj }); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - //configure the outImage for compute shader (render into the swapchain image) - computeWrites.writeStorageImage(2, swapchainInput); - core.writeDescriptorSet(computeDescriptorSet, computeWrites); - core.prepareImageForStorage (cmdStream, swapchainInput); - - //fill pushconstants for compute shader - struct RaytracingPushConstantData { - glm::mat4 viewToWorld; - int32_t lightCount; - int32_t sphereCount; - }; - - RaytracingPushConstantData raytracingPushData; - raytracingPushData.lightCount = lights.size(); - raytracingPushData.sphereCount = spheres.size(); - raytracingPushData.viewToWorld = glm::inverse(cameraManager.getActiveCamera().getView()); - - vkcv::PushConstants pushConstantsCompute = vkcv::pushConstants<RaytracingPushConstantData>(); - pushConstantsCompute.appendDrawcall(raytracingPushData); - - //dispatch compute shader - const auto computeDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(16, 16) - ); - - core.recordComputeDispatchToCmdStream(cmdStream, - computePipeline, - computeDispatchCount, - { vkcv::useDescriptorSet(0, computeDescriptorSet) }, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, lightsBuffer.getHandle()); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/saf_r/src/safrScene.hpp b/projects/saf_r/src/safrScene.hpp deleted file mode 100644 index fc149a7b6ba11fd832cf7ec1040d57c401bab87a..0000000000000000000000000000000000000000 --- a/projects/saf_r/src/safrScene.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <chrono> -#include <limits> -#include <cmath> -#include <vector> -#include <string.h> // memcpy(3) - -class safrScene { - -public: - - /* - * Light struct with a position and intensity of the light source - */ - struct Light { - Light(const glm::vec3& p, const float& i) : position(p), intensity(i) {} - glm::vec3 position; - float intensity; - }; - - /* - * Material struct with defuse color, albedo and specular component - */ - struct Material { - Material(const glm::vec4& a, const glm::vec3& color, const float& spec, const float& r) : albedo(a), diffuse_color(color), specular_exponent(spec), refractive_index(r) {} - Material() : albedo(1, 0, 0, 0), diffuse_color(), specular_exponent(), refractive_index(1) {} - glm::vec4 albedo; - alignas(16) glm::vec3 diffuse_color; - float specular_exponent; - float refractive_index; - }; - - /* - * the sphere is defined by it's center, the radius and the material - */ - struct Sphere { - glm::vec3 center; - float radius; - Material material; - - Sphere(const glm::vec3& c, const float& r, const Material& m) : center(c), radius(r), material(m) {} - - }; - - -}; \ No newline at end of file diff --git a/projects/sph/.gitignore b/projects/sph/.gitignore deleted file mode 100644 index 3968dc30067c92efde65779bc5eebecf167dfc75..0000000000000000000000000000000000000000 --- a/projects/sph/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sph \ No newline at end of file diff --git a/projects/sph/CMakeLists.txt b/projects/sph/CMakeLists.txt deleted file mode 100644 index 685004f7be9d8f4ef3e0409543dbb0f964d55e9c..0000000000000000000000000000000000000000 --- a/projects/sph/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(sph) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(sph - src/main.cpp - src/Particle.hpp - src/Particle.cpp - src/PipelineInit.hpp - src/PipelineInit.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(sph SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_testing_include} - ${vkcv_camera_include} - ${vkcv_shader_compiler_include} - ${vkcv_effects_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(sph - vkcv - vkcv_testing - vkcv_camera - vkcv_shader_compiler - vkcv_effects) diff --git a/projects/sph/shaders/flip.comp b/projects/sph/shaders/flip.comp deleted file mode 100644 index f5cd7bf3ea5ed8d04de970c816989230421c0b52..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/flip.comp +++ /dev/null @@ -1,53 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float padding; - vec3 velocity; - float density; - vec3 force; - float pressure; -}; - -layout(std430, binding = 1) readonly buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout(std430, binding = 0) writeonly buffer buffer_outParticle -{ - Particle outParticle[]; -}; - -layout( push_constant ) uniform constants{ - float h; - float mass; - float gasConstant; - float offset; - float gravity; - float viscosity; - float ABSORBTION; - float dt; - vec3 gravityDir; - float particleCount; -}; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if(id >= int(particleCount)) - { - return; - } - - outParticle[id].force = inParticle[id].force; - outParticle[id].density = inParticle[id].density; - outParticle[id].pressure = inParticle[id].pressure; - outParticle[id].position = inParticle[id].position; - outParticle[id].velocity = inParticle[id].velocity; -} diff --git a/projects/sph/shaders/force.comp b/projects/sph/shaders/force.comp deleted file mode 100644 index 694ddbdf7009d4e493a5f8dd8ba462e42d1e8b68..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/force.comp +++ /dev/null @@ -1,152 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -const float PI = 3.1415926535897932384626433832795; - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float padding; - vec3 velocity; - float density; - vec3 force; - float pressure; - -}; - -layout(std430, binding = 1) readonly buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout(std430, binding = 0) writeonly buffer buffer_outParticle -{ - Particle outParticle[]; -}; - -layout( push_constant ) uniform constants{ - float h; - float mass; - float gasConstant; - float offset; - float gravity; - float viscosity; - float ABSORBTION; - float dt; - vec3 gravityDir; - float particleCount; -}; - -float grad_spiky(float r) -{ - return -45.f / (PI * pow(h, 6)) * pow((h-r), 2); -} - -float laplacian(float r) -{ - return (45.f / (PI * pow(h,6)) * (h - r)); -} - -vec3 pressureForce = vec3(0, 0, 0); -vec3 viscosityForce = vec3(0, 0, 0); -vec3 externalForce = vec3(0, 0, 0); - -struct ParticleData -{ - vec3 position; - float density; - vec3 velocity; - float pressure; -}; - -shared ParticleData particle_data [256]; - -void main() { - uint id = gl_GlobalInvocationID.x; - - if (id >= int(particleCount)) { - particle_data[gl_LocalInvocationIndex].position = vec3(0.0f); - particle_data[gl_LocalInvocationIndex].density = 0.0f; - particle_data[gl_LocalInvocationIndex].velocity = vec3(0.0f); - particle_data[gl_LocalInvocationIndex].pressure = 0.0f; - } else { - particle_data[gl_LocalInvocationIndex].position = inParticle[id].position; - particle_data[gl_LocalInvocationIndex].density = inParticle[id].density; - particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity; - particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure; - } - - uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; - - memoryBarrierShared(); - barrier(); - - const float h6 = pow(h, 6); - externalForce = particle_data[gl_LocalInvocationIndex].density * gravity * vec3(-gravityDir.x,gravityDir.y,gravityDir.z); - - for(uint j = 1; j < group_size; j++) { - uint i = (gl_LocalInvocationIndex + j) % group_size; - - vec3 dir = particle_data[gl_LocalInvocationIndex].position - particle_data[i].position; - float dist = length(dir); - - if ((dist > 0.0f) && (dist <= h)) - { - const float h_dist = (h - dist); - - float laplacian = 45.f / (PI * h6) * h_dist; - float grad_spiky = -1.0f * laplacian * h_dist; - - pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + particle_data[i].pressure)/(2.f * particle_data[i].density) * grad_spiky * normalize(dir); - viscosityForce += mass * (particle_data[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/particle_data[i].density * laplacian; - } - } - - for(uint i = 0; i < index_offset; i++) - { - vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position; - float dist = length(dir); - - if ((dist > 0.0f) && (dist <= h)) - { - const float h_dist = (h - dist); - - float laplacian = 45.f / (PI * h6) * h_dist; - float grad_spiky = -1.0f * laplacian * h_dist; - - pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * grad_spiky * normalize(dir); - viscosityForce += mass * (inParticle[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/inParticle[i].density * laplacian; - } - } - - for(uint i = index_offset + group_size; i < int(particleCount); i++) - { - vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position; - float dist = length(dir); - - if ((dist > 0.0f) && (dist <= h)) - { - const float h_dist = (h - dist); - - float laplacian = 45.f / (PI * h6) * h_dist; - float grad_spiky = -1.0f * laplacian * h_dist; - - pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * grad_spiky * normalize(dir); - viscosityForce += mass * (inParticle[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/inParticle[i].density * laplacian; - } - } - - viscosityForce *= viscosity; - - if (id < int(particleCount)) { - outParticle[id].force = externalForce + pressureForce + viscosityForce; - outParticle[id].density = particle_data[gl_LocalInvocationIndex].density; - outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure; - outParticle[id].position = particle_data[gl_LocalInvocationIndex].position; - outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity; - } -} diff --git a/projects/sph/shaders/particleShading.inc b/projects/sph/shaders/particleShading.inc deleted file mode 100644 index b2d1832b9ccd6ba05a585b59bdfdedd4729e80f8..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/particleShading.inc +++ /dev/null @@ -1,6 +0,0 @@ -float circleFactor(vec2 triangleCoordinates){ - // percentage of distance from center to circle edge - float p = clamp((0.4 - length(triangleCoordinates)) / 0.4, 0, 1); - // remapping for nice falloff - return sqrt(p); -} \ No newline at end of file diff --git a/projects/sph/shaders/particle_params.inc b/projects/sph/shaders/particle_params.inc deleted file mode 100644 index e35cce13be1bc84f045da276fe46666d0b852984..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/particle_params.inc +++ /dev/null @@ -1,8 +0,0 @@ -#define h 0.4 -#define mass 0.15 -#define gasConstant 3000 -#define offset 1800 -#define gravity -1000 -#define viscosity 1500 -#define ABSORBTION 0.9 -#define dt 0.0005 diff --git a/projects/sph/shaders/pressure.comp b/projects/sph/shaders/pressure.comp deleted file mode 100644 index 8fa2e4762bddb3b9b28d8a3c184ceaaf7ab4421c..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/pressure.comp +++ /dev/null @@ -1,94 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -const float PI = 3.1415926535897932384626433832795; - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float padding; - vec3 velocity; - float density; - vec3 force; - float pressure; - -}; - -layout(std430, binding = 0) readonly buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout(std430, binding = 1) writeonly buffer buffer_outParticle -{ - Particle outParticle[]; -}; - -layout( push_constant ) uniform constants{ - float h; - float mass; - float gasConstant; - float offset; - float gravity; - float viscosity; - float ABSORBTION; - float dt; - vec3 gravityDir; - float particleCount; -}; - -float poly6(float r) -{ - return (315.f * pow((pow(h,2)-pow(r,2)), 3)/(64.f*PI*pow(h, 9))) * int(r<=h); -} - -float densitySum = 0.f; - -shared vec3 position_data [256]; - -void main() { - - uint id = gl_GlobalInvocationID.x; - - if (id >= int(particleCount)) { - position_data[gl_LocalInvocationIndex] = vec3(0.0f); - } else { - position_data[gl_LocalInvocationIndex] = inParticle[id].position; - } - - uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; - - memoryBarrierShared(); - barrier(); - - for(uint j = 1; j < group_size; j++) { - uint i = (gl_LocalInvocationIndex + j) % group_size; - - float dist = distance(position_data[gl_LocalInvocationIndex], position_data[i]); - densitySum += mass * poly6(dist); - } - - for(uint i = 0; i < index_offset; i++) - { - float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position); - densitySum += mass * poly6(dist); - } - - for(uint i = index_offset + group_size; i < int(particleCount); i++) - { - float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position); - densitySum += mass * poly6(dist); - } - - if (id < int(particleCount)) { - outParticle[id].density = max(densitySum, 0.0000001f); - outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant; - outParticle[id].position = position_data[gl_LocalInvocationIndex]; - outParticle[id].velocity = inParticle[id].velocity; - outParticle[id].force = inParticle[id].force; - } -} diff --git a/projects/sph/shaders/shader.vert b/projects/sph/shaders/shader.vert deleted file mode 100644 index f5531ffa4f26d3652e8e35971c16af6dda2e3b45..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/shader.vert +++ /dev/null @@ -1,49 +0,0 @@ -#version 460 core -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 particle; - -struct Particle -{ - vec3 position; - float padding; - vec3 velocity; - float density; - vec3 force; - float pressure; -}; - -layout(std430, binding = 2) readonly buffer buffer_inParticle1 -{ - Particle inParticle1[]; -}; - -layout(std430, binding = 3) readonly buffer buffer_inParticle2 -{ - Particle inParticle2[]; -}; - -layout( push_constant ) uniform constants{ - mat4 view; - mat4 projection; -}; - -layout(location = 0) out vec2 passTriangleCoordinates; -layout(location = 1) out vec3 passVelocity; - -void main() -{ - int id = gl_InstanceIndex; - passVelocity = inParticle1[id].velocity; - - // particle position in view space - vec4 positionView = view * vec4(inParticle1[id].position, 1); - // by adding the triangle position in view space the mesh is always camera facing - positionView.xyz += particle; - // multiply with projection matrix for final position - gl_Position = projection * positionView; - - // 0.01 corresponds to vertex position size in main - float normalizationDivider = 0.012; - passTriangleCoordinates = particle.xy / normalizationDivider; -} \ No newline at end of file diff --git a/projects/sph/shaders/shader_water.frag b/projects/sph/shaders/shader_water.frag deleted file mode 100644 index 2aee4ec692a2ada060a77389099b2c279e9c338c..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/shader_water.frag +++ /dev/null @@ -1,28 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "particleShading.inc" - -layout(location = 0) in vec2 passTriangleCoordinates; -layout(location = 1) in vec3 passVelocity; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform uColor { - vec4 color; -} Color; - -layout(set=0,binding=1) uniform uPosition{ - vec2 position; -} Position; - -void main() -{ - float p = length(passVelocity)/100.f; - outColor = vec3(0.f+p/3.f, 0.05f+p/2.f, 0.4f+p); - - // make the triangle look like a circle - outColor *= circleFactor(passTriangleCoordinates); - -} diff --git a/projects/sph/shaders/tonemapping.comp b/projects/sph/shaders/tonemapping.comp deleted file mode 100644 index 26f0232d66e3475afdd1266c0cc6288b47ed1c38..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/tonemapping.comp +++ /dev/null @@ -1,19 +0,0 @@ -#version 440 - -layout(set=0, binding=0, rgba16f) uniform image2D inImage; -layout(set=0, binding=1, rgba8) uniform image2D outImage; - - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){ - return; - } - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - vec3 linearColor = imageLoad(inImage, uv).rgb; - vec3 tonemapped = linearColor / (dot(linearColor, vec3(0.21, 0.71, 0.08)) + 1); // reinhard tonemapping - vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); - imageStore(outImage, uv, vec4(gammaCorrected, 0.f)); -} \ No newline at end of file diff --git a/projects/sph/shaders/updateData.comp b/projects/sph/shaders/updateData.comp deleted file mode 100644 index 3c2321b0d2fcfdd7e6691da2df7e7609af8eb6cf..0000000000000000000000000000000000000000 --- a/projects/sph/shaders/updateData.comp +++ /dev/null @@ -1,101 +0,0 @@ -#version 450 core -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 256) in; - -struct Particle -{ - vec3 position; - float padding; - vec3 velocity; - float density; - vec3 force; - float pressure; - -}; - -layout(std430, binding = 0) readonly buffer buffer_inParticle -{ - Particle inParticle[]; -}; - -layout(std430, binding = 1) writeonly buffer buffer_outParticle -{ - Particle outParticle[]; -}; - -layout( push_constant ) uniform constants{ - float h; - float mass; - float gasConstant; - float offset; - float gravity; - float viscosity; - float ABSORBTION; - float dt; - vec3 gravityDir; - float particleCount; -}; - -void main() { - - uint id = gl_GlobalInvocationID.x; - - if(id >= int(particleCount)) - { - return; - } - - vec3 accel = inParticle[id].force / inParticle[id].density; - vec3 vel_new = inParticle[id].velocity + (dt * accel); - - vec3 out_force = inParticle[id].force; - float out_density = inParticle[id].density; - float out_pressure = inParticle[id].pressure; - - vec3 pos_new = inParticle[id].position + (dt * vel_new); - - // Überprüfe Randbedingungen x - if (inParticle[id].position.x < -1.0) - { - vel_new = reflect(vel_new.xyz, vec3(1.f,0.f,0.f)) * ABSORBTION; - pos_new.x = -1.0 + 0.01f; - } - else if (inParticle[id].position.x > 1.0) - { - vel_new = reflect(vel_new,vec3(1.f,0.f,0.f)) * ABSORBTION; - pos_new.x = 1.0 - 0.01f; - } - - // Überprüfe Randbedingungen y - if (inParticle[id].position.y < -1.0) - { - vel_new = reflect(vel_new,vec3(0.f,1.f,0.f)) * ABSORBTION; - pos_new.y = -1.0 + 0.01f; - - } - else if (inParticle[id].position.y > 1.0) - { - vel_new = reflect(vel_new,vec3(0.f,1.f,0.f)) * ABSORBTION; - pos_new.y = 1.0 - 0.01f; - } - - // Überprüfe Randbedingungen z - if (inParticle[id].position.z < -1.0 ) - { - vel_new = reflect(vel_new,vec3(0.f,0.f,1.f)) * ABSORBTION; - pos_new.z = -1.0 + 0.01f; - } - else if (inParticle[id].position.z > 1.0 ) - { - vel_new = reflect(vel_new,vec3(0.f,0.f,1.f)) * ABSORBTION; - pos_new.z = 1.0 - 0.01f; - } - - outParticle[id].force = out_force; - outParticle[id].density = out_density; - outParticle[id].pressure = out_pressure; - outParticle[id].position = pos_new; - outParticle[id].velocity = vel_new; -} diff --git a/projects/sph/src/Particle.cpp b/projects/sph/src/Particle.cpp deleted file mode 100644 index 329236989b7cab502e7a4e1bb5aa27869bed53cb..0000000000000000000000000000000000000000 --- a/projects/sph/src/Particle.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -#include "Particle.hpp" - -Particle::Particle(glm::vec3 position, glm::vec3 velocity) -: m_position(position), - m_velocity(velocity) -{ - m_density = 0.f; - m_force = glm::vec3(0.f); - m_pressure = 0.f; -} - -const glm::vec3& Particle::getPosition()const{ - return m_position; -} - -void Particle::setPosition( const glm::vec3 pos ){ - m_position = pos; -} - -const glm::vec3& Particle::getVelocity()const{ - return m_velocity; -} - -void Particle::setVelocity( const glm::vec3 vel ){ - m_velocity = vel; -} - -const float& Particle::getDensity()const { - return m_density; -} - -const glm::vec3& Particle::getForce()const { - return m_force; -} - -const float& Particle::getPressure()const { - return m_pressure; -} \ No newline at end of file diff --git a/projects/sph/src/Particle.hpp b/projects/sph/src/Particle.hpp deleted file mode 100644 index 6c4ab50b74cc4544976318c23e36f4b91989ee66..0000000000000000000000000000000000000000 --- a/projects/sph/src/Particle.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include <glm/glm.hpp> - -class Particle { - -public: - Particle(glm::vec3 position, glm::vec3 velocity); - - const glm::vec3& getPosition()const; - - void setPosition( const glm::vec3 pos ); - - const glm::vec3& getVelocity()const; - - void setVelocity( const glm::vec3 vel ); - - const float& getDensity()const; - - const glm::vec3& getForce()const; - - const float& getPressure()const; - - - -private: - // all properties of the Particle - glm::vec3 m_position; - float m_padding1; - glm::vec3 m_velocity; - float m_density; - glm::vec3 m_force; - float m_pressure; -}; diff --git a/projects/sph/src/PipelineInit.cpp b/projects/sph/src/PipelineInit.cpp deleted file mode 100644 index e507f1edebf6e39fb65bf81dbd4cf4915602313b..0000000000000000000000000000000000000000 --- a/projects/sph/src/PipelineInit.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "PipelineInit.hpp" - -vkcv::DescriptorSetHandle PipelineInit::ComputePipelineInit(vkcv::Core *pCore, vkcv::ShaderStage shaderStage, std::filesystem::path includePath, - vkcv::ComputePipelineHandle &pipeline) { - vkcv::ShaderProgram shaderProgram; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(shaderStage, includePath, - [&](vkcv::ShaderStage shaderStage1, const std::filesystem::path& path1) {shaderProgram.addShader(shaderStage1, path1); - }); - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = pCore->createDescriptorSetLayout( - shaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle descriptorSet = pCore->createDescriptorSet(descriptorSetLayout); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = shaderProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> bindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - const vkcv::VertexLayout layout { bindings }; - - pipeline = pCore->createComputePipeline({ - shaderProgram, - { descriptorSetLayout } - }); - - return descriptorSet; -} \ No newline at end of file diff --git a/projects/sph/src/PipelineInit.hpp b/projects/sph/src/PipelineInit.hpp deleted file mode 100644 index 54979cfdaffb2aba0915f87552e75e6d2ad3a958..0000000000000000000000000000000000000000 --- a/projects/sph/src/PipelineInit.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include <vkcv/Core.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <fstream> - -class PipelineInit{ -public: - /** - * Helperfunction to initialize a compute Pipeline. Goal is to reduce repetitive code in main. - * @param pCore Pointer to core object - * @param shaderStage Type of shaderstage - currently only supports COMPUTE - * @param includePath filepath to shaderprogram - * @param pipeline handle of the pipeline that is to be initialized. This handle is replaced with the handle of the generated pipeline - * @return returns the descriptorset handle from the generated descriptorset of the reflected shader - */ - static vkcv::DescriptorSetHandle ComputePipelineInit(vkcv::Core *pCore, - vkcv::ShaderStage shaderStage, - std::filesystem::path includePath, - vkcv::ComputePipelineHandle& pipeline); -}; diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp deleted file mode 100644 index 043d135257ce63398ec34e5f6d47e4f4ffd6c61d..0000000000000000000000000000000000000000 --- a/projects/sph/src/main.cpp +++ /dev/null @@ -1,422 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <vkcv/Buffer.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> -#include <random> -#include <ctime> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/effects/BloomAndFlaresEffect.hpp> -#include "PipelineInit.hpp" -#include "Particle.hpp" - -int main(int argc, const char **argv) { - const std::string applicationName = "SPH"; - - // creating core object that will handle all vulkan objects - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - { VK_KHR_SWAPCHAIN_EXTENSION_NAME } - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 1280, 720, true); - vkcv::Window& window = core.getWindow(windowHandle); - - vkcv::camera::CameraManager cameraManager(window); - - auto particleIndexBuffer = vkcv::buffer<uint16_t>(core, vkcv::BufferType::INDEX, 3); - uint16_t indices[3] = {0, 1, 2}; - particleIndexBuffer.fill(&indices[0], sizeof(indices)); - - vk::Format colorFormat = vk::Format::eR16G16B16A16Sfloat; - vkcv::PassHandle particlePass = vkcv::passFormat(core, colorFormat); - - //rotation - float rotationx = 0; - float rotationy = 0; - - // params - float param_h = 0.20; - float param_mass = 0.03; - float param_gasConstant = 3500; - float param_offset = 200; - float param_gravity = -5000; - float param_viscosity = 10; - float param_ABSORBTION = 0.5; - float param_dt = 0.0005; - - if (!particlePass) - { - std::cout << "Error. Could not create renderpass. Exiting." << std::endl; - return EXIT_FAILURE; - } - vkcv::shader::GLSLCompiler compiler; - - // pressure shader --> computes the pressure for all particles - vkcv::ComputePipelineHandle pressurePipeline; - vkcv::DescriptorSetHandle pressureDescriptorSet = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE, - "shaders/pressure.comp", pressurePipeline); - // force shader --> computes the force that effects the particles - vkcv::ComputePipelineHandle forcePipeline; - vkcv::DescriptorSetHandle forceDescriptorSet = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE, - "shaders/force.comp", forcePipeline); - - // update data shader --> applies the force on all particles and updates their position - vkcv::ComputePipelineHandle updateDataPipeline; - vkcv::DescriptorSetHandle updateDataDescriptorSet = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE, - "shaders/updateData.comp", updateDataPipeline); - - // flip shader --> flips input and output buffer - vkcv::ComputePipelineHandle flipPipeline; - vkcv::DescriptorSetHandle flipDescriptorSet = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE, - "shaders/flip.comp", flipPipeline); - - // particle rendering shaders - vkcv::ShaderProgram particleShaderProgram{}; - compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/shader.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "shaders/shader_water.frag", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - particleShaderProgram.addShader(shaderStage, path); - }); - - // generating descriptorsets from shader reflection - vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout( - particleShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); - - vkcv::Buffer<glm::vec3> vertexBuffer = vkcv::buffer<glm::vec3>( - core, - vkcv::BufferType::VERTEX, - 3 - ); - const std::vector<vkcv::VertexAttachment> vertexAttachments = particleShaderProgram.getVertexAttachments(); - - const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::vertexBufferBinding(vertexBuffer.getHandle()) - }; - - std::vector<vkcv::VertexBinding> bindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - bindings.push_back(vkcv::createVertexBinding(i, {vertexAttachments[i]})); - } - - const vkcv::VertexLayout particleLayout { bindings }; - - // initializing graphics pipeline - vkcv::GraphicsPipelineConfig particlePipelineDefinition ( - particleShaderProgram, - particlePass, - {particleLayout}, - {descriptorSetLayout} - ); - - particlePipelineDefinition.setBlendMode(vkcv::BlendMode::Additive); - - const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0), - glm::vec3(0.012, 0.012, 0), - glm::vec3(0, -0.012, 0)}; - - vertexBuffer.fill(vertices); - - vkcv::GraphicsPipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition); - - vkcv::Buffer<glm::vec4> color = vkcv::buffer<glm::vec4>( - core, - vkcv::BufferType::UNIFORM, - 1 - ); - - vkcv::Buffer<glm::vec2> position = vkcv::buffer<glm::vec2>( - core, - vkcv::BufferType::UNIFORM, - 1 - ); - - // generating particles - int numberParticles = 20000; - std::vector<Particle> particles; - for (int i = 0; i < numberParticles; i++) { - const float lo = 0.6; - const float hi = 0.9; - const float vlo = 0; - const float vhi = 70; - float x = lo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(hi-lo))); - float y = lo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(hi-lo))); - float z = lo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(hi-lo))); - float vx = vlo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(vhi-vlo))); - float vy = vlo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(vhi-vlo))); - float vz = vlo + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(vhi-vlo))); - glm::vec3 pos = glm::vec3(x,y,z); - glm::vec3 vel = glm::vec3(vx,vy,vz); - //glm::vec3 vel = glm::vec3(0.0,0.0,0.0); - particles.push_back(Particle(pos, vel)); - } - - // creating and filling particle buffer - vkcv::Buffer<Particle> particleBuffer1 = vkcv::buffer<Particle>( - core, - vkcv::BufferType::STORAGE, - numberParticles - ); - - vkcv::Buffer<Particle> particleBuffer2 = vkcv::buffer<Particle>( - core, - vkcv::BufferType::STORAGE, - numberParticles - ); - - particleBuffer1.fill(particles); - particleBuffer2.fill(particles); - - vkcv::DescriptorWrites setWrites; - setWrites.writeUniformBuffer(0, color.getHandle()).writeUniformBuffer(1, position.getHandle()); - setWrites.writeStorageBuffer(2, particleBuffer1.getHandle()).writeStorageBuffer(3, particleBuffer2.getHandle()); - core.writeDescriptorSet(descriptorSet, setWrites); - - vkcv::DescriptorWrites computeWrites; - computeWrites.writeStorageBuffer( - 0, particleBuffer1.getHandle() - ).writeStorageBuffer( - 1, particleBuffer2.getHandle() - ); - - core.writeDescriptorSet(pressureDescriptorSet, computeWrites); - core.writeDescriptorSet(forceDescriptorSet, computeWrites); - core.writeDescriptorSet(updateDataDescriptorSet, computeWrites); - core.writeDescriptorSet(flipDescriptorSet, computeWrites); - - // error message if creation of one pipeline failed - if (!particlePipeline || !pressurePipeline || !forcePipeline || !updateDataPipeline || !flipPipeline) - { - std::cout << "Error. Could not create at least one pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::VertexData vertexData (vertexBufferBindings); - vertexData.setIndexBuffer(particleIndexBuffer.getHandle()); - vertexData.setCount(particleIndexBuffer.getCount()); - - auto pos = glm::vec2(0.f); - - vkcv::InstanceDrawcall drawcall (vertexData, numberParticles); - drawcall.useDescriptorSet(0, descriptorSet); - - glm::vec4 colorData = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setNearFar(0.1, 30); - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(0, 0, -2.5)); - - cameraManager.setActiveCamera(camHandle1); - - cameraManager.getCamera(camHandle1).setNearFar(0.1, 30); - cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0.0f, 0.0f, -2.5f)); - cameraManager.getCamera(camHandle1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f)); - - const auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); - - vkcv::ImageHandle colorBuffer = core.createImage( - colorFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - - vkcv::effects::BloomAndFlaresEffect bloomAndFlares (core); - bloomAndFlares.setUpsamplingLimit(3); - - //tone mapping shader & pipeline - vkcv::ComputePipelineHandle tonemappingPipe; - vkcv::DescriptorSetHandle tonemappingDescriptor = PipelineInit::ComputePipelineInit( - &core, - vkcv::ShaderStage::COMPUTE, - "shaders/tonemapping.comp", - tonemappingPipe - ); - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((core.getImageWidth(colorBuffer) != swapchainWidth) || - (core.getImageHeight(colorBuffer) != swapchainHeight)) { - colorBuffer = core.createImage( - colorFormat, - swapchainWidth, - swapchainHeight, - 1, false, true, true - ); - } - - color.fill(&colorData); - position.fill(&pos); - - cameraManager.update(dt); - - // split view and projection to allow for easy billboarding in shader - struct { - glm::mat4 view; - glm::mat4 projection; - } renderingMatrices; - - glm::vec3 gravityDir = glm::rotate(glm::mat4(1.0), glm::radians(rotationx), glm::vec3(0.f,0.f,1.f)) * glm::vec4(0.f,1.f,0.f,0.f); - gravityDir = glm::rotate(glm::mat4(1.0), glm::radians(rotationy), glm::vec3(0.f,1.f,0.f)) * glm::vec4(gravityDir,0.f); - - renderingMatrices.view = cameraManager.getActiveCamera().getView(); - renderingMatrices.view = glm::rotate(renderingMatrices.view, glm::radians(rotationx), glm::vec3(0.f, 0.f, 1.f)); - renderingMatrices.view = glm::rotate(renderingMatrices.view, glm::radians(rotationy), glm::vec3(0.f, 1.f, 0.f)); - renderingMatrices.projection = cameraManager.getActiveCamera().getProjection(); - - // keybindings rotation - if (glfwGetKey(window.getWindow(), GLFW_KEY_LEFT) == GLFW_PRESS) - rotationx += dt * 50; - if (glfwGetKey(window.getWindow(), GLFW_KEY_RIGHT) == GLFW_PRESS) - rotationx -= dt * 50; - - if (glfwGetKey(window.getWindow(), GLFW_KEY_UP) == GLFW_PRESS) - rotationy += dt * 50; - if (glfwGetKey(window.getWindow(), GLFW_KEY_DOWN) == GLFW_PRESS) - rotationy -= dt * 50; - - // keybindings params - if (glfwGetKey(window.getWindow(), GLFW_KEY_T) == GLFW_PRESS) - param_h += dt * 0.2; - if (glfwGetKey(window.getWindow(), GLFW_KEY_G) == GLFW_PRESS) - param_h -= dt * 0.2; - - if (glfwGetKey(window.getWindow(), GLFW_KEY_Y) == GLFW_PRESS) - param_mass += dt * 0.2; - if (glfwGetKey(window.getWindow(), GLFW_KEY_H) == GLFW_PRESS) - param_mass -= dt * 0.2; - - if (glfwGetKey(window.getWindow(), GLFW_KEY_U) == GLFW_PRESS) - param_gasConstant += dt * 1500.0; - if (glfwGetKey(window.getWindow(), GLFW_KEY_J) == GLFW_PRESS) - param_gasConstant -= dt * 1500.0; - - if (glfwGetKey(window.getWindow(), GLFW_KEY_I) == GLFW_PRESS) - param_offset += dt * 400.0; - if (glfwGetKey(window.getWindow(), GLFW_KEY_K) == GLFW_PRESS) - param_offset -= dt * 400.0; - - if (glfwGetKey(window.getWindow(), GLFW_KEY_O) == GLFW_PRESS) - param_viscosity = 50; - if (glfwGetKey(window.getWindow(), GLFW_KEY_L) == GLFW_PRESS) - param_viscosity = 1200; - - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - glm::vec4 pushData[3] = { - glm::vec4(param_h,param_mass,param_gasConstant,param_offset), - glm::vec4(param_gravity,param_viscosity,param_ABSORBTION,param_dt), - glm::vec4(gravityDir.x,gravityDir.y,gravityDir.z,(float)numberParticles) - }; - - std::cout << "h: " << param_h << " | mass: " << param_mass << " | gasConstant: " << param_gasConstant << " | offset: " << param_offset << " | viscosity: " << param_viscosity << std::endl; - - vkcv::PushConstants pushConstantsCompute (sizeof(pushData)); - pushConstantsCompute.appendDrawcall(pushData); - - const auto computeDispatchCount = vkcv::dispatchInvocations(numberParticles, 256); - - // computing pressure pipeline - core.recordComputeDispatchToCmdStream( - cmdStream, - pressurePipeline, - computeDispatchCount, - { vkcv::useDescriptorSet(0, pressureDescriptorSet) }, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle()); - - // computing force pipeline - core.recordComputeDispatchToCmdStream( - cmdStream, - forcePipeline, - computeDispatchCount, - { vkcv::useDescriptorSet(0, forceDescriptorSet) }, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle()); - - // computing update data pipeline - core.recordComputeDispatchToCmdStream( - cmdStream, - updateDataPipeline, - computeDispatchCount, - { vkcv::useDescriptorSet(0, updateDataDescriptorSet) }, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle()); - - // computing flip pipeline - core.recordComputeDispatchToCmdStream( - cmdStream, - flipPipeline, - computeDispatchCount, - { vkcv::useDescriptorSet(0, flipDescriptorSet) }, - pushConstantsCompute - ); - - core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle()); - core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle()); - - - // bloomAndFlares & tonemapping - vkcv::PushConstants pushConstantsDraw (sizeof(renderingMatrices)); - pushConstantsDraw.appendDrawcall(renderingMatrices); - - core.recordDrawcallsToCmdStream( - cmdStream, - particlePipeline, - pushConstantsDraw, - { drawcall }, - { colorBuffer }, - windowHandle - ); - - bloomAndFlares.recordEffect(cmdStream, colorBuffer, colorBuffer); - - core.prepareImageForStorage(cmdStream, colorBuffer); - core.prepareImageForStorage(cmdStream, swapchainInput); - - vkcv::DescriptorWrites tonemappingDescriptorWrites; - tonemappingDescriptorWrites.writeStorageImage( - 0, colorBuffer - ).writeStorageImage( - 1, swapchainInput - ); - - core.writeDescriptorSet(tonemappingDescriptor, tonemappingDescriptorWrites); - - const auto tonemappingDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(8, 8) - ); - - core.recordComputeDispatchToCmdStream( - cmdStream, - tonemappingPipe, - tonemappingDispatchCount, - { vkcv::useDescriptorSet(0, tonemappingDescriptor) }, - vkcv::PushConstants(0) - ); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - }); - - return 0; -} diff --git a/projects/voxelization/.gitignore b/projects/voxelization/.gitignore deleted file mode 100644 index f07a22d4e0641a9114e998212f38ca9cb83a9655..0000000000000000000000000000000000000000 --- a/projects/voxelization/.gitignore +++ /dev/null @@ -1 +0,0 @@ -voxelization \ No newline at end of file diff --git a/projects/voxelization/CMakeLists.txt b/projects/voxelization/CMakeLists.txt deleted file mode 100644 index 34178021a517485e54ef8dcafe0f170a834e5186..0000000000000000000000000000000000000000 --- a/projects/voxelization/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(voxelization) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(voxelization src/main.cpp) - -target_sources(voxelization PRIVATE - src/Voxelization.hpp - src/Voxelization.cpp - src/ShadowMapping.hpp - src/ShadowMapping.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(voxelization SYSTEM BEFORE PRIVATE - ${vkcv_include} - ${vkcv_includes} - ${vkcv_asset_loader_include} - ${vkcv_camera_include} - ${vkcv_shader_compiler_include} - ${vkcv_gui_include} - ${vkcv_upscaling_include} - ${vkcv_effects_include} - ${vkcv_algorithm_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(voxelization - vkcv - ${vkcv_libraries} - vkcv_asset_loader - ${vkcv_asset_loader_libraries} - vkcv_camera - vkcv_shader_compiler - vkcv_gui - vkcv_upscaling - vkcv_effects - vkcv_algorithm) diff --git a/projects/voxelization/assets/RadialLUT.png b/projects/voxelization/assets/RadialLUT.png deleted file mode 100644 index 8b7056cf2a35c4d41f142e52bbc48dd1a91e4758..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/RadialLUT.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70d59d4e9c1ce2a077ed60c19c8c4665bf0723c952612a2ca8ec32c55f9ec498 -size 900 diff --git a/projects/voxelization/assets/Sponza/Sponza.bin b/projects/voxelization/assets/Sponza/Sponza.bin deleted file mode 100644 index eb0523cb55746451c1b20f25fb4ecfed22ef6047..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Sponza.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232d9c216b72dc0ee6089bc070cf8a12cabecd6a00c1f04aea78ac361da53839 -size 10819832 diff --git a/projects/voxelization/assets/Sponza/Sponza.gltf b/projects/voxelization/assets/Sponza/Sponza.gltf deleted file mode 100644 index 18d697f622eab38c3b3089a56c1680ff4a443171..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Sponza.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:748597f56b7228dddbe4c5d1cb84a35d645941933faf89c4c0f81dd9b602291e -size 73667 diff --git a/projects/voxelization/assets/Sponza/Textures/Arch_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Arch_Diff.jpg deleted file mode 100644 index 95900bdf9c8d57666b92929109a6750dc04a548b..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Arch_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e8b68080eb4c5709536dfb7858d595d51d4bb725003e11b0f383acf76a7e05a3 -size 521947 diff --git a/projects/voxelization/assets/Sponza/Textures/Arch_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Arch_Norm.jpg deleted file mode 100644 index 28e407a7c96acc4fbc9e75c7c8d6399914d409e3..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Arch_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86defcb4c007b80b9d23bcc9fdccd994f6a68f710eb75f11396d92faa2fbe368 -size 206244 diff --git a/projects/voxelization/assets/Sponza/Textures/Arch_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Arch_Spec.jpg deleted file mode 100644 index d1e0df9e5b0613ee476440b7e86d23535d5f4d05..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Arch_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:259b6659cb2681e06ef04becd49298d379f2f25b2cc468acf0c2ade4d190637c -size 570081 diff --git a/projects/voxelization/assets/Sponza/Textures/Background_Albedo.png b/projects/voxelization/assets/Sponza/Textures/Background_Albedo.png deleted file mode 100644 index 668c3b6d389e9675bf8e482a51936fe1dff0c889..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Background_Albedo.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a64b98be19acc30b95d071fb9dd1f0eaaf066612a2c757b32f8b7487f4600e9 -size 1653594 diff --git a/projects/voxelization/assets/Sponza/Textures/Background_Normal.png b/projects/voxelization/assets/Sponza/Textures/Background_Normal.png deleted file mode 100644 index 6f03475bdcf3d26f1b152c30680998fbb6dec321..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Background_Normal.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e7fe693f80bbf4b543d3afc614390e498bb84664fd0251c3cfb4e99b4885a12 -size 1299002 diff --git a/projects/voxelization/assets/Sponza/Textures/Background_Roughness.png b/projects/voxelization/assets/Sponza/Textures/Background_Roughness.png deleted file mode 100644 index 1f47f6a071463d13bb0f719570e3c53c4a65c079..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Background_Roughness.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:15339be54f1f86593a48875dfde6947adf4ba49b3b945619ce3b4fbea64afbd1 -size 791544 diff --git a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Bricks_A_Diff.jpg deleted file mode 100644 index cff7cf6ceb272d99378ce4b7facd09ade9f7c61a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9330cf1d51c8f6924b6c9ce09f2dedb21a82e1c7406c37d49ce95beca40bb3be -size 564801 diff --git a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Bricks_A_Norm.jpg deleted file mode 100644 index f83f46eb02cbf045886b8867b2dac93321800bf5..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0821ec8dc8226fd5ac70f068e134d014a9952276a7100cc7f0660853471b39f6 -size 339486 diff --git a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Bricks_A_Spec.jpg deleted file mode 100644 index da82e3992c1cdac7b90f294809193f4227da08cf..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Bricks_A_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bee42826d56d3ff719c4908c11ef65584fbe19e08273862fde7ec1408e44ba25 -size 530384 diff --git a/projects/voxelization/assets/Sponza/Textures/Ceiling_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Ceiling_Diff.jpg deleted file mode 100644 index 20f8871aa9bb13d4c2ccc7a0aa9ddddcd226080b..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Ceiling_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5bbd0cbf2da7416d5620514ebb0c4837b0ccc841b649cf4070281aa333ff8520 -size 520162 diff --git a/projects/voxelization/assets/Sponza/Textures/Ceiling_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Ceiling_Norm.jpg deleted file mode 100644 index 8a8fba3de7e4b68e5d5a095cb30442fb30c53be6..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Ceiling_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e309f1e6310dc0bb85df0a5f3b139207876f067378796a7aa666b0bb169587ae -size 919134 diff --git a/projects/voxelization/assets/Sponza/Textures/Ceiling_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Ceiling_Spec.jpg deleted file mode 100644 index 59ec4fabc2df618dce40d73a1e71c23e780b0422..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Ceiling_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:81b21b9352f1fb9ccfeaf237f8547b985ddbf0cfd7ade7a4a8670b73a72b2cb5 -size 608687 diff --git a/projects/voxelization/assets/Sponza/Textures/Chain_Diff.png b/projects/voxelization/assets/Sponza/Textures/Chain_Diff.png deleted file mode 100644 index 9629f2f279c8b2d338724b96538f2858a9f3f4ff..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Chain_Diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6df943a0dcf535d9dfb009c2833e0c7dc21939cfe3a2c10316c552b3dc3441b -size 1077432 diff --git a/projects/voxelization/assets/Sponza/Textures/Chain_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Chain_Norm.jpg deleted file mode 100644 index 127484f4ff3aa31597262c8e675c9d1f4dc979f1..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Chain_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:763740af8d22f0bfc6a43bd46050ef24bb661833bcace92f1f3326b9d5d7dc16 -size 137384 diff --git a/projects/voxelization/assets/Sponza/Textures/Cloth1_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Cloth1_Norm.jpg deleted file mode 100644 index cd117615246364139418024db5474e3e29ccc40b..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Cloth1_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3af8848a1a952ad8cc83199bbda0c095f9ed136be839659aa668f72afac91508 -size 1034060 diff --git a/projects/voxelization/assets/Sponza/Textures/Cloth1_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Cloth1_Spec.jpg deleted file mode 100644 index e505337ce76a797c4b385c89c25f9486eccab9a8..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Cloth1_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21bb124f5b5d4d5e9c8d9773cd31dedfc41b30eb302af36e7257cf930152908e -size 486634 diff --git a/projects/voxelization/assets/Sponza/Textures/Cloth2_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Cloth2_Norm.jpg deleted file mode 100644 index 35885a182fc5cf119afbebbeb2cc060850970731..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Cloth2_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:231d919288db7c977fda3091549195c1bd5197e9e63c039e972da8764f5435c1 -size 844768 diff --git a/projects/voxelization/assets/Sponza/Textures/Cloth2_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Cloth2_Spec.jpg deleted file mode 100644 index 982536602c4633893fa19c27c0b0e08a8ea0aec8..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Cloth2_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8ad0e8a9ca6de602225a527361bc718881de8741bc48927e27259a8803e7fed7 -size 623144 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothBlue1_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothBlue1_Diff.jpg deleted file mode 100644 index ae58b3bb674bec1f07a3f7de7eb52c8b4c23f4be..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothBlue1_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:005b774a968c1f6af00e4bf97afd668a6a045126a94f524df722ba19edc77d61 -size 1151448 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff.jpg deleted file mode 100644 index e8597404fcae24e14967eb2220faa1d5cd4d8170..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:751606c94a5fe5bda3bf6709e7f6a74363bd7902bf2353d54e55ef3b50007487 -size 785678 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff_jpg.jpg b/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff_jpg.jpg deleted file mode 100644 index ae58b3bb674bec1f07a3f7de7eb52c8b4c23f4be..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothBlue2_Diff_jpg.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:005b774a968c1f6af00e4bf97afd668a6a045126a94f524df722ba19edc77d61 -size 1151448 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothGreen1_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothGreen1_Diff.jpg deleted file mode 100644 index 833de50475dc9d4db7c36e0447bd8e17a5de41f5..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothGreen1_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f55814430f289e89c7d675c3db925eee904fbc566ff83f4b49904de53138e98 -size 1044330 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothGreen2_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothGreen2_Diff.jpg deleted file mode 100644 index 63ca00ba7ca17e80054fdf35b87aad4227edadef..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothGreen2_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d5fd79619a52db0232edb2287f5f05c0124c304355e3b035a4e48c0871090bf -size 764529 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothRed1_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothRed1_Diff.jpg deleted file mode 100644 index 406d620bf21db33765c00f87f3750f73c8df2de0..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothRed1_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23c32277c33d8eac091cd73daf81561ebe3640eede49b037546ed5c244a01347 -size 1079152 diff --git a/projects/voxelization/assets/Sponza/Textures/ClothRed2_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/ClothRed2_Diff.jpg deleted file mode 100644 index f5b06c8dcee807f739981bfc061e4cd3d8f0a291..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/ClothRed2_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:88861c8c7f10517c1d7942f316aae3b74dc5b8ae2faa2021d9dfe9d2c09fb24f -size 780166 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_B_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Column_B_Diff.jpg deleted file mode 100644 index ba6158fe4718103e6f37ee0f1e482e4e5dfc25d8..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_B_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:170f6c637ebd71a101244eb4d80c3dcf7063caf89e42053d3114d8aeca755cdf -size 643517 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_B_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Column_B_Norm.jpg deleted file mode 100644 index af99619ce8ff2b71246c00a79d94999c89f40e2e..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_B_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46ffc9123ee3ad94b2595843b4446fd67dbf5a2f79dc1e3b4e637f5ea4578630 -size 652476 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_B_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Column_B_Spec.jpg deleted file mode 100644 index 52c8e41dbc885800512ccc8527932be0f6964c63..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_B_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:93d495e33d754c5723c910e322ac94108fc753b65af082a19be5252905aa741b -size 388462 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_C_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Column_C_Diff.jpg deleted file mode 100644 index 53c725db4dece66f1458bc93dfb95ab20f8927cb..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_C_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9edc7c1c73661658cd8ed7733728002d45fecd17cb37a962fb654ff1d8c1933d -size 665796 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_C_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Column_C_Norm.jpg deleted file mode 100644 index 9d2c5f3fe9792c825c50743e80969cb3bca660a9..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_C_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58942b73c8f209ab9cc6ea174375adfde9c1875cbfe093f993086a0ab6570724 -size 698410 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_C_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Column_C_Spec.jpg deleted file mode 100644 index cf4a888d7023a9d23248a68d6217e5e1317c9b46..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_C_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:06c6480e207ce64f9e7c08df3f7f21638da7da43f77682657f4c823acd8c81a5 -size 193077 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Column_Diff.jpg deleted file mode 100644 index f6e1fc5dfdbc52d8bf80bd736b6c7881f260b10d..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c39c9f304c2605be791b4c0a58cd0f8eb20de2dd6a4a4af893c4eb112d158353 -size 518310 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Column_Norm.jpg deleted file mode 100644 index 549b3a7e290e79a4275124ce339c2d7a6b308cb2..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d54c520da7e60e2a62630e9cf946faf139648a7ab831c4531272238e4ade8fa8 -size 557865 diff --git a/projects/voxelization/assets/Sponza/Textures/Column_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Column_Spec.jpg deleted file mode 100644 index 5c3770a5faebbe1e98df4b39367a87246b0161cc..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Column_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f06c93f8e9f90be44a2e78847e57acec82bd793f58f7be7f86b088150730b88 -size 260119 diff --git a/projects/voxelization/assets/Sponza/Textures/Detail_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Detail_Diff.jpg deleted file mode 100644 index 8ede3e8fff423456faf51cb1419261a33ab708d0..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Detail_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98e4c4a091fea684cd693f3ae7ebe83e491969b501b4cd6e1fdd6a3cc1fa5cab -size 321375 diff --git a/projects/voxelization/assets/Sponza/Textures/Detail_norm.jpg b/projects/voxelization/assets/Sponza/Textures/Detail_norm.jpg deleted file mode 100644 index 6dad5879bba40f4273658e28f6d7fa3e3d8a663b..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Detail_norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9552937c9fa0481a07dc66768958b4be382544add46d1d66a687af54c51ab6da -size 547553 diff --git a/projects/voxelization/assets/Sponza/Textures/Detail_spec.jpg b/projects/voxelization/assets/Sponza/Textures/Detail_spec.jpg deleted file mode 100644 index d3918da21cdc2bcb27db235749791c45b1fb88f4..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Detail_spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:967005ccfbf4d38f674df41aebb3e58ac1fdcd91f554ead7acfcc132372f8ec6 -size 551432 diff --git a/projects/voxelization/assets/Sponza/Textures/Fill_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Fill_Spec.jpg deleted file mode 100644 index b7dfccb5c93c5d215f3466b9352b6e77f4034555..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Fill_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5562f0e76ca213d72295e48b8a14a59ee1971f58a47f95e5c022a4e78371c5aa -size 12575 diff --git a/projects/voxelization/assets/Sponza/Textures/Flagpole_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Flagpole_Diff.jpg deleted file mode 100644 index 43e93c048438d4d57501c198f45d5888d5a478fd..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flagpole_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fbdb7bcced57a005b84b4c3bbf744bae6309804cca51dabd9237e03a72fbc505 -size 399027 diff --git a/projects/voxelization/assets/Sponza/Textures/Flagpole_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Flagpole_Norm.jpg deleted file mode 100644 index 8a8c2891f2c44d175806df7d1451dea97649154a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flagpole_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:62a52f200082c02a0fbfa25c0bc40ea7d105a21f10d5aa0ec9408c4f45523794 -size 772201 diff --git a/projects/voxelization/assets/Sponza/Textures/Flagpole_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Flagpole_Spec.jpg deleted file mode 100644 index 145dc9d42327723970227151f945048b34471287..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flagpole_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d939d2e8bf11c2cf375154129f861b982c786b83db79cb9fde1a2b94b46caf62 -size 682743 diff --git a/projects/voxelization/assets/Sponza/Textures/Floor_A_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Floor_A_Diff.jpg deleted file mode 100644 index d1c351ca22197a2556ff0acc08c73912f63fdac5..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Floor_A_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:34b464edddbd2295b0ee23fa7a7a440a19456888c586acdc47032f841b302abd -size 573157 diff --git a/projects/voxelization/assets/Sponza/Textures/Floor_A_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Floor_A_Norm.jpg deleted file mode 100644 index 0304c61dbae476fb226b151d44612fca91892e44..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Floor_A_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a2c2aeb87a490a9bd37a8aa912a00e5f5c13974879fcb4f4f0ef39b17c52a7a -size 718904 diff --git a/projects/voxelization/assets/Sponza/Textures/Floor_A_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Floor_A_Spec.jpg deleted file mode 100644 index 90621f970579c5c8e268be5d415cab1162cf5910..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Floor_A_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9158388312a76ba25a40d3b57978e1ace224882e53198a766494d98f9118aeba -size 313460 diff --git a/projects/voxelization/assets/Sponza/Textures/Flower_Diff.png b/projects/voxelization/assets/Sponza/Textures/Flower_Diff.png deleted file mode 100644 index 0f297bbb9581dddb4bc61f8e29c14537a3415736..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flower_Diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75328d1aac87f8539be2456e6a5392cef7c6d08476d75585eafcd334dbeee0c5 -size 1225157 diff --git a/projects/voxelization/assets/Sponza/Textures/Flower_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Flower_Norm.jpg deleted file mode 100644 index 23b8b1d0bc30d90e0dbf2964b7591e3a4c90c215..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flower_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:81ede4ce51045540817c1efb83dbb65a9a9701f1abd78fa130def51d227162fc -size 421442 diff --git a/projects/voxelization/assets/Sponza/Textures/Flower_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Flower_Spec.jpg deleted file mode 100644 index fc60f6df8ee0a01601294062d585377ec14f28f3..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Flower_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d81efcb42b3a044595ca984cb46d941b159064bddae9a43ed8d9582db68d6b47 -size 280745 diff --git a/projects/voxelization/assets/Sponza/Textures/Lion_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Lion_Diff.jpg deleted file mode 100644 index 51286b49a1eb9d1e52ad599f1d1a4abccc53d7f7..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Lion_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ea4f9bc86354d363ea8153df9b7593c3bd3da153c53b9624c1fd8a960cb3ebc -size 599959 diff --git a/projects/voxelization/assets/Sponza/Textures/Lion_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Lion_Norm.jpg deleted file mode 100644 index 49132519e6e14b0a0964575ad92c86f805500421..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Lion_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f296e43c0d4c92953d4899ea0c38e8af992ba471acc87feb10f08e29a94aaef6 -size 512035 diff --git a/projects/voxelization/assets/Sponza/Textures/Lion_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Lion_Spec.jpg deleted file mode 100644 index 3058c29c325e5768bc3189a8c61548d44d88db55..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Lion_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c26ae9523cfae7a062fd074f74e0ddbb61630772f9a2130489e1d6e4724c38b -size 281980 diff --git a/projects/voxelization/assets/Sponza/Textures/Roof_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Roof_Diff.jpg deleted file mode 100644 index 1e9b6f6f9a00a99b4563229f76997abf402bcc7f..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Roof_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dfa17f2dee2cd2d850585673d19d5cda477a63e21659b346d8730e80edd3b347 -size 822373 diff --git a/projects/voxelization/assets/Sponza/Textures/Roof_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Roof_Norm.jpg deleted file mode 100644 index 88ee02405bb090eed4ea2b658d0adcb93b1a8ed6..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Roof_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e5166a5fba339e44a9d197dedc168683971f8acb2156034248a80674cbba0dd5 -size 1607263 diff --git a/projects/voxelization/assets/Sponza/Textures/Roof_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Roof_Spec.jpg deleted file mode 100644 index dccdb78a2b439240d6cb3d79ce1694e53f83217f..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Roof_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e90e94cadf80528a3df3496035d3c77900eba24d88b1c1d31c9dce77990fc44 -size 872255 diff --git a/projects/voxelization/assets/Sponza/Textures/Shield_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Shield_Norm.jpg deleted file mode 100644 index da701b850fd9bb49714263dba7c0d2681808ad5a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Shield_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70d85bff3bc017177124942ae187db117ba2588e490746f440f2cef085852956 -size 357112 diff --git a/projects/voxelization/assets/Sponza/Textures/Shield_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Shield_Spec.jpg deleted file mode 100644 index c918da16e61180632dae222a622bd8d479ff9031..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Shield_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9cbd61fcb8047f1c21450eff05207b29d71824edd75483267b5fbc2f7b21378c -size 329124 diff --git a/projects/voxelization/assets/Sponza/Textures/Shield_diff.jpg b/projects/voxelization/assets/Sponza/Textures/Shield_diff.jpg deleted file mode 100644 index 90aa71962d62e0370f1d3550fc35781c54a466bf..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Shield_diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73a94a12fb0a9ab4c75e40996c9a2d49ac45ac18a8c8ae81d5ceb1c8ae52d6dc -size 362437 diff --git a/projects/voxelization/assets/Sponza/Textures/Thorn_Diff.png b/projects/voxelization/assets/Sponza/Textures/Thorn_Diff.png deleted file mode 100644 index cd52793a05b4f0827299d86c7446315ce67c1c68..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Thorn_Diff.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6fbdbf67d3501831ad3a4e2adbf3d27e4c3d13ba1d655e5861c3f39b5f899f65 -size 2427921 diff --git a/projects/voxelization/assets/Sponza/Textures/Thorn_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Thorn_Norm.jpg deleted file mode 100644 index d85686c7aa40b03a94d00fa86dcd1f41681f1e1f..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Thorn_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dc5bf5f3091b548f1dfe40410b1aa1e2e55d82e2d77ba57dbd1f92955a0d8ff8 -size 413837 diff --git a/projects/voxelization/assets/Sponza/Textures/Thorn_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Thorn_Spec.jpg deleted file mode 100644 index dc414f0ea13433f7fe9832f4a64d0514ae9a2239..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Thorn_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da2a0b308b4d6d57ffbcf4bb7509d4afe91156d5d86d0396e83d7cac883a4857 -size 668962 diff --git a/projects/voxelization/assets/Sponza/Textures/VaseRound_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/VaseRound_Diff.jpg deleted file mode 100644 index 74e6d243f6da2015398ef9a08de663c59f32c329..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/VaseRound_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:430758549ba2189d94f06abeaae092bfc0a1d8c22afc56f5caf3f99c5ee7407c -size 572245 diff --git a/projects/voxelization/assets/Sponza/Textures/VaseRound_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/VaseRound_Norm.jpg deleted file mode 100644 index 154b1fa17729990b54b368febb55a259b7a47292..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/VaseRound_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8af8fb0810bf3493242491da44f7ae14f7c0bfa6cbacea4be01f6f4261db4559 -size 618837 diff --git a/projects/voxelization/assets/Sponza/Textures/VaseRound_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/VaseRound_Spec.jpg deleted file mode 100644 index 97c19f41117e9a3aaec02885b236349c8ba9c6ca..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/VaseRound_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12e1f2ea3c2714a6ec455fa8e623a702e33ef95765ebd09f7874a68fa55fd104 -size 399963 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_Diff.jpg deleted file mode 100644 index 4d53ec1a796184e24893aff99f53652d08bd4f47..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1da7664b7b88ae58386a6e6b5eca2829537818061d704f002356d8fc483c1a28 -size 531156 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Diff.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Diff.jpg deleted file mode 100644 index 149a0f1c47e15ebfc2a9de474e8dda46ed3ab2de..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Diff.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f849f0510ca0df66ba1cba2380a6a1b481444d9e64b68da6b2ce202b54d9cec -size 302363 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Norm.jpg deleted file mode 100644 index bcdd65e4b718c0dc7e74f03aa50cac22f10febea..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b93291121303b5a24a488a3e29e0645a24bb471413cfd25c0917d306dff1d038 -size 208352 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Spec.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Spec.jpg deleted file mode 100644 index 8976a203dfe463d121d48e743b3ecb662ac52d09..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_Hanging_Spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c288a37ed8373d1132644873624b096a72ba81d03cda601e050a5de24ba13c39 -size 104626 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_Norm.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_Norm.jpg deleted file mode 100644 index de5758090ab8ab0aaa374110aa08df6c7f53d599..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_Norm.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:728dd0fe3b570103e51dbfcc1eac64ad09916a7a31603c62a4090a2f2afaa6f8 -size 876227 diff --git a/projects/voxelization/assets/Sponza/Textures/Vase_spec.jpg b/projects/voxelization/assets/Sponza/Textures/Vase_spec.jpg deleted file mode 100644 index 0cce3ebf638a3ca932bca8b28c31b8474f123349..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/Vase_spec.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb09708202859d08764601acc9c9ea3b5254b2c4fd39dcc6b6055768c77aee9b -size 370061 diff --git a/projects/voxelization/assets/Sponza/Textures/white.png b/projects/voxelization/assets/Sponza/Textures/white.png deleted file mode 100644 index 98e867371da9926f451d5754604bc97b3186296a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/Sponza/Textures/white.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e2ab2939dda535ad28779e41c20c98368f630f29c5824a0a5a430f47b3b6da12 -size 951 diff --git a/projects/voxelization/assets/lensDirt.jpg b/projects/voxelization/assets/lensDirt.jpg deleted file mode 100644 index f941567527fe92f23aa6955e15ba95dc46881dad..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/lensDirt.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95982351ecf3d4d129d17612b40a8092944a285c0bffdd74d4886dd8489695ca -size 107603 diff --git a/projects/voxelization/assets/shaders/brdf.inc b/projects/voxelization/assets/shaders/brdf.inc deleted file mode 100644 index 4cf334eaceedd18815ab928aed38d5f8d3f51c1e..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/brdf.inc +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef BRDF_INC -#define BRDF_INC - -const float pi = 3.1415; - -vec3 lambertBRDF(vec3 albedo){ - return albedo / pi; -} - -vec3 fresnelSchlick(float cosTheta, vec3 f0){ - return f0 + (vec3(1) - f0) * pow(1 - cosTheta, 5); -} - -float GGXDistribution(float r, float NoH){ - float r2 = r * r; - float denom = pi * pow(NoH * NoH * (r2 - 1) + 1, 2); - return r2 / max(denom, 0.00001); -} - -float GGXSmithShadowingPart(float r, float cosTheta){ - float nom = cosTheta * 2; - float r2 = r * r; - float denom = cosTheta + sqrt(r2 + (1 - r2) * cosTheta * cosTheta); - return nom / max(denom, 0.00001); -} - -float GGXSmithShadowing(float r, float NoV, float NoL){ - return GGXSmithShadowingPart(r, NoV) * GGXSmithShadowingPart(r, NoL); -} - -#endif // #ifndef BRDF_INC \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/depthPrepass.frag b/projects/voxelization/assets/shaders/depthPrepass.frag deleted file mode 100644 index 5e2f7a092ca300af40cc039608a44d080c28730f..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/depthPrepass.frag +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "perMeshResources.inc" - -layout(location = 0) in vec2 passUV; - -layout(location = 0) out vec4 outColor; // only used for alpha to coverage, not actually written to - -// coverage to alpha techniques explained in: https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f -void main() { - float alpha = texture(sampler2D(albedoTexture, textureSampler), passUV).a; - float alphaCutoff = 0.5; - - // scale alpha to one pixel width - alpha = (alpha - alphaCutoff) / max(fwidth(alpha), 0.0001) + 0.5; - - outColor.a = alpha; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/depthPrepass.vert b/projects/voxelization/assets/shaders/depthPrepass.vert deleted file mode 100644 index 4bb3500eb59214e30fce84862e181fd7e24b7340..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/depthPrepass.vert +++ /dev/null @@ -1,18 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -#extension GL_GOOGLE_include_directive : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec2 passUV; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passUV = inUV; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/depthToMoments.comp b/projects/voxelization/assets/shaders/depthToMoments.comp deleted file mode 100644 index 79e47cdef02143ed97d53e533f47e822db8c0f6f..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/depthToMoments.comp +++ /dev/null @@ -1,38 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#extension GL_ARB_texture_multisample : enable - -#include "shadowMapping.inc" - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -layout(set=0, binding=0) uniform texture2DMS srcTexture; -layout(set=0, binding=1) uniform sampler depthSampler; -layout(set=0, binding=2, rgba16) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - int msaaCount; -}; - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - - float z = 0; - for(int i = 0; i < msaaCount; i++){ - z += texelFetch(sampler2DMS(srcTexture, depthSampler), uv, i).r; - } - z /= msaaCount; - z = 2 * z - 1; // algorithm expects depth in range [-1:1] - - float z2 = z*z; - vec4 moments = vec4(z, z2, z2*z, z2*z2); - vec4 momentsQuantized = quantizeMoments(moments); - - imageStore(outImage, uv, momentsQuantized); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/lightInfo.inc b/projects/voxelization/assets/shaders/lightInfo.inc deleted file mode 100644 index a87f9ce7bebc1db1688dd20dd80608e99925755a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/lightInfo.inc +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef LIGHT_INFO_INC -#define LIGHT_INFO_INC - -struct LightInfo{ - vec3 L; - float padding; - vec3 sunColor; - float sunStrength; - mat4 lightMatrix; -}; - -#endif // #ifndef LIGHT_INFO_INC \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/luma.inc b/projects/voxelization/assets/shaders/luma.inc deleted file mode 100644 index 17b3b282830ab155ce62e9b1394c0985ceccecd9..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/luma.inc +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef LUMA_INC -#define LUMA_INC - -float computeLuma(vec3 c){ - return dot(c, vec3(0.21, 0.72, 0.07)); -} - -#endif // #ifndef LUMA_INC \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/msaa4XResolve.comp b/projects/voxelization/assets/shaders/msaa4XResolve.comp deleted file mode 100644 index 8bb1a946e3ba43f4e80f21f6bd730e020276f2d8..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/msaa4XResolve.comp +++ /dev/null @@ -1,83 +0,0 @@ -#version 450 -#extension GL_ARB_texture_multisample : enable -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) uniform texture2DMS srcTexture; -layout(set=0, binding=1) uniform sampler MSAASampler; -layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; - -#include "luma.inc" - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -vec3 tonemap(vec3 c){ - return c / (1 + computeLuma(c)); -} - -vec3 tonemapReverse(vec3 c){ - return c / (1 - computeLuma(c)); -} - -float reconstructionFilter(float d){ - // gauß filter, tuned so that distance of one has weight around 20% - float a = 1.6; - return exp(-a * d*d); -} - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 uv = ivec2(gl_GlobalInvocationID.xy); - - vec2 samplePositions[4] = { - vec2(0.375, 0.125), - vec2(0.875, 0.375), - vec2(0.125, 0.625), - vec2(0.625, 0.875)}; - - vec3 color = vec3(0); - float wTotal = 0; - - // four samples from main pixel - for(int i = 0; i < 4; i++){ - vec3 msaaSample = texelFetch(sampler2DMS(srcTexture, MSAASampler), uv, i).rgb; - float d = distance(vec2(0.5), samplePositions[i]); - float w = reconstructionFilter(d); - color += tonemap(msaaSample) * w; - wTotal += w; - } - - ivec2 neighbourOffsets[4] = { - ivec2( 1, 0), // right - ivec2(-1, 0), // left - ivec2( 0, 1), // top - ivec2( 0, -1) // bot - }; - - int neighbourSampleIndices[8] = { - 0, 2, // left samples of right neighbour - 1, 3, // right samples of left neighbour - 2, 3, // bot samples of top neighbour - 0, 1 // top samples of bot neighbour - }; - - // two additional samples from each neighbour - for(int neighbour = 0; neighbour < 4; neighbour++){ - for(int i = 0; i < 2; i++){ - int sampleIndex = neighbourSampleIndices[neighbour * 2 + i]; - ivec2 pixelOffset = neighbourOffsets[neighbour]; - ivec2 pixelUV = uv + pixelOffset; - vec3 msaaSample = texelFetch(sampler2DMS(srcTexture, MSAASampler), pixelUV, sampleIndex).rgb; - float d = distance(vec2(0.5), samplePositions[sampleIndex] + pixelOffset); - float w = reconstructionFilter(d); - color += tonemap(msaaSample) * w; - wTotal += w; - } - } - color /= wTotal; - color = tonemapReverse(color); - - imageStore(outImage, uv, vec4(color, 0.f)); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/perMeshResources.inc b/projects/voxelization/assets/shaders/perMeshResources.inc deleted file mode 100644 index b1523713cf2040f672f74be3f47f9bf43996c614..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/perMeshResources.inc +++ /dev/null @@ -1,4 +0,0 @@ -layout(set=1, binding=0) uniform texture2D albedoTexture; -layout(set=1, binding=1) uniform sampler textureSampler; -layout(set=1, binding=2) uniform texture2D normalTexture; -layout(set=1, binding=3) uniform texture2D specularTexture; \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/postEffects.comp b/projects/voxelization/assets/shaders/postEffects.comp deleted file mode 100644 index c0f9fe1a764bcdabac5501e2f82692c6f476e9e6..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/postEffects.comp +++ /dev/null @@ -1,149 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -#include "luma.inc" - -layout(set=0, binding=0) uniform texture2D inTexture; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2, rgba8) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - float time; -}; - -// from: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 ACESFilm(vec3 x) -{ - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0, 1); -} - -// From Dave Hoskins: https://www.shadertoy.com/view/4djSRW. -float hash(vec3 p3){ - p3 = fract(p3 * 0.1031); - p3 += dot(p3,p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -// From iq: https://www.shadertoy.com/view/4sfGzS. -float noise(vec3 x){ - vec3 i = floor(x); - vec3 f = fract(x); - f = f*f*(3.0-2.0*f); - return mix(mix(mix(hash(i+vec3(0, 0, 0)), - hash(i+vec3(1, 0, 0)),f.x), - mix(hash(i+vec3(0, 1, 0)), - hash(i+vec3(1, 1, 0)),f.x),f.y), - mix(mix(hash(i+vec3(0, 0, 1)), - hash(i+vec3(1, 0, 1)),f.x), - mix(hash(i+vec3(0, 1, 1)), - hash(i+vec3(1, 1, 1)),f.x),f.y),f.z); -} - -// From: https://www.shadertoy.com/view/3sGSWVF -// Slightly high-passed continuous value-noise. -float grainSource(vec3 x, float strength, float pitch){ - float center = noise(x); - float v1 = center - noise(vec3( 1, 0, 0)/pitch + x) + 0.5; - float v2 = center - noise(vec3( 0, 1, 0)/pitch + x) + 0.5; - float v3 = center - noise(vec3(-1, 0, 0)/pitch + x) + 0.5; - float v4 = center - noise(vec3( 0,-1, 0)/pitch + x) + 0.5; - - float total = (v1 + v2 + v3 + v4) / 4.0; - return mix(1, 0.5 + total, strength); -} - -vec3 applyGrain(ivec2 uv, vec3 c){ - float grainLift = 0.6; - float grainStrength = 0.4; - float grainTimeFactor = 0.1; - - float timeColorOffset = 1.2; - vec3 grain = vec3( - grainSource(vec3(uv, floor(grainTimeFactor*time)), grainStrength, grainLift), - grainSource(vec3(uv, floor(grainTimeFactor*time + timeColorOffset)), grainStrength, grainLift), - grainSource(vec3(uv, floor(grainTimeFactor*time - timeColorOffset)), grainStrength, grainLift)); - - return c * grain; -} - -vec2 computeDistortedUV(vec2 uv, float aspectRatio){ - uv = uv * 2 - 1; - float r2 = dot(uv, uv); - float k1 = 0.02f; - - float maxR2 = dot(vec2(1), vec2(1)); - float maxFactor = maxR2 * k1; - - // correction only needed for pincushion distortion - maxFactor = min(maxFactor, 0); - - uv /= 1 + r2*k1; - - // correction to avoid going out of [-1, 1] range when using barrel distortion - uv *= 1 + maxFactor; - - return uv * 0.5 + 0.5; -} - -float computeLocalContrast(vec2 uv){ - float lumaMin = 100; - float lumaMax = 0; - - vec2 pixelSize = vec2(1) / textureSize(sampler2D(inTexture, textureSampler), 0); - - for(int x = -1; x <= 1; x++){ - for(int y = -1; y <= 1; y++){ - vec3 c = texture(sampler2D(inTexture, textureSampler), uv + vec2(x, y) * pixelSize).rgb; - float luma = computeLuma(c); - lumaMin = min(lumaMin, luma); - lumaMax = max(lumaMax, luma); - } - } - - return lumaMax - lumaMin; -} - -vec3 computeChromaticAberrationScale(vec2 uv){ - float localContrast = computeLocalContrast(uv); - vec3 colorScales = vec3(-1, 0, 1); - float aberrationScale = 0.004; - vec3 maxScaleFactors = colorScales * aberrationScale; - float factor = clamp(localContrast, 0, 1); - return mix(vec3(0), maxScaleFactors, factor); -} - -vec3 sampleColorChromaticAberration(vec2 uv){ - vec2 toCenter = (vec2(0.5) - uv); - - vec3 scaleFactors = computeChromaticAberrationScale(uv); - - float r = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.r).r; - float g = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.g).g; - float b = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.b).b; - return vec3(r, g, b); -} - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 textureRes = textureSize(sampler2D(inTexture, textureSampler), 0); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec2 uv = vec2(coord) / textureRes; - float aspectRatio = float(textureRes.x) / textureRes.y; - uv = computeDistortedUV(uv, aspectRatio); - - vec3 tonemapped = sampleColorChromaticAberration(uv); - tonemapped = applyGrain(coord, tonemapped); - - vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); - imageStore(outImage, coord, vec4(gammaCorrected, 0.f)); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shader.frag b/projects/voxelization/assets/shaders/shader.frag deleted file mode 100644 index 25ec69acb77bace1134920bbcee56deb40bb936b..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shader.frag +++ /dev/null @@ -1,170 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "perMeshResources.inc" -#include "lightInfo.inc" -#include "shadowMapping.inc" -#include "brdf.inc" -#include "voxel.inc" - -layout(location = 0) in vec3 passNormal; -layout(location = 1) in vec2 passUV; -layout(location = 2) in vec3 passPos; -layout(location = 3) in vec4 passTangent; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform sunBuffer { - LightInfo lightInfo; -}; -layout(set=0, binding=1) uniform texture2D shadowMap; -layout(set=0, binding=2) uniform sampler shadowMapSampler; - -layout(set=0, binding=3) uniform cameraBuffer { - vec3 cameraPos; -}; - -layout(set=0, binding=4) uniform texture3D voxelTexture; -layout(set=0, binding=5) uniform sampler voxelSampler; - -layout(set=0, binding=6) uniform VoxelInfoBuffer{ - VoxelInfo voxelInfo; -}; - -layout(set=0, binding=7) uniform VolumetricSettings { - vec3 scatteringCoefficient; - float volumetricAmbientLight; - vec3 absorptionCoefficient; -}; - - -vec3 cookTorrance(vec3 f0, float r, vec3 N, vec3 V, vec3 L){ - - vec3 H = normalize(L + V); - - float NoH = clamp(dot(N, H), 0, 1); - float NoL = clamp(dot(N, L), 0, 1); - float NoV = clamp(abs(dot(N, V)), 0, 1); // abs to account for wrong visibility caused by normal mapping - - vec3 F = fresnelSchlick(NoH, f0); - float D = GGXDistribution(r, NoH); - float G = GGXSmithShadowing(r, NoV, NoL); - - return (F * D * G) / max(4 * NoV * NoL, 0.00001); -} - -float roughnessToConeAngleDegree(float r){ - return mix(degreeToRadian(3), degreeToRadian(60), r); -} - -// from: "Next Generation Post Processing in Call Of Duty Advanced Warfare" slide page 123 -float interleavedGradientNoise(vec2 uv){ - vec3 magic = vec3(0.06711056, 0.00583715, 62.9829189); - return fract(magic.z * fract(dot(uv, magic.xy))); -} - -// from: https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile -vec3 EnvBRDFApprox(vec3 SpecularColor, float Roughness, float NoV ) -{ - const vec4 c0 = { -1, -0.0275, -0.572, 0.022 }; - const vec4 c1 = { 1, 0.0425, 1.04, -0.04 }; - vec4 r = Roughness * c0 + c1; - float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; - vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; - return SpecularColor * AB.x + AB.y; -} - -float isotropicPhase(){ - return 1 / (4 * pi); -} - -vec3 volumetricLighting(vec3 colorIn, vec3 V, vec3 pos, float d){ - vec3 color = colorIn; - - int sampleCount = 20; - float stepSize = d / sampleCount; - - vec3 extinctionCoefficient = scatteringCoefficient + absorptionCoefficient; - - float noise = 2 * pi * interleavedGradientNoise(gl_FragCoord.xy); - vec2 shadowOffset = 3.f * vec2(sin(noise), cos(noise)) / textureSize(sampler2D(shadowMap, shadowMapSampler), 0); - - float noiseScale = 0.1f; - pos += V * noiseScale * interleavedGradientNoise(gl_FragCoord.xy); - - for(int i = 0; i < sampleCount; i++){ - vec3 samplePoint = pos + V * i * stepSize; - float phase = isotropicPhase(); - vec3 light = lightInfo.sunColor * lightInfo.sunStrength; - float shadow = shadowTest(samplePoint, lightInfo, shadowMap, shadowMapSampler, shadowOffset); - light *= shadow; - light += volumetricAmbientLight; - - color += phase * light * scatteringCoefficient * stepSize; - color *= exp(-stepSize * extinctionCoefficient); - } - return color; -} - -void main() { - - vec3 albedoTexel = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; - vec3 normalTexel = texture(sampler2D(normalTexture, textureSampler), passUV).rgb; - vec3 specularTexel = texture(sampler2D(specularTexture, textureSampler), passUV).rgb; - - float r = specularTexel.g; - - float metal = specularTexel.b; - vec3 albedo = mix(albedoTexel, vec3(0), metal); - vec3 f0_dielectric = vec3(0.04f); - vec3 f0 = mix(f0_dielectric, albedoTexel, metal); - - vec3 T = normalize(passTangent.xyz); - vec3 N_geo = normalize(passNormal); - vec3 B = cross(N_geo, T) * passTangent.w; - mat3 TBN = mat3(T, B, N_geo); - normalTexel = normalTexel * 2 - 1; - - vec3 N = normalize(TBN * normalTexel); - vec3 L = lightInfo.L; - vec3 V = normalize(cameraPos - passPos); - - float NoL = clamp(dot(N, L), 0, 1); - float NoV = clamp(abs(dot(N, V)), 0, 1); - - vec3 sunSpecular = cookTorrance(f0, r, N, V, L); - vec3 sun = lightInfo.sunStrength * lightInfo.sunColor * NoL; - - float noise = 2 * pi * interleavedGradientNoise(gl_FragCoord.xy); - vec2 shadowOffset = 0.05f * vec2(sin(noise), cos(noise)) / textureSize(sampler2D(shadowMap, shadowMapSampler), 0); - float shadow = shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler, shadowOffset); - sun *= shadow; - - vec3 F_in = fresnelSchlick(NoL, f0); - vec3 F_out = fresnelSchlick(NoV, f0); - vec3 diffuse = lambertBRDF(albedo) * (1 - F_in) * (1 - F_out); - - vec3 up = abs(N_geo.y) >= 0.99 ? vec3(1, 0, 0) : vec3(0, 1, 0); - vec3 right = normalize(cross(up, N)); - up = cross(N, right); - mat3 toSurface = mat3(right, up, N); - - vec3 diffuseTrace = diffuseVoxelTraceHemisphere(toSurface, passPos, voxelTexture, voxelSampler, voxelInfo); - - vec3 R = reflect(-V, N); - float reflectionConeAngle = roughnessToConeAngleDegree(r); - vec3 offsetTraceStart = passPos + N_geo * 0.1f; - offsetTraceStart += R * interleavedGradientNoise(gl_FragCoord.xy) * 0.5; - vec3 specularTrace = voxelConeTrace(R, offsetTraceStart, reflectionConeAngle, voxelTexture, voxelSampler, voxelInfo); - specularTrace *= clamp(dot(N, R), 0, 1); - vec3 reflectionBRDF = EnvBRDFApprox(f0, r, NoV); - - outColor = - (diffuse + sunSpecular) * sun + - lambertBRDF(albedo) * diffuseTrace + - reflectionBRDF * specularTrace; - - float d = distance(cameraPos, passPos); - outColor = volumetricLighting(outColor, V, passPos, d); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shader.vert b/projects/voxelization/assets/shaders/shader.vert deleted file mode 100644 index e3873f98a308347592725e794d6b7102cbbe3e5c..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shader.vert +++ /dev/null @@ -1,25 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; -layout(location = 3) in vec4 inTangent; - -layout(location = 0) out vec3 passNormal; -layout(location = 1) out vec2 passUV; -layout(location = 2) out vec3 passPos; -layout(location = 3) out vec4 passTangent; - -layout( push_constant ) uniform constants{ - mat4 mvp; - mat4 model; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = mat3(model) * inNormal; // assuming no weird stuff like shearing or non-uniform scaling - passUV = inUV; - passPos = (model * vec4(inPosition, 1)).xyz; - passTangent = vec4(mat3(model) * inTangent.xyz, inTangent.w); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadow.frag b/projects/voxelization/assets/shaders/shadow.frag deleted file mode 100644 index 65592d2cfe161b8522de1a0c3e68fa1d6afa80be..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadow.frag +++ /dev/null @@ -1,7 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -void main() { - -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadow.vert b/projects/voxelization/assets/shaders/shadow.vert deleted file mode 100644 index d800c547368c4f2126c880534276a3be3cf336f5..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadow.vert +++ /dev/null @@ -1,14 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -#extension GL_GOOGLE_include_directive : enable - -layout(location = 0) in vec3 inPosition; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadowBlur.inc b/projects/voxelization/assets/shaders/shadowBlur.inc deleted file mode 100644 index ed4994ed1ace34afdafff15920d18a2433a3c0a4..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadowBlur.inc +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SHADOW_BLUR_INC -#define SHADOW_BLUR_INC - -vec4 blurMomentShadowMap1D(ivec2 coord, ivec2 blurDirection, texture2D srcTexture, sampler depthSampler){ - - int blurRadius = 7; - int minOffset = -(blurRadius-1) / 2; - int maxOffset = -minOffset; - - vec2 pixelSize = vec2(1) / textureSize(sampler2D(srcTexture, depthSampler), 0); - - float wTotal = 0; - vec4 moments = vec4(0); - - float weights1D[4] = { 0.5, 0.25, 0.125, 0.0625 }; // gaussian - - for(int i = minOffset; i <= maxOffset; i++){ - vec2 uv = (coord + i * blurDirection) * pixelSize; - uv += 0.5 * pixelSize * blurDirection * sign(i); // half pixel shift to take advantage of bilinear filtering - float w = weights1D[abs(i)]; - moments += w * texture(sampler2D(srcTexture, depthSampler), uv); - wTotal += w; - } - return moments / wTotal; -} - -#endif // #ifndef SHADOW_BLUR_INC \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadowBlurX.comp b/projects/voxelization/assets/shaders/shadowBlurX.comp deleted file mode 100644 index 41d127fdf5ce46dec883d49af4f284b5787d5d38..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadowBlurX.comp +++ /dev/null @@ -1,23 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -#include "shadowBlur.inc" - -layout(set=0, binding=0) uniform texture2D srcTexture; -layout(set=0, binding=1) uniform sampler depthSampler; -layout(set=0, binding=2, rgba16) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec4 moments = blurMomentShadowMap1D(coord, ivec2(1, 0), srcTexture, depthSampler); - // moments = texelFetch(sampler2D(srcTexture, depthSampler), coord, 0); - imageStore(outImage, coord, moments); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadowBlurY.comp b/projects/voxelization/assets/shaders/shadowBlurY.comp deleted file mode 100644 index c1710d7d6c75ef0093fecfe708272f56f9541eaf..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadowBlurY.comp +++ /dev/null @@ -1,23 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -#include "shadowBlur.inc" - -layout(set=0, binding=0) uniform texture2D srcTexture; -layout(set=0, binding=1) uniform sampler depthSampler; -layout(set=0, binding=2, rgba16) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec4 moments = blurMomentShadowMap1D(coord, ivec2(0, 1), srcTexture, depthSampler); - // moments = texelFetch(sampler2D(srcTexture, depthSampler), coord, 0); - imageStore(outImage, coord, moments); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/shadowMapping.inc b/projects/voxelization/assets/shaders/shadowMapping.inc deleted file mode 100644 index 9124a05c310c2cc16e6b02802f5adb36bde42804..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/shadowMapping.inc +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef SHADOW_MAPPING_INC -#define SHADOW_MAPPING_INC - -#include "lightInfo.inc" - -// nice math blob from the moment shadow mapping presentation -float ComputeMSMShadowIntensity(vec4 _4Moments, float FragmentDepth, float DepthBias, float MomentBias) -{ - vec4 b=mix(_4Moments, vec4(0, 0.63, 0, 0.63),MomentBias); - - vec3 z; - z[0]=FragmentDepth-DepthBias; - float L32D22=fma(-b[0], b[1], b[2]); - float D22=fma(-b[0], b[0], b[1]); - float SquaredDepthVariance=fma(-b[1], b[1], b[3]); - float D33D22=dot(vec2(SquaredDepthVariance,-L32D22), - vec2(D22, L32D22)); - - float InvD22=1.0/D22; - float L32=L32D22*InvD22; - vec3 c=vec3(1.0,z[0],z[0]*z[0]); - c[1]-=b.x; - c[2]-=b.y+L32*c[1]; - c[1]*=InvD22; - c[2]*=D22/D33D22; - c[1]-=L32*c[2]; - c[0]-=dot(c.yz,b.xy); - float p=c[1]/c[2]; - float q=c[0]/c[2]; - float r=sqrt((p*p*0.25)-q); - z[1]=-p*0.5-r; - z[2]=-p*0.5+r; - vec4 Switch= - (z[2]<z[0])?vec4(z[1],z[0],1.0,1.0):( - (z[1]<z[0])?vec4(z[0],z[1],0.0,1.0): - vec4(0.0)); - float Quotient=(Switch[0]*z[2]-b[0]*(Switch[0]+z[2])+b[1]) - /((z[2]-Switch[1])*(z[0]-z[1])); - return 1-clamp(Switch[2]+Switch[3]*Quotient, 0, 1); -} - -vec4 quantizeMoments(vec4 moments){ - vec4 quantized; - quantized.r = 1.5 * moments.r - 2 * moments.b + 0.5; - quantized.g = 4 * moments.g - 4 * moments.a; - quantized.b = sqrt(3)/2 * moments.r - sqrt(12)/9 * moments.b + 0.5; - quantized.a = 0.5 * moments.g + 0.5 * moments.a; - - return quantized; -} - -vec4 unquantizeMoments(vec4 moments){ - moments -= vec4(0.5, 0, 0.5, 0); - vec4 unquantized; - unquantized.r = -1.f / 3 * moments.r + sqrt(3) * moments.b; - unquantized.g = 0.125 * moments.g + moments.a; - unquantized.b = -0.75 * moments.r + 0.75 * sqrt(3) * moments.b; - unquantized.a = -0.125 * moments.g + moments.a; - return unquantized / 0.98; // division reduces light bleeding -} - -float rescaleRange(float a, float b, float v) -{ - return clamp((v - a) / (b - a), 0, 1); -} - -float reduceLightBleeding(float shadow, float amount) -{ - return rescaleRange(amount, 1.0f, shadow); -} - -float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sampler shadowMapSampler, vec2 offset){ - vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1); - lightPos /= lightPos.w; - lightPos.xy = lightPos.xy * 0.5 + 0.5; - lightPos.xy += offset; - - if(any(lessThan(lightPos.xy, vec2(0))) || any(greaterThan(lightPos.xy, vec2(1)))){ - return 1; - } - - lightPos.z = clamp(lightPos.z, 0, 1); - lightPos.z = 2 * lightPos.z - 1; // algorithm expects depth in range [-1:1] - - vec4 shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy); - - shadowMapSample = unquantizeMoments(shadowMapSample); - - float depthBias = 0.f; - float momentBias = 0.0006; - - float shadow = ComputeMSMShadowIntensity(shadowMapSample, lightPos.z, depthBias, momentBias); - return clamp(shadow, 0, 1); - // return reduceLightBleeding(shadow, 0.1f); -} - -#endif // #ifndef SHADOW_MAPPING_INC \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/sky.frag b/projects/voxelization/assets/shaders/sky.frag deleted file mode 100644 index 2a3b2ad03e1936641a565b2f3fbd1f19f186ff7a..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/sky.frag +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) out vec3 outColor; - -layout( push_constant ) uniform constants{ - vec3 skyColor; - float skyStrength; -}; - -void main() { - outColor = skyColor * skyStrength; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/sky.vert b/projects/voxelization/assets/shaders/sky.vert deleted file mode 100644 index 686e6f352e9bb1054656f58340a9cfc9b55fcff4..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/sky.vert +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -const vec2 positions[3] = { - vec2(-1, -1), - vec2(-1, 4), - vec2(4, -1) -}; - -void main() { - gl_Position = vec4(positions[gl_VertexIndex], 1, 1); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/tonemapping.comp b/projects/voxelization/assets/shaders/tonemapping.comp deleted file mode 100644 index ffadc9a71e207f97fec9a8815aa1c61bc709c369..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/tonemapping.comp +++ /dev/null @@ -1,34 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) uniform texture2D inTexture; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2, rgba8) uniform image2D outImage; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; - -// from: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 ACESFilm(vec3 x) -{ - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0, 1); -} - -void main(){ - - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ - return; - } - ivec2 textureRes = textureSize(sampler2D(inTexture, textureSampler), 0); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec2 uv = vec2(coord) / textureRes; - - vec3 linearColor = texture(sampler2D(inTexture, textureSampler), uv).rgb; - vec3 tonemapped = ACESFilm(linearColor); - - imageStore(outImage, coord, vec4(tonemapped, 0.f)); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxel.inc b/projects/voxelization/assets/shaders/voxel.inc deleted file mode 100644 index 6133ca7cfc52ca77cb70fb8c2cc0e83ef6da4016..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxel.inc +++ /dev/null @@ -1,179 +0,0 @@ -#include "brdf.inc" - -struct VoxelInfo{ - vec3 offset; - float extent; -}; - -struct PackedVoxelData{ - uint color; - uint normal; - uint albedo; -}; - -uint flattenVoxelUVToIndex(ivec3 UV, ivec3 voxelImageSize){ - return UV.x + UV.y * voxelImageSize.x + UV.z * voxelImageSize.x* voxelImageSize.y; -} - -vec3 worldToVoxelCoordinates(vec3 world, VoxelInfo info){ - return (world - info.offset) / info.extent + 0.5f; -} - -ivec3 voxelCoordinatesToUV(vec3 voxelCoordinates, ivec3 voxelImageResolution){ - return ivec3(voxelCoordinates * voxelImageResolution); -} - -vec3 voxelCoordinatesToWorldPosition(ivec3 coord, int voxelResolution, VoxelInfo voxelInfo, float voxelHalfSize){ - return (vec3(coord) / voxelResolution - 0.5) * voxelInfo.extent + voxelHalfSize + voxelInfo.offset; -} - -// packed voxel data: -// 1 bit opacity -// 7 bit exposure -// 8 bit blue -// 8 bit green -// 8 bit red -float maxExposure = 16.f; - -uint packVoxelColor(vec3 color){ - - color = clamp(color, vec3(0), vec3(maxExposure)); - float maxComponent = max(max(max(color.r, color.g), color.b), 1.f); - color /= maxComponent; - - uint opaqueBit = 1 << 31; - uint exposureBits = (0x0000007F & uint(maxComponent / maxExposure * 127)) << 24; - uint redBits = (0x000000FF & uint(color.r * 255)) << 0; - uint greenBits = (0x000000FF & uint(color.g * 255)) << 8; - uint blueBits = (0x000000FF & uint(color.b * 255)) << 16; - return opaqueBit | exposureBits | blueBits | greenBits | redBits; -} - -vec4 unpackVoxelColor(uint packed){ - vec4 rgba; - rgba.r = (packed >> 0 & 0x000000FF) / 255.f; - rgba.g = (packed >> 8 & 0x000000FF) / 255.f; - rgba.b = (packed >> 16 & 0x000000FF) / 255.f; - rgba.a = packed >> 31; - - rgba.rgb *= (packed >> 24 & 0x0000007F) / 127.f * maxExposure; - - return rgba; -} - -uint packSNormInto9Bits(float x){ - uint lengthBits = 0x000000FF & uint(abs(x) * 255.f); - uint signBits = (x < 0 ? 1 : 0) << 8; - return lengthBits | signBits; -} - -float unpack9LowBitsIntoSNorm(uint bits){ - bits = (0x000001FF & bits); - float length = bits / 255.f; - float sign = (bits >> 8) == 0 ? 1 : -1; - return sign * length; -} - -// normals are packed with 9 bits each, 8 for length and 1 for sign -uint packVoxelNormal(vec3 N){ - N = clamp(N, vec3(0), vec3(1)); - uint xBits = packSNormInto9Bits(N.x) << 0; - uint yBits = packSNormInto9Bits(N.y) << 9; - uint zBits = packSNormInto9Bits(N.z) << 18; - return zBits | yBits | xBits; -} - -vec3 unpackVoxelNormal(uint packed){ - vec3 N; - N.x = unpack9LowBitsIntoSNorm(packed >> 0); - N.y = unpack9LowBitsIntoSNorm(packed >> 9); - N.z = unpack9LowBitsIntoSNorm(packed >> 18); - return normalize(N); -} - -uint packUNormInto8Bits(float x){ - return 0x000000FF & uint(abs(x) * 255.f); -} - -float unpack8LowBitsIntoUNorm(uint bits){ - bits = (0x000000FF & bits); - return bits / 255.f; -} - -// albedo is packed with 8 bits each -uint packVoxelAlbedo(vec3 albedo){ - albedo = clamp(albedo, vec3(0), vec3(1)); - uint rBits = packUNormInto8Bits(albedo.r) << 0; - uint gBits = packUNormInto8Bits(albedo.g) << 8; - uint bBits = packUNormInto8Bits(albedo.b) << 16; - return bBits | gBits | rBits; -} - -vec3 unpackVoxelAlbedo(uint packed){ - vec3 albedo; - albedo.r = unpack8LowBitsIntoUNorm(packed >> 0); - albedo.g = unpack8LowBitsIntoUNorm(packed >> 8); - albedo.b = unpack8LowBitsIntoUNorm(packed >> 16); - return albedo; -} - -vec3 voxelConeTrace(vec3 direction, vec3 startPosition, float coneAngleRadian, texture3D voxelTexture, sampler voxelSampler, VoxelInfo voxelInfo){ - - int voxelResolution = textureSize(sampler3D(voxelTexture, voxelSampler), 0).x; - float voxelSize = voxelInfo.extent / voxelResolution; - float maxMip = float(log2(voxelResolution)); - float maxStableMip = 4; // must be the same as in Voxelization::voxelizeMeshes - maxMip = min(maxMip, maxStableMip); - float d = 2 * sqrt(3 * pow(voxelSize, 2)); - vec3 color = vec3(0); - float a = 0; - - float coneAngleHalf = coneAngleRadian * 0.5f; - - int maxSamples = 16; - for(int i = 0; i < maxSamples; i++){ - - vec3 samplePos = startPosition + d * direction; - vec3 sampleUV = worldToVoxelCoordinates(samplePos, voxelInfo); - - if(a >= 0.95 || any(lessThan(sampleUV, vec3(0))) || any(greaterThan(sampleUV, vec3(1)))){ - break; - } - - float coneDiameter = 2 * tan(coneAngleHalf) * d; - float mip = log2(coneDiameter / voxelSize); - mip = min(mip, maxMip); - - vec4 voxelSample = textureLod(sampler3D(voxelTexture, voxelSampler), sampleUV , mip); - - color += (1 - a) * voxelSample.rgb; - a += (1 - a) * voxelSample.a; - - float minStepSize = 1.f; - d += max(coneDiameter, minStepSize); - } - return color; -} - -float degreeToRadian(float d){ - return d / 180.f * pi; -} - -vec3 diffuseVoxelTraceHemisphere(mat3 toSurface, vec3 position, texture3D voxelTexture, sampler voxelSampler, VoxelInfo voxelInfo){ - float coneAngle = degreeToRadian(60.f); - vec3 diffuseTrace = vec3(0); - { - vec3 sampleDirection = toSurface * vec3(0, 0, 1); - float weight = pi / 4.f; - diffuseTrace += weight * voxelConeTrace(sampleDirection, position, coneAngle, voxelTexture, voxelSampler, voxelInfo); - } - for(int i = 0; i < 6;i++){ - float theta = 2 * pi / i; - float phi = pi / 3; // 60 degrees - vec3 sampleDirection = toSurface * vec3(cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi)); - float weight = pi * (3.f / 4.f) / 6; - vec3 trace = voxelConeTrace(sampleDirection, position, coneAngle, voxelTexture, voxelSampler, voxelInfo); - diffuseTrace += weight * trace; - } - return diffuseTrace; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelBufferToImage.comp b/projects/voxelization/assets/shaders/voxelBufferToImage.comp deleted file mode 100644 index 2c2cffe856c8b0fc7db07202572aaa35e8445603..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelBufferToImage.comp +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#include "voxel.inc" - -layout(set=0, binding=0, std430) buffer voxelBuffer{ - PackedVoxelData packedVoxelData[]; -}; - -layout(set=0, binding=1, rgba16f) uniform image3D voxelImage; - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -void main(){ - - ivec3 voxelImageSize = imageSize(voxelImage); - if(any(greaterThanEqual(gl_GlobalInvocationID, voxelImageSize))){ - return; - } - ivec3 UV = ivec3(gl_GlobalInvocationID); - uint flatIndex = flattenVoxelUVToIndex(UV, voxelImageSize); - - vec4 color = unpackVoxelColor(packedVoxelData[flatIndex].color); - - // for proper visualisation voxel secondary bounce should be disabled, otherwise it adds color - - // for debugging: write normal into image, so voxel visualisation draws normal - // color = vec4(unpackVoxelNormal(packedVoxelData[flatIndex].normal), color.a); - - // for debugging: write albedo into image, so voxel visualisation draws albedo - // color = vec4(unpackVoxelAlbedo(packedVoxelData[flatIndex].albedo), color.a); - - imageStore(voxelImage, UV, vec4(color)); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelReset.comp b/projects/voxelization/assets/shaders/voxelReset.comp deleted file mode 100644 index 79eda9ec95e703d39af57bc3b29044f0ad6c1bf9..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelReset.comp +++ /dev/null @@ -1,23 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#include "voxel.inc" - -layout(set=0, binding=0) buffer voxelizationBuffer{ - PackedVoxelData packedVoxelData[]; -}; - -layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; - -layout( push_constant ) uniform constants{ - uint voxelCount; -}; - -void main(){ - - if(gl_GlobalInvocationID.x> voxelCount){ - return; - } - packedVoxelData[gl_GlobalInvocationID.x].color = 0; - packedVoxelData[gl_GlobalInvocationID.x].normal = 0; - packedVoxelData[gl_GlobalInvocationID.x].albedo = 0; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelSecondaryBounce.comp b/projects/voxelization/assets/shaders/voxelSecondaryBounce.comp deleted file mode 100644 index 29026e7052861ab190200b23d9f860bc609d1550..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelSecondaryBounce.comp +++ /dev/null @@ -1,46 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#include "voxel.inc" -#include "brdf.inc" - -layout(set=0, binding=0, std430) buffer voxelBuffer{ - PackedVoxelData packedVoxelData[]; -}; -layout(set=0, binding=1) uniform texture3D voxelImageIn; -layout(set=0, binding=2) uniform sampler voxelSampler; -layout(set=0, binding=3, rgba16f) uniform image3D voxelImageOut; -layout(set=0, binding=4) uniform voxelizationInfo{ - VoxelInfo voxelInfo; -}; - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -void main(){ - - ivec3 voxelImageSize = imageSize(voxelImageOut); - if(any(greaterThanEqual(gl_GlobalInvocationID, voxelImageSize))){ - return; - } - ivec3 UV = ivec3(gl_GlobalInvocationID); - - vec4 color = texelFetch(sampler3D(voxelImageIn, voxelSampler), UV, 0); - - if(color.a > 0){ - uint flatIndex = flattenVoxelUVToIndex(UV, voxelImageSize); - vec3 N = unpackVoxelNormal(packedVoxelData[flatIndex].normal); - - float halfVoxelSize = voxelInfo.extent / float(voxelImageSize.x) * 0.5f; - vec3 pos = voxelCoordinatesToWorldPosition(UV, voxelImageSize.x, voxelInfo, halfVoxelSize); - - vec3 up = abs(N.y) >= 0.99 ? vec3(1, 0, 0) : vec3(0, 1, 0); - vec3 right = normalize(cross(up, N)); - up = cross(N, right); - mat3 toSurface = mat3(right, up, N); - - vec3 secondaryBounce = diffuseVoxelTraceHemisphere(toSurface, pos, voxelImageIn, voxelSampler, voxelInfo); - vec3 albedo = unpackVoxelAlbedo(packedVoxelData[flatIndex].albedo); - color.rgb += lambertBRDF(albedo) * secondaryBounce; - } - - imageStore(voxelImageOut, UV, color); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelVisualisation.frag b/projects/voxelization/assets/shaders/voxelVisualisation.frag deleted file mode 100644 index 0b02beb7e848ab20cda4b012f77d1fa664b6ab53..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelVisualisation.frag +++ /dev/null @@ -1,9 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location=0) in vec3 passColorToFrag; -layout(location=0) out vec3 outColor; - -void main() { - outColor = passColorToFrag; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelVisualisation.geom b/projects/voxelization/assets/shaders/voxelVisualisation.geom deleted file mode 100644 index e98076fcc83a69a903df454cb00267da84e3f223..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelVisualisation.geom +++ /dev/null @@ -1,104 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(points) in; -layout (triangle_strip, max_vertices = 24) out; - -layout( push_constant ) uniform constants{ - mat4 viewProjection; -}; - -layout(location = 0) in float passCubeHalf[1]; -layout(location = 1) in vec3 passColorToGeom[1]; - - -layout(location = 0) out vec3 passColorToFrag; - -void main() { - float cubeHalf = passCubeHalf[0]; - // right - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); - // left - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); - // back - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); - // front - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); - // bot - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); - passColorToFrag = passColorToGeom[0]; - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); - // top - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); - passColorToFrag = passColorToGeom[0]; - EmitVertex(); - EndPrimitive(); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelVisualisation.vert b/projects/voxelization/assets/shaders/voxelVisualisation.vert deleted file mode 100644 index e26e2209ffb9bd3e62103fa9e7eeccce13d7d602..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelVisualisation.vert +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "voxel.inc" - -layout(location = 0) out float passCubeHalf; -layout(location = 1) out vec3 passColorToGeom; - -layout( push_constant ) uniform constants{ - mat4 viewProjection; -}; - -layout(set=0, binding=0, rgba16f) uniform image3D voxelImage; -layout(set=0, binding=1) uniform voxelizationInfo{ - VoxelInfo voxelInfo; -}; - - -void main() { - passCubeHalf = voxelInfo.extent / float(imageSize(voxelImage).x) * 0.5f; - int voxelResolution = imageSize(voxelImage).x; - int slicePixelCount = voxelResolution * voxelResolution; - int z = gl_VertexIndex / slicePixelCount; - int index2D = gl_VertexIndex % slicePixelCount; - int y = index2D / voxelResolution; - int x = index2D % voxelResolution; - vec3 position = voxelCoordinatesToWorldPosition(ivec3(x, y, z), voxelResolution, voxelInfo, passCubeHalf); - gl_Position = vec4(position, 1.0); - - vec4 voxelColor = imageLoad(voxelImage, ivec3(x,y,z)); - if(voxelColor.a == 0){ - gl_Position.x /= 0; // clip - } - passColorToGeom = voxelColor.rgb; -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelization.frag b/projects/voxelization/assets/shaders/voxelization.frag deleted file mode 100644 index 0bbd26bff249db1390399b26f2f4b5a139195fef..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelization.frag +++ /dev/null @@ -1,52 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_GOOGLE_include_directive : enable - -#include "voxel.inc" -#include "perMeshResources.inc" -#include "lightInfo.inc" -#include "shadowMapping.inc" -#include "brdf.inc" - -layout(location = 0) in vec3 passPos; -layout(location = 1) in vec2 passUV; -layout(location = 2) in vec3 passN; - -layout(set=0, binding=0, std430) buffer voxelizationBuffer{ - PackedVoxelData packedVoxelData[]; -}; - -layout(set=0, binding=1) uniform voxelizationInfo{ - VoxelInfo voxelInfo; -}; - -layout(set=0, binding=2, r8) uniform image3D voxelImage; - -layout(set=0, binding=3) uniform sunBuffer { - LightInfo lightInfo; -}; - -layout(set=0, binding=4) uniform texture2D shadowMap; -layout(set=0, binding=5) uniform sampler shadowMapSampler; - -void main() { - vec3 voxelCoordinates = worldToVoxelCoordinates(passPos, voxelInfo); - ivec3 voxelImageSize = imageSize(voxelImage); - ivec3 UV = voxelCoordinatesToUV(voxelCoordinates, voxelImageSize); - if(any(lessThan(UV, ivec3(0))) || any(greaterThanEqual(UV, voxelImageSize))){ - return; - } - uint flatIndex = flattenVoxelUVToIndex(UV, voxelImageSize); - - vec3 albedo = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; - - vec3 N = normalize(passN); - float NoL = clamp(dot(N, lightInfo.L), 0, 1); - vec3 sun = lightInfo.sunStrength * lightInfo.sunColor * NoL * shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler, vec2(0)); - vec3 color = albedo * sun; - color = lambertBRDF(albedo) * sun; - - atomicMax(packedVoxelData[flatIndex].color, packVoxelColor(color)); - atomicMax(packedVoxelData[flatIndex].normal, packVoxelNormal(N)); - atomicMax(packedVoxelData[flatIndex].albedo, packVoxelAlbedo(albedo)); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelization.geom b/projects/voxelization/assets/shaders/voxelization.geom deleted file mode 100644 index 56542d960d65db6ca12c5f84837cb0c0a9ff0ded..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelization.geom +++ /dev/null @@ -1,38 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(triangles) in; -layout (triangle_strip, max_vertices = 3) out; - -layout(location = 0) in vec3 passPosIn[3]; -layout(location = 1) in vec2 passUVIn[3]; -layout(location = 2) in vec3 passNIn[3]; - -layout(location = 0) out vec3 passPos; -layout(location = 1) out vec2 passUV; -layout(location = 2) out vec3 passN; - -void main() { - // compute geometric normal, no normalization necessary - vec3 N = cross(passPosIn[0] - passPosIn[1], passPosIn[0] - passPosIn[2]); - N = abs(N); // only interested in the magnitude - - for(int i = 0; i < 3; i++){ - // swizzle position, so biggest side is rasterized - if(N.z > N.x && N.z > N.y){ - gl_Position = gl_in[i].gl_Position.xyzw; - } - else if(N.x > N.y){ - gl_Position = gl_in[i].gl_Position.yzxw; - } - else{ - gl_Position = gl_in[i].gl_Position.xzyw; - } - gl_Position.z = gl_Position.z * 0.5 + 0.5; // xyz are kept in NDC range [-1, 1] so swizzling works, but vulkan needs final z in range [0, 1] - passPos = passPosIn[i]; - passUV = passUVIn[i]; - passN = passNIn[i]; - EmitVertex(); - } - EndPrimitive(); -} \ No newline at end of file diff --git a/projects/voxelization/assets/shaders/voxelization.vert b/projects/voxelization/assets/shaders/voxelization.vert deleted file mode 100644 index 221d0f6d189cfe1d6fb8e9e8e2fc9c04884c40c1..0000000000000000000000000000000000000000 --- a/projects/voxelization/assets/shaders/voxelization.vert +++ /dev/null @@ -1,22 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inNormal; -layout(location = 2) in vec2 inUV; - -layout(location = 0) out vec3 passPos; -layout(location = 1) out vec2 passUV; -layout(location = 2) out vec3 passN; - -layout( push_constant ) uniform constants{ - mat4 mvp; - mat4 model; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passPos = (model * vec4(inPosition, 1)).xyz; - passUV = inUV; - passN = mat3(model) * inNormal; -} \ No newline at end of file diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp deleted file mode 100644 index 73f98cd3ea35d7f2bdf99d29f803df0abbc1adac..0000000000000000000000000000000000000000 --- a/projects/voxelization/src/ShadowMapping.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include "ShadowMapping.hpp" - -#include <vkcv/Pass.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -const vk::Format shadowMapFormat = vk::Format::eR16G16B16A16Unorm; -const vk::Format shadowMapDepthFormat = vk::Format::eD32Sfloat; -const uint32_t shadowMapResolution = 1024; -const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA8X; - -vkcv::ShaderProgram loadShadowShader() { - vkcv::ShaderProgram shader; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::VERTEX, "assets/shaders/shadow.vert", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "assets/shaders/shadow.frag", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadDepthToMomentsShader() { - vkcv::ShaderProgram shader; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/depthToMoments.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadShadowBlurXShader() { - vkcv::ShaderProgram shader; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/shadowBlurX.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadShadowBlurYShader() { - vkcv::ShaderProgram shader; - vkcv::shader::GLSLCompiler compiler; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/shadowBlurY.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -glm::mat4 computeShadowViewProjectionMatrix( - const glm::vec3& lightDirection, - const vkcv::camera::Camera& camera, - float maxShadowDistance, - const glm::vec3& voxelVolumeOffset, - float voxelVolumeExtent) { - - const glm::vec3 cameraPos = camera.getPosition(); - const glm::vec3 forward = glm::normalize(camera.getFront()); - glm::vec3 up = glm::normalize(camera.getUp()); - const glm::vec3 right = glm::normalize(glm::cross(forward, up)); - up = glm::cross(right, forward); - - const float fov = camera.getFov(); - const float aspectRatio = camera.getRatio(); - - float near; - float far; - camera.getNearFar(near, far); - far = std::min(maxShadowDistance, far); - - const glm::vec3 nearCenter = cameraPos + forward * near; - const float nearUp = near * tan(fov * 0.5); - const float nearRight = nearUp * aspectRatio; - - const glm::vec3 farCenter = cameraPos + forward * far; - const float farUp = far * tan(fov * 0.5); - const float farRight = farUp * aspectRatio; - - std::array<glm::vec3, 8> viewFrustumCorners = { - nearCenter + right * nearRight + nearUp * up, - nearCenter + right * nearRight - nearUp * up, - nearCenter - right * nearRight + nearUp * up, - nearCenter - right * nearRight - nearUp * up, - - farCenter + right * farRight + farUp * up, - farCenter + right * farRight - farUp * up, - farCenter - right * farRight + farUp * up, - farCenter - right * farRight - farUp * up - }; - - std::array<glm::vec3, 8> voxelVolumeCorners = { - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(1, 1, 1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(1, 1, -1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(1, -1, 1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(1, -1, -1), - - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(-1, 1, 1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(-1, 1, -1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(-1, -1, 1), - voxelVolumeOffset + voxelVolumeExtent * glm::vec3(-1, -1, -1), - }; - - glm::vec3 minView(std::numeric_limits<float>::max()); - glm::vec3 maxView(std::numeric_limits<float>::lowest()); - - const glm::mat4 view = glm::lookAt(glm::vec3(0), -lightDirection, glm::vec3(0, -1, 0)); - - auto getMinMaxView = [&](std::array<glm::vec3, 8> points) { - for (const glm::vec3& p : points) { - const auto& pView = glm::vec3(view * glm::vec4(p, 1)); - minView = glm::min(minView, pView); - maxView = glm::max(maxView, pView); - } - }; - - getMinMaxView(viewFrustumCorners); - getMinMaxView(voxelVolumeCorners); - - // rotationaly invariant to avoid shadow swimming when moving camera - // could potentially be wasteful, but guarantees stability, regardless of camera and voxel volume - glm::vec3 scale = glm::vec3(1.f / glm::max(far, voxelVolumeExtent)); - - glm::vec3 offset = -0.5f * (maxView + minView) * scale; - - // snap to texel to avoid shadow swimming when moving - glm::vec2 offset2D = glm::vec2(offset); - glm::vec2 frustumExtent2D = glm::vec2(1) / glm::vec2(scale); - glm::vec2 texelSize = glm::vec2(frustumExtent2D / static_cast<float>(shadowMapResolution)); - offset2D = glm::ceil(offset2D / texelSize) * texelSize; - offset.x = offset2D.x; - offset.y = offset2D.y; - - glm::mat4 crop(1); - crop[0][0] = scale.x; - crop[1][1] = scale.y; - crop[2][2] = scale.z; - - crop[3][0] = offset.x; - crop[3][1] = offset.y; - crop[3][2] = offset.z; - - glm::mat4 vulkanCorrectionMatrix(1.f); - vulkanCorrectionMatrix[2][2] = 0.5; - vulkanCorrectionMatrix[3][2] = 0.5; - - return vulkanCorrectionMatrix * crop * view; -} - -ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) : - m_corePtr(corePtr), - m_shadowMap(vkcv::image(*corePtr, shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, true, true)), - m_shadowMapIntermediate(vkcv::image(*corePtr, shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, true)), - m_shadowMapDepth(vkcv::image(*corePtr, shadowMapDepthFormat, shadowMapResolution, shadowMapResolution, 1, false, false, false, msaa)), - m_lightInfoBuffer(buffer<LightInfo>(*corePtr, vkcv::BufferType::UNIFORM, 1)){ - - vkcv::ShaderProgram shadowShader = loadShadowShader(); - - // pass - m_shadowMapPass = vkcv::passFormat(*corePtr, shadowMapDepthFormat, true, msaa); - - // pipeline - vkcv::GraphicsPipelineConfig shadowPipeConfig ( - shadowShader, - m_shadowMapPass, - vertexLayout, - {} - ); - - shadowPipeConfig.setResolution(shadowMapResolution, shadowMapResolution); - shadowPipeConfig.setDepthClampingEnabled(true); - shadowPipeConfig.setCulling(vkcv::CullMode::Front); - m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig); - - m_shadowSampler = corePtr->createSampler( - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerMipmapMode::LINEAR, - vkcv::SamplerAddressMode::CLAMP_TO_EDGE - ); - - // depth to moments - vkcv::ShaderProgram depthToMomentsShader = loadDepthToMomentsShader(); - - m_depthToMomentsDescriptorSetLayout = corePtr->createDescriptorSetLayout(depthToMomentsShader.getReflectedDescriptors().at(0)); - m_depthToMomentsDescriptorSet = corePtr->createDescriptorSet(m_depthToMomentsDescriptorSetLayout); - m_depthToMomentsPipe = corePtr->createComputePipeline({ depthToMomentsShader, { m_depthToMomentsDescriptorSetLayout }}); - - vkcv::DescriptorWrites depthToMomentDescriptorWrites; - depthToMomentDescriptorWrites.writeSampledImage(0, m_shadowMapDepth.getHandle()); - depthToMomentDescriptorWrites.writeSampler(1, m_shadowSampler); - depthToMomentDescriptorWrites.writeStorageImage(2, m_shadowMap.getHandle()); - corePtr->writeDescriptorSet(m_depthToMomentsDescriptorSet, depthToMomentDescriptorWrites); - - // shadow blur X - vkcv::ShaderProgram shadowBlurXShader = loadShadowBlurXShader(); - m_shadowBlurXDescriptorSetLayout = corePtr->createDescriptorSetLayout(shadowBlurXShader.getReflectedDescriptors().at(0)); - m_shadowBlurXDescriptorSet = corePtr->createDescriptorSet(m_shadowBlurXDescriptorSetLayout); - m_shadowBlurXPipe = corePtr->createComputePipeline({ shadowBlurXShader, { m_shadowBlurXDescriptorSetLayout }}); - - vkcv::DescriptorWrites shadowBlurXDescriptorWrites; - shadowBlurXDescriptorWrites.writeSampledImage(0, m_shadowMap.getHandle()); - shadowBlurXDescriptorWrites.writeSampler(1, m_shadowSampler); - shadowBlurXDescriptorWrites.writeStorageImage(2, m_shadowMapIntermediate.getHandle()); - corePtr->writeDescriptorSet(m_shadowBlurXDescriptorSet, shadowBlurXDescriptorWrites); - - // shadow blur Y - vkcv::ShaderProgram shadowBlurYShader = loadShadowBlurYShader(); - m_shadowBlurYDescriptorSetLayout = corePtr->createDescriptorSetLayout(shadowBlurYShader.getReflectedDescriptors().at(0)); - m_shadowBlurYDescriptorSet = corePtr->createDescriptorSet(m_shadowBlurYDescriptorSetLayout); - m_shadowBlurYPipe = corePtr->createComputePipeline({ shadowBlurYShader, { m_shadowBlurYDescriptorSetLayout }}); - - vkcv::DescriptorWrites shadowBlurYDescriptorWrites; - shadowBlurYDescriptorWrites.writeSampledImage(0, m_shadowMapIntermediate.getHandle()); - shadowBlurYDescriptorWrites.writeSampler(1, m_shadowSampler); - shadowBlurYDescriptorWrites.writeStorageImage(2, m_shadowMap.getHandle()); - corePtr->writeDescriptorSet(m_shadowBlurYDescriptorSet, shadowBlurYDescriptorWrites); -} - -void ShadowMapping::recordShadowMapRendering( - const vkcv::CommandStreamHandle& cmdStream, - const glm::vec2& lightAngleRadian, - const glm::vec3& lightColor, - float lightStrength, - float maxShadowDistance, - const std::vector<vkcv::VertexData>& meshes, - const std::vector<glm::mat4>& modelMatrices, - const vkcv::camera::Camera& camera, - const glm::vec3& voxelVolumeOffset, - float voxelVolumeExtent, - const vkcv::WindowHandle& windowHandle, - vkcv::Downsampler& downsampler) { - - LightInfo lightInfo; - lightInfo.sunColor = lightColor; - lightInfo.sunStrength = lightStrength; - lightInfo.direction = glm::normalize(glm::vec3( - std::cos(lightAngleRadian.x) * std::cos(lightAngleRadian.y), - std::sin(lightAngleRadian.x), - std::cos(lightAngleRadian.x) * std::sin(lightAngleRadian.y))); - - lightInfo.lightMatrix = computeShadowViewProjectionMatrix( - lightInfo.direction, - camera, - maxShadowDistance, - voxelVolumeOffset, - voxelVolumeExtent); - m_lightInfoBuffer.fill({ lightInfo }); - - vkcv::PushConstants shadowPushConstants = vkcv::pushConstants<glm::mat4>(); - - for (const auto& m : modelMatrices) { - shadowPushConstants.appendDrawcall(lightInfo.lightMatrix * m); - } - - std::vector<vkcv::InstanceDrawcall> drawcalls; - for (const auto& mesh : meshes) { - drawcalls.push_back(vkcv::InstanceDrawcall(mesh)); - } - - m_corePtr->recordBeginDebugLabel(cmdStream, "Shadow map depth", {1, 1, 1, 1}); - m_corePtr->recordDrawcallsToCmdStream( - cmdStream, - m_shadowMapPipe, - shadowPushConstants, - drawcalls, - { m_shadowMapDepth.getHandle() }, - windowHandle - ); - m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapDepth.getHandle()); - m_corePtr->recordEndDebugLabel(cmdStream); - - // depth to moments - const auto dispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(shadowMapResolution, shadowMapResolution), - vkcv::DispatchSize(8, 8) - ); - - const uint32_t msaaSampleCount = vkcv::msaaToSampleCount(msaa); - - vkcv::PushConstants msaaPushConstants = vkcv::pushConstants<uint32_t>(); - msaaPushConstants.appendDrawcall(msaaSampleCount); - - m_corePtr->recordBeginDebugLabel(cmdStream, "Depth to moments", { 1, 1, 1, 1 }); - - m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.getHandle()); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_depthToMomentsPipe, - dispatchCount, - { vkcv::useDescriptorSet(0, m_depthToMomentsDescriptorSet) }, - msaaPushConstants - ); - m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); - m_corePtr->recordEndDebugLabel(cmdStream); - - m_corePtr->recordBeginDebugLabel(cmdStream, "Moment shadow map blur", { 1, 1, 1, 1 }); - - // blur X - m_corePtr->prepareImageForStorage(cmdStream, m_shadowMapIntermediate.getHandle()); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_shadowBlurXPipe, - dispatchCount, - { vkcv::useDescriptorSet(0, m_shadowBlurXDescriptorSet) }, - vkcv::PushConstants(0) - ); - m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapIntermediate.getHandle()); - - // blur Y - m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.getHandle()); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_shadowBlurYPipe, - dispatchCount, - { vkcv::useDescriptorSet(0, m_shadowBlurYDescriptorSet) }, - vkcv::PushConstants(0) - ); - m_shadowMap.recordMipChainGeneration(cmdStream, downsampler); - - m_corePtr->recordEndDebugLabel(cmdStream); -} - -vkcv::ImageHandle ShadowMapping::getShadowMap() { - return m_shadowMap.getHandle(); -} - -vkcv::SamplerHandle ShadowMapping::getShadowSampler() { - return m_shadowSampler; -} - -vkcv::BufferHandle ShadowMapping::getLightInfoBuffer() { - return m_lightInfoBuffer.getHandle(); -} \ No newline at end of file diff --git a/projects/voxelization/src/ShadowMapping.hpp b/projects/voxelization/src/ShadowMapping.hpp deleted file mode 100644 index a843a7de9c9e4c731b16ae0c8d5bdfd2ac263711..0000000000000000000000000000000000000000 --- a/projects/voxelization/src/ShadowMapping.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/camera/Camera.hpp> -#include <vkcv/Downsampler.hpp> -#include <vkcv/Image.hpp> - -#include <glm/glm.hpp> -#define GLM_ENABLE_EXPERIMENTAL // use this before inclusion, else error! -#include <glm/gtx/transform.hpp> - -struct LightInfo { - glm::vec3 direction; - float padding; - glm::vec3 sunColor; - float sunStrength; - glm::mat4 lightMatrix; -}; - -class ShadowMapping { -public: - ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout); - - void recordShadowMapRendering( - const vkcv::CommandStreamHandle& cmdStream, - const glm::vec2& lightAngleRadian, - const glm::vec3& lightColor, - float lightStrength, - float maxShadowDistance, - const std::vector<vkcv::VertexData>& meshes, - const std::vector<glm::mat4>& modelMatrices, - const vkcv::camera::Camera& camera, - const glm::vec3& voxelVolumeOffset, - float voxelVolumeExtent, - const vkcv::WindowHandle& windowHandle, - vkcv::Downsampler& downsampler); - - vkcv::ImageHandle getShadowMap(); - vkcv::SamplerHandle getShadowSampler(); - vkcv::BufferHandle getLightInfoBuffer(); - -private: - vkcv::Core* m_corePtr; - - vkcv::Image m_shadowMap; - vkcv::Image m_shadowMapIntermediate; - vkcv::Image m_shadowMapDepth; - vkcv::SamplerHandle m_shadowSampler; - vkcv::Buffer<LightInfo> m_lightInfoBuffer; - - vkcv::PassHandle m_shadowMapPass; - vkcv::GraphicsPipelineHandle m_shadowMapPipe; - - vkcv::ComputePipelineHandle m_depthToMomentsPipe; - vkcv::DescriptorSetLayoutHandle m_depthToMomentsDescriptorSetLayout; - vkcv::DescriptorSetHandle m_depthToMomentsDescriptorSet; - - vkcv::ComputePipelineHandle m_shadowBlurXPipe; - vkcv::DescriptorSetLayoutHandle m_shadowBlurXDescriptorSetLayout; - vkcv::DescriptorSetHandle m_shadowBlurXDescriptorSet; - - vkcv::ComputePipelineHandle m_shadowBlurYPipe; - vkcv::DescriptorSetLayoutHandle m_shadowBlurYDescriptorSetLayout; - vkcv::DescriptorSetHandle m_shadowBlurYDescriptorSet; -}; \ No newline at end of file diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp deleted file mode 100644 index 5c70b9dd0b3fe21118c4eddc32fca53e6e21c329..0000000000000000000000000000000000000000 --- a/projects/voxelization/src/Voxelization.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "Voxelization.hpp" - -#include <vkcv/Pass.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include <glm/gtc/matrix_transform.hpp> -#include <algorithm> - -vkcv::ShaderProgram loadVoxelizationShader() { - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram shader; - compiler.compile(vkcv::ShaderStage::VERTEX, "assets/shaders/voxelization.vert", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::GEOMETRY, "assets/shaders/voxelization.geom", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "assets/shaders/voxelization.frag", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadVoxelVisualisationShader() { - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram shader; - compiler.compile(vkcv::ShaderStage::VERTEX, "assets/shaders/voxelVisualisation.vert", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::GEOMETRY, "assets/shaders/voxelVisualisation.geom", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, "assets/shaders/voxelVisualisation.frag", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadVoxelResetShader() { - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram shader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/voxelReset.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadVoxelBufferToImageShader() { - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram shader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/voxelBufferToImage.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -vkcv::ShaderProgram loadSecondaryBounceShader() { - vkcv::shader::GLSLCompiler compiler; - vkcv::ShaderProgram shader; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/voxelSecondaryBounce.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - shader.addShader(shaderStage, path); - }); - return shader; -} - -const uint32_t voxelResolution = 128; -uint32_t voxelCount = voxelResolution * voxelResolution * voxelResolution; -const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm; -const int maxStableMip = 4; // must be the same as in voxelConeTrace shader function - -Voxelization::Voxelization( - vkcv::Core* corePtr, - const Dependencies& dependencies, - vkcv::BufferHandle lightInfoBuffer, - vkcv::ImageHandle shadowMap, - vkcv::SamplerHandle shadowSampler, - vkcv::SamplerHandle voxelSampler, - vkcv::Multisampling msaa) - : - m_corePtr(corePtr), - m_voxelImageIntermediate(vkcv::image(*m_corePtr, vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, true, true)), - m_voxelImage(vkcv::image(*m_corePtr, vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, true, true)), - m_voxelBuffer(buffer<VoxelBufferContent>(*m_corePtr, vkcv::BufferType::STORAGE, voxelCount)), - m_dummyRenderTarget(vkcv::image(*m_corePtr, voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, false, true)), - m_voxelInfoBuffer(buffer<VoxelizationInfo>(*m_corePtr, vkcv::BufferType::UNIFORM, 1)) { - - const vkcv::ShaderProgram voxelizationShader = loadVoxelizationShader(); - - const vkcv::PassConfig voxelizationPassConfig {{ - vkcv::AttachmentDescription( - voxelizationDummyFormat, - vkcv::AttachmentOperation::DONT_CARE, - vkcv::AttachmentOperation::DONT_CARE - ) - }, vkcv::Multisampling::None }; - m_voxelizationPass = m_corePtr->createPass(voxelizationPassConfig); - - m_voxelizationDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelizationShader.getReflectedDescriptors().at(0)); - m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(m_voxelizationDescriptorSetLayout); - - vkcv::DescriptorSetLayoutHandle dummyPerMeshDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelizationShader.getReflectedDescriptors().at(1)); - vkcv::DescriptorSetHandle dummyPerMeshDescriptorSet = m_corePtr->createDescriptorSet(dummyPerMeshDescriptorSetLayout); - - vkcv::GraphicsPipelineConfig voxelizationPipeConfig ( - voxelizationShader, - m_voxelizationPass, - dependencies.vertexLayout, - { m_voxelizationDescriptorSetLayout, dummyPerMeshDescriptorSetLayout } - ); - - voxelizationPipeConfig.setResolution(voxelResolution, voxelResolution); - voxelizationPipeConfig.setUsingConservativeRasterization(true); - - m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig); - - vkcv::DescriptorWrites voxelizationDescriptorWrites; - voxelizationDescriptorWrites.writeStorageBuffer(0, m_voxelBuffer.getHandle()); - voxelizationDescriptorWrites.writeUniformBuffer( - 1, m_voxelInfoBuffer.getHandle() - ).writeUniformBuffer( - 3, lightInfoBuffer - ); - - voxelizationDescriptorWrites.writeSampledImage(4, shadowMap); - voxelizationDescriptorWrites.writeSampler(5, shadowSampler); - voxelizationDescriptorWrites.writeStorageImage(2, m_voxelImageIntermediate.getHandle()); - m_corePtr->writeDescriptorSet(m_voxelizationDescriptorSet, voxelizationDescriptorWrites); - - vkcv::ShaderProgram voxelVisualisationShader = loadVoxelVisualisationShader(); - - m_visualisationDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelVisualisationShader.getReflectedDescriptors().at(0)); - m_visualisationDescriptorSet = m_corePtr->createDescriptorSet(m_visualisationDescriptorSetLayout); - - m_visualisationPass = vkcv::passFormats( - *m_corePtr, - { dependencies.colorBufferFormat, dependencies.depthBufferFormat }, - false, - msaa - ); - - vkcv::GraphicsPipelineConfig voxelVisualisationPipeConfig ( - voxelVisualisationShader, - m_visualisationPass, - {}, - { m_visualisationDescriptorSetLayout } - ); // points are extended to cubes in the geometry shader - - voxelVisualisationPipeConfig.setPrimitiveTopology(vkcv::PrimitiveTopology::PointList); - m_visualisationPipe = m_corePtr->createGraphicsPipeline(voxelVisualisationPipeConfig); - - std::vector<uint16_t> voxelIndexData; - for (uint32_t i = 0; i < voxelCount; i++) { - voxelIndexData.push_back(static_cast<uint16_t>(i)); - } - - const auto voxelizationDescriptorUsage = vkcv::useDescriptorSet(0, m_visualisationDescriptorSet); - - vkcv::ShaderProgram resetVoxelShader = loadVoxelResetShader(); - - m_voxelResetDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(resetVoxelShader.getReflectedDescriptors().at(0)); - m_voxelResetDescriptorSet = m_corePtr->createDescriptorSet(m_voxelResetDescriptorSetLayout); - m_voxelResetPipe = m_corePtr->createComputePipeline({ - resetVoxelShader, - { m_voxelResetDescriptorSetLayout } - }); - - vkcv::DescriptorWrites resetVoxelWrites; - resetVoxelWrites.writeStorageBuffer(0, m_voxelBuffer.getHandle()); - m_corePtr->writeDescriptorSet(m_voxelResetDescriptorSet, resetVoxelWrites); - - // buffer to image - vkcv::ShaderProgram bufferToImageShader = loadVoxelBufferToImageShader(); - - m_bufferToImageDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(bufferToImageShader.getReflectedDescriptors().at(0)); - m_bufferToImageDescriptorSet = m_corePtr->createDescriptorSet(m_bufferToImageDescriptorSetLayout); - m_bufferToImagePipe = m_corePtr->createComputePipeline({ - bufferToImageShader, - { m_bufferToImageDescriptorSetLayout } - }); - - vkcv::DescriptorWrites bufferToImageDescriptorWrites; - bufferToImageDescriptorWrites.writeStorageBuffer(0, m_voxelBuffer.getHandle()); - bufferToImageDescriptorWrites.writeStorageImage(1, m_voxelImageIntermediate.getHandle()); - m_corePtr->writeDescriptorSet(m_bufferToImageDescriptorSet, bufferToImageDescriptorWrites); - - // secondary bounce - vkcv::ShaderProgram secondaryBounceShader = loadSecondaryBounceShader(); - - m_secondaryBounceDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(secondaryBounceShader.getReflectedDescriptors().at(0)); - m_secondaryBounceDescriptorSet = m_corePtr->createDescriptorSet(m_secondaryBounceDescriptorSetLayout); - m_secondaryBouncePipe = m_corePtr->createComputePipeline({ - secondaryBounceShader, - { m_secondaryBounceDescriptorSetLayout } - }); - - vkcv::DescriptorWrites secondaryBounceDescriptorWrites; - secondaryBounceDescriptorWrites.writeStorageBuffer(0, m_voxelBuffer.getHandle()); - secondaryBounceDescriptorWrites.writeSampledImage(1, m_voxelImageIntermediate.getHandle()); - secondaryBounceDescriptorWrites.writeSampler(2, voxelSampler); - secondaryBounceDescriptorWrites.writeStorageImage(3, m_voxelImage.getHandle()); - secondaryBounceDescriptorWrites.writeUniformBuffer(4, m_voxelInfoBuffer.getHandle()); - m_corePtr->writeDescriptorSet(m_secondaryBounceDescriptorSet, secondaryBounceDescriptorWrites); -} - -void Voxelization::voxelizeMeshes( - vkcv::CommandStreamHandle cmdStream, - const std::vector<vkcv::VertexData>& meshes, - const std::vector<glm::mat4>& modelMatrices, - const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets, - const vkcv::WindowHandle& windowHandle, - vkcv::Downsampler& downsampler) { - - m_voxelInfoBuffer.fill({ m_voxelInfo }); - - const float voxelizationHalfExtent = 0.5f * m_voxelInfo.extent; - const glm::mat4 voxelizationProjection = glm::ortho( - -voxelizationHalfExtent, - voxelizationHalfExtent, - -voxelizationHalfExtent, - voxelizationHalfExtent, - -voxelizationHalfExtent, - voxelizationHalfExtent); - - const glm::mat4 voxelizationView = glm::translate(glm::mat4(1.f), -m_voxelInfo.offset); - const glm::mat4 voxelizationViewProjection = voxelizationProjection * voxelizationView; - - vkcv::PushConstants voxelizationPushConstants (2 * sizeof(glm::mat4)); - - for (const auto& m : modelMatrices) { - voxelizationPushConstants.appendDrawcall(std::array<glm::mat4, 2>{ voxelizationViewProjection * m, m }); - } - - // reset voxels - const uint32_t resetVoxelGroupSize = 64; - - vkcv::PushConstants voxelCountPushConstants = vkcv::pushConstants<uint32_t>(); - voxelCountPushConstants.appendDrawcall(voxelCount); - - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel reset", { 1, 1, 1, 1 }); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_voxelResetPipe, - vkcv::dispatchInvocations(voxelCount, resetVoxelGroupSize), - { vkcv::useDescriptorSet(0, m_voxelResetDescriptorSet) }, - voxelCountPushConstants - ); - m_corePtr->recordBufferMemoryBarrier(cmdStream, m_voxelBuffer.getHandle()); - m_corePtr->recordEndDebugLabel(cmdStream); - - // voxelization - std::vector<vkcv::InstanceDrawcall> drawcalls; - for (size_t i = 0; i < meshes.size(); i++) { - vkcv::InstanceDrawcall drawcall (meshes[i]); - drawcall.useDescriptorSet(0, m_voxelizationDescriptorSet); - drawcall.useDescriptorSet(1, perMeshDescriptorSets[i]); - drawcalls.push_back(drawcall); - } - - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxelization", { 1, 1, 1, 1 }); - m_corePtr->prepareImageForStorage(cmdStream, m_voxelImageIntermediate.getHandle()); - m_corePtr->recordDrawcallsToCmdStream( - cmdStream, - m_voxelizationPipe, - voxelizationPushConstants, - drawcalls, - { m_dummyRenderTarget.getHandle() }, - windowHandle - ); - m_corePtr->recordEndDebugLabel(cmdStream); - - // buffer to image - const auto bufferToImageDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(voxelResolution, voxelResolution, voxelResolution), - vkcv::DispatchSize(4, 4, 4) - ); - - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel buffer to image", { 1, 1, 1, 1 }); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_bufferToImagePipe, - bufferToImageDispatchCount, - { vkcv::useDescriptorSet(0, m_bufferToImageDescriptorSet) }, - vkcv::PushConstants(0) - ); - - m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImageIntermediate.getHandle()); - m_corePtr->recordEndDebugLabel(cmdStream); - - // intermediate image mipchain - m_corePtr->recordBeginDebugLabel(cmdStream, "Intermediate Voxel mipmap generation", { 1, 1, 1, 1 }); - m_voxelImageIntermediate.recordMipChainGeneration(cmdStream, downsampler); - m_corePtr->recordEndDebugLabel(cmdStream); - - // secondary bounce - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel secondary bounce", { 1, 1, 1, 1 }); - m_corePtr->prepareImageForStorage(cmdStream, m_voxelImage.getHandle()); - m_corePtr->recordComputeDispatchToCmdStream( - cmdStream, - m_secondaryBouncePipe, - bufferToImageDispatchCount, - { vkcv::useDescriptorSet(0, m_secondaryBounceDescriptorSet) }, - vkcv::PushConstants(0)); - m_voxelImage.recordMipChainGeneration(cmdStream, downsampler); - m_corePtr->recordEndDebugLabel(cmdStream); - - // final image mipchain - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel mipmap generation", { 1, 1, 1, 1 }); - m_voxelImage.recordMipChainGeneration(cmdStream, downsampler); - m_corePtr->recordEndDebugLabel(cmdStream); -} - -void Voxelization::renderVoxelVisualisation( - vkcv::CommandStreamHandle cmdStream, - const glm::mat4& viewProjectin, - const std::vector<vkcv::ImageHandle>& renderTargets, - uint32_t mipLevel, - const vkcv::WindowHandle& windowHandle) { - - vkcv::PushConstants voxelVisualisationPushConstants = vkcv::pushConstants<glm::mat4>(); - voxelVisualisationPushConstants.appendDrawcall(viewProjectin); - - mipLevel = std::clamp(mipLevel, (uint32_t) 0, m_voxelImage.getMipLevels() - 1); - - // write descriptor set - vkcv::DescriptorWrites voxelVisualisationDescriptorWrite; - voxelVisualisationDescriptorWrite.writeStorageImage(0, m_voxelImage.getHandle(), mipLevel); - voxelVisualisationDescriptorWrite.writeUniformBuffer(1, m_voxelInfoBuffer.getHandle()); - m_corePtr->writeDescriptorSet(m_visualisationDescriptorSet, voxelVisualisationDescriptorWrite); - - uint32_t drawVoxelCount = voxelCount / exp2(mipLevel); - - vkcv::VertexData voxelData; - voxelData.setCount(drawVoxelCount); - - vkcv::InstanceDrawcall drawcall (voxelData); - drawcall.useDescriptorSet(0, m_visualisationDescriptorSet); - - m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel visualisation", { 1, 1, 1, 1 }); - m_corePtr->prepareImageForStorage(cmdStream, m_voxelImage.getHandle()); - m_corePtr->recordDrawcallsToCmdStream( - cmdStream, - m_visualisationPipe, - voxelVisualisationPushConstants, - { drawcall }, - renderTargets, - windowHandle - ); - m_corePtr->recordEndDebugLabel(cmdStream); -} - -void Voxelization::updateVoxelOffset(const vkcv::camera::Camera& camera) { - - // move voxel offset with camera in voxel sized steps - const float voxelSize = m_voxelInfo.extent / voxelResolution; - const float snapSize = voxelSize * exp2(maxStableMip); - - glm::vec3 voxelVolumeCenter = camera.getPosition() + (1.f / 3.f) * m_voxelInfo.extent * glm::normalize(camera.getFront()); - voxelVolumeCenter.y = camera.getPosition().y; - m_voxelInfo.offset = glm::floor(voxelVolumeCenter / snapSize) * snapSize; -} - -void Voxelization::setVoxelExtent(float extent) { - m_voxelInfo.extent = extent; -} - -vkcv::ImageHandle Voxelization::getVoxelImageHandle() const { - return m_voxelImage.getHandle(); -} - -vkcv::BufferHandle Voxelization::getVoxelInfoBufferHandle() const { - return m_voxelInfoBuffer.getHandle(); -} - -glm::vec3 Voxelization::getVoxelOffset() const{ - return m_voxelInfo.offset; -} - -float Voxelization::getVoxelExtent() const { - return m_voxelInfo.extent; -} diff --git a/projects/voxelization/src/Voxelization.hpp b/projects/voxelization/src/Voxelization.hpp deleted file mode 100644 index f624d03503b67cc2de0632367d90742fb975473e..0000000000000000000000000000000000000000 --- a/projects/voxelization/src/Voxelization.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Image.hpp> -#include <glm/glm.hpp> -#include <vkcv/camera/Camera.hpp> -#include <vkcv/Downsampler.hpp> - -class Voxelization{ -public: - struct Dependencies { - vkcv::VertexLayout vertexLayout; - vk::Format colorBufferFormat; - vk::Format depthBufferFormat; - }; - Voxelization( - vkcv::Core* corePtr, - const Dependencies& dependencies, - vkcv::BufferHandle lightInfoBuffer, - vkcv::ImageHandle shadowMap, - vkcv::SamplerHandle shadowSampler, - vkcv::SamplerHandle voxelSampler, - vkcv::Multisampling msaa); - - void voxelizeMeshes( - vkcv::CommandStreamHandle cmdStream, - const std::vector<vkcv::VertexData>& meshes, - const std::vector<glm::mat4>& modelMatrices, - const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets, - const vkcv::WindowHandle& windowHandle, - vkcv::Downsampler& downsampler); - - void renderVoxelVisualisation( - vkcv::CommandStreamHandle cmdStream, - const glm::mat4& viewProjectin, - const std::vector<vkcv::ImageHandle>& renderTargets, - uint32_t mipLevel, - const vkcv::WindowHandle& windowHandle); - - void updateVoxelOffset(const vkcv::camera::Camera& camera); - void setVoxelExtent(float extent); - - vkcv::ImageHandle getVoxelImageHandle() const; - vkcv::BufferHandle getVoxelInfoBufferHandle() const; - - glm::vec3 getVoxelOffset() const; - float getVoxelExtent() const; - -private: - vkcv::Core* m_corePtr; - - struct VoxelBufferContent{ - uint32_t lightEncoded; - uint32_t normalEncoded; - uint32_t albedoEncoded; - }; - - vkcv::Image m_voxelImageIntermediate; - vkcv::Image m_voxelImage; - vkcv::Buffer<VoxelBufferContent> m_voxelBuffer; - - vkcv::Image m_dummyRenderTarget; - vkcv::PassHandle m_voxelizationPass; - vkcv::GraphicsPipelineHandle m_voxelizationPipe; - vkcv::DescriptorSetLayoutHandle m_voxelizationDescriptorSetLayout; - vkcv::DescriptorSetHandle m_voxelizationDescriptorSet; - - vkcv::ComputePipelineHandle m_voxelResetPipe; - vkcv::DescriptorSetLayoutHandle m_voxelResetDescriptorSetLayout; - vkcv::DescriptorSetHandle m_voxelResetDescriptorSet; - - vkcv::ComputePipelineHandle m_bufferToImagePipe; - vkcv::DescriptorSetLayoutHandle m_bufferToImageDescriptorSetLayout; - vkcv::DescriptorSetHandle m_bufferToImageDescriptorSet; - - vkcv::PassHandle m_visualisationPass; - vkcv::GraphicsPipelineHandle m_visualisationPipe; - - vkcv::ComputePipelineHandle m_secondaryBouncePipe; - vkcv::DescriptorSetLayoutHandle m_secondaryBounceDescriptorSetLayout; - vkcv::DescriptorSetHandle m_secondaryBounceDescriptorSet; - - vkcv::DescriptorSetLayoutHandle m_visualisationDescriptorSetLayout; - vkcv::DescriptorSetHandle m_visualisationDescriptorSet; - - struct VoxelizationInfo { - glm::vec3 offset; - float extent; - }; - vkcv::Buffer<VoxelizationInfo> m_voxelInfoBuffer; - - VoxelizationInfo m_voxelInfo; -}; \ No newline at end of file diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp deleted file mode 100644 index ac2b2b6a19c23e039178da43705a4f1033fa6682..0000000000000000000000000000000000000000 --- a/projects/voxelization/src/main.cpp +++ /dev/null @@ -1,1000 +0,0 @@ -#include <iostream> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Sampler.hpp> -#include <GLFW/glfw3.h> -#include <vkcv/camera/CameraManager.hpp> -#include <chrono> -#include <vkcv/asset/asset_loader.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> -#include "Voxelization.hpp" -#include "vkcv/gui/GUI.hpp" -#include "ShadowMapping.hpp" -#include <vkcv/upscaling/FSRUpscaling.hpp> -#include <vkcv/upscaling/BilinearUpscaling.hpp> -#include <vkcv/upscaling/NISUpscaling.hpp> -#include <vkcv/effects/BloomAndFlaresEffect.hpp> -#include <vkcv/algorithm/SinglePassDownsampler.hpp> - -int main(int argc, const char** argv) { - const std::string applicationName = "Voxelization"; - - const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA4X; - const bool usingMsaa = msaa != vkcv::Multisampling::None; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - features.requireExtensionFeature<vk::PhysicalDeviceDescriptorIndexingFeatures>( - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, - [](vk::PhysicalDeviceDescriptorIndexingFeatures& features) { - features.setDescriptorBindingPartiallyBound(true); - } - ); - - features.tryExtensionFeature<vk::PhysicalDeviceShaderSubgroupExtendedTypesFeatures>( - VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME, - [](vk::PhysicalDeviceShaderSubgroupExtendedTypesFeatures& features) { - features.setShaderSubgroupExtendedTypes(true); - } - ); - - features.tryExtensionFeature<vk::PhysicalDevice16BitStorageFeatures>( - VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, - [](vk::PhysicalDevice16BitStorageFeatures& features) { - features.setStorageBuffer16BitAccess(true); - } - ); - - features.tryExtensionFeature<vk::PhysicalDeviceShaderFloat16Int8Features>( - VK_KHR_16BIT_STORAGE_EXTENSION_NAME, - [](vk::PhysicalDeviceShaderFloat16Int8Features& features) { - features.setShaderFloat16(true); - } - ); - - const uint32_t windowWidth = 1280; - const uint32_t windowHeight = 720; - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, - features - ); - - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - - bool isFullscreen = false; - uint32_t windowedWidthBackup = window.getWidth(); - uint32_t windowedHeightBackup = window.getHeight(); - int windowedPosXBackup; - int windowedPosYBackup; - glfwGetWindowPos(window.getWindow(), &windowedPosXBackup, &windowedPosYBackup); - - window.e_key.add([&](int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_F11 && action == GLFW_PRESS) { - if (isFullscreen) { - glfwSetWindowMonitor( - window.getWindow(), - nullptr, - windowedPosXBackup, - windowedPosYBackup, - windowedWidthBackup, - windowedHeightBackup, - GLFW_DONT_CARE); - } - else { - windowedWidthBackup = window.getWidth(); - windowedHeightBackup = window.getHeight(); - - glfwGetWindowPos(window.getWindow(), &windowedPosXBackup, &windowedPosYBackup); - - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* videoMode = glfwGetVideoMode(monitor); - - glfwSetWindowMonitor( - window.getWindow(), - glfwGetPrimaryMonitor(), - 0, - 0, - videoMode->width, - videoMode->height, - videoMode->refreshRate); - } - isFullscreen = !isFullscreen; - } - }); - - vkcv::camera::CameraManager cameraManager(window); - auto camHandle0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto camHandle1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camHandle0).setPosition(glm::vec3(0.f, 0.f, 3.f)); - cameraManager.getCamera(camHandle0).setNearFar(0.1f, 30.0f); - cameraManager.getCamera(camHandle0).setYaw(180.0f); - cameraManager.getCamera(camHandle0).setFov(glm::radians(37.8)); // fov of a 35mm lens - - cameraManager.getCamera(camHandle1).setNearFar(0.1f, 30.0f); - - vkcv::asset::Scene mesh; - - const char* path = argc > 1 ? argv[1] : "assets/Sponza/Sponza.gltf"; - vkcv::asset::Scene scene; - int result = vkcv::asset::loadScene(path, scene); - - if (result == 1) { - std::cout << "Scene loading successful!" << std::endl; - } - else { - std::cout << "Scene loading failed: " << result << std::endl; - return 1; - } - - // build index and vertex buffers - assert(!scene.vertexGroups.empty()); - std::vector<std::vector<uint8_t>> vBuffers; - std::vector<std::vector<uint8_t>> iBuffers; - - std::vector<std::vector<vkcv::VertexBufferBinding>> vertexBufferBindings; - - for (size_t i = 0; i < scene.vertexGroups.size(); i++) { - vBuffers.push_back(scene.vertexGroups[i].vertexBuffer.data); - iBuffers.push_back(scene.vertexGroups[i].indexBuffer.data); - } - - std::vector<vkcv::Buffer<uint8_t>> vertexBuffers; - for (const vkcv::asset::VertexGroup& group : scene.vertexGroups) { - vertexBuffers.push_back(buffer<uint8_t>( - core, - vkcv::BufferType::VERTEX, - group.vertexBuffer.data.size())); - vertexBuffers.back().fill(group.vertexBuffer.data); - } - - std::vector<vkcv::Buffer<uint8_t>> indexBuffers; - for (const auto& dataBuffer : iBuffers) { - indexBuffers.push_back(buffer<uint8_t>( - core, - vkcv::BufferType::INDEX, - dataBuffer.size())); - indexBuffers.back().fill(dataBuffer); - } - - for (size_t i = 0; i < scene.vertexGroups.size(); i++) { - vertexBufferBindings.push_back(vkcv::asset::loadVertexBufferBindings( - scene.vertexGroups[i].vertexBuffer.attributes, - vertexBuffers[i].getHandle(), - { - vkcv::asset::PrimitiveType::POSITION, - vkcv::asset::PrimitiveType::NORMAL, - vkcv::asset::PrimitiveType::TEXCOORD_0, - vkcv::asset::PrimitiveType::TANGENT - } - )); - } - - const vk::Format colorBufferFormat = vk::Format::eB10G11R11UfloatPack32; - const vkcv::AttachmentDescription color_attachment ( - colorBufferFormat, - vkcv::AttachmentOperation::CLEAR, - vkcv::AttachmentOperation::STORE - ); - - const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; - const vkcv::AttachmentDescription depth_attachment ( - depthBufferFormat, - vkcv::AttachmentOperation::LOAD, - vkcv::AttachmentOperation::STORE - ); - - // forward shading config - vkcv::PassConfig forwardPassDefinition({ color_attachment, depth_attachment }, msaa); - vkcv::PassHandle forwardPass = core.createPass(forwardPassDefinition); - - vkcv::shader::GLSLCompiler compiler; - - vkcv::ShaderProgram forwardProgram; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/shader.vert"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - forwardProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - forwardProgram.addShader(shaderStage, path); - }); - - const std::vector<vkcv::VertexAttachment> vertexAttachments = forwardProgram.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> vertexBindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { - vertexBindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] })); - } - const vkcv::VertexLayout vertexLayout { vertexBindings }; - - vkcv::DescriptorSetLayoutHandle forwardShadingDescriptorSetLayout = core.createDescriptorSetLayout(forwardProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle forwardShadingDescriptorSet = core.createDescriptorSet(forwardShadingDescriptorSetLayout); - - // depth prepass config - vkcv::ShaderProgram depthPrepassShader; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/depthPrepass.vert"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - depthPrepassShader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/depthPrepass.frag"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - depthPrepassShader.addShader(shaderStage, path); - }); - - const std::vector<vkcv::VertexAttachment> prepassVertexAttachments = depthPrepassShader.getVertexAttachments(); - - std::vector<vkcv::VertexBinding> prepassVertexBindings; - for (size_t i = 0; i < prepassVertexAttachments.size(); i++) { - prepassVertexBindings.push_back(vkcv::createVertexBinding(i, { prepassVertexAttachments[i] })); - } - const vkcv::VertexLayout prepassVertexLayout { prepassVertexBindings }; - - vkcv::PassHandle prepassPass = vkcv::passFormat(core, depthBufferFormat, true, msaa); - - // create descriptor sets - vkcv::SamplerHandle colorSampler = vkcv::samplerLinear(core); - - std::vector<vkcv::DescriptorSetLayoutHandle> materialDescriptorSetLayouts; - std::vector<vkcv::DescriptorSetHandle> materialDescriptorSets; - std::vector<vkcv::Image> sceneImages; - - vkcv::algorithm::SinglePassDownsampler spdDownsampler (core, colorSampler); - - auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics); - - for (const auto& material : scene.materials) { - int albedoIndex = material.baseColor; - int normalIndex = material.normal; - int specularIndex = material.metalRough; - - if (albedoIndex < 0) { - vkcv_log(vkcv::LogLevel::WARNING, "Material lacks albedo"); - albedoIndex = 0; - } - if (normalIndex < 0) { - vkcv_log(vkcv::LogLevel::WARNING, "Material lacks normal"); - normalIndex = 0; - } - if (specularIndex < 0) { - vkcv_log(vkcv::LogLevel::WARNING, "Material lacks specular"); - specularIndex = 0; - } - - materialDescriptorSetLayouts.push_back(core.createDescriptorSetLayout(forwardProgram.getReflectedDescriptors().at(1))); - materialDescriptorSets.push_back(core.createDescriptorSet(materialDescriptorSetLayouts.back())); - - vkcv::asset::Texture& albedoTexture = scene.textures[albedoIndex]; - vkcv::asset::Texture& normalTexture = scene.textures[normalIndex]; - vkcv::asset::Texture& specularTexture = scene.textures[specularIndex]; - - // albedo texture - sceneImages.push_back(vkcv::image(core, vk::Format::eR8G8B8A8Srgb, albedoTexture.w, albedoTexture.h, 1, true)); - sceneImages.back().fill(albedoTexture.data.data()); - sceneImages.back().recordMipChainGeneration(mipStream, spdDownsampler); - const vkcv::ImageHandle albedoHandle = sceneImages.back().getHandle(); - - // normal texture - sceneImages.push_back(vkcv::image(core, vk::Format::eR8G8B8A8Unorm, normalTexture.w, normalTexture.h, 1, true, true)); - sceneImages.back().fill(normalTexture.data.data()); - sceneImages.back().recordMipChainGeneration(mipStream, spdDownsampler); - const vkcv::ImageHandle normalHandle = sceneImages.back().getHandle(); - - // specular texture - sceneImages.push_back(vkcv::image(core, vk::Format::eR8G8B8A8Unorm, specularTexture.w, specularTexture.h, 1, true, true)); - sceneImages.back().fill(specularTexture.data.data()); - sceneImages.back().recordMipChainGeneration(mipStream, spdDownsampler); - const vkcv::ImageHandle specularHandle = sceneImages.back().getHandle(); - - vkcv::DescriptorWrites setWrites; - setWrites.writeSampledImage( - 0, albedoHandle - ).writeSampledImage( - 2, normalHandle - ).writeSampledImage( - 3, specularHandle - ); - - setWrites.writeSampler(1, colorSampler); - core.writeDescriptorSet(materialDescriptorSets.back(), setWrites); - } - - core.submitCommandStream(mipStream, false); - - std::vector<vkcv::DescriptorSetLayoutHandle> perMeshDescriptorSetLayouts; - std::vector<vkcv::DescriptorSetHandle> perMeshDescriptorSets; - for (const auto& vertexGroup : scene.vertexGroups) { - perMeshDescriptorSetLayouts.push_back(materialDescriptorSetLayouts[vertexGroup.materialIndex]); - perMeshDescriptorSets.push_back(materialDescriptorSets[vertexGroup.materialIndex]); - } - - // prepass pipeline - vkcv::DescriptorSetLayoutHandle prepassDescriptorSetLayout = core.createDescriptorSetLayout({}); - vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(prepassDescriptorSetLayout); - - auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); - - vkcv::GraphicsPipelineConfig prepassPipelineConfig ( - depthPrepassShader, - prepassPass, - vertexLayout, - { prepassDescriptorSetLayout, perMeshDescriptorSetLayouts[0] } - ); - - prepassPipelineConfig.setCulling(vkcv::CullMode::Back); - prepassPipelineConfig.setDepthTest(vkcv::DepthTest::LessEqual); - prepassPipelineConfig.setWritingAlphaToCoverage(true); - - vkcv::GraphicsPipelineHandle prepassPipeline = core.createGraphicsPipeline(prepassPipelineConfig); - - // forward pipeline - vkcv::GraphicsPipelineConfig forwardPipelineConfig ( - forwardProgram, - forwardPass, - vertexLayout, - { forwardShadingDescriptorSetLayout, perMeshDescriptorSetLayouts[0] } - ); - - forwardPipelineConfig.setCulling(vkcv::CullMode::Back); - forwardPipelineConfig.setDepthTest(vkcv::DepthTest::Equal); - forwardPipelineConfig.setWritingDepth(false); - - vkcv::GraphicsPipelineHandle forwardPipeline = core.createGraphicsPipeline(forwardPipelineConfig); - - if (!forwardPipeline) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - // sky - struct SkySettings { - glm::vec3 color; - float strength; - }; - SkySettings skySettings; - skySettings.color = glm::vec3(0.15, 0.65, 1); - skySettings.strength = 5; - - vkcv::PassHandle skyPass = vkcv::passFormats( - core, - { colorBufferFormat, depthBufferFormat }, - false, - msaa - ); - - vkcv::ShaderProgram skyShader; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/sky.vert"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - skyShader.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/sky.frag"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - skyShader.addShader(shaderStage, path); - }); - - vkcv::GraphicsPipelineConfig skyPipeConfig ( - skyShader, - skyPass, - {}, - {} - ); - - skyPipeConfig.setWritingDepth(false); - - vkcv::GraphicsPipelineHandle skyPipe = core.createGraphicsPipeline(skyPipeConfig); - - // render targets - vkcv::ImageHandle depthBuffer = core.createImage( - depthBufferFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, false, false, msaa - ); - - const bool colorBufferRequiresStorage = !usingMsaa; - vkcv::ImageHandle colorBuffer = core.createImage( - colorBufferFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, colorBufferRequiresStorage, true, msaa - ); - - vkcv::ImageHandle resolvedColorBuffer; - if (usingMsaa) { - resolvedColorBuffer = core.createImage( - colorBufferFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true, true - ); - } - else { - resolvedColorBuffer = colorBuffer; - } - - vkcv::ImageHandle swapBuffer = core.createImage( - colorBufferFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true - ); - - vkcv::ImageHandle swapBuffer2 = core.createImage( - colorBufferFormat, - swapchainExtent.width, - swapchainExtent.height, - 1, false, true - ); - - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - bool renderVoxelVis = false; - window.e_key.add([&renderVoxelVis](int key ,int scancode, int action, int mods) { - if (key == GLFW_KEY_V && action == GLFW_PRESS) { - renderVoxelVis = !renderVoxelVis; - } - }); - - bool renderUI = true; - window.e_key.add([&renderUI](int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_I && action == GLFW_PRESS) { - renderUI = !renderUI; - } - }); - - // tonemapping compute shader - vkcv::ShaderProgram tonemappingProgram; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/tonemapping.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - tonemappingProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle tonemappingDescriptorSetLayout = core.createDescriptorSetLayout( - tonemappingProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle tonemappingDescriptorSet = core.createDescriptorSet(tonemappingDescriptorSetLayout); - vkcv::ComputePipelineHandle tonemappingPipeline = core.createComputePipeline({ - tonemappingProgram, - { tonemappingDescriptorSetLayout } - }); - - // tonemapping compute shader - vkcv::ShaderProgram postEffectsProgram; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/postEffects.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - postEffectsProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle postEffectsDescriptorSetLayout = core.createDescriptorSetLayout( - postEffectsProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle postEffectsDescriptorSet = core.createDescriptorSet(postEffectsDescriptorSetLayout); - vkcv::ComputePipelineHandle postEffectsPipeline = core.createComputePipeline({ - postEffectsProgram, - { postEffectsDescriptorSetLayout } - }); - - // resolve compute shader - vkcv::ShaderProgram resolveProgram; - compiler.compile(vkcv::ShaderStage::COMPUTE, "assets/shaders/msaa4XResolve.comp", - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - resolveProgram.addShader(shaderStage, path); - }); - - vkcv::DescriptorSetLayoutHandle resolveDescriptorSetLayout = core.createDescriptorSetLayout( - resolveProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle resolveDescriptorSet = core.createDescriptorSet(resolveDescriptorSetLayout); - vkcv::ComputePipelineHandle resolvePipeline = core.createComputePipeline({ - resolveProgram, - { resolveDescriptorSetLayout } - }); - - vkcv::SamplerHandle resolveSampler = vkcv::samplerNearest(core, true); - - // model matrices per mesh - std::vector<glm::mat4> modelMatrices; - modelMatrices.resize(scene.vertexGroups.size(), glm::mat4(1.f)); - for (const auto& mesh : scene.meshes) { - const glm::mat4 m = *reinterpret_cast<const glm::mat4*>(&mesh.modelMatrix[0]); - for (const auto& vertexGroupIndex : mesh.vertexGroups) { - modelMatrices[vertexGroupIndex] = m; - } - } - - // prepare meshes - std::vector<vkcv::VertexData> meshes; - for (size_t i = 0; i < scene.vertexGroups.size(); i++) { - vkcv::VertexData mesh (vertexBufferBindings[i]); - mesh.setIndexBuffer(indexBuffers[i].getHandle()); - mesh.setCount(scene.vertexGroups[i].numIndices); - meshes.push_back(mesh); - } - - std::vector<vkcv::InstanceDrawcall> drawcalls; - std::vector<vkcv::InstanceDrawcall> prepassDrawcalls; - for (size_t i = 0; i < meshes.size(); i++) { - vkcv::InstanceDrawcall drawcall (meshes[i]); - drawcall.useDescriptorSet(0, forwardShadingDescriptorSet); - drawcall.useDescriptorSet(1, perMeshDescriptorSets[i]); - - vkcv::InstanceDrawcall prepassDrawcall (meshes[i]); - prepassDrawcall.useDescriptorSet(0, prepassDescriptorSet); - prepassDrawcall.useDescriptorSet(1, perMeshDescriptorSets[i]); - - drawcalls.push_back(drawcall); - prepassDrawcalls.push_back(prepassDrawcall); - } - - vkcv::SamplerHandle voxelSampler = vkcv::samplerLinear(core, true); - - ShadowMapping shadowMapping(&core, vertexLayout); - - Voxelization::Dependencies voxelDependencies; - voxelDependencies.colorBufferFormat = colorBufferFormat; - voxelDependencies.depthBufferFormat = depthBufferFormat; - voxelDependencies.vertexLayout = vertexLayout; - Voxelization voxelization( - &core, - voxelDependencies, - shadowMapping.getLightInfoBuffer(), - shadowMapping.getShadowMap(), - shadowMapping.getShadowSampler(), - voxelSampler, - msaa); - - vkcv::effects::BloomAndFlaresEffect bloomFlares (core, true); - vkcv::Buffer<glm::vec3> cameraPosBuffer = buffer<glm::vec3>(core, vkcv::BufferType::UNIFORM, 1); - - struct VolumetricSettings { - glm::vec3 scatteringCoefficient; - float ambientLight; - glm::vec3 absorptionCoefficient; - }; - vkcv::Buffer<VolumetricSettings> volumetricSettingsBuffer - = buffer<VolumetricSettings>(core, vkcv::BufferType::UNIFORM ,1); - - // write forward pass descriptor set - vkcv::DescriptorWrites forwardDescriptorWrites; - forwardDescriptorWrites.writeUniformBuffer( - 0, shadowMapping.getLightInfoBuffer() - ).writeUniformBuffer( - 3, cameraPosBuffer.getHandle() - ).writeUniformBuffer( - 6, voxelization.getVoxelInfoBufferHandle() - ).writeUniformBuffer( - 7, volumetricSettingsBuffer.getHandle() - ); - - forwardDescriptorWrites.writeSampledImage( - 1, shadowMapping.getShadowMap() - ).writeSampledImage( - 4, voxelization.getVoxelImageHandle() - ); - - forwardDescriptorWrites.writeSampler( - 2, shadowMapping.getShadowSampler() - ).writeSampler( - 5, voxelSampler - ); - - core.writeDescriptorSet(forwardShadingDescriptorSet, forwardDescriptorWrites); - - vkcv::upscaling::FSRUpscaling upscaling (core); - uint32_t fsrWidth = swapchainExtent.width, fsrHeight = swapchainExtent.height; - - vkcv::upscaling::FSRQualityMode fsrMode = vkcv::upscaling::FSRQualityMode::NONE; - int fsrModeIndex = static_cast<int>(fsrMode); - - const std::vector<const char*> fsrModeNames = { - "None", - "Ultra Quality", - "Quality", - "Balanced", - "Performance" - }; - - bool fsrMipLoadBiasFlag = true; - bool fsrMipLoadBiasFlagBackup = fsrMipLoadBiasFlag; - - vkcv::upscaling::BilinearUpscaling upscaling1 (core); - vkcv::upscaling::NISUpscaling upscaling2 (core); - - const std::vector<const char*> modeNames = { - "Bilinear Upscaling", - "FSR Upscaling", - "NIS Upscaling" - }; - - int upscalingMode = 0; - - vkcv::gui::GUI gui(core, windowHandle); - - glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f); - glm::vec3 lightColor = glm::vec3(1); - float lightStrength = 25.f; - float maxShadowDistance = 30.f; - - int voxelVisualisationMip = 0; - float voxelizationExtent = 35.f; - - bool msaaCustomResolve = true; - - glm::vec3 scatteringColor = glm::vec3(1); - float scatteringDensity = 0.005; - glm::vec3 absorptionColor = glm::vec3(1); - float absorptionDensity = 0.005; - float volumetricAmbient = 0.2; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - uint32_t width, height; - vkcv::upscaling::getFSRResolution( - fsrMode, - swapchainWidth, swapchainHeight, - width, height - ); - - if ((width != fsrWidth) || ((height != fsrHeight)) || (fsrMipLoadBiasFlagBackup != fsrMipLoadBiasFlag)) { - fsrWidth = width; - fsrHeight = height; - fsrMipLoadBiasFlagBackup = fsrMipLoadBiasFlag; - - colorSampler = core.createSampler( - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerMipmapMode::LINEAR, - vkcv::SamplerAddressMode::REPEAT, - fsrMipLoadBiasFlag? vkcv::upscaling::getFSRLodBias(fsrMode) : 0.0f - ); - - for (size_t i = 0; i < scene.materials.size(); i++) { - vkcv::DescriptorWrites setWrites; - setWrites.writeSampler(1, colorSampler); - core.writeDescriptorSet(materialDescriptorSets[i], setWrites); - } - - depthBuffer = core.createImage( - depthBufferFormat, - fsrWidth, fsrHeight, 1, - false, false, false, - msaa - ); - - colorBuffer = core.createImage( - colorBufferFormat, - fsrWidth, fsrHeight, 1, - false, colorBufferRequiresStorage, true, - msaa - ); - - if (usingMsaa) { - resolvedColorBuffer = core.createImage( - colorBufferFormat, - fsrWidth, fsrHeight, 1, - false, true, true - ); - } else { - resolvedColorBuffer = colorBuffer; - } - - swapBuffer = core.createImage( - colorBufferFormat, - fsrWidth, fsrHeight, 1, - false, true - ); - - swapBuffer2 = core.createImage( - colorBufferFormat, - swapchainWidth, swapchainHeight, 1, - false, true - ); - } - - // update descriptor sets which use swapchain image - vkcv::DescriptorWrites tonemappingDescriptorWrites; - tonemappingDescriptorWrites.writeSampledImage(0, resolvedColorBuffer); - tonemappingDescriptorWrites.writeSampler(1, colorSampler); - tonemappingDescriptorWrites.writeStorageImage(2, swapBuffer); - - core.writeDescriptorSet(tonemappingDescriptorSet, tonemappingDescriptorWrites); - - // update descriptor sets which use swapchain image - vkcv::DescriptorWrites postEffectsDescriptorWrites; - postEffectsDescriptorWrites.writeSampledImage(0, swapBuffer2); - postEffectsDescriptorWrites.writeSampler(1, colorSampler); - postEffectsDescriptorWrites.writeStorageImage(2, swapchainInput); - - core.writeDescriptorSet(postEffectsDescriptorSet, postEffectsDescriptorWrites); - - // update resolve descriptor, color images could be changed - vkcv::DescriptorWrites resolveDescriptorWrites; - resolveDescriptorWrites.writeSampledImage(0, colorBuffer); - resolveDescriptorWrites.writeSampler(1, resolveSampler); - resolveDescriptorWrites.writeStorageImage(2, resolvedColorBuffer); - core.writeDescriptorSet(resolveDescriptorSet, resolveDescriptorWrites); - - cameraManager.update(dt); - cameraPosBuffer.fill({ cameraManager.getActiveCamera().getPosition() }); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - voxelization.updateVoxelOffset(cameraManager.getActiveCamera()); - - // shadow map - glm::vec2 lightAngleRadian = glm::radians(lightAnglesDegree); - shadowMapping.recordShadowMapRendering( - cmdStream, - lightAngleRadian, - lightColor, - lightStrength, - maxShadowDistance, - meshes, - modelMatrices, - cameraManager.getActiveCamera(), - voxelization.getVoxelOffset(), - voxelization.getVoxelExtent(), - windowHandle, - spdDownsampler - ); - - // voxelization - voxelization.setVoxelExtent(voxelizationExtent); - voxelization.voxelizeMeshes( - cmdStream, - meshes, - modelMatrices, - perMeshDescriptorSets, - windowHandle, - spdDownsampler - ); - - // depth prepass - const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); - - vkcv::PushConstants prepassPushConstants = vkcv::pushConstants<glm::mat4>(); - - std::vector<glm::mat4> prepassMatrices; - for (const auto& m : modelMatrices) { - prepassPushConstants.appendDrawcall(viewProjectionCamera * m); - } - - const std::vector<vkcv::ImageHandle> prepassRenderTargets = { depthBuffer }; - - core.recordBeginDebugLabel(cmdStream, "Depth prepass", { 1, 1, 1, 1 }); - core.recordDrawcallsToCmdStream( - cmdStream, - prepassPipeline, - prepassPushConstants, - prepassDrawcalls, - prepassRenderTargets, - windowHandle - ); - - core.recordImageMemoryBarrier(cmdStream, depthBuffer); - core.recordEndDebugLabel(cmdStream); - - vkcv::PushConstants pushConstants (2 * sizeof(glm::mat4)); - - // main pass - for (const auto& m : modelMatrices) { - pushConstants.appendDrawcall(std::array<glm::mat4, 2>{ viewProjectionCamera * m, m }); - } - - VolumetricSettings volumeSettings; - volumeSettings.scatteringCoefficient = scatteringColor * scatteringDensity; - volumeSettings.absorptionCoefficient = absorptionColor * absorptionDensity; - volumeSettings.ambientLight = volumetricAmbient; - volumetricSettingsBuffer.fill({ volumeSettings }); - - const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; - - core.recordBeginDebugLabel(cmdStream, "Forward rendering", { 1, 1, 1, 1 }); - core.recordDrawcallsToCmdStream( - cmdStream, - forwardPipeline, - pushConstants, - drawcalls, - renderTargets, - windowHandle - ); - core.recordEndDebugLabel(cmdStream); - - if (renderVoxelVis) { - voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets, voxelVisualisationMip, windowHandle); - } - - vkcv::PushConstants skySettingsPushConstants = vkcv::pushConstants<SkySettings>(); - skySettingsPushConstants.appendDrawcall(skySettings); - - vkcv::VertexData skyData; - skyData.setCount(3); - - // sky - core.recordBeginDebugLabel(cmdStream, "Sky", { 1, 1, 1, 1 }); - core.recordDrawcallsToCmdStream( - cmdStream, - skyPipe, - skySettingsPushConstants, - { vkcv::InstanceDrawcall(skyData) }, - renderTargets, - windowHandle - ); - core.recordEndDebugLabel(cmdStream); - - const uint32_t fullscreenLocalGroupSize = 8; - auto fullscreenDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(fsrWidth, fsrHeight), - vkcv::DispatchSize(fullscreenLocalGroupSize, fullscreenLocalGroupSize) - ); - - if (usingMsaa) { - core.recordBeginDebugLabel(cmdStream, "MSAA resolve", { 1, 1, 1, 1 }); - if (msaaCustomResolve) { - core.prepareImageForSampling(cmdStream, colorBuffer); - core.prepareImageForStorage(cmdStream, resolvedColorBuffer); - - assert(msaa == vkcv::Multisampling::MSAA4X); // shaders is written for msaa 4x - core.recordComputeDispatchToCmdStream( - cmdStream, - resolvePipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, resolveDescriptorSet) }, - vkcv::PushConstants(0) - ); - - core.recordImageMemoryBarrier(cmdStream, resolvedColorBuffer); - } - else { - core.resolveMSAAImage(cmdStream, colorBuffer, resolvedColorBuffer); - } - core.recordEndDebugLabel(cmdStream); - } - - bloomFlares.updateCameraDirection(cameraManager.getActiveCamera()); - bloomFlares.recordEffect(cmdStream, resolvedColorBuffer, resolvedColorBuffer); - - core.prepareImageForStorage(cmdStream, swapBuffer); - core.prepareImageForSampling(cmdStream, resolvedColorBuffer); - - core.recordBeginDebugLabel(cmdStream, "Tonemapping", { 1, 1, 1, 1 }); - core.recordComputeDispatchToCmdStream( - cmdStream, - tonemappingPipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, tonemappingDescriptorSet) }, - vkcv::PushConstants(0) - ); - - core.prepareImageForStorage(cmdStream, swapBuffer2); - core.prepareImageForSampling(cmdStream, swapBuffer); - core.recordEndDebugLabel(cmdStream); - - switch (upscalingMode) { - case 0: - upscaling1.recordUpscaling(cmdStream, swapBuffer, swapBuffer2); - break; - case 1: - upscaling.recordUpscaling(cmdStream, swapBuffer, swapBuffer2); - break; - case 2: - upscaling2.recordUpscaling(cmdStream, swapBuffer, swapBuffer2); - break; - default: - break; - } - - core.prepareImageForStorage(cmdStream, swapchainInput); - core.prepareImageForSampling(cmdStream, swapBuffer2); - - vkcv::PushConstants timePushConstants = vkcv::pushConstants<float>(); - timePushConstants.appendDrawcall(static_cast<float>(t * 100000.0)); - - fullscreenDispatchCount = vkcv::dispatchInvocations( - vkcv::DispatchSize(swapchainWidth, swapchainHeight), - vkcv::DispatchSize(fullscreenLocalGroupSize, fullscreenLocalGroupSize) - ); - - core.recordBeginDebugLabel(cmdStream, "Post Processing", { 1, 1, 1, 1 }); - core.recordComputeDispatchToCmdStream( - cmdStream, - postEffectsPipeline, - fullscreenDispatchCount, - { vkcv::useDescriptorSet(0, postEffectsDescriptorSet) }, - timePushConstants - ); - core.recordEndDebugLabel(cmdStream); - - // present and end - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - // draw UI - gui.beginGUI(); - - if (renderUI) { - ImGui::Begin("Settings"); - - ImGui::Checkbox("MSAA custom resolve", &msaaCustomResolve); - - ImGui::DragFloat2("Light angles", &lightAnglesDegree.x); - ImGui::ColorEdit3("Sun color", &lightColor.x); - ImGui::DragFloat("Sun strength", &lightStrength); - ImGui::DragFloat("Max shadow distance", &maxShadowDistance); - maxShadowDistance = std::max(maxShadowDistance, 1.f); - - ImGui::ColorEdit3("Sky color", &skySettings.color.x); - ImGui::DragFloat("Sky strength", &skySettings.strength, 0.1); - - ImGui::Checkbox("Draw voxel visualisation", &renderVoxelVis); - ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7); - ImGui::DragFloat("Voxelization extent", &voxelizationExtent, 1.f, 0.f); - voxelizationExtent = std::max(voxelizationExtent, 1.f); - voxelVisualisationMip = std::max(voxelVisualisationMip, 0); - - ImGui::ColorEdit3("Scattering color", &scatteringColor.x); - ImGui::DragFloat("Scattering density", &scatteringDensity, 0.0001); - ImGui::ColorEdit3("Absorption color", &absorptionColor.x); - ImGui::DragFloat("Absorption density", &absorptionDensity, 0.0001); - ImGui::DragFloat("Volumetric ambient", &volumetricAmbient, 0.002); - - float sharpness = upscaling.getSharpness(); - - ImGui::Combo("FSR Quality Mode", &fsrModeIndex, fsrModeNames.data(), fsrModeNames.size()); - ImGui::DragFloat("FSR Sharpness", &sharpness, 0.001, 0.0f, 1.0f); - ImGui::Checkbox("FSR Mip Lod Bias", &fsrMipLoadBiasFlag); - ImGui::Combo("Upscaling Mode", &upscalingMode, modeNames.data(), modeNames.size()); - - if ((fsrModeIndex >= 0) && (fsrModeIndex <= 4)) { - fsrMode = static_cast<vkcv::upscaling::FSRQualityMode>(fsrModeIndex); - } - - upscaling.setSharpness(sharpness); - upscaling2.setSharpness(sharpness); - - if (ImGui::Button("Reload forward pass")) { - - vkcv::ShaderProgram newForwardProgram; - compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("assets/shaders/shader.vert"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - newForwardProgram.addShader(shaderStage, path); - }); - compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("assets/shaders/shader.frag"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - newForwardProgram.addShader(shaderStage, path); - }); - - forwardPipelineConfig.setShaderProgram(newForwardProgram); - vkcv::GraphicsPipelineHandle newPipeline = core.createGraphicsPipeline(forwardPipelineConfig); - - if (newPipeline) { - forwardPipeline = newPipeline; - } - } - if (ImGui::Button("Reload tonemapping")) { - - vkcv::ShaderProgram newProgram; - compiler.compile(vkcv::ShaderStage::COMPUTE, std::filesystem::path("assets/shaders/tonemapping.comp"), - [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - newProgram.addShader(shaderStage, path); - }); - - vkcv::ComputePipelineHandle newPipeline = core.createComputePipeline({ - newProgram, - { tonemappingDescriptorSetLayout } - }); - - if (newPipeline) { - tonemappingPipeline = newPipeline; - } - } - ImGui::End(); - } - - gui.endGUI(); - }); - - return 0; -} diff --git a/projects/wobble_bobble/.gitignore b/projects/wobble_bobble/.gitignore deleted file mode 100644 index 7ed07ed409373206a95d74e6dbdc27a4cb391fea..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/.gitignore +++ /dev/null @@ -1 +0,0 @@ -wobble_bobble diff --git a/projects/wobble_bobble/CMakeLists.txt b/projects/wobble_bobble/CMakeLists.txt deleted file mode 100644 index 6c90d5222859ccd829cbb5a63ea367cc47214fb3..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(wobble_bobble) - -# setting c++ standard for the project -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# adding source files to the project -add_project(wobble_bobble src/main.cpp) - -# including headers of dependencies and the VkCV framework -target_include_directories(wobble_bobble SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_camera_include} ${vkcv_gui_include} ${vkcv_shader_compiler_include}) - -# linking with libraries from all dependencies and the VkCV framework -target_link_libraries(wobble_bobble vkcv vkcv_camera vkcv_gui vkcv_shader_compiler) diff --git a/projects/wobble_bobble/shaders/.gitignore b/projects/wobble_bobble/shaders/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/projects/wobble_bobble/shaders/grid.frag b/projects/wobble_bobble/shaders/grid.frag deleted file mode 100644 index 8eb2fbc2173bbddb5bdc44c52ce81d2e5d52d389..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/grid.frag +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 - -layout(location = 0) in vec2 passPos; -layout(location = 1) in vec3 passVelocity; -layout(location = 2) in float passMass; - -layout(location = 0) out vec3 outColor; - -void main() { - if (passMass <= 0.0f) { - discard; - } - - const float value = length(passPos); - - float z = sqrt(0.25 - value * value); - - if (value < 0.5f) { - vec3 surface = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f); - vec3 velocity = vec3(0.5f); - - if (length(passVelocity) > 0.0f) { - velocity = vec3(0.5f) + 0.5f * normalize(passVelocity.xyz); - } - - outColor = velocity; - } else { - discard; - } -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/grid.vert b/projects/wobble_bobble/shaders/grid.vert deleted file mode 100644 index 54de3f3e1da43e3ea3d018e5c54003b83e055c4c..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/grid.vert +++ /dev/null @@ -1,58 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -#include "particle.inc" - -layout(set=0, binding=0) uniform texture3D gridImage; -layout(set=0, binding=1) uniform sampler gridSampler; - -layout(set=0, binding=2) uniform simulationBlock { - Simulation simulation; -}; - -layout(location = 0) in vec2 vertexPos; - -layout(location = 0) out vec2 passPos; -layout(location = 1) out vec3 passVelocity; -layout(location = 2) out float passMass; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -ivec3 actual_mod(ivec3 x, ivec3 y) { - return x - y * (x/y); -} - -void main() { - ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); - - ivec3 gridID = ivec3( - gl_InstanceIndex, - gl_InstanceIndex / gridResolution.x, - gl_InstanceIndex / gridResolution.x / gridResolution.y - ); - - gridID = actual_mod(gridID, gridResolution); - - vec3 position = (vec3(gridID) + vec3(0.5f)) / gridResolution; - - vec3 size = vec3(1.0f) / vec3(gridResolution); - float volume = size.x * size.y * size.z; - float radius = cube_radius(volume); - - vec4 gridData = texture(sampler3D(gridImage, gridSampler), position); - - float mass = gridData.w; - float density = mass / volume; - - float alpha = clamp(density / simulation.density, 0.0f, 1.0f); - - passPos = vertexPos; - passVelocity = gridData.xyz; - passMass = mass; - - // align voxel to face camera - gl_Position = mvp * vec4(position, 1); // transform position into projected view space - gl_Position.xy += vertexPos * (radius * 2.0f) * alpha; // move position directly in view space -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/init_particle_weights.comp b/projects/wobble_bobble/shaders/init_particle_weights.comp deleted file mode 100644 index 9b821e88fc7cc3fcea87b7eb6de0f8f6d629d911..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/init_particle_weights.comp +++ /dev/null @@ -1,43 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; - -#include "particle.inc" - -layout(set=0, binding=0, std430) restrict buffer particleBuffer { - Particle particles []; -}; - -layout(set=1, binding=0) uniform texture3D gridImage; -layout(set=1, binding=1) uniform sampler gridSampler; - -void main() { - if (gl_GlobalInvocationID.x < particles.length()) { - ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal; - - minimal.weight_sum = 1.0f; - - ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); - ivec3 gridWindow = ivec3(minimal.size * 2.0f * gridResolution); - - float weight_sum = 0.0f; - - int i, j, k; - - for (i = -gridWindow.x; i <= gridWindow.x; i++) { - for (j = -gridWindow.y; j <= gridWindow.y; j++) { - for (k = -gridWindow.z; k <= gridWindow.z; k++) { - vec3 offset = vec3(i, j, k) / gridResolution; - vec3 voxel = minimal.position + offset; - - weight_sum += voxel_particle_weight(voxel, minimal); - } - } - } - - if (weight_sum > 0.0f) { - particles[gl_GlobalInvocationID.x].minimal.weight_sum = weight_sum; - } - } -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/lines.frag b/projects/wobble_bobble/shaders/lines.frag deleted file mode 100644 index 37d79d30d2ce751a59b1b467764b2fe464aa5c17..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/lines.frag +++ /dev/null @@ -1,7 +0,0 @@ -#version 450 - -layout(location = 0) out vec3 outColor; - -void main() { - outColor = vec3(1.0f); -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/lines.vert b/projects/wobble_bobble/shaders/lines.vert deleted file mode 100644 index b8e3b01c67986156ad980899697ffea05409b752..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/lines.vert +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -layout(location = 0) in vec3 vertexPos; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(vertexPos, 1); -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.frag b/projects/wobble_bobble/shaders/particle.frag deleted file mode 100644 index 81c0a3594359e816a28b5e3f0301b47ce74a3cd7..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/particle.frag +++ /dev/null @@ -1,18 +0,0 @@ -#version 450 - -layout(location = 0) in vec2 passPos; -layout(location = 1) in float passMass; - -layout(location = 0) out vec3 outColor; - -void main() { - const float value = length(passPos); - - float z = sqrt(0.25 - value * value); - - if (value < 0.5f) { - outColor = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f); - } else { - discard; - } -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.inc b/projects/wobble_bobble/shaders/particle.inc deleted file mode 100644 index a622485eab5bbcafdc51c030281e53b1cc1c5f11..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/particle.inc +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef PARTICLE_INC -#define PARTICLE_INC - -#define EPSILON 0.00000001f - -struct ParticleMinimal { - vec3 position; - float size; - vec3 velocity; - float mass; - - vec3 pad; - float weight_sum; -}; - -struct Particle { - ParticleMinimal minimal; - mat4 deformation; - mat4 mls; -}; - -#define SIM_FORM_SPHERE 0 -#define SIM_FORM_CUBE 1 - -#define SIM_TYPE_HYPERELASTIC 0 -#define SIM_TYPE_FLUID 1 - -#define SIM_MODE_RANDOM 0 -#define SIM_MODE_ORDERED 1 - -struct Simulation { - float density; - float size; - float lame1; - float lame2; - - int form; - int type; - float K; - float E; - - float gamma; - int mode; - float gravity; - int count; -}; - -const float PI = 3.1415926535897932384626433832795; - -float sphere_volume(float radius) { - return 4.0f * (radius * radius * radius) * PI / 3.0f; -} - -float sphere_radius(float volume) { - return pow(volume * 3.0f / 4.0f / PI, 1.0f / 3.0f); -} - -float cube_volume(float radius) { - return 8.0f * (radius * radius * radius); -} - -float cube_radius(float volume) { - return pow(volume / 8.0f, 1.0f / 3.0f); -} - -float weight_A(float x) { - return max(1.0f - x, 0.0f); -} - -float weight_B(float x) { - if (x < 0.5f) { - return 0.75f - x * x; - } else - if (x < 1.5f) { - float y = (1.5f - x); - return 0.5f * y * y; - } else { - return 0.0f; - } -} - -float weight_C(float x) { - if (x < 1.0f) { - return (0.5f * x - 1.0f) * x*x + 2.0f / 3.0f; - } else - if (x < 2.0f) { - float y = (2.0f - x); - return 0.5f / 3.0f * y * y * y; - } else { - return 0.0f; - } -} - -float voxel_particle_weight(vec3 voxel, ParticleMinimal particle) { - vec3 delta = abs(particle.position - voxel) / particle.size; - - if (any(isnan(delta)) || any(isinf(delta))) { - return 0.0f; - } - - vec3 weight = vec3( - weight_C(delta.x), - weight_C(delta.y), - weight_C(delta.z) - ); - - float result = ( - weight.x * weight.y * weight.z - ) / particle.weight_sum; - - if ((isnan(result)) || (isinf(result))) { - return 0.0f; - } else { - return result; - } -} - -#endif // PARTICLE_INC \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/particle.vert b/projects/wobble_bobble/shaders/particle.vert deleted file mode 100644 index a8f697e79eacba361d80b5858405add675e761bb..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/particle.vert +++ /dev/null @@ -1,31 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -#include "particle.inc" - -layout(set=0, binding=0, std430) readonly buffer particleBuffer { - Particle particles []; -}; - -layout(location = 0) in vec2 vertexPos; - -layout(location = 0) out vec2 passPos; -layout(location = 1) out float passMass; - -layout( push_constant ) uniform constants{ - mat4 mvp; -}; - -void main() { - vec3 position = particles[gl_InstanceIndex].minimal.position; - float size = particles[gl_InstanceIndex].minimal.size; - - float mass = particles[gl_InstanceIndex].minimal.mass; - - passPos = vertexPos; - passMass = mass; - - // align particle to face camera - gl_Position = mvp * vec4(position, 1); // transform position into projected view space - gl_Position.xy += vertexPos * size * 2.0f; // move position directly in view space -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp deleted file mode 100644 index 1be18c41303ab2208c8cb4a8c33f41b350315d63..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp +++ /dev/null @@ -1,101 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; - -#include "particle.inc" - -layout(set=0, binding=0, std430) readonly buffer particleBuffer { - Particle particles []; -}; - -layout(set=1, binding=0) uniform simulationBlock { - Simulation simulation; -}; - -layout(set=2, binding=0, rgba16f) restrict writeonly uniform image3D gridImage; - -layout( push_constant ) uniform constants { - float t; - float dt; - float speedfactor; -}; - -#define SHARED_PARTICLES_BATCH_SIZE 64 - -shared ParticleMinimal shared_particles [SHARED_PARTICLES_BATCH_SIZE]; - -void main() { - const vec3 position = (vec3(gl_GlobalInvocationID) + vec3(0.5f)) / imageSize(gridImage); - - float dts = dt * speedfactor; - - vec4 gridValue = vec4(0.0f); - - uint offset = 0; - - for (offset = 0; offset < particles.length(); offset += SHARED_PARTICLES_BATCH_SIZE) { - uint localOffset = offset + gl_LocalInvocationIndex; - - if (localOffset < particles.length()) { - shared_particles[gl_LocalInvocationIndex] = particles[localOffset].minimal; - - shared_particles[gl_LocalInvocationIndex].pad = ( - mat3(particles[localOffset].mls) * - (position - shared_particles[gl_LocalInvocationIndex].position) - ) + ( - shared_particles[gl_LocalInvocationIndex].velocity * - shared_particles[gl_LocalInvocationIndex].mass - ); - } else { - shared_particles[gl_LocalInvocationIndex].position = vec3(0.0f); - shared_particles[gl_LocalInvocationIndex].size = 0.0f; - shared_particles[gl_LocalInvocationIndex].velocity = vec3(0.0f); - shared_particles[gl_LocalInvocationIndex].mass = 0.0f; - - shared_particles[gl_LocalInvocationIndex].pad = vec3(0.0f); - shared_particles[gl_LocalInvocationIndex].weight_sum = 1.0f; - } - - barrier(); - memoryBarrierShared(); - - for (uint i = 0; i < SHARED_PARTICLES_BATCH_SIZE; i++) { - float weight = voxel_particle_weight(position, shared_particles[i]); - - gridValue += vec4( - shared_particles[i].pad * weight, - shared_particles[i].mass * weight - ); - } - - barrier(); - memoryBarrierShared(); - } - - if (any(isnan(gridValue.xyz)) || any(isinf(gridValue.xyz))) { - gridValue.xyz = vec3(0.0f); - } - - gridValue.xyz += vec3(0.0f, -simulation.gravity * dts * gridValue.w, 0.0f); - - bvec3 lowerID = lessThanEqual(gl_GlobalInvocationID, ivec3(0)); - bvec3 negativeVelocity = lessThan(gridValue.xyz, vec3(0.0f)); - - bvec3 greaterID = greaterThanEqual(gl_GlobalInvocationID + ivec3(1), imageSize(gridImage)); - bvec3 positiveVelocity = greaterThan(gridValue.xyz, vec3(0.0f)); - - bvec3 collision = bvec3( - (lowerID.x && negativeVelocity.x) || (greaterID.x && positiveVelocity.x), - (lowerID.y && negativeVelocity.y) || (greaterID.y && positiveVelocity.y), - (lowerID.z && negativeVelocity.z) || (greaterID.z && positiveVelocity.z) - ); - - gridValue.xyz = mix(gridValue.xyz, -gridValue.xyz, collision); - - imageStore( - gridImage, - ivec3(gl_GlobalInvocationID), - gridValue - ); -} \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/update_particle_velocities.comp b/projects/wobble_bobble/shaders/update_particle_velocities.comp deleted file mode 100644 index 4420bc9575bcde4d04d7d4f5531d0091362285c2..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/shaders/update_particle_velocities.comp +++ /dev/null @@ -1,161 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable -#extension GL_EXT_control_flow_attributes : enable - -layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; - -#include "particle.inc" - -layout(set=0, binding=0, std430) restrict buffer particleBuffer { - Particle particles []; -}; - -layout(set=1, binding=0) uniform simulationBlock { - Simulation simulation; -}; - -layout(set=2, binding=0) uniform texture3D gridImage; -layout(set=2, binding=1) uniform sampler gridSampler; - -layout( push_constant ) uniform constants { - float t; - float dt; - float speedfactor; -}; - -void main() { - float dts = dt * speedfactor; - - if (gl_GlobalInvocationID.x < particles.length()) { - Particle particle = particles[gl_GlobalInvocationID.x]; - - vec3 position = particle.minimal.position; - float size = particle.minimal.size; - float mass = particle.minimal.mass; - - ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); - ivec3 gridWindow = ivec3(size * 2.0f * gridResolution); - - mat3 affine_D = mat3(0.0f); - mat3 affine_B = mat3(0.0f); - - vec3 velocity_pic = vec3(0.0f); - vec3 velocity_flip = vec3(particle.minimal.velocity); - - int i, j, k; - - for (i = -gridWindow.x; i <= gridWindow.x; i++) { - for (j = -gridWindow.y; j <= gridWindow.y; j++) { - for (k = -gridWindow.z; k <= gridWindow.z; k++) { - vec3 offset = vec3(i, j, k) / gridResolution; - vec3 voxel = position + offset; - - vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel); - - float weight = voxel_particle_weight(voxel, particle.minimal); - vec3 velocity = gridSample.xyz * weight / gridSample.w; - - if (any(isnan(velocity)) || any(isinf(velocity))) { - velocity = vec3(0.0f); - } - - affine_D += outerProduct(weight * offset, offset); - affine_B += outerProduct(velocity, offset); - - velocity_pic += velocity; - } - } - } - - mat3 mls_Q = mat3(0.0f); - mat3 affine_C = mat3(0.0f); - - mat3 F = mat3(particle.deformation); - - mat3 D_inv = inverse(affine_D); - float D_det = determinant(D_inv); - - if ((isnan(D_det)) || (isinf(D_det))) { - D_inv = mat3(0.0f); - } else { - D_inv *= min(abs(D_det), 1.0f / EPSILON) / abs(D_det); - } - - float J = max(determinant(F), EPSILON); - float volume = sphere_volume(size); - - mat3 stress = mat3(0.0f); - - switch (simulation.type) { - case SIM_TYPE_HYPERELASTIC: - mat3 F_T = transpose(F); - mat3 F_T_inv = inverse(F_T); - - mat3 P_term_0 = simulation.lame2 * (F - F_T_inv); - mat3 P_term_1 = simulation.lame1 * log(J) * F_T_inv; - - mat3 P = P_term_0 + P_term_1; - - stress = P * F_T; - break; - case SIM_TYPE_FLUID: - float pressure = simulation.K * (1.0f / pow(J, simulation.gamma) - 1.0f); - - stress = mat3(-pressure * J); - break; - default: - break; - } - - mls_Q -= dts * volume * stress * D_inv; - - affine_C = affine_B * D_inv; - mls_Q += affine_C * mass; - - F = (mat3(1.0f) + dts * affine_C) * F; - - position = position + velocity_pic * dts; - - const float gridRange = (1.0f - 2.0f * size); - - for (uint i = 0; i < 3; i++) { - if (position[i] - size < 0.0f) { - float a = (size - position[i]) / gridRange; - int b = int(floor(a)); - - a = (a - b) * gridRange; - - if (b % 2 == 0) { - position[i] = size + a; - } else { - position[i] = 1.0f - size - a; - } - - if ((velocity_pic[i] < 0.0f) == (b % 2 == 0)) { - velocity_pic[i] *= -1.0f; - } - } else - if (position[i] + size > 1.0f) { - float a = (position[i] + size - 1.0f) / gridRange; - int b = int(floor(a)); - - a = (a - b) * gridRange; - - if (b % 2 == 0) { - position[i] = 1.0f - size - a; - } else { - position[i] = size + a; - } - - if ((velocity_pic[i] > 0.0f) == (b % 2 == 0)) { - velocity_pic[i] *= -1.0f; - } - } - } - - particles[gl_GlobalInvocationID.x].minimal.position = position; - particles[gl_GlobalInvocationID.x].minimal.velocity = velocity_pic; - particles[gl_GlobalInvocationID.x].deformation = mat4(F); - particles[gl_GlobalInvocationID.x].mls = mat4(mls_Q); - } -} \ No newline at end of file diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp deleted file mode 100644 index 1c3eb776b43d29ffe53aa62a03e3bc06fe145767..0000000000000000000000000000000000000000 --- a/projects/wobble_bobble/src/main.cpp +++ /dev/null @@ -1,838 +0,0 @@ - -#include <vkcv/Buffer.hpp> -#include <vkcv/Core.hpp> -#include <vkcv/Pass.hpp> -#include <vkcv/Image.hpp> -#include <vkcv/camera/CameraManager.hpp> -#include <vkcv/gui/GUI.hpp> -#include <vkcv/shader/GLSLCompiler.hpp> - -#include <random> - -struct Particle { - glm::vec3 position; - float size; - glm::vec3 velocity; - float mass; - - glm::vec3 pad; - float weight_sum; - - glm::mat4 deformation; - glm::mat4 mls; -}; - -#define SIM_FORM_SPHERE 0 -#define SIM_FORM_CUBE 1 - -#define SIM_TYPE_HYPERELASTIC 0 -#define SIM_TYPE_FLUID 1 - -#define SIM_MODE_RANDOM 0 -#define SIM_MODE_ORDERED 1 - -struct Simulation { - float density; - float size; - float lame1; - float lame2; - - int form; - int type; - float K; - float E; - - float gamma; - int mode; - float gravity; - int count; -}; - -struct Physics { - float t; - float dt; - float speedfactor; -}; - -float sphere_volume(float radius) { - return 4.0f * (radius * radius * radius) * M_PI / 3.0f; -} - -float sphere_radius(float volume) { - return std::pow(volume * 3.0f / 4.0f / M_PI, 1.0f / 3.0f); -} - -float cube_volume(float radius) { - return 8.0f * (radius * radius * radius); -} - -float cube_radius(float volume) { - return std::pow(volume / 8.0f, 1.0f / 3.0f); -} - -std::random_device random_dev; -std::uniform_int_distribution<int> dist(0, RAND_MAX); - -float randomFloat(float min, float max) { - return min + (max - min) * dist(random_dev) / static_cast<float>(RAND_MAX); -} - -float mod(float x, float y) { - return x - std::floor(x / y) * y; -} - -void distributeParticlesCube(Particle *particles, size_t count, const glm::vec3& center, float radius, - float mass, const glm::vec3& velocity, bool random) { - const float side = cube_radius(static_cast<float>(count)) * 2.0f; - - float volume = 0.0f; - - for (size_t i = 0; i < count; i++) { - glm::vec3 offset; - - if (random) { - offset.x = randomFloat(-1.0f, +1.0f); - offset.y = randomFloat(-1.0f, +1.0f); - offset.z = randomFloat(-1.0f, +1.0f); - } else { - const float s = static_cast<float>(i) + 0.5f; - - offset.x = 2.0f * mod(s, side) / side - 1.0f; - offset.y = 2.0f * mod(s / side, side) / side - 1.0f; - offset.z = 2.0f * mod(s / side / side, side) / side - 1.0f; - } - - offset *= radius; - - float size = 0.0f; - - if (random) { - const float ax = std::abs(offset.x); - const float ay = std::abs(offset.y); - const float az = std::abs(offset.z); - - const float a = std::max(std::max(ax, ay), az); - - size = (radius - a); - } else { - size = 2.0f * radius / side; - } - - particles[i].position = center + offset; - particles[i].size = size; - particles[i].velocity = velocity; - - volume += cube_volume(size); - } - - for (size_t i = 0; i < count; i++) { - particles[i].mass = (mass * cube_volume(particles[i].size) / volume); - particles[i].deformation = glm::mat4(1.0f); - - particles[i].pad = glm::vec3(0.0f); - particles[i].weight_sum = 1.0f; - - particles[i].mls = glm::mat4(0.0f); - } -} - -void distributeParticlesSphere(Particle *particles, size_t count, const glm::vec3& center, float radius, - float mass, const glm::vec3& velocity, bool random) { - const float side = sphere_radius(static_cast<float>(count)) * 2.0f; - - float volume = 0.0f; - - for (size_t i = 0; i < count; i++) { - glm::vec3 offset; - - if (random) { - offset.x = randomFloat(-1.0f, +1.0f); - offset.y = randomFloat(-1.0f, +1.0f); - offset.z = randomFloat(-1.0f, +1.0f); - - if (glm::length(offset) > 0.0f) - offset = glm::normalize(offset); - - offset *= randomFloat(0.0f, 1.0f); - } else { - const float range = 0.5f * side; - const float s = static_cast<float>(i) + 0.5f; - - float a = mod(s, range) / range; - float b = mod(s / range, M_PI * range); - float c = mod(s / range / M_PI / range, M_PI * range * 2.0f); - - offset.x = a * std::sin(c) * std::sin(b); - offset.y = a * std::cos(b); - offset.z = a * std::cos(c) * std::sin(b); - } - - offset *= radius; - - float size = 0.0f; - - if (random) { - size = (radius - glm::length(offset)); - } else { - size = 2.0f * radius / side; - } - - particles[i].position = center + offset; - particles[i].size = size; - particles[i].velocity = velocity; - - volume += sphere_volume(size); - } - - // Keep the same densitiy as planned! - mass *= (volume / sphere_volume(radius)); - - for (size_t i = 0; i < count; i++) { - particles[i].mass = (mass * sphere_volume(particles[i].size) / volume); - particles[i].deformation = glm::mat4(1.0f); - - particles[i].pad = glm::vec3(0.0f); - particles[i].weight_sum = 1.0f; - - particles[i].mls = glm::mat4(0.0f); - } -} - -vkcv::ComputePipelineHandle createComputePipeline(vkcv::Core& core, vkcv::shader::GLSLCompiler& compiler, - const std::string& path, - std::vector<vkcv::DescriptorSetHandle>& descriptorSets) { - vkcv::ShaderProgram shaderProgram; - - compiler.compile( - vkcv::ShaderStage::COMPUTE, - path, - [&shaderProgram](vkcv::ShaderStage stage, const std::filesystem::path& path) { - shaderProgram.addShader(stage, path); - } - ); - - const auto& descriptors = shaderProgram.getReflectedDescriptors(); - - size_t count = 0; - - for (const auto& descriptor : descriptors) { - if (descriptor.first >= count) { - count = (descriptor.first + 1); - } - } - - std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayouts; - - descriptorSetLayouts.resize(count); - descriptorSets.resize(count); - - for (const auto& descriptor : descriptors) { - descriptorSetLayouts[descriptor.first] = core.createDescriptorSetLayout(descriptor.second); - descriptorSets[descriptor.first] = core.createDescriptorSet(descriptorSetLayouts[descriptor.first]); - } - - vkcv::ComputePipelineConfig config { - shaderProgram, - descriptorSetLayouts - }; - - return core.createComputePipeline(config); -} - -vkcv::BufferHandle resetParticles(vkcv::Core& core, size_t count, const glm::vec3& velocity, - float density, float size, int form, int mode) { - vkcv::Buffer<Particle> particles = vkcv::buffer<Particle>( - core, - vkcv::BufferType::STORAGE, - count - ); - - std::vector<Particle> particles_vec (particles.getCount()); - - switch (form) { - case SIM_FORM_SPHERE: - distributeParticlesSphere( - particles_vec.data(), - particles_vec.size(), - glm::vec3(0.5f), - size, - density * sphere_volume(size), - velocity, - (mode == 0) - ); - break; - case SIM_FORM_CUBE: - distributeParticlesCube( - particles_vec.data(), - particles_vec.size(), - glm::vec3(0.5f), - size, - density * sphere_volume(size), - velocity, - (mode == 0) - ); - break; - default: - break; - } - - particles.fill(particles_vec); - return particles.getHandle(); -} - -int main(int argc, const char **argv) { - const std::string applicationName = "Wobble Bobble"; - - uint32_t windowWidth = 800; - uint32_t windowHeight = 600; - - vkcv::Features features; - features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - vkcv::Core core = vkcv::Core::create( - applicationName, - VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, - features - ); - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); - vkcv::Window& window = core.getWindow(windowHandle); - vkcv::camera::CameraManager cameraManager(window); - - vkcv::gui::GUI gui (core, windowHandle); - - auto trackballHandle = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - cameraManager.getCamera(trackballHandle).setCenter(glm::vec3(0.5f, 0.5f, 0.5f)); // set camera to look at the center of the particle volume - cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - - auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); - - vkcv::ImageHandle depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainExtent.width, - swapchainExtent.height - ); - - vkcv::Image grid = vkcv::image( - core, - vk::Format::eR16G16B16A16Sfloat, - 32, - 32, - 32, - false, - true - ); - - vkcv::SamplerHandle gridSampler = core.createSampler( - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerMipmapMode::NEAREST, - vkcv::SamplerAddressMode::CLAMP_TO_BORDER, - 0.0f, - vkcv::SamplerBorderColor::FLOAT_ZERO_TRANSPARENT - ); - - vkcv::Buffer<Simulation> simulation = vkcv::buffer<Simulation>( - core, vkcv::BufferType::UNIFORM, 1, vkcv::BufferMemoryType::HOST_VISIBLE - ); - - Simulation* sim = simulation.map(); - - glm::vec3 initialVelocity (0.0f, 0.1f, 0.0f); - - sim->density = 2500.0f; - sim->size = 0.1f; - sim->lame1 = 10.0f; - sim->lame2 = 20.0f; - sim->form = SIM_FORM_SPHERE; - sim->type = SIM_TYPE_HYPERELASTIC; - sim->K = 2.2f; - sim->E = 35.0f; - sim->gamma = 1.330f; - sim->mode = SIM_MODE_RANDOM; - sim->gravity = 9.81f; - sim->count = 1024; - - vkcv::BufferHandle particlesHandle = resetParticles( - core, - sim->count, - initialVelocity, - sim->density, - sim->size, - sim->form, - sim->mode - ); - - vkcv::shader::GLSLCompiler compiler; - - std::vector<vkcv::DescriptorSetHandle> initParticleWeightsSets; - vkcv::ComputePipelineHandle initParticleWeightsPipeline = createComputePipeline( - core, compiler, - "shaders/init_particle_weights.comp", - initParticleWeightsSets - ); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particlesHandle); - core.writeDescriptorSet(initParticleWeightsSets[0], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeSampledImage(0, grid.getHandle()); - writes.writeSampler(1, gridSampler); - core.writeDescriptorSet(initParticleWeightsSets[1], writes); - } - - std::vector<vkcv::DescriptorSetHandle> transformParticlesToGridSets; - vkcv::ComputePipelineHandle transformParticlesToGridPipeline = createComputePipeline( - core, compiler, - "shaders/transform_particles_to_grid.comp", - transformParticlesToGridSets - ); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particlesHandle); - core.writeDescriptorSet(transformParticlesToGridSets[0], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeUniformBuffer(0, simulation.getHandle()); - core.writeDescriptorSet(transformParticlesToGridSets[1], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeStorageImage(0, grid.getHandle()); - core.writeDescriptorSet(transformParticlesToGridSets[2], writes); - } - - std::vector<vkcv::DescriptorSetHandle> updateParticleVelocitiesSets; - vkcv::ComputePipelineHandle updateParticleVelocitiesPipeline = createComputePipeline( - core, compiler, - "shaders/update_particle_velocities.comp", - updateParticleVelocitiesSets - ); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particlesHandle); - core.writeDescriptorSet(updateParticleVelocitiesSets[0], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeUniformBuffer(0, simulation.getHandle()); - core.writeDescriptorSet(updateParticleVelocitiesSets[1], writes); - } - - { - vkcv::DescriptorWrites writes; - writes.writeSampledImage(0, grid.getHandle()); - writes.writeSampler(1, gridSampler); - core.writeDescriptorSet(updateParticleVelocitiesSets[2], writes); - } - - vkcv::ShaderProgram gfxProgramGrid; - - compiler.compileProgram(gfxProgramGrid, { - { vkcv::ShaderStage::VERTEX, "shaders/grid.vert" }, - { vkcv::ShaderStage::FRAGMENT, "shaders/grid.frag" } - }, nullptr); - - vkcv::ShaderProgram gfxProgramParticles; - - compiler.compileProgram(gfxProgramParticles, { - { vkcv::ShaderStage::VERTEX, "shaders/particle.vert" }, - { vkcv::ShaderStage::FRAGMENT, "shaders/particle.frag" } - }, nullptr); - - vkcv::ShaderProgram gfxProgramLines; - - compiler.compileProgram(gfxProgramLines, { - { vkcv::ShaderStage::VERTEX, "shaders/lines.vert" }, - { vkcv::ShaderStage::FRAGMENT, "shaders/lines.frag" } - }, nullptr); - - vkcv::DescriptorSetLayoutHandle gfxSetLayoutGrid = core.createDescriptorSetLayout( - gfxProgramGrid.getReflectedDescriptors().at(0) - ); - - vkcv::DescriptorSetHandle gfxSetGrid = core.createDescriptorSet(gfxSetLayoutGrid); - - { - vkcv::DescriptorWrites writes; - writes.writeSampledImage(0, grid.getHandle()); - writes.writeSampler(1, gridSampler); - writes.writeUniformBuffer(2, simulation.getHandle()); - core.writeDescriptorSet(gfxSetGrid, writes); - } - - vkcv::DescriptorSetLayoutHandle gfxSetLayoutParticles = core.createDescriptorSetLayout( - gfxProgramParticles.getReflectedDescriptors().at(0) - ); - - vkcv::DescriptorSetHandle gfxSetParticles = core.createDescriptorSet(gfxSetLayoutParticles); - - { - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particlesHandle); - core.writeDescriptorSet(gfxSetParticles, writes); - } - - vkcv::PassHandle gfxPassGrid = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - vkcv::PassHandle gfxPassParticles = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat } - ); - - vkcv::PassHandle gfxPassLines = vkcv::passSwapchain( - core, - window.getSwapchain(), - { vk::Format::eUndefined, vk::Format::eD32Sfloat }, - false - ); - - vkcv::VertexLayout vertexLayoutGrid ({ - vkcv::createVertexBinding(0, gfxProgramGrid.getVertexAttachments()) - }); - - vkcv::GraphicsPipelineConfig gfxPipelineConfigGrid ( - gfxProgramGrid, - gfxPassGrid, - vertexLayoutGrid, - { gfxSetLayoutGrid } - ); - - vkcv::VertexLayout vertexLayoutParticles ({ - vkcv::createVertexBinding(0, gfxProgramParticles.getVertexAttachments()) - }); - - vkcv::GraphicsPipelineConfig gfxPipelineConfigParticles ( - gfxProgramParticles, - gfxPassParticles, - vertexLayoutParticles, - { gfxSetLayoutParticles } - ); - - vkcv::VertexLayout vertexLayoutLines ({ - vkcv::createVertexBinding(0, gfxProgramLines.getVertexAttachments()) - }); - - vkcv::GraphicsPipelineConfig gfxPipelineConfigLines ( - gfxProgramLines, - gfxPassLines, - vertexLayoutLines, - {} - ); - - gfxPipelineConfigLines.setPrimitiveTopology(vkcv::PrimitiveTopology::LineList); - - vkcv::GraphicsPipelineHandle gfxPipelineGrid = core.createGraphicsPipeline(gfxPipelineConfigGrid); - vkcv::GraphicsPipelineHandle gfxPipelineParticles = core.createGraphicsPipeline(gfxPipelineConfigParticles); - vkcv::GraphicsPipelineHandle gfxPipelineLines = core.createGraphicsPipeline(gfxPipelineConfigLines); - - vkcv::Buffer<glm::vec2> trianglePositions = vkcv::buffer<glm::vec2>(core, vkcv::BufferType::VERTEX, 3); - trianglePositions.fill({ - glm::vec2(-1.0f, -1.0f), - glm::vec2(+0.0f, +1.5f), - glm::vec2(+1.0f, -1.0f) - }); - - vkcv::VertexData triangleData ({ vkcv::vertexBufferBinding(trianglePositions.getHandle()) }); - triangleData.setCount(trianglePositions.getCount()); - - vkcv::Buffer<glm::vec3> linesPositions = vkcv::buffer<glm::vec3>(core, vkcv::BufferType::VERTEX, 8); - linesPositions.fill({ - glm::vec3(0.0f, 0.0f, 0.0f), - glm::vec3(1.0f, 0.0f, 0.0f), - glm::vec3(0.0f, 1.0f, 0.0f), - glm::vec3(1.0f, 1.0f, 0.0f), - glm::vec3(0.0f, 0.0f, 1.0f), - glm::vec3(1.0f, 0.0f, +1.0f), - glm::vec3(0.0f, 1.0f, 1.0f), - glm::vec3(1.0f, 1.0f, 1.0f) - }); - - vkcv::Buffer<uint16_t> linesIndices = vkcv::buffer<uint16_t>(core, vkcv::BufferType::INDEX, 24); - linesIndices.fill({ - 0, 1, - 1, 3, - 3, 2, - 2, 0, - - 4, 5, - 5, 7, - 7, 6, - 6, 4, - - 0, 4, - 1, 5, - 2, 6, - 3, 7 - }); - - vkcv::VertexData linesData ({ vkcv::vertexBufferBinding(linesPositions.getHandle()) }); - linesData.setIndexBuffer(linesIndices.getHandle()); - linesData.setCount(linesIndices.getCount()); - - vkcv::InstanceDrawcall drawcallGrid ( - triangleData, - grid.getWidth() * grid.getHeight() * grid.getDepth() - ); - - drawcallGrid.useDescriptorSet(0, gfxSetGrid); - - vkcv::InstanceDrawcall drawcallParticle (triangleData, sim->count); - drawcallParticle.useDescriptorSet(0, gfxSetParticles); - - vkcv::InstanceDrawcall drawcallLines (linesData); - - bool renderGrid = true; - float speed_factor = 1.0f; - - core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, - uint32_t swapchainWidth, uint32_t swapchainHeight) { - if ((swapchainWidth != swapchainExtent.width) || ((swapchainHeight != swapchainExtent.height))) { - depthBuffer = core.createImage( - vk::Format::eD32Sfloat, - swapchainWidth, - swapchainHeight - ); - - swapchainExtent.width = swapchainWidth; - swapchainExtent.height = swapchainHeight; - } - - Physics physics; - physics.t = static_cast<float>(t); - physics.dt = static_cast<float>(dt); - physics.speedfactor = speed_factor; - - vkcv::PushConstants physicsPushConstants = vkcv::pushConstants<Physics>(); - physicsPushConstants.appendDrawcall(physics); - - cameraManager.update(physics.dt); - - glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); - vkcv::PushConstants cameraPushConstants = vkcv::pushConstants<glm::mat4>(); - cameraPushConstants.appendDrawcall(mvp); - - auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - - const auto dispatchSizeGrid = vkcv::dispatchInvocations( - vkcv::DispatchSize(grid.getWidth(), grid.getHeight(), grid.getDepth()), - vkcv::DispatchSize(4, 4, 4) - ); - - const auto dispatchSizeParticles = vkcv::dispatchInvocations(sim->count, 64); - - for (int step = 0; step < 1; step++) { - core.recordBeginDebugLabel(cmdStream, "INIT PARTICLE WEIGHTS", {0.78f, 0.89f, 0.94f, 1.0f}); - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - core.prepareImageForSampling(cmdStream, grid.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - initParticleWeightsPipeline, - dispatchSizeParticles, - { - vkcv::useDescriptorSet( - 0, initParticleWeightsSets[0] - ), - vkcv::useDescriptorSet( - 1, initParticleWeightsSets[1] - ) - }, - vkcv::PushConstants(0) - ); - - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "TRANSFORM PARTICLES TO GRID", {0.47f, 0.77f, 0.85f, 1.0f}); - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - core.prepareImageForStorage(cmdStream, grid.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - transformParticlesToGridPipeline, - dispatchSizeGrid, - { - vkcv::useDescriptorSet( - 0, transformParticlesToGridSets[0] - ), - vkcv::useDescriptorSet( - 1, transformParticlesToGridSets[1] - ), - vkcv::useDescriptorSet( - 2, transformParticlesToGridSets[2] - ) - }, - physicsPushConstants - ); - - core.recordImageMemoryBarrier(cmdStream, grid.getHandle()); - core.recordEndDebugLabel(cmdStream); - - core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE VELOCITIES", {0.78f, 0.89f, 0.94f, 1.0f}); - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - core.recordBufferMemoryBarrier(cmdStream, simulation.getHandle()); - core.prepareImageForSampling(cmdStream, grid.getHandle()); - - core.recordComputeDispatchToCmdStream( - cmdStream, - updateParticleVelocitiesPipeline, - dispatchSizeParticles, - { - vkcv::useDescriptorSet( - 0, updateParticleVelocitiesSets[0] - ), - vkcv::useDescriptorSet( - 1, updateParticleVelocitiesSets[1] - ), - vkcv::useDescriptorSet( - 2, updateParticleVelocitiesSets[2] - ) - }, - physicsPushConstants - ); - - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - core.recordEndDebugLabel(cmdStream); - } - - std::vector<vkcv::ImageHandle> renderTargets { - vkcv::ImageHandle::createSwapchainImageHandle(), - depthBuffer - }; - - if (renderGrid) { - core.recordBeginDebugLabel(cmdStream, "RENDER GRID", { 0.13f, 0.20f, 0.22f, 1.0f }); - core.recordBufferMemoryBarrier(cmdStream, simulation.getHandle()); - core.prepareImageForSampling(cmdStream, grid.getHandle()); - - core.recordDrawcallsToCmdStream( - cmdStream, - gfxPipelineGrid, - cameraPushConstants, - { drawcallGrid }, - renderTargets, - windowHandle - ); - - core.recordEndDebugLabel(cmdStream); - } else { - core.recordBeginDebugLabel(cmdStream, "RENDER PARTICLES", { 0.13f, 0.20f, 0.22f, 1.0f }); - core.recordBufferMemoryBarrier(cmdStream, particlesHandle); - - core.recordDrawcallsToCmdStream( - cmdStream, - gfxPipelineParticles, - cameraPushConstants, - { drawcallParticle }, - renderTargets, - windowHandle - ); - - core.recordEndDebugLabel(cmdStream); - } - - core.recordBeginDebugLabel(cmdStream, "RENDER LINES", { 0.13f, 0.20f, 0.22f, 1.0f }); - - core.recordDrawcallsToCmdStream( - cmdStream, - gfxPipelineLines, - cameraPushConstants, - { drawcallLines }, - renderTargets, - windowHandle - ); - - core.recordEndDebugLabel(cmdStream); - - core.prepareSwapchainImageForPresent(cmdStream); - core.submitCommandStream(cmdStream); - - gui.beginGUI(); - ImGui::Begin("Settings"); - - ImGui::BeginGroup(); - ImGui::Combo("Mode", &(sim->mode), "Random\0Ordered\0", 2); - ImGui::Combo("Form", &(sim->form), "Sphere\0Cube\0", 2); - ImGui::Combo("Type", &(sim->type), "Hyperelastic\0Fluid\0", 2); - ImGui::EndGroup(); - - ImGui::Spacing(); - - ImGui::SliderInt("Particle Count", &(sim->count), 1, 100000); - ImGui::SliderFloat("Density", &(sim->density), std::numeric_limits<float>::epsilon(), 5000.0f); - ImGui::SameLine(0.0f, 10.0f); - if (ImGui::SmallButton("Reset##density")) { - sim->density = 2500.0f; - } - - ImGui::SliderFloat("Radius", &(sim->size), 0.0f, 0.5f); - ImGui::SameLine(0.0f, 10.0f); - if (ImGui::SmallButton("Reset##radius")) { - sim->size = 0.1f; - } - - ImGui::Spacing(); - - ImGui::BeginGroup(); - ImGui::SliderFloat("Bulk Modulus", &(sim->K), 0.0f, 1000.0f); - ImGui::SliderFloat("Young's Modulus", &(sim->E), 0.0f, 1000.0f); - ImGui::SliderFloat("Heat Capacity Ratio", &(sim->gamma), 1.0f, 2.0f); - ImGui::SliderFloat("Lame1", &(sim->lame1), 0.0f, 1000.0f); - ImGui::SliderFloat("Lame2", &(sim->lame2), 0.0f, 1000.0f); - ImGui::EndGroup(); - - ImGui::Spacing(); - - ImGui::SliderFloat("Simulation Speed", &speed_factor, 0.0f, 2.0f); - - ImGui::Spacing(); - ImGui::Checkbox("Render Grid", &renderGrid); - - ImGui::DragFloat3("Initial Velocity", reinterpret_cast<float*>(&initialVelocity), 0.001f); - ImGui::SameLine(0.0f, 10.0f); - if (ImGui::Button("Reset##particle_velocity")) { - particlesHandle = resetParticles( - core, - sim->count, - initialVelocity, - sim->density, - sim->size, - sim->form, - sim->mode - ); - - vkcv::DescriptorWrites writes; - writes.writeStorageBuffer(0, particlesHandle); - - core.writeDescriptorSet(initParticleWeightsSets[0], writes); - core.writeDescriptorSet(transformParticlesToGridSets[0], writes); - core.writeDescriptorSet(updateParticleVelocitiesSets[0], writes); - - core.writeDescriptorSet(gfxSetParticles, writes); - } - - ImGui::SliderFloat("Gravity", &(sim->gravity), 0.0f, 10.0f); - - ImGui::End(); - gui.endGUI(); - }); - - simulation.unmap(); - return 0; -}