From 1ef5798017f723db470908bf20abdae55e1b2839 Mon Sep 17 00:00:00 2001 From: mrq Date: Sun, 8 Dec 2024 11:41:00 -0600 Subject: [PATCH] Fixed bloom --- bin/data/config.json | 2 +- bin/data/scenes/scene.json | 10 ++-- bin/data/scenes/sourceengine/scene.json | 20 -------- bin/data/shaders/display/bloom/comp.glsl | 35 +++++++------- docs/README.md | 4 +- ext/behaviors/scene/behavior.cpp | 58 ++++++++++-------------- ext/behaviors/scene/behavior.h | 7 ++- 7 files changed, 50 insertions(+), 86 deletions(-) diff --git a/bin/data/config.json b/bin/data/config.json index dfed9af2..7d805a38 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -117,7 +117,7 @@ "hdr": true, "vxgi": true, "culling": true, - "bloom": false, + "bloom": true, "rt": false, "fsr": false, "postProcess": false // "postProcess.chromab" // false diff --git a/bin/data/scenes/scene.json b/bin/data/scenes/scene.json index bba4ab2a..834a1d9a 100644 --- a/bin/data/scenes/scene.json +++ b/bin/data/scenes/scene.json @@ -39,19 +39,15 @@ "light": { "enabled": true, - "ambient": [ 0.0, 0.0, 0.0 ], - // "ambient": [ 0.1, 0.1, 0.2 ], + "ambient": [ 0.1, 0.1, 0.1 ], "exposure": 1.0, - // "gamma": 2.2, "gamma": 1.0, "bloom": { "threshold": 1.0, - "scale": 1.0, - "strength": 0.25, - "sigma": 1.0, - "samples": 4 + "size": 4, + "smoothness": 1 }, "shadows": { "enabled": true diff --git a/bin/data/scenes/sourceengine/scene.json b/bin/data/scenes/sourceengine/scene.json index 0efb8572..73620f73 100644 --- a/bin/data/scenes/sourceengine/scene.json +++ b/bin/data/scenes/sourceengine/scene.json @@ -6,26 +6,6 @@ ], "metadata": { "light": { - // "ambient": [ 0, 0, 0 ], - // "ambient": [ 0.05, 0.05, 0.05 ], - "ambient": [ 0.15, 0.15, 0.15 ], - // "ambient": [ 0.5, 0.5, 0.5 ], - // "ambient": [ 0.8, 0.8, 0.8 ], - // "ambient": [ 0.1, 0.1, 0.2 ], - - // "exposure": 0.125, - // "gamma": 2.2, - "exposure": 1.0, - "gamma": 1.0, - - "bloom": { - "threshold": 1.2, - "scale": 1.0, - "strength": 1, - "sigma": 2.0, - "samples": 4 - }, - "fog-": { // "color": [ 0.1, 0.1, 0.1 ], // "color": [ 0.2, 0.2, 0.2 ], diff --git a/bin/data/shaders/display/bloom/comp.glsl b/bin/data/shaders/display/bloom/comp.glsl index 639cc811..d5b709bc 100644 --- a/bin/data/shaders/display/bloom/comp.glsl +++ b/bin/data/shaders/display/bloom/comp.glsl @@ -6,7 +6,7 @@ #define CUBEMAPS 0 #define BLOOM 1 -layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in; +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; layout( push_constant ) uniform PushBlock { uint eye; @@ -14,15 +14,10 @@ layout( push_constant ) uniform PushBlock { } PushConstant; layout (binding = 0) uniform UBO { - float scale; - float strength; float threshold; - float sigma; - - float gamma; - float exposure; - uint samples; - uint padding; + float smoothness; + uint size; + uint padding1; } ubo; layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor; @@ -39,24 +34,30 @@ void main() { const ivec2 size = imageSize( imageColor ); if ( texel.x >= size.x || texel.y >= size.y ) return; + uint kernelSize = ubo.size * 2 + 1; + float sigma = kernelSize / (6 * max(0.001f, ubo.smoothness)); + float strength = 1.0f; + float scale = 1.0f; + if ( mode == 0 ) { // fill bloom vec3 result = imageLoad( imageColor, texel ).rgb; float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722)); if ( brightness < ubo.threshold ) result = vec3(0, 0, 0); imageStore( imageBloom, texel, vec4( result, 1.0 ) ); } else if ( mode == 1 ) { // bloom horizontal - vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength; - for( int i = 1; i < ubo.samples; ++i ) { - result += imageLoad( imageBloom, texel + ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength; - result += imageLoad( imageBloom, texel - ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength; + + vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, sigma ) * strength; + for( int i = 1; i < ubo.size; ++i ) { + result += imageLoad( imageBloom, texel + ivec2(i * scale, 0.0)).rgb * gauss( i * scale / ubo.size, sigma ) * strength; + result += imageLoad( imageBloom, texel - ivec2(i * scale, 0.0)).rgb * gauss( i * scale / ubo.size, sigma ) * strength; } // write to PingPong imageStore( imagePingPong, texel, vec4( result, 1.0 ) ); } else if ( mode == 2 ) { // bloom vertical - vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength; - for( int i = 1; i < ubo.samples; ++i ) { - result += imageLoad( imagePingPong, texel + ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength; - result += imageLoad( imagePingPong, texel - ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength; + vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, sigma ) * strength; + for( int i = 1; i < ubo.size; ++i ) { + result += imageLoad( imagePingPong, texel + ivec2(0.0, i * scale)).rgb * gauss( i * scale / ubo.size, sigma ) * strength; + result += imageLoad( imagePingPong, texel - ivec2(0.0, i * scale)).rgb * gauss( i * scale / ubo.size, sigma ) * strength; } // write to Bloom imageStore( imageBloom, texel, vec4( result, 1.0 ) ); diff --git a/docs/README.md b/docs/README.md index 017c1328..8798a713 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,8 +19,8 @@ To be filled. * point lights are treated as a cubemap * basic PBR shading * a sovlful (sloppy) VXGI for GI and reflections - * (currently broken) hardware RT support - * (currently broken) bloom and additional post processing + * (partially broken) hardware RT support + * bloom and additional post processing * FSR2 or something cringe * OpenGL uses a very, very naive OpenGL 1.2 API with a homebrewed command recording system * ReactPhysics3D for physics diff --git a/ext/behaviors/scene/behavior.cpp b/ext/behaviors/scene/behavior.cpp index 6b6ffa82..b6889592 100644 --- a/ext/behaviors/scene/behavior.cpp +++ b/ext/behaviors/scene/behavior.cpp @@ -815,10 +815,8 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali /*this->*/light.useLightmaps = serializer["light"]["useLightmaps"].as(/*this->*/light.useLightmaps); /*this->*/bloom.threshold = serializer["light"]["bloom"]["threshold"].as(/*this->*/bloom.threshold); - /*this->*/bloom.scale = serializer["light"]["bloom"]["scale"].as(/*this->*/bloom.scale); - /*this->*/bloom.strength = serializer["light"]["bloom"]["strength"].as(/*this->*/bloom.strength); - /*this->*/bloom.sigma = serializer["light"]["bloom"]["sigma"].as(/*this->*/bloom.sigma); - /*this->*/bloom.samples = serializer["light"]["bloom"]["samples"].as(/*this->*/bloom.samples); + /*this->*/bloom.size = serializer["light"]["bloom"]["size"].as(/*this->*/bloom.size); + /*this->*/bloom.smoothness = serializer["light"]["bloom"]["smoothness"].as(/*this->*/bloom.smoothness); /*this->*/fog.color = uf::vector::decode( serializer["light"]["fog"]["color"], /*this->*/fog.color ); /*this->*/fog.stepScale = serializer["light"]["fog"]["step scale"].as( /*this->*/fog.stepScale ); @@ -870,37 +868,6 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali #endif #if UF_USE_VULKAN auto& renderMode = this->hasComponent() ? this->getComponent() : uf::renderer::getRenderMode("", true); - if ( uf::renderer::settings::pipelines::bloom ) { - auto& blitter = renderMode.getBlitter(); - if ( blitter.material.hasShader("compute", "bloom") ) { - auto& shader = blitter.material.getShader("compute", "bloom"); - - struct UniformDescriptor { - float scale; - float strength; - float threshold; - float sigma; - - float gamma; - float exposure; - uint32_t samples; - uint32_t padding; - }; - - UniformDescriptor uniforms = { - .scale = bloom.scale, - .strength = bloom.strength, - .threshold = bloom.threshold, - .sigma = bloom.sigma, - - .gamma = light.gamma, - .exposure = light.exposure, - .samples = bloom.samples, - }; - - if ( shader.hasUniform("UBO") ) shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") ); - } - } #if UF_USE_FFX_FSR /*this->*/framebuffer.scale = serializer["system"]["renderer"]["scale"].as(/*this->*/framebuffer.scale); @@ -941,6 +908,27 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic if ( !graphic.initialized ) return; #if UF_USE_VULKAN + // only update this when requested + // done outside of deserialize because the rendermode might not be initialized in time + if ( uf::renderer::settings::pipelines::bloom && metadata.bloom.outOfDate && graphic.material.hasShader("compute", "bloom") ) { + auto& shader = graphic.material.getShader("compute", "bloom"); + + struct UniformDescriptor { + float threshold; + float smoothness; + uint32_t size; + uint32_t padding; + }; + + UniformDescriptor uniforms = { + .threshold = metadata.bloom.threshold, + .smoothness = metadata.bloom.smoothness, + .size = metadata.bloom.size, + }; + metadata.bloom.outOfDate = false; + if ( shader.hasUniform("UBO") ) shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") ); + } + struct UniformDescriptor { struct Matrices { alignas(16) pod::Matrix4f view; diff --git a/ext/behaviors/scene/behavior.h b/ext/behaviors/scene/behavior.h index 7a4c16f2..692d9d37 100644 --- a/ext/behaviors/scene/behavior.h +++ b/ext/behaviors/scene/behavior.h @@ -29,10 +29,9 @@ namespace ext { } light; struct { float threshold = 1.0f; - float scale = 1.0f; - float strength = 1.0f; - float sigma = 0.8f; - uint32_t samples = 1; + float smoothness = 1.0f; + uint32_t size = 1; + bool outOfDate = true; } bloom; struct { bool enabled = true;