diff options
author | clayjohn <claynjohn@gmail.com> | 2022-07-31 16:20:24 -0700 |
---|---|---|
committer | clayjohn <claynjohn@gmail.com> | 2022-08-31 12:14:46 -0700 |
commit | 385ee5c70b110fc4e6a47c847428bfe3da89e18e (patch) | |
tree | 79a98b11b042372e99ed209f033dd721f5a74e14 /servers/rendering/renderer_rd/environment | |
parent | 736632ee7ed00a3474448cfd227f696f82905ac7 (diff) |
Implement Physical Light Units as an optional setting.
This allows light sources to be specified in physical light units in addition to the regular energy multiplier. In order to avoid loss of precision at high values, brightness values are premultiplied by an exposure normalization value.
In support of Physical Light Units this PR also renames CameraEffects to CameraAttributes.
Diffstat (limited to 'servers/rendering/renderer_rd/environment')
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.cpp | 101 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.h | 18 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/sky.cpp | 51 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/sky.h | 18 |
4 files changed, 149 insertions, 39 deletions
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 66e984174c..bc4f8d5855 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -287,6 +287,19 @@ float GI::voxel_gi_get_energy(RID p_voxel_gi) const { return voxel_gi->energy; } +void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); + + voxel_gi->baked_exposure = p_baked_exposure; +} + +float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->baked_exposure; +} + void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); @@ -1292,7 +1305,7 @@ void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) { push_constant.y_mult = y_mult; if (reads_sky && p_env.is_valid()) { - push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env); if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; @@ -1840,6 +1853,11 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r c.probe_world_offset[2] = probe_ofs.z; c.to_cell = 1.0 / cascades[i].cell_size; + c.exposure_normalization = 1.0; + if (p_render_data->camera_attributes.is_valid()) { + float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + c.exposure_normalization = exposure_normalization / cascades[i].baked_exposure_normalization; + } } RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE); @@ -1876,6 +1894,14 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r lights[idx].color[2] = color.b; lights[idx].type = RS::LIGHT_DIRECTIONAL; lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (p_scene_render->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + } + + if (p_render_data->camera_attributes.is_valid()) { + lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); idx++; @@ -1920,7 +1946,25 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; lights[idx].type = RSG::light_storage->light_get_type(li->light); + lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (p_scene_render->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + + // Convert from Luminous Power to Luminous Intensity + if (lights[idx].type == RS::LIGHT_OMNI) { + lights[idx].energy *= 1.0 / (Math_PI * 4.0); + } else if (lights[idx].type == RS::LIGHT_SPOT) { + // 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. + lights[idx].energy *= 1.0 / Math_PI; + } + } + + if (p_render_data->camera_attributes.is_valid()) { + lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); @@ -1938,7 +1982,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r } } -void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization) { //print_line("rendering region " + itos(p_region)); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -1960,7 +2004,7 @@ void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArr } //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size)); - p_scene_render->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing); + p_scene_render->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization); if (cascade_next != cascade) { RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); @@ -1989,6 +2033,7 @@ void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArr } cascades[cascade].all_dynamic_lights_dirty = true; + cascades[cascade].baked_exposure_normalization = p_exposure_normalization; push_constant.grid_size = cascade_size; push_constant.cascade = cascade; @@ -2297,7 +2342,7 @@ void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArr } } -void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -2358,7 +2403,25 @@ void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_co lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; + lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + if (p_scene_render->is_using_physical_light_units()) { + lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY); + + // Convert from Luminous Power to Luminous Intensity + if (lights[idx].type == RS::LIGHT_OMNI) { + lights[idx].energy *= 1.0 / (Math_PI * 4.0); + } else if (lights[idx].type == RS::LIGHT_SPOT) { + // 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. + lights[idx].energy *= 1.0 / Math_PI; + } + } + + if (p_render_data->camera_attributes.is_valid()) { + lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + } + lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light); lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); @@ -2794,6 +2857,22 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); + + if (p_scene_render->is_using_physical_light_units()) { + l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); + + l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe); + + // Convert from Luminous Power to Luminous Intensity + if (l.type == RS::LIGHT_OMNI) { + l.energy *= 1.0 / (Math_PI * 4.0); + } else if (l.type == RS::LIGHT_SPOT) { + // 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. + l.energy *= 1.0 / Math_PI; + } + } + l.radius = to_cell.basis.xform(Vector3(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length(); Color color = RSG::light_storage->light_get_color(light).srgb_to_linear(); l.color[0] = color.r; @@ -3003,7 +3082,12 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID } p_scene_render->cull_argument[0] = instance; - p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size)); + float exposure_normalization = 1.0; + if (p_scene_render->is_using_physical_light_units()) { + exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe); + } + + p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization); VoxelGIDynamicPushConstant push_constant; memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant)); @@ -3496,7 +3580,7 @@ GI::SDFGI *GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t return sdfgi; } -void GI::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { +void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); r_voxel_gi_instances_used = 0; @@ -3555,6 +3639,11 @@ void GI::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_tra gipd.normal_bias = voxel_gi_get_normal_bias(base_probe); gipd.blend_ambient = !voxel_gi_is_interior(base_probe); gipd.mipmaps = gipi->mipmaps.size(); + gipd.exposure_normalization = 1.0; + if (p_render_data->camera_attributes.is_valid()) { + float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); + gipd.exposure_normalization = exposure_normalization / voxel_gi_get_baked_exposure_normalization(base_probe); + } } r_voxel_gi_instances_used++; diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index 8860445c3b..9ef1914333 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -76,6 +76,7 @@ public: float dynamic_range = 2.0; float energy = 1.0; + float baked_exposure = 1.0; float bias = 1.4; float normal_bias = 0.0; float propagation = 0.5; @@ -398,6 +399,9 @@ public: virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) 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_bias) override; virtual float voxel_gi_get_bias(RID p_voxel_gi) const override; @@ -512,6 +516,7 @@ public: float to_cell; int32_t probe_offset[3]; uint32_t pad; + float pad2[4]; }; //cascade blocks are full-size for volume (128^3), half size for albedo/emission @@ -551,6 +556,8 @@ public: RID integrate_uniform_set; RID lights_buffer; + float baked_exposure_normalization = 1.0; + bool all_dynamic_lights_dirty = true; }; @@ -630,8 +637,8 @@ public: void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); - void render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); - void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); + void render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization); + void render_static_lights(RenderDataRD *p_render_data, RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; @@ -705,6 +712,8 @@ public: float to_probe; // 1/bounds * grid_size int32_t probe_world_offset[3]; float to_cell; // 1/bounds * grid_size + float pad[3]; + float exposure_normalization; }; ProbeCascadeData cascades[SDFGI::MAX_CASCADES]; @@ -720,6 +729,9 @@ public: float normal_bias; // 4 - 88 uint32_t blend_ambient; // 4 - 92 uint32_t mipmaps; // 4 - 96 + + float pad[3]; // 12 - 108 + float exposure_normalization; // 4 - 112 }; struct SceneData { @@ -777,7 +789,7 @@ public: SDFGI *create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); - void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); + void setup_voxel_gi_instances(RenderDataRD *p_render_data, RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); RID voxel_gi_instance_create(RID p_base); diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 1d6b158d65..d1d18cdd83 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -292,7 +292,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void SkyRD::_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 Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { +void SkyRD::_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 Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); @@ -307,7 +307,6 @@ void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineC sky_push_constant.position[0] = p_position.x; sky_push_constant.position[1] = p_position.y; 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); @@ -762,7 +761,7 @@ Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, con RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; // Could be RGBA16 tf.width = p_size.width; tf.height = p_size.height; tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; @@ -868,7 +867,7 @@ void SkyRD::init() { actions.renames["COLOR"] = "color"; actions.renames["ALPHA"] = "alpha"; actions.renames["EYEDIR"] = "cube_normal"; - actions.renames["POSITION"] = "params.position_multiplier.xyz"; + actions.renames["POSITION"] = "params.position"; actions.renames["SKY_COORDS"] = "panorama_coords"; actions.renames["SCREEN_UV"] = "uv"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; @@ -1110,7 +1109,7 @@ SkyRD::~SkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void SkyRD::setup(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, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1220,6 +1219,14 @@ void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_ligh 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 (p_scene_render->is_using_physical_light_units()) { + sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); + } + + if (p_camera_attributes.is_valid()) { + sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes); + } + Color linear_col = light_storage->light_get_color(base).srgb_to_linear(); sky_light_data.color[0] = linear_col.r; sky_light_data.color[1] = linear_col.g; @@ -1351,8 +1358,6 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D ERR_FAIL_COND(!shader_data); - float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); - bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY; RS::SkyMode sky_mode = sky->mode; @@ -1415,7 +1420,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D RID texture_uniform_set = sky->get_textures(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, p_luminance_multiplier); + _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, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1434,7 +1439,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D RID texture_uniform_set = sky->get_textures(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, p_luminance_multiplier); + _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, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1449,7 +1454,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D RID texture_uniform_set = sky->get_textures(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, p_luminance_multiplier); + _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, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } RD::get_singleton()->draw_command_end_label(); @@ -1475,7 +1480,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D } sky->processing_layer = 1; } - + sky->baked_exposure = p_luminance_multiplier; sky->reflection.dirty = false; } else { @@ -1491,7 +1496,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D } } -void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { +void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(p_env.is_null()); @@ -1536,7 +1541,6 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera @@ -1567,7 +1571,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth 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, 1.0); + _render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1580,7 +1584,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth 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, 1.0); + _render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1594,7 +1598,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth } 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, 1.0); + _render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1634,7 +1638,6 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera @@ -1665,7 +1668,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio 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, p_luminance_multiplier); + _render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1678,7 +1681,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio 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, p_luminance_multiplier); + _render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } } @@ -1728,7 +1731,6 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera @@ -1759,7 +1761,7 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie 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, p_luminance_multiplier); + _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier); } void SkyRD::invalidate_sky(Sky *p_sky) { @@ -1881,6 +1883,13 @@ RID SkyRD::sky_get_material(RID p_sky) const { return sky->material; } +float SkyRD::sky_get_baked_exposure(RID p_sky) const { + Sky *sky = get_sky(p_sky); + ERR_FAIL_COND_V(!sky, 1.0); + + return sky->baked_exposure; +} + RID SkyRD::allocate_sky_rid() { return sky_owner.allocate_rid(); } diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 080165c112..bac8f44ef7 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -100,10 +100,9 @@ private: float orientation[12]; // 48 - 48 float projections[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 80 float position[3]; // 12 - 92 - float multiplier; // 4 - 96 - float time; // 4 - 100 - float luminance_multiplier; // 4 - 104 - float pad[2]; // 8 - 112 // Using pad to align on 16 bytes + float time; // 4 - 96 + float pad[3]; // 12 - 108 + float luminance_multiplier; // 4 - 112 // 128 is the max size of a push constant. We can replace "pad" but we can't add any more. }; @@ -143,7 +142,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 Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier); + 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 Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); public: struct SkySceneState { @@ -264,6 +263,7 @@ public: bool dirty = false; int processing_layer = 0; Sky *dirty_list = nullptr; + float baked_exposure = 1.0; //State to track when radiance cubemap needs updating SkyMaterialData *prev_material = nullptr; @@ -296,9 +296,9 @@ public: void set_texture_format(RD::DataFormat p_texture_format); ~SkyRD(); - void setup(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, RendererSceneRenderRD *p_scene_render); + void setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); void update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer + void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); // only called by clustered renderer void update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); void draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); @@ -306,6 +306,8 @@ public: void update_dirty_skys(); RID sky_get_material(RID p_sky) const; + RID sky_get_radiance_texture_rd(RID p_sky) const; + float sky_get_baked_exposure(RID p_sky) const; RID allocate_sky_rid(); void initialize_sky_rid(RID p_rid); @@ -315,8 +317,6 @@ public: void sky_set_mode(RID p_sky, RS::SkyMode p_mode); void sky_set_material(RID p_sky, RID p_material); Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size); - - RID sky_get_radiance_texture_rd(RID p_sky) const; }; } // namespace RendererRD |