summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/environment
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd/environment')
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp101
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h18
-rw-r--r--servers/rendering/renderer_rd/environment/sky.cpp51
-rw-r--r--servers/rendering/renderer_rd/environment/sky.h18
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