Fixed bloom

This commit is contained in:
mrq 2024-12-08 11:41:00 -06:00 committed by ecker
parent e076b2f53d
commit 1ef5798017
7 changed files with 50 additions and 86 deletions

View File

@ -117,7 +117,7 @@
"hdr": true, "hdr": true,
"vxgi": true, "vxgi": true,
"culling": true, "culling": true,
"bloom": false, "bloom": true,
"rt": false, "rt": false,
"fsr": false, "fsr": false,
"postProcess": false // "postProcess.chromab" // false "postProcess": false // "postProcess.chromab" // false

View File

@ -39,19 +39,15 @@
"light": { "light": {
"enabled": true, "enabled": true,
"ambient": [ 0.0, 0.0, 0.0 ], "ambient": [ 0.1, 0.1, 0.1 ],
// "ambient": [ 0.1, 0.1, 0.2 ],
"exposure": 1.0, "exposure": 1.0,
// "gamma": 2.2,
"gamma": 1.0, "gamma": 1.0,
"bloom": { "bloom": {
"threshold": 1.0, "threshold": 1.0,
"scale": 1.0, "size": 4,
"strength": 0.25, "smoothness": 1
"sigma": 1.0,
"samples": 4
}, },
"shadows": { "shadows": {
"enabled": true "enabled": true

View File

@ -6,26 +6,6 @@
], ],
"metadata": { "metadata": {
"light": { "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-": { "fog-": {
// "color": [ 0.1, 0.1, 0.1 ], // "color": [ 0.1, 0.1, 0.1 ],
// "color": [ 0.2, 0.2, 0.2 ], // "color": [ 0.2, 0.2, 0.2 ],

View File

@ -6,7 +6,7 @@
#define CUBEMAPS 0 #define CUBEMAPS 0
#define BLOOM 1 #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 { layout( push_constant ) uniform PushBlock {
uint eye; uint eye;
@ -14,15 +14,10 @@ layout( push_constant ) uniform PushBlock {
} PushConstant; } PushConstant;
layout (binding = 0) uniform UBO { layout (binding = 0) uniform UBO {
float scale;
float strength;
float threshold; float threshold;
float sigma; float smoothness;
uint size;
float gamma; uint padding1;
float exposure;
uint samples;
uint padding;
} ubo; } ubo;
layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor; layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor;
@ -39,24 +34,30 @@ void main() {
const ivec2 size = imageSize( imageColor ); const ivec2 size = imageSize( imageColor );
if ( texel.x >= size.x || texel.y >= size.y ) return; 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 if ( mode == 0 ) { // fill bloom
vec3 result = imageLoad( imageColor, texel ).rgb; vec3 result = imageLoad( imageColor, texel ).rgb;
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722)); float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
if ( brightness < ubo.threshold ) result = vec3(0, 0, 0); if ( brightness < ubo.threshold ) result = vec3(0, 0, 0);
imageStore( imageBloom, texel, vec4( result, 1.0 ) ); imageStore( imageBloom, texel, vec4( result, 1.0 ) );
} else if ( mode == 1 ) { // bloom horizontal } 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 ) { vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, sigma ) * strength;
result += imageLoad( imageBloom, texel + ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength; for( int i = 1; i < ubo.size; ++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 * 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 // write to PingPong
imageStore( imagePingPong, texel, vec4( result, 1.0 ) ); imageStore( imagePingPong, texel, vec4( result, 1.0 ) );
} else if ( mode == 2 ) { // bloom vertical } else if ( mode == 2 ) { // bloom vertical
vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength; vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, sigma ) * strength;
for( int i = 1; i < ubo.samples; ++i ) { for( int i = 1; i < ubo.size; ++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 * scale)).rgb * gauss( i * scale / ubo.size, sigma ) * strength;
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 * scale)).rgb * gauss( i * scale / ubo.size, sigma ) * strength;
} }
// write to Bloom // write to Bloom
imageStore( imageBloom, texel, vec4( result, 1.0 ) ); imageStore( imageBloom, texel, vec4( result, 1.0 ) );

View File

@ -19,8 +19,8 @@ To be filled.
* point lights are treated as a cubemap * point lights are treated as a cubemap
* basic PBR shading * basic PBR shading
* a sovlful (sloppy) VXGI for GI and reflections * a sovlful (sloppy) VXGI for GI and reflections
* (currently broken) hardware RT support * (partially broken) hardware RT support
* (currently broken) bloom and additional post processing * bloom and additional post processing
* FSR2 or something cringe * FSR2 or something cringe
* OpenGL uses a very, very naive OpenGL 1.2 API with a homebrewed command recording system * OpenGL uses a very, very naive OpenGL 1.2 API with a homebrewed command recording system
* ReactPhysics3D for physics * ReactPhysics3D for physics

View File

@ -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->*/light.useLightmaps = serializer["light"]["useLightmaps"].as(/*this->*/light.useLightmaps);
/*this->*/bloom.threshold = serializer["light"]["bloom"]["threshold"].as(/*this->*/bloom.threshold); /*this->*/bloom.threshold = serializer["light"]["bloom"]["threshold"].as(/*this->*/bloom.threshold);
/*this->*/bloom.scale = serializer["light"]["bloom"]["scale"].as(/*this->*/bloom.scale); /*this->*/bloom.size = serializer["light"]["bloom"]["size"].as(/*this->*/bloom.size);
/*this->*/bloom.strength = serializer["light"]["bloom"]["strength"].as(/*this->*/bloom.strength); /*this->*/bloom.smoothness = serializer["light"]["bloom"]["smoothness"].as(/*this->*/bloom.smoothness);
/*this->*/bloom.sigma = serializer["light"]["bloom"]["sigma"].as(/*this->*/bloom.sigma);
/*this->*/bloom.samples = serializer["light"]["bloom"]["samples"].as(/*this->*/bloom.samples);
/*this->*/fog.color = uf::vector::decode( serializer["light"]["fog"]["color"], /*this->*/fog.color ); /*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 ); /*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 #endif
#if UF_USE_VULKAN #if UF_USE_VULKAN
auto& renderMode = this->hasComponent<uf::renderer::DeferredRenderMode>() ? this->getComponent<uf::renderer::DeferredRenderMode>() : uf::renderer::getRenderMode("", true); auto& renderMode = this->hasComponent<uf::renderer::DeferredRenderMode>() ? this->getComponent<uf::renderer::DeferredRenderMode>() : 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 #if UF_USE_FFX_FSR
/*this->*/framebuffer.scale = serializer["system"]["renderer"]["scale"].as(/*this->*/framebuffer.scale); /*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 ( !graphic.initialized ) return;
#if UF_USE_VULKAN #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 UniformDescriptor {
struct Matrices { struct Matrices {
alignas(16) pod::Matrix4f view; alignas(16) pod::Matrix4f view;

View File

@ -29,10 +29,9 @@ namespace ext {
} light; } light;
struct { struct {
float threshold = 1.0f; float threshold = 1.0f;
float scale = 1.0f; float smoothness = 1.0f;
float strength = 1.0f; uint32_t size = 1;
float sigma = 0.8f; bool outOfDate = true;
uint32_t samples = 1;
} bloom; } bloom;
struct { struct {
bool enabled = true; bool enabled = true;