diff options
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/environment/gi.cpp | 7 | ||||
-rw-r--r-- | drivers/gles3/environment/gi.h | 3 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 154 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 36 | ||||
-rw-r--r-- | drivers/gles3/shaders/sky.glsl | 3 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.cpp | 9 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.h | 6 | ||||
-rw-r--r-- | drivers/gles3/storage/utilities.cpp | 5 |
8 files changed, 163 insertions, 60 deletions
diff --git a/drivers/gles3/environment/gi.cpp b/drivers/gles3/environment/gi.cpp index 84cdb81d35..5b16d3539f 100644 --- a/drivers/gles3/environment/gi.cpp +++ b/drivers/gles3/environment/gi.cpp @@ -98,6 +98,13 @@ float GI::voxel_gi_get_energy(RID p_voxel_gi) const { return 0.0; } +void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) { +} + +float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const { + return 1.0; +} + void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_range) { } diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h index 7a0634f22b..5b0aad380e 100644 --- a/drivers/gles3/environment/gi.h +++ b/drivers/gles3/environment/gi.h @@ -74,6 +74,9 @@ public: virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override; virtual float voxel_gi_get_energy(RID p_voxel_gi) const override; + virtual void voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) override; + virtual float voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const override; + virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override; virtual float voxel_gi_get_bias(RID p_voxel_gi) const override; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index cb479dda39..504a7e218d 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -483,6 +483,13 @@ void RasterizerSceneGLES3::sky_set_material(RID p_sky, RID p_material) { _invalidate_sky(sky); } +float RasterizerSceneGLES3::sky_get_baked_exposure(RID p_sky) const { + Sky *sky = sky_owner.get_or_null(p_sky); + ERR_FAIL_COND_V(!sky, 1.0); + + return sky->baked_exposure; +} + void RasterizerSceneGLES3::_invalidate_sky(Sky *p_sky) { if (!p_sky->dirty) { p_sky->dirty = true; @@ -561,13 +568,13 @@ void RasterizerSceneGLES3::_update_dirty_skys() { dirty_sky_list = nullptr; } -void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { +void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(p_env.is_null()); + ERR_FAIL_COND(p_render_data->environment.is_null()); GLES3::SkyMaterialData *material = nullptr; - Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment)); RID sky_material; @@ -639,6 +646,14 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag float sign = light_storage->light_is_negative(base) ? -1 : 1; sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); + if (is_using_physical_light_units()) { + sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + } + + if (p_render_data->camera_attributes.is_valid()) { + sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + Color linear_col = light_storage->light_get_color(base); sky_light_data.color[0] = linear_col.r; sky_light_data.color[1] = linear_col.g; @@ -708,7 +723,7 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag } } -void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -768,12 +783,13 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); glBindVertexArray(sky_globals.screen_triangle_array); glDrawArrays(GL_TRIANGLES, 0, 3); } -void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -866,6 +882,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.matrix[2][0], cm.matrix[0][0], cm.matrix[2][1], cm.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); glBindVertexArray(sky_globals.screen_triangle_array); @@ -887,7 +904,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p _filter_sky_radiance(sky, 0); //Just copy over the first mipmap } sky->processing_layer = 1; - + sky->baked_exposure = p_luminance_multiplier; sky->reflection_dirty = false; } else { if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) { @@ -1061,25 +1078,6 @@ Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bak return Ref<Image>(); } -RID RasterizerSceneGLES3::camera_effects_allocate() { - return RID(); -} - -void RasterizerSceneGLES3::camera_effects_initialize(RID p_rid) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { -} - -void RasterizerSceneGLES3::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { -} - -void RasterizerSceneGLES3::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { -} - void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) { } @@ -1403,8 +1401,9 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_render_data->environment); - scene_state.ubo.ambient_light_color_energy[3] = bg_energy; + float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); + + scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier; scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); @@ -1413,9 +1412,9 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; - scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy; - scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy; + scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; + scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { @@ -1459,6 +1458,25 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da } else { } + if (p_render_data->camera_attributes.is_valid()) { + scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + scene_state.ubo.IBL_exposure_normalization = 1.0; + if (is_environment(p_render_data->environment)) { + RID sky_rid = environment_get_sky(p_render_data->environment); + if (sky_rid.is_valid()) { + float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment); + scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky_get_baked_exposure(sky_rid)); + } + } + } else if (scene_state.ubo.emissive_exposure_normalization > 0.0) { + // This branch is triggered when using render_material(). + // Emissive is set outside the function, so don't set it. + // IBL isn't used don't set it. + } else { + scene_state.ubo.emissive_exposure_normalization = 1.0; + scene_state.ubo.IBL_exposure_normalization = 1.0; + } + if (scene_state.ubo_buffer == 0) { glGenBuffers(1, &scene_state.ubo_buffer); } @@ -1510,7 +1528,17 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b float sign = light_storage->light_is_negative(base) ? -1 : 1; - light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; + light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); + + if (is_using_physical_light_units()) { + light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + } else { + light_data.energy *= Math_PI; + } + + if (p_render_data->camera_attributes.is_valid()) { + light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } Color linear_col = light_storage->light_get_color(base).srgb_to_linear(); light_data.color[0] = linear_col.r; @@ -1590,7 +1618,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b for (uint32_t i = 0; i < (r_omni_light_count + r_spot_light_count); i++) { uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count); LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index]; - //RS::LightType type = (i < omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; + RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance; RID base = li->light; @@ -1634,7 +1662,26 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b } } - float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade; + float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * fade; + + if (is_using_physical_light_units()) { + energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + + // Convert from Luminous Power to Luminous Intensity + if (type == RS::LIGHT_OMNI) { + energy *= 1.0 / (Math_PI * 4.0); + } else { + // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle. + // We make this assumption to keep them easy to control. + energy *= 1.0 / Math_PI; + } + } else { + energy *= Math_PI; + } + + if (p_render_data->camera_attributes.is_valid()) { + energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } light_data.color[0] = linear_col.r * energy; light_data.color[1] = linear_col.g * energy; @@ -1671,7 +1718,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -1707,7 +1754,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * render_data.lights = &p_lights; render_data.reflection_probes = &p_reflection_probes; render_data.environment = p_environment; - render_data.camera_effects = p_camera_effects; + render_data.camera_attributes = p_camera_attributes; render_data.reflection_probe = p_reflection_probe; render_data.reflection_probe_pass = p_reflection_probe_pass; @@ -1768,6 +1815,8 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW); + scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization. + _setup_lights(&render_data, false, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count); _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, !render_data.reflection_probe.is_valid(), clear_color, false); @@ -1778,17 +1827,24 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * bool draw_sky = false; bool draw_sky_fog_only = false; bool keep_color = false; + float sky_energy_multiplier = 1.0; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black } else if (render_data.environment.is_valid()) { RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); - float bg_energy = environment_get_bg_energy(render_data.environment); + float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment); + bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment); + + if (render_data.camera_attributes.is_valid()) { + bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes); + } + switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); @@ -1796,9 +1852,9 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * } break; case RS::ENV_BG_COLOR: { clear_color = environment_get_bg_color(render_data.environment); - clear_color.r *= bg_energy; - clear_color.g *= bg_energy; - clear_color.b *= bg_energy; + clear_color.r *= bg_energy_multiplier; + clear_color.g *= bg_energy_multiplier; + clear_color.b *= bg_energy_multiplier; if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); @@ -1828,11 +1884,13 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * projection = correction * render_data.cam_projection; } - _setup_sky(render_data.environment, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); + sky_energy_multiplier *= bg_energy_multiplier; + + _setup_sky(&render_data, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); if (environment_get_sky(render_data.environment).is_valid()) { if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) { - _update_sky_radiance(render_data.environment, projection, render_data.cam_transform); + _update_sky_radiance(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier); } } else { // do not try to draw sky if invalid @@ -1936,7 +1994,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED; scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; - _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform); + _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier); } RENDER_TIMESTAMP("Render 3D Transparent Pass"); @@ -2406,6 +2464,9 @@ bool RasterizerSceneGLES3::free(RID p_rid) { LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!light_instance, false); light_instance_owner.free(p_rid); + } else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) { + //not much to delete, just free it + RSG::camera_attributes->camera_attributes_free(p_rid); } else { return false; } @@ -2431,6 +2492,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); + // Quality settings. + use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units"); + { // Setup Lights diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index a54d87a3a3..526da88ef6 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -111,7 +111,7 @@ struct RenderDataGLES3 { const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; RID environment = RID(); - RID camera_effects = RID(); + RID camera_attributes = RID(); RID reflection_probe = RID(); int reflection_probe_pass = 0; @@ -344,7 +344,7 @@ private: float ambient_color_sky_mix; uint32_t material_uv2_mode; - float pad2; + float emissive_exposure_normalization; uint32_t use_ambient_light = 0; uint32_t use_ambient_cubemap = 0; @@ -357,7 +357,7 @@ private: uint32_t directional_light_count; float z_far; float z_near; - float pad1; + float IBL_exposure_normalization; uint32_t fog_enabled; float fog_density; @@ -537,6 +537,16 @@ protected: void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer); + /* Camera Attributes */ + + struct CameraAttributes { + float exposure_multiplier = 1.0; + float exposure_normalization = 1.0; + }; + + bool use_physical_light_units = false; + mutable RID_Owner<CameraAttributes, true> camera_attributes_owner; + /* Environment */ RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; @@ -605,6 +615,7 @@ protected: bool dirty = false; int processing_layer = 0; Sky *dirty_list = nullptr; + float baked_exposure = 1.0; //State to track when radiance cubemap needs updating GLES3::SkyMaterialData *prev_material; @@ -615,12 +626,12 @@ protected: Sky *dirty_sky_list = nullptr; mutable RID_Owner<Sky, true> sky_owner; - void _setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); + void _setup_sky(const RenderDataGLES3 *p_render_data, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); void _invalidate_sky(Sky *p_sky); void _update_dirty_skys(); - void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform); + void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier); void _filter_sky_radiance(Sky *p_sky, int p_base_layer); - void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform); + void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier); void _free_sky_data(Sky *p_sky); public: @@ -665,6 +676,7 @@ public: void sky_set_mode(RID p_sky, RS::SkyMode p_mode) override; void sky_set_material(RID p_sky, RID p_material) override; Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override; + float sky_get_baked_exposure(RID p_sky) const; /* ENVIRONMENT API */ @@ -686,13 +698,9 @@ public: Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; - RID camera_effects_allocate() override; - void camera_effects_initialize(RID p_rid) override; - void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override; - void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override; - - void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override; - void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override; + _FORCE_INLINE_ bool is_using_physical_light_units() { + return use_physical_light_units; + } void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override; void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override; @@ -743,7 +751,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override; - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index eb1befe38e..21f01d2a8f 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -92,6 +92,7 @@ uniform mat4 orientation; uniform vec4 projection; uniform vec3 position; uniform float time; +uniform float luminance_multiplier; uniform float fog_aerial_perspective; uniform vec3 fog_light_color; @@ -149,6 +150,8 @@ void main() { } + color *= luminance_multiplier; + // Convert to Linear for tonemapping so color matches scene shader better color = srgb_to_linear(color); color *= exposure; diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index 683716ca99..6411590aee 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -422,13 +422,17 @@ float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const { /* LIGHTMAP CAPTURE */ RID LightStorage::lightmap_allocate() { - return RID(); + return lightmap_owner.allocate_rid(); } void LightStorage::lightmap_initialize(RID p_rid) { + lightmap_owner.initialize_rid(p_rid, Lightmap()); } void LightStorage::lightmap_free(RID p_rid) { + Lightmap *lightmap = lightmap_owner.get_or_null(p_rid); + lightmap->dependency.deleted_notify(p_rid); + lightmap_owner.free(p_rid); } void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { @@ -443,6 +447,9 @@ void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { } +void LightStorage::lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) { +} + PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const { return PackedVector3Array(); } diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index fa012a7b58..f054f0fdc6 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -92,6 +92,7 @@ struct ReflectionProbe { bool enable_shadows = false; uint32_t cull_mask = (1 << 20) - 1; float mesh_lod_threshold = 0.01; + float baked_exposure = 1.0; Dependency dependency; }; @@ -103,6 +104,7 @@ struct Lightmap { bool uses_spherical_harmonics = false; bool interior = false; AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); + float baked_exposure = 1.0; int32_t array_index = -1; //unassigned PackedVector3Array points; PackedColorArray point_sh; @@ -297,6 +299,9 @@ public: /* LIGHTMAP CAPTURE */ + Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); }; + bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }; + virtual RID lightmap_allocate() override; virtual void lightmap_initialize(RID p_rid) override; virtual void lightmap_free(RID p_rid) override; @@ -305,6 +310,7 @@ public: virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override; virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override; virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override; + virtual void lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) override; virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override; virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override; virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override; diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index 654104722b..16bacf1829 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -82,6 +82,8 @@ RS::InstanceType Utilities::get_base_type(RID p_rid) const { return RS::INSTANCE_MULTIMESH; } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) { return RS::INSTANCE_LIGHT; + } else if (GLES3::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + return RS::INSTANCE_LIGHTMAP; } return RS::INSTANCE_NONE; } @@ -114,6 +116,9 @@ bool Utilities::free(RID p_rid) { } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) { GLES3::LightStorage::get_singleton()->light_free(p_rid); return true; + } else if (GLES3::LightStorage::get_singleton()->owns_lightmap(p_rid)) { + GLES3::LightStorage::get_singleton()->lightmap_free(p_rid); + return true; } else { return false; } |