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,
"vxgi": true,
"culling": true,
"bloom": false,
"bloom": true,
"rt": false,
"fsr": false,
"postProcess": false // "postProcess.chromab" // false

View File

@ -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

View File

@ -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 ],

View File

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

View File

@ -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

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->*/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<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
/*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;

View File

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