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

Use half float precision buffer for 3D when HDR2D is enabled

This is necessary for Environment effects like Glow to work correctly.
This commit is contained in:
clayjohn
2025-08-25 14:03:31 -07:00
parent c7b1767560
commit f61ee7bdf6
13 changed files with 60 additions and 53 deletions

View File

@@ -689,7 +689,9 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
}
}
p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, p_apply_alpha_multiplier);
float luminance_multiplier = rd.is_valid() ? rd->get_luminance_multiplier() : 1.0;
p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, luminance_multiplier, p_opaque_render_buffers, p_apply_alpha_multiplier);
// now do implementation UBO
@@ -1434,7 +1436,7 @@ void RenderForwardClustered::_process_ssr(Ref<RenderSceneBuffersRD> p_render_buf
RENDER_TIMESTAMP("Process SSR");
ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, _render_buffers_get_color_format());
ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, p_render_buffers->get_base_data_format());
Projection reprojections[RendererSceneRender::MAX_RENDER_VIEWS];
@@ -1946,7 +1948,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool draw_sky = false;
bool draw_sky_fog_only = false;
// We invert luminance_multiplier for sky so that we can combine it with exposure value.
float sky_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier();
float sky_luminance_multiplier = 1.0 / rb->get_luminance_multiplier();
float sky_brightness_multiplier = 1.0;
Color clear_color;
@@ -2472,7 +2474,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
} else if (using_taa) {
RD::get_singleton()->draw_command_begin_label("TAA");
RENDER_TIMESTAMP("TAA");
taa->process(rb, _render_buffers_get_color_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far);
taa->process(rb, rb->get_base_data_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far);
RD::get_singleton()->draw_command_end_label();
}
}
@@ -4505,7 +4507,7 @@ void RenderForwardClustered::_mesh_compile_pipelines_for_surface(const SurfacePi
// Retrieve from the scene shader which groups are currently enabled.
const bool multiview_enabled = p_global.use_multiview && scene_shader.is_multiview_shader_group_enabled();
const RD::DataFormat buffers_color_format = _render_buffers_get_color_format();
const RD::DataFormat buffers_color_format = _render_buffers_get_preferred_color_format();
const bool buffers_can_be_storage = _render_buffers_can_be_storage();
// Set the attributes common to all pipelines.

View File

@@ -414,19 +414,12 @@ void RenderForwardMobile::update() {
/* Render functions */
float RenderForwardMobile::_render_buffers_get_luminance_multiplier() {
// On mobile renderer we need to multiply source colors by 2 due to using a UNORM buffer
// and multiplying by the output color during 3D rendering by 0.5
return 2.0;
}
RD::DataFormat RenderForwardMobile::_render_buffers_get_color_format() {
RD::DataFormat RenderForwardMobile::_render_buffers_get_preferred_color_format() {
// Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs)
return RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
}
bool RenderForwardMobile::_render_buffers_can_be_storage() {
// Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs)
// Doesn't support storage
return false;
}
@@ -1002,8 +995,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool draw_sky = false;
bool draw_sky_fog_only = false;
// We invert luminance_multiplier for sky so that we can combine it with exposure value.
float inverse_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier();
float sky_luminance_multiplier = inverse_luminance_multiplier;
float inverse_luminance_multiplier = 1.0 / rb->get_luminance_multiplier();
float sky_luminance_multiplier = 1.0 / 2.0; // Hardcoded since sky always uses LDR in the mobile renderer
float sky_brightness_multiplier = 1.0;
Color clear_color = p_default_bg_color;
@@ -1122,6 +1115,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap;
base_specialization.scene_use_reflection_cubemap = use_reflection_cubemap;
base_specialization.scene_roughness_limiter_enabled = p_render_data->render_buffers.is_valid() && screen_space_roughness_limiter_is_active();
base_specialization.luminance_multiplier = p_render_data->render_buffers.is_valid() ? p_render_data->render_buffers->get_luminance_multiplier() : 1.0;
}
{
@@ -2201,7 +2195,9 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
}
}
p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, false);
float luminance_multiplier = p_render_data->render_buffers.is_valid() ? p_render_data->render_buffers->get_luminance_multiplier() : 1.0;
p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, luminance_multiplier, p_opaque_render_buffers, false);
}
/// RENDERING ///
@@ -3141,7 +3137,6 @@ void RenderForwardMobile::_mesh_compile_pipelines_for_surface(const SurfacePipel
pipeline_key.wireframe = false;
const bool multiview_enabled = p_global.use_multiview && scene_shader.is_multiview_shader_group_enabled();
const RD::DataFormat buffers_color_format = _render_buffers_get_color_format();
const bool buffers_can_be_storage = _render_buffers_can_be_storage();
const uint32_t vrs_iterations = p_global.use_vrs ? 2 : 1;
@@ -3155,6 +3150,7 @@ void RenderForwardMobile::_mesh_compile_pipelines_for_surface(const SurfacePipel
for (uint32_t use_post_pass = post_pass_start; use_post_pass < post_pass_iterations; use_post_pass++) {
const uint32_t hdr_iterations = use_post_pass ? hdr_target_iterations : (hdr_start + 1);
for (uint32_t use_hdr = hdr_start; use_hdr < hdr_iterations; use_hdr++) {
const RD::DataFormat buffers_color_format = use_hdr ? RD::DATA_FORMAT_R16G16B16A16_SFLOAT : _render_buffers_get_preferred_color_format();
pipeline_key.version = SceneShaderForwardMobile::SHADER_VERSION_COLOR_PASS;
pipeline_key.framebuffer_format_id = _get_color_framebuffer_format_for_pipeline(buffers_color_format, buffers_can_be_storage, RD::TextureSamples(p_global.texture_samples), RD::TextureSamples(p_global.target_samples), use_vrs, use_post_pass, use_hdr, 1);
_mesh_compile_pipeline_for_surface(p_surface.shader, p_surface.mesh_surface, p_surface.instanced, p_source, pipeline_key, r_pipeline_pairs);
@@ -3340,7 +3336,7 @@ void RenderForwardMobile::_update_shader_quality_settings() {
RenderForwardMobile::RenderForwardMobile() {
singleton = this;
sky.set_texture_format(_render_buffers_get_color_format());
sky.set_texture_format(_render_buffers_get_preferred_color_format());
String defines;

View File

@@ -413,8 +413,7 @@ protected:
/* setup */
virtual void _update_shader_quality_settings() override;
virtual float _render_buffers_get_luminance_multiplier() override;
virtual RD::DataFormat _render_buffers_get_color_format() override;
virtual RD::DataFormat _render_buffers_get_preferred_color_format() override;
virtual bool _render_buffers_can_be_storage() override;
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;

View File

@@ -242,7 +242,7 @@ Ref<RenderSceneBuffers> RendererSceneRenderRD::render_buffers_create() {
rb->set_can_be_storage(_render_buffers_can_be_storage());
rb->set_max_cluster_elements(max_cluster_elements);
rb->set_base_data_format(_render_buffers_get_color_format());
rb->set_preferred_data_format(_render_buffers_get_preferred_color_format());
if (vrs) {
rb->set_vrs(vrs);
}
@@ -587,7 +587,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
}
float luminance_multiplier = _render_buffers_get_luminance_multiplier();
float luminance_multiplier = rb->get_luminance_multiplier();
for (uint32_t l = 0; l < rb->get_view_count(); l++) {
for (int i = 0; i < (max_glow_level + 1); i++) {
Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i);
@@ -693,7 +693,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
}
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
tonemap.luminance_multiplier = rb->get_luminance_multiplier();
tonemap.view_count = rb->get_view_count();
RID dest_fb;
@@ -702,7 +702,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
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.
dest_fb_format = _render_buffers_get_color_format();
dest_fb_format = rb->get_base_data_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);
if (use_smaa) {
@@ -758,7 +758,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
bool using_hdr = texture_storage->render_target_is_using_hdr(render_target);
RID dest_fb;
if (spatial_upscaler) {
rb->create_texture(SNAME("SMAA"), 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);
rb->create_texture(SNAME("SMAA"), SNAME("destination"), rb->get_base_data_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);
}
if (rb->get_view_count() > 1) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
@@ -802,7 +802,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RD::DataFormat format_for_debanding;
if (spatial_upscaler) {
RID dest_texture = rb->create_texture(SNAME("SMAA"), 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);
RID dest_texture = rb->create_texture(SNAME("SMAA"), SNAME("destination"), rb->get_base_data_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);
// Debanding is currently not supported when using spatial upscaling, so apply it before scaling.
// This produces suboptimal results because the image will be modified by spatial upscaling after
@@ -935,7 +935,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
tonemap.texture_size = Vector2i(target_size.x, target_size.y);
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
tonemap.luminance_multiplier = rb->get_luminance_multiplier();
tonemap.view_count = rb->get_view_count();
if (rb->get_use_debanding()) {
@@ -1115,11 +1115,7 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() {
return gi.default_voxel_gi_buffer;
}
float RendererSceneRenderRD::_render_buffers_get_luminance_multiplier() {
return 1.0;
}
RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() {
RD::DataFormat RendererSceneRenderRD::_render_buffers_get_preferred_color_format() {
return RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
}

View File

@@ -244,9 +244,7 @@ public:
virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; }
/* render buffers */
virtual float _render_buffers_get_luminance_multiplier();
virtual RD::DataFormat _render_buffers_get_color_format();
virtual RD::DataFormat _render_buffers_get_preferred_color_format();
virtual bool _render_buffers_can_be_storage();
virtual Ref<RenderSceneBuffers> render_buffers_create() override;
virtual void gi_set_use_half_resolution(bool p_enable) override;

View File

@@ -142,6 +142,8 @@ float sc_luminance_multiplier() {
return 1.0;
}
#define REFLECTION_MULTIPLIER 1.0
#define SDFGI_MAX_CASCADES 8
/* Set 0: Base Pass (never changes) */

View File

@@ -1563,7 +1563,7 @@ void main() {
indirect_specular_light = hvec3(textureLod(samplerCube(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec3(ref_vec), lod).rgb);
#endif //USE_RADIANCE_CUBEMAP_ARRAY
indirect_specular_light *= sc_luminance_multiplier();
indirect_specular_light *= REFLECTION_MULTIPLIER;
indirect_specular_light *= half(scene_data.IBL_exposure_normalization);
indirect_specular_light *= horizon * horizon;
indirect_specular_light *= half(scene_data.ambient_light_color_energy.a);
@@ -1585,7 +1585,7 @@ void main() {
#else
hvec3 cubemap_ambient = hvec3(textureLod(samplerCube(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), ambient_dir, MAX_ROUGHNESS_LOD).rgb);
#endif //USE_RADIANCE_CUBEMAP_ARRAY
cubemap_ambient *= sc_luminance_multiplier();
cubemap_ambient *= REFLECTION_MULTIPLIER;
cubemap_ambient *= half(scene_data.IBL_exposure_normalization);
ambient_light = mix(ambient_light, cubemap_ambient * half(scene_data.ambient_light_color_energy.a), half(scene_data.ambient_color_sky_mix));
}

View File

@@ -215,6 +215,10 @@ half sc_luminance_multiplier() {
return half(sc_packed_2());
}
// Like the luminance multiplier, but it is only for sky and reflection probes
// since they are always LDR.
#define REFLECTION_MULTIPLIER half(2.0)
/* Set 0: Base Pass (never changes) */
#include "../light_data_inc.glsl"

View File

@@ -957,7 +957,7 @@ void reflection_process(uint ref_index, vec3 vertex, hvec3 ref_vec, hvec3 normal
hvec4 reflection;
half reflection_blend = max(half(0.0), blend - reflection_accum.a);
reflection.rgb = hvec3(textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb) * sc_luminance_multiplier();
reflection.rgb = hvec3(textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb) * REFLECTION_MULTIPLIER;
reflection.rgb *= half(reflections.data[ref_index].exposure_normalization);
reflection.a = reflection_blend;

View File

@@ -1542,7 +1542,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
}
atlas->reflections.resize(atlas->count);
for (int i = 0; i < atlas->count; i++) {
atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format());
atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format());
for (int j = 0; j < 6; j++) {
atlas->reflections.write[i].fbs[j] = RendererSceneRenderRD::get_singleton()->reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
}
@@ -1814,7 +1814,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
}
RD::DataFormat LightStorage::get_reflection_probe_color_format() {
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format();
}
uint32_t LightStorage::get_reflection_probe_color_usage_bits() {

View File

@@ -152,6 +152,8 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
render_target = p_config->get_render_target();
force_hdr = texture_storage->render_target_is_using_hdr(render_target);
target_size = p_config->get_target_size();
internal_size = p_config->get_internal_size();
view_count = p_config->get_view_count();
@@ -177,7 +179,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
// Create our color buffer.
const bool resolve_target = msaa_3d != RS::VIEWPORT_MSAA_DISABLED;
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, base_data_format, get_color_usage_bits(resolve_target, false, can_be_storage));
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, get_base_data_format(), get_color_usage_bits(resolve_target, false, can_be_storage));
// TODO: Detect when it is safe to use RD::TEXTURE_USAGE_TRANSIENT_BIT for RB_TEX_DEPTH, RB_TEX_COLOR_MSAA and/or RB_TEX_DEPTH_MSAA.
// (it means we cannot sample from it, we cannot copy from/to it) to save VRAM (and maybe performance too).
@@ -190,7 +192,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co
texture_samples = RD::TEXTURE_SAMPLES_1;
} else {
texture_samples = msaa_to_samples(msaa_3d);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, base_data_format, get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, get_base_data_format(), get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, get_depth_format(false, true, can_be_storage), get_depth_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true);
}
@@ -267,7 +269,7 @@ void RenderSceneBuffersRD::ensure_mfx(RendererRD::MFXSpatialEffect *p_effect) {
RendererRD::MFXSpatialEffect::CreateParams params = {
.input_size = internal_size,
.output_size = target_size,
.input_format = base_data_format,
.input_format = get_base_data_format(),
.output_format = output_format,
};
@@ -525,12 +527,12 @@ void RenderSceneBuffersRD::allocate_blur_textures() {
usage_bits += RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1);
// if !can_be_storage we need a half width version
if (!can_be_storage) {
create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required);
}
// TODO redo this:
@@ -646,7 +648,7 @@ void RenderSceneBuffersRD::ensure_upscaled() {
if (!has_upscaled_texture()) {
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (can_be_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : 0) | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
usage_bits |= RD::TEXTURE_USAGE_INPUT_ATTACHMENT_BIT;
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, target_size);
create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, target_size);
}
}
@@ -775,3 +777,9 @@ RD::DataFormat RenderSceneBuffersRD::get_vrs_format() {
uint32_t RenderSceneBuffersRD::get_vrs_usage_bits() {
return RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
}
float RenderSceneBuffersRD::get_luminance_multiplier() const {
// On mobile renderer when not using HDR2D we need to scale HDR values by two
// to fit 0-2 range color values into a UNORM buffer.
return (force_hdr || can_be_storage) ? 1.0 : 2.0;
}

View File

@@ -65,8 +65,9 @@ class RenderSceneBuffersRD : public RenderSceneBuffers {
private:
bool can_be_storage = true;
bool force_hdr = false;
uint32_t max_cluster_elements = 512;
RD::DataFormat base_data_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
RD::DataFormat preferred_data_format = RD::DATA_FORMAT_MAX;
RendererRD::VRS *vrs = nullptr;
uint64_t auto_exposure_version = 1;
RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED;
@@ -186,8 +187,10 @@ public:
bool get_can_be_storage() const { return can_be_storage; }
void set_max_cluster_elements(const uint32_t p_max_elements) { max_cluster_elements = p_max_elements; }
uint32_t get_max_cluster_elements() { return max_cluster_elements; }
void set_base_data_format(const RD::DataFormat p_base_data_format) { base_data_format = p_base_data_format; }
RD::DataFormat get_base_data_format() const { return base_data_format; }
void set_preferred_data_format(const RD::DataFormat p_preferred_data_format) { preferred_data_format = p_preferred_data_format; }
RD::DataFormat get_preferred_data_format() const { return preferred_data_format; }
RD::DataFormat get_base_data_format() const { return force_hdr ? RD::DATA_FORMAT_R16G16B16A16_SFLOAT : preferred_data_format; }
float get_luminance_multiplier() const;
void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; }
RS::ViewportVRSMode get_vrs_mode() { return vrs_mode; }

View File

@@ -1504,8 +1504,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
Ref<Image> image;
// Expand RGB10_A2 into RGBAH. This is needed for capturing viewport data
// when using the mobile renderer with HDR mode on.
// Expand RGB10_A2 into RGBAH.
if (tex->rd_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) {
Vector<uint8_t> new_data;
new_data.resize(data.size() * 2);
@@ -4533,7 +4532,7 @@ RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const {
RD::DataFormat TextureStorage::render_target_get_color_format(bool p_use_hdr, bool p_srgb) {
if (p_use_hdr) {
return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
return RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
} else {
return p_srgb ? RD::DATA_FORMAT_R8G8B8A8_SRGB : RD::DATA_FORMAT_R8G8B8A8_UNORM;
}