diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a1af49ba57d2c8189f8387d6263cbe884daae70..e2418971bd4e066f2be54f91d059c3a7b19f385e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -750,9 +750,11 @@ message("======================================================================= strategy/depth_peeling_reprojection/dpr_reproject.tese strategy/depth_peeling_reprojection/dpr_reproject.frag - utility/deferred_local_light.vert - utility/deferred_local_light.frag - utility/deferred_local_light_with_shadow.frag + utility/deferred_lighting.vert + utility/deferred_lighting.frag + utility/deferred_lighting_shadow.frag + utility/deferred_lighting_indirect.frag + utility/deferred_lighting_indirect_shadow.frag utility/indirect_capture.vert utility/indirect_capture.frag diff --git a/res/dpr/strategy/multi_view/multi_view_stereo.frag b/res/dpr/strategy/multi_view/multi_view_stereo.frag index 831480eb0eb659e10894b6395864ca3353dc4aa1..9dd9da3b03a32adb155e1f29ab714d25e745c76a 100644 --- a/res/dpr/strategy/multi_view/multi_view_stereo.frag +++ b/res/dpr/strategy/multi_view/multi_view_stereo.frag @@ -5,6 +5,7 @@ #define MATERIAL_DESCRIPTOR_SET 3 #define LIGHT_DESCRIPTOR_SET 4 #define SHADOW_DESCRIPTOR_SET 5 +#define INDIRECT_DESCRIPTOR_SET 6 #include "math_library.glsl" #include "material_library.glsl" diff --git a/res/dpr/utility/deferred_lighting.frag b/res/dpr/utility/deferred_lighting.frag new file mode 100644 index 0000000000000000000000000000000000000000..c571998b2e6ba1f8f178d4fb29b14154bdf70506 --- /dev/null +++ b/res/dpr/utility/deferred_lighting.frag @@ -0,0 +1,6 @@ +#version 450 core +#extension GL_GOOGLE_include_directive : require + +#define LIGHT_DESCRIPTOR_SET 1 + +#include "deferred_lighting_base.glsl" \ No newline at end of file diff --git a/res/dpr/utility/deferred_local_light.vert b/res/dpr/utility/deferred_lighting.vert similarity index 100% rename from res/dpr/utility/deferred_local_light.vert rename to res/dpr/utility/deferred_lighting.vert diff --git a/res/dpr/utility/deferred_local_light.frag b/res/dpr/utility/deferred_lighting_base.glsl similarity index 93% rename from res/dpr/utility/deferred_local_light.frag rename to res/dpr/utility/deferred_lighting_base.glsl index 759b2bd6fbb7026eb208cfdd38cf8b91a333728a..ac28b69110b89fa1e1d03dc256db67946d306bdb 100644 --- a/res/dpr/utility/deferred_local_light.frag +++ b/res/dpr/utility/deferred_lighting_base.glsl @@ -1,8 +1,3 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : require - -#define LIGHT_DESCRIPTOR_SET 1 - #include "math_library.glsl" #include "light_library.glsl" #include "per_frame.inc" diff --git a/res/dpr/utility/deferred_lighting_indirect.frag b/res/dpr/utility/deferred_lighting_indirect.frag new file mode 100644 index 0000000000000000000000000000000000000000..5b03f084e2fbaf51f8ebdca640ad0746c90e2a18 --- /dev/null +++ b/res/dpr/utility/deferred_lighting_indirect.frag @@ -0,0 +1,7 @@ +#version 450 core +#extension GL_GOOGLE_include_directive : require + +#define LIGHT_DESCRIPTOR_SET 1 +#define INDIRECT_DESCRIPTOR_SET 3 + +#include "deferred_lighting_base.glsl" \ No newline at end of file diff --git a/res/dpr/utility/deferred_lighting_indirect_shadow.frag b/res/dpr/utility/deferred_lighting_indirect_shadow.frag new file mode 100644 index 0000000000000000000000000000000000000000..a8a28ae3d8b62591c7957b0b5a14c5fd387e7638 --- /dev/null +++ b/res/dpr/utility/deferred_lighting_indirect_shadow.frag @@ -0,0 +1,8 @@ +#version 450 core +#extension GL_GOOGLE_include_directive : require + +#define LIGHT_DESCRIPTOR_SET 1 +#define SHADOW_DESCRIPTOR_SET 3 +#define INDIRECT_DESCRIPTOR_SET 4 + +#include "deferred_lighting_base.glsl" \ No newline at end of file diff --git a/res/dpr/utility/deferred_lighting_shadow.frag b/res/dpr/utility/deferred_lighting_shadow.frag new file mode 100644 index 0000000000000000000000000000000000000000..f61a91b62072e01a0c439e86a46ba381023d9609 --- /dev/null +++ b/res/dpr/utility/deferred_lighting_shadow.frag @@ -0,0 +1,7 @@ +#version 450 core +#extension GL_GOOGLE_include_directive : require + +#define LIGHT_DESCRIPTOR_SET 1 +#define SHADOW_DESCRIPTOR_SET 3 + +#include "deferred_lighting_base.glsl" \ No newline at end of file diff --git a/res/dpr/utility/deferred_local_light_with_shadow.frag b/res/dpr/utility/deferred_local_light_with_shadow.frag deleted file mode 100644 index c93f5f8d63edba16c20021fabf3ae23228e991e4..0000000000000000000000000000000000000000 --- a/res/dpr/utility/deferred_local_light_with_shadow.frag +++ /dev/null @@ -1,47 +0,0 @@ -#version 450 core -#extension GL_GOOGLE_include_directive : require - -#define LIGHT_DESCRIPTOR_SET 1 -#define SHADOW_DESCRIPTOR_SET 3 - -#include "math_library.glsl" -#include "light_library.glsl" -#include "per_frame.inc" - -layout(location = 0) out vec4 outColor; -layout(location = 0) in vec2 inCoord; - -layout(set = 0, binding = 0) uniform sampler2D samplerDepthBuffer; -layout(set = 0, binding = 1) uniform sampler2D samplerColorBuffer; -layout(set = 0, binding = 2) uniform sampler2D samplerNormalBuffer; -layout(set = 0, binding = 3) uniform sampler2D samplerMaterialBuffer; - -layout(set = 2, binding = 0) uniform PerFrameBuffer -{ - PerFrameData per_frame; -}; - -void main() -{ - float buffer_depth = texture(samplerDepthBuffer, inCoord).x; - vec4 buffer_color = texture(samplerColorBuffer, inCoord); - vec4 buffer_normal = texture(samplerNormalBuffer, inCoord); - vec4 buffer_material = texture(samplerMaterialBuffer, inCoord); - - vec4 surface_position = per_frame.invProjection * (vec4(inCoord * 2.0 - 1.0, buffer_depth, 1.0)); - surface_position /= surface_position.w; - surface_position = per_frame.invView * surface_position; - - vec3 surface_normal = decode_normal(buffer_normal.xy); - - Material material; - material.base_color = buffer_color.xyz; - material.occlusion = buffer_color.w; - material.roughness = buffer_material.x; - material.metallic = buffer_material.y; - material.emissive.xy = unpackHalf2x16(packUnorm2x16(buffer_normal.zw)); - material.emissive.z = unpackHalf2x16(packUnorm4x8(buffer_material.zwzw)).x; - - vec3 lighting = apply_lighting(per_frame.eyePosition, surface_position.xyz, surface_normal, material); - outColor = vec4(lighting, 1.0); -} \ No newline at end of file diff --git a/res/dpr/utility/indirect_injection.geom b/res/dpr/utility/indirect_injection.geom index 58d3a2881b091799336fd7e4e9fc614b4e92936e..386e1677912ee6e075032471ef9083f67b3092b7 100644 --- a/res/dpr/utility/indirect_injection.geom +++ b/res/dpr/utility/indirect_injection.geom @@ -28,7 +28,6 @@ void main() outNormal = inNormal[0]; gl_Position = vec4(position.xy, 0.5, 1.0); gl_Layer = int(position.z); - gl_PointSize = 1.0; EmitVertex(); EndPrimitive(); diff --git a/src/scene.cpp b/src/scene.cpp index b8c0657b1052cdb8f5a37a9a517d4a2653862be1..d7ecaf573f07ab1e7e499b8f6c5f31e0b0fde94a 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1190,6 +1190,15 @@ bool Scene::load_lights(const aiScene* scene, float scale, const std::map<std::s return false; } + float light_scale = 1.0; + + if (light->mType == aiLightSource_DIRECTIONAL) + { + //NOTE: If the scene is in centimeters assume that directional light intensity is given as watt / cm^2. + // In this case the intensity has to be converted into watt / meter^2 + light_scale = glm::pow(scale, 1); //It should be a 2 instead of a 1 + } + SceneLight& scene_light = this->lights.emplace_back(); scene_light.node_index = node_indices.at(light->mName.C_Str()); scene_light.initial_position = glm::make_vec3(&light->mPosition.x) * scale; @@ -1197,7 +1206,7 @@ bool Scene::load_lights(const aiScene* scene, float scale, const std::map<std::s glsl::LightData& light_data = scene_light.data; light_data.position = scene_light.initial_position; - light_data.color = glm::make_vec3(&light->mColorDiffuse.r); + light_data.color = glm::make_vec3(&light->mColorDiffuse.r) * light_scale; light_data.outer_angle = light->mAngleOuterCone; light_data.direction = scene_light.initial_direction; light_data.inner_angle = light->mAngleInnerCone; diff --git a/src/scene.hpp b/src/scene.hpp index 1e490fef3890aae0aee8a958e56c61714cd76ba2..6b9635ecb57a373fb0e8d68e95313a541b9f97ae 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -216,7 +216,7 @@ private: glm::vec3 scene_min = glm::vec3(0.0f); glm::vec3 scene_max = glm::vec3(0.0f); - const glm::vec3 ambient_color = glm::vec3(0.5f); //NOTE: This factor is used so that the Bistro scene looks okay. + const glm::vec3 ambient_color = glm::vec3(0.0f); //NOTE: Indirect should be compute using an indirect cache. float exposure = 0.1f; //NOTE: This factor is used so that the Bistro scene looks okay. bool exposure_changed = false; diff --git a/src/strategy/multi_view_stereo.cpp b/src/strategy/multi_view_stereo.cpp index 3fe3e1922ec8325009c3f791e31335b2663b1876..afb9be602191bbe55ecabf370bbbba366c2d679e 100644 --- a/src/strategy/multi_view_stereo.cpp +++ b/src/strategy/multi_view_stereo.cpp @@ -28,6 +28,13 @@ bool MultiViewStereo::on_create() return false; } + this->indirect_cache = make_indirect_cache(); + + if (!this->indirect_cache->create(this->get_scene(), IndirectCacheSettings())) + { + return false; + } + if (!this->create_pipeline_layout()) { return false; @@ -53,6 +60,12 @@ void MultiViewStereo::on_destroy() this->shadow_cache->destroy(); } + if (this->indirect_cache != nullptr) + { + this->indirect_cache->destroy(); + this->indirect_computed = false; + } + if (this->pipeline_layout != nullptr) { this->pipeline_layout->destroy(); @@ -93,6 +106,12 @@ bool MultiViewStereo::on_render(VkCommandBuffer command_buffer, lava::index fram { this->get_headset()->submit_metadata(FrameMetadata()); + if (!this->indirect_computed) + { + this->indirect_cache->compute_indirect(command_buffer, frame); + this->indirect_computed = true; + } + this->get_pass_timer()->begin_pass(command_buffer, "shadow"); this->shadow_cache->compute_shadow(command_buffer, frame); this->get_pass_timer()->end_pass(command_buffer); @@ -228,6 +247,7 @@ bool MultiViewStereo::create_pipeline_layout() this->pipeline_layout->add(this->get_scene()->get_material_descriptor()); this->pipeline_layout->add(this->get_scene()->get_light_descriptor()); this->pipeline_layout->add(this->shadow_cache->get_descriptor()); + this->pipeline_layout->add(this->indirect_cache->get_descriptor()); if (!this->pipeline_layout->create(this->get_device())) { @@ -411,6 +431,7 @@ void MultiViewStereo::pipeline_function(VkCommandBuffer command_buffer) this->pipeline_layout->bind(command_buffer, this->get_stereo_transform()->get_descriptor_set(EYE_RIGHT, frame_index), 1); this->pipeline_layout->bind(command_buffer, this->get_scene()->get_light_descriptor_set(frame_index), 4); this->pipeline_layout->bind(command_buffer, this->shadow_cache->get_descriptor_set(), 5); + this->pipeline_layout->bind(command_buffer, this->indirect_cache->get_descriptor_set(), 6); const std::vector<SceneMaterial>& materials = this->get_scene()->get_materials(); diff --git a/src/strategy/multi_view_stereo.hpp b/src/strategy/multi_view_stereo.hpp index 895a6fb387f1baa0a180969b0b2b5b0d2c4682ca..c597d223efa85804690c0460c032815b0f0d0aba 100644 --- a/src/strategy/multi_view_stereo.hpp +++ b/src/strategy/multi_view_stereo.hpp @@ -4,6 +4,7 @@ #include "stereo_strategy.hpp" #include "utility/shadow_cache.hpp" +#include "utility/indirect_cache.hpp" class MultiViewStereo final : public StereoStrategy { @@ -37,6 +38,9 @@ private: VkPhysicalDeviceMultiviewFeatures features; ShadowCache::Ptr shadow_cache; + IndirectCache::Ptr indirect_cache; + bool indirect_computed = false; + lava::pipeline_layout::ptr pipeline_layout; lava::graphics_pipeline::ptr pipeline; diff --git a/src/strategy/native_stereo_deferred.cpp b/src/strategy/native_stereo_deferred.cpp index d8e5b1bac31823e1fa07caa0daddbc6e55373b8e..1bad6edf476267abf96b8a977405467fe6336737 100644 --- a/src/strategy/native_stereo_deferred.cpp +++ b/src/strategy/native_stereo_deferred.cpp @@ -10,6 +10,13 @@ bool NativeStereoDeferred::on_create() return false; } + this->indirect_cache = make_indirect_cache(); + + if (!this->indirect_cache->create(this->get_scene(), IndirectCacheSettings())) + { + return false; + } + if (!this->create_pipeline_layout()) { return false; @@ -45,6 +52,12 @@ void NativeStereoDeferred::on_destroy() this->shadow_cache->destroy(); } + if (this->indirect_cache != nullptr) + { + this->indirect_cache->destroy(); + this->indirect_computed = false; + } + if (this->pipeline_layout != nullptr) { this->pipeline_layout->destroy(); @@ -83,6 +96,12 @@ bool NativeStereoDeferred::on_render(VkCommandBuffer command_buffer, lava::index { this->get_headset()->submit_metadata(FrameMetadata()); + if (!this->indirect_computed) + { + this->indirect_cache->compute_indirect(command_buffer, frame); + this->indirect_computed = true; + } + this->get_pass_timer()->begin_pass(command_buffer, "shadow"); this->shadow_cache->compute_shadow(command_buffer, frame); this->get_pass_timer()->end_pass(command_buffer); @@ -145,7 +164,7 @@ bool NativeStereoDeferred::create_render_pass(Eye eye) { GeometryBuffer::Ptr geometry_buffer = make_geometry_buffer(); - if (!geometry_buffer->create(this->get_headset()->get_framebuffer(eye), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, this->get_stereo_transform()->get_descriptor(), this->get_scene(), this->shadow_cache)) + if (!geometry_buffer->create(this->get_headset()->get_framebuffer(eye), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, this->get_stereo_transform()->get_descriptor(), this->get_scene(), this->shadow_cache, this->indirect_cache)) { lava::log()->error("Can't create geometry buffer for native stereo deferred!"); diff --git a/src/strategy/native_stereo_deferred.hpp b/src/strategy/native_stereo_deferred.hpp index 0bb1bc86f2e5c94613b8536910a73a7f772398f6..df8c17dc57d6a757897622eebfceaa10e31c9fff 100644 --- a/src/strategy/native_stereo_deferred.hpp +++ b/src/strategy/native_stereo_deferred.hpp @@ -5,6 +5,7 @@ #include "stereo_strategy.hpp" #include "utility/geometry_buffer.hpp" #include "utility/shadow_cache.hpp" +#include "utility/indirect_cache.hpp" struct NativeStereoDeferredPass { @@ -40,6 +41,9 @@ private: private: ShadowCache::Ptr shadow_cache; + IndirectCache::Ptr indirect_cache; + bool indirect_computed = false; + lava::pipeline_layout::ptr pipeline_layout; std::array<NativeStereoDeferredPass, 2> eye_passes; }; diff --git a/src/strategy/native_stereo_forward.cpp b/src/strategy/native_stereo_forward.cpp index 6a6d8709c93a085b68c2e128360db47a4ba0987c..5b00e4b1008ce423d517ce5f9c69e1fb7faf61dc 100644 --- a/src/strategy/native_stereo_forward.cpp +++ b/src/strategy/native_stereo_forward.cpp @@ -12,7 +12,7 @@ bool NativeStereoForward::on_create() this->indirect_cache = make_indirect_cache(); - if (!this->indirect_cache->create(this->get_scene(), IndirectSettings())) + if (!this->indirect_cache->create(this->get_scene(), IndirectCacheSettings())) { return false; } @@ -55,6 +55,7 @@ void NativeStereoForward::on_destroy() if (this->indirect_cache != nullptr) { this->indirect_cache->destroy(); + this->indirect_computed = false; } if (this->pipeline_layout != nullptr) diff --git a/src/utility/geometry_buffer.cpp b/src/utility/geometry_buffer.cpp index d05b06b9066b4071a01d0b7e52b4d1df74e4af14..2482ef4d192740d799de857c43bde4c06bfc45df 100644 --- a/src/utility/geometry_buffer.cpp +++ b/src/utility/geometry_buffer.cpp @@ -1,12 +1,13 @@ #include "geometry_buffer.hpp" -bool GeometryBuffer::create(lava::image::ptr output_image, VkImageLayout output_layout, lava::descriptor::ptr per_frame_descriptor, Scene::Ptr scene, ShadowCache::Ptr shadow_cache) +bool GeometryBuffer::create(lava::image::ptr output_image, VkImageLayout output_layout, lava::descriptor::ptr per_frame_descriptor, Scene::Ptr scene, ShadowCache::Ptr shadow_cache, IndirectCache::Ptr indirect_cache) { lava::device_ptr device = output_image->get_device(); glm::uvec2 size = output_image->get_size(); this->scene = scene; this->shadow_cache = shadow_cache; + this->indirect_cache = indirect_cache; this->output_image = output_image; this->output_layout = output_layout; @@ -482,6 +483,11 @@ bool GeometryBuffer::create_pipeline(lava::device_ptr device, lava::descriptor:: this->pipeline_layout->add(this->shadow_cache->get_descriptor()); //descriptor-set index 3: shadow-information } + if (this->indirect_cache != nullptr) + { + this->pipeline_layout->add(this->indirect_cache->get_descriptor()); //descriptor-set index 3 or 4: shadow-information + } + if (!this->pipeline_layout->create(device)) { lava::log()->error("Can't create pipeline layout for deferred local light pass!"); @@ -504,31 +510,32 @@ bool GeometryBuffer::create_pipeline(lava::device_ptr device, lava::descriptor:: this->pipeline->set_input_assembly_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); this->pipeline->add_color_blend_attachment(output_blend_state); - if (!this->pipeline->add_shader(lava::file_data("dpr/binary/deferred_local_light_vertex.spirv"), VK_SHADER_STAGE_VERTEX_BIT)) + if (!this->pipeline->add_shader(lava::file_data("dpr/binary/deferred_lighting_vertex.spirv"), VK_SHADER_STAGE_VERTEX_BIT)) { - lava::log()->error("Can't load vertex shader for deferred local light pass!"); + lava::log()->error("Can't load vertex shader for deferred lighting pass!"); return false; } - if (this->shadow_cache != nullptr) + std::string shader_name = "dpr/binary/deferred_lighting"; + + if (this->indirect_cache != nullptr) { - if (!this->pipeline->add_shader(lava::file_data("dpr/binary/deferred_local_light_with_shadow_fragment.spirv"), VK_SHADER_STAGE_FRAGMENT_BIT)) - { - lava::log()->error("Can't load fragment shader for deferred local light with shadow pass!"); + shader_name += "_indirect"; + } - return false; - } + if (this->shadow_cache != nullptr) + { + shader_name += "_shadow"; } - else + shader_name += "_fragment.spirv"; + + if (!this->pipeline->add_shader(lava::file_data(shader_name.c_str()), VK_SHADER_STAGE_FRAGMENT_BIT)) { - if (!this->pipeline->add_shader(lava::file_data("dpr/binary/deferred_local_light_fragment.spirv"), VK_SHADER_STAGE_FRAGMENT_BIT)) - { - lava::log()->error("Can't load fragment shader for deferred local light without shadow pass!"); + lava::log()->error("Can't load fragment shader for deferred lighting pass!"); - return false; - } + return false; } this->pipeline->on_process = [this](VkCommandBuffer command_buffer) @@ -553,9 +560,20 @@ void GeometryBuffer::pipline_function(VkCommandBuffer command_buffer) this->pipeline_layout->bind(command_buffer, this->buffer_descriptor_set, 0); this->pipeline_layout->bind(command_buffer, this->scene->get_light_descriptor_set(this->frame), 1); - if (this->shadow_cache != nullptr) + if (this->shadow_cache != nullptr && this->indirect_cache != nullptr) { this->pipeline_layout->bind(command_buffer, this->shadow_cache->get_descriptor_set(), 3); + this->pipeline_layout->bind(command_buffer, this->indirect_cache->get_descriptor_set(), 4); + } + + else if (this->shadow_cache != nullptr) + { + this->pipeline_layout->bind(command_buffer, this->shadow_cache->get_descriptor_set(), 3); + } + + else if (this->indirect_cache != nullptr) + { + this->pipeline_layout->bind(command_buffer, this->indirect_cache->get_descriptor_set(), 4); } vkCmdDraw(command_buffer, 4, 1, 0, 0); //draw fullscreen quad diff --git a/src/utility/geometry_buffer.hpp b/src/utility/geometry_buffer.hpp index d9a89437a6a47eb4a4da7c794488431a86b153e4..735e3bd86316c5516b02a08318fa9da4e3fe91da 100644 --- a/src/utility/geometry_buffer.hpp +++ b/src/utility/geometry_buffer.hpp @@ -60,6 +60,7 @@ #include "scene.hpp" #include "shadow_cache.hpp" +#include "indirect_cache.hpp" class GeometryBuffer { @@ -69,7 +70,7 @@ public: public: GeometryBuffer() = default; - bool create(lava::image::ptr output_image, VkImageLayout output_layout, lava::descriptor::ptr per_frame_descriptor, Scene::Ptr scene, ShadowCache::Ptr shadow_cache = {}); + bool create(lava::image::ptr output_image, VkImageLayout output_layout, lava::descriptor::ptr per_frame_descriptor, Scene::Ptr scene, ShadowCache::Ptr shadow_cache = {}, IndirectCache::Ptr indirect_cache = {}); void destroy(); // Apply local lighting based on the perspective defined by the per_frame_descriptor_set and write the results into the output image @@ -106,6 +107,7 @@ private: private: Scene::Ptr scene; ShadowCache::Ptr shadow_cache; + IndirectCache::Ptr indirect_cache; uint32_t frame = 0; lava::image::ptr output_image; diff --git a/src/utility/indirect_cache.cpp b/src/utility/indirect_cache.cpp index 6770fbf7857c9e38d81760c1d3ad0d7f22fa5a72..1eb521f840a6dd2e8f71056f4ce6973883d7fd32 100644 --- a/src/utility/indirect_cache.cpp +++ b/src/utility/indirect_cache.cpp @@ -8,10 +8,13 @@ namespace glsl #include "res/dpr/data/indirect_data.inc" } -bool IndirectCache::create(Scene::Ptr scene, const IndirectSettings& settings) +bool IndirectCache::create(Scene::Ptr scene, const IndirectCacheSettings& settings) { lava::device_ptr device = scene->get_light_descriptor()->get_device(); + this->scene = scene; + this->settings = settings; + this->compute_domain(scene, settings); if (!this->create_buffers(device, settings)) @@ -64,15 +67,118 @@ bool IndirectCache::create(Scene::Ptr scene, const IndirectSettings& settings) return false; } - this->scene = scene; - this->settings = settings; - return true; } void IndirectCache::destroy() { - //TODO: .... + lava::device_ptr device = this->scene->get_light_descriptor()->get_device(); + + if (this->capture_pipeline != nullptr) + { + this->capture_pipeline->destroy(); + } + + if (this->injection_pipeline != nullptr) + { + this->capture_pipeline->destroy(); + } + + if (this->propagation_pipeline != nullptr) + { + this->propagation_pipeline->destroy(); + } + + if (this->capture_pass != nullptr) + { + this->capture_pass->destroy(); + } + + if (this->injection_pass != nullptr) + { + this->injection_pass->destroy(); + } + + if (this->capture_layout != nullptr) + { + this->capture_layout->destroy(); + } + + if (this->injection_layout != nullptr) + { + this->injection_layout->destroy(); + } + + if (this->propagation_layout != nullptr) + { + this->propagation_layout->destroy(); + } + + if (this->indirect_descriptor != nullptr) + { + this->indirect_descriptor->free(this->indirect_descriptor_set, this->descriptor_pool->get()); + this->indirect_descriptor->destroy(); + } + + if (this->injection_descriptor != nullptr) + { + this->injection_descriptor->free(this->injection_descriptor_set, this->descriptor_pool->get()); + this->injection_descriptor->destroy(); + } + + if (this->propagation_descriptor != nullptr) + { + this->propagation_descriptor->free(this->propagation_descriptor_set[0], this->descriptor_pool->get()); + this->propagation_descriptor->free(this->propagation_descriptor_set[1], this->descriptor_pool->get()); + this->propagation_descriptor->destroy(); + } + + if (this->descriptor_pool != nullptr) + { + this->descriptor_pool->destroy(); + } + + if (this->capture_depth_image != nullptr) + { + this->capture_depth_image->destroy(); + } + + if (this->capture_flux_image != nullptr) + { + this->capture_flux_image->destroy(); + } + + if (this->capture_normal_image != nullptr) + { + this->capture_normal_image->destroy(); + } + + if (this->domain_buffer != nullptr) + { + this->domain_buffer->destroy(); + } + + vkDestroySampler(device->get(), this->indirect_sampler, lava::memory::alloc()); + vkDestroySampler(device->get(), this->injection_sampler, lava::memory::alloc()); + + for (uint32_t index = 0; index < distribution_red_image.size(); index++) + { + vkDestroyImageView(device->get(), distribution_red_image_view[index], lava::memory::alloc()); + vkDestroyImageView(device->get(), distribution_green_image_view[index], lava::memory::alloc()); + vkDestroyImageView(device->get(), distribution_blue_image_view[index], lava::memory::alloc()); + + vkDestroyImageView(device->get(), distribution_red_image_array_view[index], lava::memory::alloc()); + vkDestroyImageView(device->get(), distribution_green_image_array_view[index], lava::memory::alloc()); + vkDestroyImageView(device->get(), distribution_blue_image_array_view[index], lava::memory::alloc()); + + vkDestroyImage(device->get(), distribution_red_image[index], lava::memory::alloc()); + vkDestroyImage(device->get(), distribution_green_image[index], lava::memory::alloc()); + vkDestroyImage(device->get(), distribution_blue_image[index], lava::memory::alloc()); + + vmaFreeMemory(device->get_allocator()->get(), distribution_red_image_memory[index]); + vmaFreeMemory(device->get_allocator()->get(), distribution_green_image_memory[index]); + vmaFreeMemory(device->get_allocator()->get(), distribution_blue_image_memory[index]); + } } void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index frame) @@ -234,12 +340,12 @@ VkDescriptorSet IndirectCache::get_descriptor_set() const return this->indirect_descriptor_set; } -const IndirectSettings& IndirectCache::get_settings() const +const IndirectCacheSettings& IndirectCache::get_settings() const { return this->settings; } -void IndirectCache::compute_domain(Scene::Ptr scene, const IndirectSettings& settings) +void IndirectCache::compute_domain(Scene::Ptr scene, const IndirectCacheSettings& settings) { glm::vec3 scene_min = scene->get_scene_min(); glm::vec3 scene_max = scene->get_scene_max(); @@ -272,7 +378,7 @@ void IndirectCache::compute_domain(Scene::Ptr scene, const IndirectSettings& set this->propagation_iterations = 2 * glm::max(this->domain_resolution.x, glm::max(this->domain_resolution.y, this->domain_resolution.z)); } -bool IndirectCache::create_buffers(lava::device_ptr device, const IndirectSettings& settings) +bool IndirectCache::create_buffers(lava::device_ptr device, const IndirectCacheSettings& settings) { glsl::IndirectDomain indirect_domain; indirect_domain.resolution = this->domain_resolution; @@ -294,7 +400,7 @@ bool IndirectCache::create_buffers(lava::device_ptr device, const IndirectSettin return true; } -bool IndirectCache::create_images(lava::device_ptr device, const IndirectSettings& settings) +bool IndirectCache::create_images(lava::device_ptr device, const IndirectCacheSettings& settings) { this->capture_depth_image = lava::make_image(VK_FORMAT_D16_UNORM); this->capture_depth_image->set_usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); @@ -517,7 +623,7 @@ bool IndirectCache::create_samplers(lava::device_ptr device) sampler_info.compareEnable = VK_FALSE; sampler_info.compareOp = VK_COMPARE_OP_LESS; sampler_info.minLod = 0.0f; - sampler_info.maxLod = VK_LOD_CLAMP_NONE; + sampler_info.maxLod = 0.0f; sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; sampler_info.unnormalizedCoordinates = VK_FALSE; @@ -807,7 +913,7 @@ bool IndirectCache::create_layouts(lava::device_ptr device, Scene::Ptr scene) return true; } -bool IndirectCache::create_capture_pass(lava::device_ptr device, const IndirectSettings& settings) +bool IndirectCache::create_capture_pass(lava::device_ptr device, const IndirectCacheSettings& settings) { VkClearValue clear_depth; clear_depth.depthStencil.depth = 1.0; diff --git a/src/utility/indirect_cache.hpp b/src/utility/indirect_cache.hpp index 49fefcbfc3a1c9aca5e885701ff60c399487e799..df471b1a8379c2713382d55f33dc38ef348f27ae 100644 --- a/src/utility/indirect_cache.hpp +++ b/src/utility/indirect_cache.hpp @@ -8,10 +8,10 @@ #include "scene.hpp" -struct IndirectSettings +struct IndirectCacheSettings { uint32_t capture_resolution = 1024; - float cell_size = 0.8f; //Where cell size is in meters + float cell_size = 1.0f; //Where cell size is in meters }; class IndirectCache @@ -22,7 +22,7 @@ public: public: IndirectCache() = default; - bool create(Scene::Ptr scene, const IndirectSettings& settings); + bool create(Scene::Ptr scene, const IndirectCacheSettings& settings); void destroy(); void compute_indirect(VkCommandBuffer command_buffer, lava::index frame); @@ -30,17 +30,17 @@ public: lava::descriptor::ptr get_descriptor() const; VkDescriptorSet get_descriptor_set() const; - const IndirectSettings& get_settings() const; + const IndirectCacheSettings& get_settings() const; private: - void compute_domain(Scene::Ptr scene, const IndirectSettings& settings); + void compute_domain(Scene::Ptr scene, const IndirectCacheSettings& settings); - bool create_buffers(lava::device_ptr device, const IndirectSettings& settings); - bool create_images(lava::device_ptr device, const IndirectSettings& settings); + bool create_buffers(lava::device_ptr device, const IndirectCacheSettings& settings); + bool create_images(lava::device_ptr device, const IndirectCacheSettings& settings); bool create_samplers(lava::device_ptr device); bool create_descriptors(lava::device_ptr device); bool create_layouts(lava::device_ptr device, Scene::Ptr scene); - bool create_capture_pass(lava::device_ptr device, const IndirectSettings& settings); + bool create_capture_pass(lava::device_ptr device, const IndirectCacheSettings& settings); bool create_capture_pipeline(lava::device_ptr device); bool create_injection_pass(lava::device_ptr device); bool create_injection_pipeline(lava::device_ptr device); @@ -53,7 +53,7 @@ private: private: Scene::Ptr scene; - IndirectSettings settings; + IndirectCacheSettings settings; uint32_t frame = 0; uint32_t light_index = 0;