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);