Merge pull request #50883 from BastiaanOlij/mobile_hdr
Scale color output in the mobile renderer to provide HDR support
This commit is contained in:
commit
6e87d62873
|
@ -812,6 +812,7 @@ void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Tone
|
|||
tonemap.push_constant.exposure = p_settings.exposure;
|
||||
tonemap.push_constant.white = p_settings.white;
|
||||
tonemap.push_constant.auto_exposure_grey = p_settings.auto_exposure_grey;
|
||||
tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;
|
||||
|
||||
tonemap.push_constant.use_color_correction = p_settings.use_color_correction;
|
||||
|
||||
|
@ -864,6 +865,7 @@ void EffectsRD::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_colo
|
|||
tonemap.push_constant.use_color_correction = p_settings.use_color_correction;
|
||||
|
||||
tonemap.push_constant.use_debanding = p_settings.use_debanding;
|
||||
tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;
|
||||
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_subpass_draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_dst_format_id, false, RD::get_singleton()->draw_list_get_current_pass()));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_for_input(p_source_color), 0);
|
||||
|
|
|
@ -255,7 +255,7 @@ private:
|
|||
float exposure; // 4 - 84
|
||||
float white; // 4 - 88
|
||||
float auto_exposure_grey; // 4 - 92
|
||||
uint32_t pad2; // 4 - 96
|
||||
float luminance_multiplier; // 4 - 96
|
||||
|
||||
float pixel_size[2]; // 8 - 104
|
||||
uint32_t use_fxaa; // 4 - 108
|
||||
|
@ -308,7 +308,7 @@ private:
|
|||
float exposure_adjust;
|
||||
float min_luminance;
|
||||
float max_luminance;
|
||||
float pad[1];
|
||||
uint32_t pad1;
|
||||
};
|
||||
|
||||
struct LuminanceReduceFragment {
|
||||
|
@ -818,6 +818,7 @@ public:
|
|||
bool use_auto_exposure = false;
|
||||
float auto_exposure_grey = 0.5;
|
||||
RID exposure_texture;
|
||||
float luminance_multiplier = 1.0;
|
||||
|
||||
bool use_bcs = false;
|
||||
float brightness = 1.0;
|
||||
|
|
|
@ -271,6 +271,12 @@ bool RenderForwardMobile::free(RID p_rid) {
|
|||
|
||||
/* 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() {
|
||||
// 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;
|
||||
|
@ -631,7 +637,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
|
||||
RID sky_rid = env->sky;
|
||||
if (sky_rid.is_valid()) {
|
||||
sky.update(env, projection, p_render_data->cam_transform, time);
|
||||
sky.update(env, projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier());
|
||||
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
|
||||
} else {
|
||||
// do not try to draw sky if invalid
|
||||
|
@ -750,9 +756,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
CameraMatrix correction;
|
||||
correction.set_depth_correction(true);
|
||||
CameraMatrix projection = correction * p_render_data->cam_projection;
|
||||
sky.draw(draw_list, env, framebuffer, 1, &projection, p_render_data->cam_transform, time);
|
||||
sky.draw(draw_list, env, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier());
|
||||
} else {
|
||||
sky.draw(draw_list, env, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
|
||||
sky.draw(draw_list, env, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier());
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass
|
||||
|
|
|
@ -202,6 +202,7 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
virtual float _render_buffers_get_luminance_multiplier() override;
|
||||
virtual RD::DataFormat _render_buffers_get_color_format() override;
|
||||
virtual bool _render_buffers_can_be_storage() override;
|
||||
|
||||
|
|
|
@ -665,6 +665,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
|
|||
actions.global_buffer_array_variable = "global_variables.data";
|
||||
actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
|
||||
|
||||
actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture
|
||||
|
||||
compiler.initialize(actions);
|
||||
}
|
||||
|
||||
|
|
|
@ -2237,6 +2237,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
}
|
||||
}
|
||||
|
||||
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
|
||||
tonemap.view_count = p_render_data->view_count;
|
||||
|
||||
storage->get_effects()->tonemapper(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
|
||||
|
@ -2301,6 +2302,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
|
|||
tonemap.use_debanding = rb->use_debanding;
|
||||
tonemap.texture_size = Vector2i(rb->width, rb->height);
|
||||
|
||||
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
|
||||
tonemap.view_count = p_render_data->view_count;
|
||||
|
||||
storage->get_effects()->tonemapper(draw_list, p_source_texture, RD::get_singleton()->framebuffer_get_format(p_framebuffer), tonemap);
|
||||
|
@ -2573,6 +2575,10 @@ float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID
|
|||
return rb->volumetric_fog->spread;
|
||||
}
|
||||
|
||||
float RendererSceneRenderRD::_render_buffers_get_luminance_multiplier() {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() {
|
||||
return RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
}
|
||||
|
|
|
@ -1190,6 +1190,7 @@ public:
|
|||
|
||||
/* render buffers */
|
||||
|
||||
virtual float _render_buffers_get_luminance_multiplier();
|
||||
virtual RD::DataFormat _render_buffers_get_color_format();
|
||||
virtual bool _render_buffers_can_be_storage();
|
||||
virtual RID render_buffers_create() override;
|
||||
|
|
|
@ -259,7 +259,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
|
|||
p_array[11] = 0;
|
||||
}
|
||||
|
||||
void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
|
||||
void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) {
|
||||
SkyPushConstant sky_push_constant;
|
||||
|
||||
memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
|
||||
|
@ -276,6 +276,7 @@ void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_
|
|||
sky_push_constant.position[2] = p_position.z;
|
||||
sky_push_constant.multiplier = p_multiplier;
|
||||
sky_push_constant.time = p_time;
|
||||
sky_push_constant.luminance_multiplier = p_luminance_multiplier;
|
||||
store_transform_3x3(p_orientation, sky_push_constant.orientation);
|
||||
|
||||
RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb);
|
||||
|
@ -1195,7 +1196,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
|
|||
RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
|
||||
}
|
||||
|
||||
void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time) {
|
||||
void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
||||
ERR_FAIL_COND(!p_env);
|
||||
|
||||
Sky *sky = get_sky(p_env->sky);
|
||||
|
@ -1287,7 +1288,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
|
|||
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1306,7 +1307,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
|
|||
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1321,7 +1322,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
|
|||
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1439,7 +1440,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
|
|||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
|
@ -1452,7 +1453,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
|
|||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
|
@ -1466,11 +1467,11 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
|
|||
}
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) {
|
||||
void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
||||
ERR_FAIL_COND(!p_env);
|
||||
|
||||
ERR_FAIL_COND(p_view_count == 0);
|
||||
|
@ -1546,7 +1547,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
|
|||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
|
@ -1559,12 +1560,12 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
|
|||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) {
|
||||
void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
||||
ERR_FAIL_COND(!p_env);
|
||||
|
||||
ERR_FAIL_COND(p_view_count == 0);
|
||||
|
@ -1640,7 +1641,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
|
|||
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
|
||||
}
|
||||
|
||||
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
|
||||
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
}
|
||||
|
||||
void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) {
|
||||
|
|
|
@ -100,7 +100,8 @@ private:
|
|||
float position[3]; // 12 - 92
|
||||
float multiplier; // 4 - 96
|
||||
float time; // 4 - 100
|
||||
float pad[3]; // 12 - 112 // Using pad to align on 16 bytes
|
||||
float luminance_multiplier; // 4 - 104
|
||||
float pad[2]; // 8 - 112 // Using pad to align on 16 bytes
|
||||
// 128 is the max size of a push constant. We can replace "pad" but we can't add any more.
|
||||
};
|
||||
|
||||
|
@ -138,7 +139,7 @@ private:
|
|||
virtual ~SkyShaderData();
|
||||
};
|
||||
|
||||
void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
|
||||
void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier);
|
||||
|
||||
public:
|
||||
struct SkySceneState {
|
||||
|
@ -293,10 +294,10 @@ public:
|
|||
~RendererSceneSkyRD();
|
||||
|
||||
void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
|
||||
void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time);
|
||||
void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time);
|
||||
void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time);
|
||||
void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time);
|
||||
void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
||||
void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer
|
||||
void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
||||
void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
||||
|
||||
void invalidate_sky(Sky *p_sky);
|
||||
void update_dirty_skys();
|
||||
|
|
|
@ -1165,6 +1165,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||
SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
|
||||
|
||||
bool is_texture_func = false;
|
||||
bool is_screen_texture = false;
|
||||
if (onode->op == SL::OP_STRUCT) {
|
||||
code += _mkid(vnode->name);
|
||||
} else if (onode->op == SL::OP_CONSTRUCT) {
|
||||
|
@ -1197,6 +1198,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||
const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]);
|
||||
|
||||
StringName texture_uniform = varnode->name;
|
||||
is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
|
||||
|
||||
String sampler_name;
|
||||
|
||||
|
@ -1236,6 +1238,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||
}
|
||||
}
|
||||
code += ")";
|
||||
if (is_screen_texture && actions.apply_luminance_multiplier) {
|
||||
code = "(" + code + " * vec4(vec3(sc_luminance_multiplier), 1.0))";
|
||||
}
|
||||
} break;
|
||||
case SL::OP_INDEX: {
|
||||
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
String global_buffer_array_variable;
|
||||
String instance_uniform_index_variable;
|
||||
uint32_t base_varying_index = 0;
|
||||
bool apply_luminance_multiplier = false;
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -38,6 +38,8 @@ layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
|
|||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
// We do not apply our color scale for our mobile renderer here, we'll leave our colors at half brightness and apply scale in the tonemap raster.
|
||||
|
||||
#ifdef MODE_MIPMAP
|
||||
|
||||
vec2 pix_size = blur.pixel_size;
|
||||
|
|
|
@ -6,6 +6,6 @@ layout(push_constant, binding = 1, std430) uniform PushConstant {
|
|||
float exposure_adjust;
|
||||
float min_luminance;
|
||||
float max_luminance;
|
||||
float pad;
|
||||
uint pad1;
|
||||
}
|
||||
settings;
|
||||
|
|
|
@ -374,6 +374,9 @@ layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4;
|
|||
layout(constant_id = 10) const bool sc_decal_use_mipmaps = true;
|
||||
layout(constant_id = 11) const bool sc_projector_use_mipmaps = true;
|
||||
|
||||
// not used in clustered renderer but we share some code with the mobile renderer that requires this.
|
||||
const float sc_luminance_multiplier = 1.0;
|
||||
|
||||
#include "scene_forward_clustered_inc.glsl"
|
||||
|
||||
/* Varyings */
|
||||
|
|
|
@ -969,7 +969,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
|
|||
|
||||
vec4 reflection;
|
||||
|
||||
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb;
|
||||
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb * sc_luminance_multiplier;
|
||||
|
||||
if (reflections.data[ref_index].exterior) {
|
||||
reflection.rgb = mix(specular_light, reflection.rgb, blend);
|
||||
|
|
|
@ -401,6 +401,8 @@ layout(constant_id = 14) const bool sc_disable_fog = false;
|
|||
|
||||
#endif //!MODE_RENDER_DEPTH
|
||||
|
||||
layout(constant_id = 15) const float sc_luminance_multiplier = 2.0;
|
||||
|
||||
/* Include our forward mobile UBOs definitions etc. */
|
||||
#include "scene_forward_mobile_inc.glsl"
|
||||
|
||||
|
@ -1551,12 +1553,15 @@ void main() {
|
|||
frag_color = vec4(albedo, alpha);
|
||||
#else // MODE_UNSHADED
|
||||
frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
|
||||
//frag_color = vec4(1.0);
|
||||
#endif // MODE_UNSHADED
|
||||
|
||||
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
|
||||
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
|
||||
|
||||
// On mobile we use a UNORM buffer with 10bpp which results in a range from 0.0 - 1.0 resulting in HDR breaking
|
||||
// We divide by sc_luminance_multiplier to support a range from 0.0 - 2.0 both increasing precision on bright and darker images
|
||||
frag_color.rgb = frag_color.rgb / sc_luminance_multiplier;
|
||||
|
||||
#endif //MODE_MULTIPLE_RENDER_TARGETS
|
||||
|
||||
#endif //MODE_RENDER_DEPTH
|
||||
|
|
|
@ -17,6 +17,8 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
|||
vec4 projections[MAX_VIEWS];
|
||||
vec4 position_multiplier;
|
||||
float time;
|
||||
float luminance_multiplier;
|
||||
float pad[2];
|
||||
}
|
||||
params;
|
||||
|
||||
|
@ -55,6 +57,8 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
|||
vec4 projections[MAX_VIEWS];
|
||||
vec4 position_multiplier;
|
||||
float time;
|
||||
float luminance_multiplier;
|
||||
float pad[2];
|
||||
}
|
||||
params;
|
||||
|
||||
|
@ -199,17 +203,17 @@ void main() {
|
|||
vec3 inverted_cube_normal = cube_normal;
|
||||
inverted_cube_normal.z *= -1.0;
|
||||
#ifdef USES_HALF_RES_COLOR
|
||||
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal);
|
||||
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;
|
||||
#endif
|
||||
#ifdef USES_QUARTER_RES_COLOR
|
||||
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal);
|
||||
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;
|
||||
#endif
|
||||
#else
|
||||
#ifdef USES_HALF_RES_COLOR
|
||||
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;
|
||||
#endif
|
||||
#ifdef USES_QUARTER_RES_COLOR
|
||||
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -246,4 +250,7 @@ void main() {
|
|||
if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
||||
// For mobile renderer we're dividing by 2.0 as we're using a UNORM buffer
|
||||
frag_color.rgb = frag_color.rgb / params.luminance_multiplier;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
|||
float exposure;
|
||||
float white;
|
||||
float auto_exposure_grey;
|
||||
uint pad2;
|
||||
float luminance_multiplier;
|
||||
|
||||
vec2 pixel_size;
|
||||
bool use_fxaa;
|
||||
|
@ -298,15 +298,15 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
|
|||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
#endif
|
||||
vec3 rgbM = color;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
|
@ -333,11 +333,11 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
|
|||
params.pixel_size;
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz);
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz) * params.luminance_multiplier;
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz) * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz);
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * params.luminance_multiplier;
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz) * params.luminance_multiplier;
|
||||
#endif
|
||||
|
||||
float lumaB = dot(rgbB, luma);
|
||||
|
@ -364,11 +364,11 @@ vec3 screen_space_dither(vec2 frag_coord) {
|
|||
void main() {
|
||||
#ifdef SUBPASS
|
||||
// SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer
|
||||
vec3 color = subpassLoad(input_color).rgb;
|
||||
vec3 color = subpassLoad(input_color).rgb * params.luminance_multiplier;
|
||||
#elif defined(MULTIVIEW)
|
||||
vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb;
|
||||
vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;
|
||||
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb * params.luminance_multiplier;
|
||||
#endif
|
||||
|
||||
// Exposure
|
||||
|
@ -377,7 +377,7 @@ void main() {
|
|||
|
||||
#ifndef SUBPASS
|
||||
if (params.use_auto_exposure) {
|
||||
exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey);
|
||||
exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r * params.luminance_multiplier / params.auto_exposure_grey);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -386,7 +386,7 @@ void main() {
|
|||
// Early Tonemap & SRGB Conversion
|
||||
#ifndef SUBPASS
|
||||
if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) {
|
||||
vec3 glow = gather_glow(source_glow, uv_interp);
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.luminance_multiplier;
|
||||
color.rgb = mix(color.rgb, glow, params.glow_intensity);
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ void main() {
|
|||
// Glow
|
||||
|
||||
if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) {
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity;
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity * params.luminance_multiplier;
|
||||
|
||||
// high dynamic range -> SRGB
|
||||
glow = apply_tonemapping(glow, params.white);
|
||||
|
|
Loading…
Reference in New Issue