1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Fix debanding for Mobile rendering method with HDR 2D.

This commit is contained in:
Allen Pestaluky
2025-07-18 17:27:18 -04:00
parent 037956dbc9
commit a033656eda
6 changed files with 83 additions and 24 deletions

View File

@@ -615,6 +615,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RendererRD::ToneMapper::TonemapSettings tonemap;
bool using_hdr = texture_storage->render_target_is_using_hdr(render_target);
tonemap.exposure_texture = luminance->get_current_luminance_buffer(rb);
if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) && tonemap.exposure_texture.is_valid()) {
tonemap.use_auto_exposure = true;
@@ -653,7 +655,6 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.use_fxaa = true;
}
tonemap.use_debanding = rb->get_use_debanding();
tonemap.texture_size = Vector2i(color_size.x, color_size.y);
if (p_render_data->environment.is_valid()) {
@@ -665,7 +666,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.use_color_correction = false;
tonemap.use_1d_color_correction = false;
tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE);
tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(render_target);
tonemap.convert_to_srgb = !using_hdr;
if (can_use_effects && p_render_data->environment.is_valid()) {
tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment);
@@ -683,10 +684,12 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.view_count = rb->get_view_count();
RID dest_fb;
RD::DataFormat dest_fb_format;
if (spatial_upscaler != nullptr || use_smaa) {
// If we use a spatial upscaler to upscale or SMAA to antialias we need to write our result into an intermediate buffer.
// Note that this is cached so we only create the texture the first time.
RID dest_texture = rb->create_texture(SNAME("Tonemapper"), SNAME("destination"), _render_buffers_get_color_format(), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true);
dest_fb_format = _render_buffers_get_color_format();
RID dest_texture = rb->create_texture(SNAME("Tonemapper"), SNAME("destination"), dest_fb_format, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true);
dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture);
} else {
// If we do a bilinear upscale we just render into our render target and our shader will upscale automatically.
@@ -694,13 +697,30 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
// Bit nasty but...
if (dest_is_msaa_2d) {
// Assume that the DataFormat of render_target_get_rd_texture_msaa is the same as render_target_get_color_format.
dest_fb_format = texture_storage->render_target_get_color_format(using_hdr, tonemap.convert_to_srgb);
dest_fb = FramebufferCacheRD::get_singleton()->get_cache(texture_storage->render_target_get_rd_texture_msaa(render_target));
texture_storage->render_target_set_msaa_needs_resolve(render_target, true); // Make sure this gets resolved.
} else {
// Assume that the DataFormat of render_target_get_rd_framebuffer is the same as render_target_get_color_format.
dest_fb_format = texture_storage->render_target_get_color_format(using_hdr, tonemap.convert_to_srgb);
dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target);
}
}
if (rb->get_use_debanding()) {
if (dest_fb_format >= RD::DATA_FORMAT_R8_UNORM && dest_fb_format <= RD::DATA_FORMAT_A8B8G8R8_SRGB_PACK32) {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_8_BIT;
} else if (dest_fb_format >= RD::DATA_FORMAT_A2R10G10B10_UNORM_PACK32 && dest_fb_format <= RD::DATA_FORMAT_A2B10G10R10_SINT_PACK32) {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_10_BIT;
} else {
// In this case, debanding will be handled later when quantizing to an integer data format. (During blit, for example.)
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_DISABLED;
}
} else {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_DISABLED;
}
tone_mapper->tonemapper(color_texture, dest_fb, tonemap);
RD::get_singleton()->draw_command_end_label();
@@ -814,6 +834,8 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
ERR_FAIL_MSG("Auto Exposure is not supported when using subpasses.");
}
bool using_hdr = texture_storage->render_target_is_using_hdr(rb->get_render_target());
tonemap.use_glow = false;
tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE);
@@ -823,7 +845,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
tonemap.use_color_correction = false;
tonemap.use_1d_color_correction = false;
tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE);
tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(rb->get_render_target());
tonemap.convert_to_srgb = !using_hdr;
if (can_use_effects && p_render_data->environment.is_valid()) {
tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment);
@@ -837,12 +859,26 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
}
}
tonemap.use_debanding = rb->get_use_debanding();
tonemap.texture_size = Vector2i(target_size.x, target_size.y);
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
tonemap.view_count = rb->get_view_count();
if (rb->get_use_debanding()) {
// Assume that the DataFormat of p_framebuffer is the same as render_target_get_color_format.
RD::DataFormat dest_fb_format = texture_storage->render_target_get_color_format(using_hdr, tonemap.convert_to_srgb);
if (dest_fb_format >= RD::DATA_FORMAT_R8_UNORM && dest_fb_format <= RD::DATA_FORMAT_A8B8G8R8_SRGB_PACK32) {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_8_BIT;
} else if (dest_fb_format >= RD::DATA_FORMAT_A2R10G10B10_UNORM_PACK32 && dest_fb_format <= RD::DATA_FORMAT_A2B10G10R10_SINT_PACK32) {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_10_BIT;
} else {
// In this case, debanding will be handled later when quantizing to an integer data format. (During blit, for example.)
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_DISABLED;
}
} else {
tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_DISABLED;
}
tone_mapper->tonemapper(draw_list, p_source_texture, RD::get_singleton()->framebuffer_get_format(p_framebuffer), tonemap);
RD::get_singleton()->draw_command_end_label();