diff --git a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp index f0e505e1f49edc32cb5235727a022caa9e60b781..471870fb1e5af3d3c448a66611d9754db9597f85 100644 --- a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp +++ b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp @@ -9,6 +9,7 @@ #include <vector> #include <array> #include <cstdint> +#include <filesystem> /** These macros define limits of the following structs. Implementations can * test against these limits when performing sanity checks. The main constraint @@ -190,5 +191,12 @@ typedef struct { * */ int loadScene(const std::string &path, Scene &scene); +struct TextureData { + int width; + int height; + int componentCount; + std::vector<char*> data; +}; +TextureData loadTexture(const std::filesystem::path& path); } diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index 0c360dfbfe6dbb7b4b720e8afe715d633e97856e..06329d8086a0b16a9b24a6c1f60f540a6e81aecb 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -366,4 +366,12 @@ int loadScene(const std::string &path, Scene &scene){ return 1; } +TextureData loadTexture(const std::filesystem::path& path) { + TextureData texture; + uint8_t* data = stbi_load("resources/RadialLut.png", &texture.width, &texture.height, &texture.componentCount, 4); + texture.data.resize(texture.width * texture.height * 4); + memcpy(texture.data.data(), data, texture.data.size()); + return texture; +} + } diff --git a/projects/voxelization/resources/RadialLUT.png b/projects/voxelization/resources/RadialLUT.png new file mode 100644 index 0000000000000000000000000000000000000000..8b7056cf2a35c4d41f142e52bbc48dd1a91e4758 --- /dev/null +++ b/projects/voxelization/resources/RadialLUT.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70d59d4e9c1ce2a077ed60c19c8c4665bf0723c952612a2ca8ec32c55f9ec498 +size 900 diff --git a/projects/voxelization/resources/shaders/bloomFlaresComposite.comp b/projects/voxelization/resources/shaders/bloomFlaresComposite.comp index eb17ea90d62ca17ccd37b4e651b8469c73620b49..2bf8a5e6aa52b3ea42cf1ae3ec583b37599c356b 100644 --- a/projects/voxelization/resources/shaders/bloomFlaresComposite.comp +++ b/projects/voxelization/resources/shaders/bloomFlaresComposite.comp @@ -5,9 +5,31 @@ layout(set=0, binding=0) uniform texture2D blurImage; layout(set=0, binding=1) uniform texture2D lensImage; layout(set=0, binding=2) uniform sampler linearSampler; layout(set=0, binding=3, r11f_g11f_b10f) uniform image2D colorBuffer; +layout(set=0, binding=4) uniform texture2D radialLUT; +layout(set=0, binding=5) uniform sampler radialLUTSampler; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout( push_constant ) uniform constants{ + vec3 cameraForward; +}; + +float starburst(vec2 uv){ + vec2 toCenter = vec2(0.5) - uv; + float d2 = dot(toCenter, toCenter); + float falloff = clamp(pow(d2 * 2, 2.5), 0, 1); + + float cosTheta = acos(normalize(toCenter).x) * sign(toCenter.y); + cosTheta *= 4; + + float thetaOffset = cameraForward.x + cameraForward.y; + thetaOffset *= 10; + cosTheta += thetaOffset; + + float burst = texture(sampler2D(radialLUT, radialLUTSampler), vec2(cosTheta, 0.5)).r; + burst = pow(burst, 2); + return mix(1, burst, falloff); +} void main() { @@ -30,9 +52,13 @@ void main() float lens_weight = 0.25f; float main_weight = 1 - (bloom_weight + lens_weight); + lens_color *= starburst(UV); + composite_color.rgb = blur_color * bloom_weight + lens_color * lens_weight + main_color * main_weight; + + //composite_color.rgb = vec3(1) * starburst(UV); imageStore(colorBuffer, pixel_coord, composite_color); } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/lensFlares.comp b/projects/voxelization/resources/shaders/lensFlares.comp index e51bc0ae03fddaae18c727557e59824aa82e25dd..afcad375c1cd3e8f547ad2386b6f1d7bdfdfa85a 100644 --- a/projects/voxelization/resources/shaders/lensFlares.comp +++ b/projects/voxelization/resources/shaders/lensFlares.comp @@ -53,18 +53,19 @@ vec3 ghost_vectors(vec2 _uv) vec3 halo(vec2 _uv) { - const float c_aspect_ratio = float(imageSize(lensBuffer).x) / float(imageSize(lensBuffer).y); - const float c_radius = 0.6f; - const float c_halo_thickness = 0.08f; + float c_aspect_ratio = float(imageSize(lensBuffer).x) / float(imageSize(lensBuffer).y); + c_aspect_ratio *= 0.55; + const float c_radius = 0.5f; + const float c_halo_thickness = 0.15f; - vec2 halo_vec = vec2(0.5) - _uv; - //halo_vec.x /= c_aspect_ratio; - halo_vec = normalize(halo_vec); - //halo_vec.x *= c_aspect_ratio; + vec2 halo_vec = vec2(0.5) - _uv; + halo_vec.x /= c_aspect_ratio; + halo_vec = normalize(halo_vec); + halo_vec.x *= c_aspect_ratio; - //vec2 w_uv = (_uv - vec2(0.5, 0.0)) * vec2(c_aspect_ratio, 1.0) + vec2(0.5, 0.0); - vec2 w_uv = _uv; + vec2 w_uv = (_uv - vec2(0.5, 0.0)) * vec2(c_aspect_ratio, 1.0) + vec2(0.5, 0.0); + //vec2 w_uv = _uv; float d = distance(w_uv, vec2(0.5)); // distance to center float distance_to_halo = abs(d - c_radius); diff --git a/projects/voxelization/src/BloomAndFlares.cpp b/projects/voxelization/src/BloomAndFlares.cpp index e4eb94007685eace1e24e7c5b8f59f75f5ef2238..03518b79fc0a9363af8cb10fe1e9033f8ac06758 100644 --- a/projects/voxelization/src/BloomAndFlares.cpp +++ b/projects/voxelization/src/BloomAndFlares.cpp @@ -1,5 +1,6 @@ #include "BloomAndFlares.hpp" #include <vkcv/shader/GLSLCompiler.hpp> +#include <vkcv/asset/asset_loader.hpp> BloomAndFlares::BloomAndFlares( vkcv::Core *p_Core, @@ -15,8 +16,13 @@ BloomAndFlares::BloomAndFlares( vkcv::SamplerFilterType::LINEAR, vkcv::SamplerMipmapMode::LINEAR, vkcv::SamplerAddressMode::CLAMP_TO_EDGE)), + m_RadialLutSampler(p_Core->createSampler(vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT)), m_Blur(p_Core->createImage(colorBufferFormat, m_Width, m_Height, 1, true, true, false)), - m_LensFeatures(p_Core->createImage(colorBufferFormat, m_Width, m_Height, 1, true, true, false)) + m_LensFeatures(p_Core->createImage(colorBufferFormat, m_Width, m_Height, 1, true, true, false)), + m_radialLut(p_Core->createImage(vk::Format::eR8G8B8A8Unorm, 128, 10, 1)) { vkcv::shader::GLSLCompiler compiler; @@ -80,6 +86,11 @@ BloomAndFlares::BloomAndFlares( m_CompositeDescSet = p_Core->createDescriptorSet(compProg.getReflectedDescriptors()[0]); m_CompositePipe = p_Core->createComputePipeline( compProg, { p_Core->getDescriptorSet(m_CompositeDescSet).layout }); + + // radial LUT + const auto texture = vkcv::asset::loadTexture("resources/radialLUT.png"); + + m_radialLut.fill((void*)texture.data.data(), texture.data.size()); } void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream, @@ -265,7 +276,7 @@ void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStr } void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle& colorAttachment, - const uint32_t attachmentWidth, const uint32_t attachmentHeight) + const uint32_t attachmentWidth, const uint32_t attachmentHeight, const glm::vec3& cameraForward) { p_Core->prepareImageForSampling(cmdStream, m_Blur.getHandle()); p_Core->prepareImageForSampling(cmdStream, m_LensFeatures.getHandle()); @@ -274,8 +285,10 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea // bloom composite descriptor write vkcv::DescriptorWrites compositeWrites; compositeWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, m_Blur.getHandle()), - vkcv::SampledImageDescriptorWrite(1, m_LensFeatures.getHandle())}; - compositeWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(2, m_LinearSampler)}; + vkcv::SampledImageDescriptorWrite(1, m_LensFeatures.getHandle()), + vkcv::SampledImageDescriptorWrite(4, m_radialLut.getHandle()) }; + compositeWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(2, m_LinearSampler), + vkcv::SamplerDescriptorWrite(5, m_RadialLutSampler) }; compositeWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(3, colorAttachment)}; p_Core->writeDescriptorSet(m_CompositeDescSet, compositeWrites); @@ -294,16 +307,16 @@ void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStrea m_CompositePipe, compositeDispatchCount, {vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)}, - vkcv::PushConstantData(nullptr, 0)); + vkcv::PushConstantData((void*)&cameraForward, sizeof(cameraForward))); } void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment, - const uint32_t attachmentWidth, const uint32_t attachmentHeight) + const uint32_t attachmentWidth, const uint32_t attachmentHeight, const glm::vec3& cameraForward) { execDownsamplePipe(cmdStream, colorAttachment); execUpsamplePipe(cmdStream); execLensFeaturePipe(cmdStream); - execCompositePipe(cmdStream, colorAttachment, attachmentWidth, attachmentHeight); + execCompositePipe(cmdStream, colorAttachment, attachmentWidth, attachmentHeight, cameraForward); } void BloomAndFlares::updateImageDimensions(uint32_t width, uint32_t height) diff --git a/projects/voxelization/src/BloomAndFlares.hpp b/projects/voxelization/src/BloomAndFlares.hpp index 7f0c523696f8f37bf2b70eabbfae10afe36077cb..f86c75c4ba21b0c78f93b7d86c824fd5af013df0 100644 --- a/projects/voxelization/src/BloomAndFlares.hpp +++ b/projects/voxelization/src/BloomAndFlares.hpp @@ -10,7 +10,7 @@ public: uint32_t height); void execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment, - const uint32_t attachmentWidth, const uint32_t attachmentHeight); + const uint32_t attachmentWidth, const uint32_t attachmentHeight, const glm::vec3& cameraForward); void updateImageDimensions(uint32_t width, uint32_t height); @@ -22,9 +22,12 @@ private: uint32_t m_Height; vkcv::SamplerHandle m_LinearSampler; + vkcv::SamplerHandle m_RadialLutSampler; vkcv::Image m_Blur; vkcv::Image m_LensFeatures; + vkcv::Image m_radialLut; + vkcv::PipelineHandle m_DownsamplePipe; std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set @@ -43,7 +46,7 @@ private: void execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream); void execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStream); void execCompositePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment, - const uint32_t attachmentWidth, const uint32_t attachmentHeight); + const uint32_t attachmentWidth, const uint32_t attachmentHeight, const glm::vec3& cameraForward); }; diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index bafcc45c054c5ebc8fe3afd91eef85c6a9f41f08..52bf09765ee7e0414db3dc930f08f9fc3af8a7de 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -451,6 +451,12 @@ int main(int argc, const char** argv) { BloomAndFlares bloomFlares(&core, colorBufferFormat, windowWidth, windowHeight); + window.e_key.add([&](int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_R && action == GLFW_PRESS) { + bloomFlares = BloomAndFlares(&core, colorBufferFormat, windowWidth, windowHeight); + } + }); + vkcv::Buffer<glm::vec3> cameraPosBuffer = core.createBuffer<glm::vec3>(vkcv::BufferType::UNIFORM, 1); struct VolumetricSettings { @@ -654,7 +660,8 @@ int main(int argc, const char** argv) { } } - bloomFlares.execWholePipeline(cmdStream, resolvedColorBuffer, windowWidth, windowHeight); + bloomFlares.execWholePipeline(cmdStream, resolvedColorBuffer, windowWidth, windowHeight, + glm::normalize(cameraManager.getActiveCamera().getFront())); core.prepareImageForStorage(cmdStream, swapchainInput); core.prepareImageForSampling(cmdStream, resolvedColorBuffer);