summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp83
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h5
-rw-r--r--servers/rendering_server.h2
3 files changed, 65 insertions, 25 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index dd68011111..4ebed78996 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -181,16 +181,14 @@ void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd,
}
}
-void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) {
- if (sky_use_cubemap_array) {
- for (int i = 0; i < rd.layers.size(); i++) {
- for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
- for (int k = 0; k < 6; k++) {
- RID view = rd.layers[i].mipmaps[j].views[k];
- RID texture = rd.layers[i].mipmaps[j + 1].views[k];
- Size2i size = rd.layers[i].mipmaps[j + 1].size;
- storage->get_effects()->make_mipmap(view, texture, size);
- }
+void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) {
+ for (int i = p_start; i < p_end; i++) {
+ for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
+ for (int k = 0; k < 6; k++) {
+ RID view = rd.layers[i].mipmaps[j].views[k];
+ RID texture = rd.layers[i].mipmaps[j + 1].views[k];
+ Size2i size = rd.layers[i].mipmaps[j + 1].size;
+ storage->get_effects()->make_mipmap(view, texture, size);
}
}
}
@@ -1924,6 +1922,7 @@ void RasterizerSceneRD::_update_dirty_skys() {
}
sky->reflection.dirty = true;
+ sky->processing_layer = 0;
Sky *next = sky->dirty_list;
sky->dirty_list = nullptr;
@@ -2276,8 +2275,32 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
float multiplier = environment_get_bg_energy(p_environment);
+ bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;
+ RS::SkyMode sky_mode = sky->mode;
+
+ if (sky_mode == RS::SKY_MODE_AUTOMATIC) {
+ if (shader_data->uses_time || shader_data->uses_position) {
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_REALTIME;
+ } else if (shader_data->uses_light || shader_data->ubo_size > 0) {
+ update_single_frame = false;
+ sky_mode = RS::SKY_MODE_INCREMENTAL;
+ } else {
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_QUALITY;
+ }
+ }
+
+ if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {
+ // On the first frame after creating sky, rebuild in single frame
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_QUALITY;
+ }
+
+ int max_processing_layer = sky_use_cubemap_array ? sky->reflection.layers.size() : sky->reflection.layers[0].mipmaps.size();
+
// Update radiance cubemap
- if (sky->reflection.dirty) {
+ if (sky->reflection.dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
static const Vector3 view_normals[6] = {
Vector3(+1, 0, 0),
Vector3(-1, 0, 0),
@@ -2349,27 +2372,41 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
storage->get_effects()->render_sky(cubemap_draw_list, time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], sky_scene_state.sampler_uniform_set, sky_scene_state.light_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
- if (sky_use_cubemap_array) {
- if (sky->mode == RS::SKY_MODE_QUALITY) {
- for (int i = 1; i < sky->reflection.layers.size(); i++) {
- _create_reflection_importance_sample(sky->reflection, sky_use_cubemap_array, 10, i);
- }
- } else {
- _create_reflection_fast_filter(sky->reflection, sky_use_cubemap_array);
- }
- _update_reflection_mipmaps(sky->reflection);
+ if (sky_mode == RS::SKY_MODE_REALTIME) {
+ _create_reflection_fast_filter(sky->reflection, sky_use_cubemap_array);
+ if (sky_use_cubemap_array) {
+ _update_reflection_mipmaps(sky->reflection, 0, sky->reflection.layers.size());
+ }
} else {
- if (sky->mode == RS::SKY_MODE_QUALITY) {
- for (int i = 1; i < sky->reflection.layers[0].mipmaps.size(); i++) {
+ if (update_single_frame) {
+ for (int i = 1; i < max_processing_layer; i++) {
_create_reflection_importance_sample(sky->reflection, sky_use_cubemap_array, 10, i);
}
+ if (sky_use_cubemap_array) {
+ _update_reflection_mipmaps(sky->reflection, 0, sky->reflection.layers.size());
+ }
} else {
- _create_reflection_fast_filter(sky->reflection, sky_use_cubemap_array);
+ if (sky_use_cubemap_array) {
+ // Multi-Frame so just update the first array level
+ _update_reflection_mipmaps(sky->reflection, 0, 1);
+ }
}
+ sky->processing_layer = 1;
}
sky->reflection.dirty = false;
+
+ } else {
+ if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
+ _create_reflection_importance_sample(sky->reflection, sky_use_cubemap_array, 10, sky->processing_layer);
+
+ if (sky_use_cubemap_array) {
+ _update_reflection_mipmaps(sky->reflection, sky->processing_layer, sky->processing_layer + 1);
+ }
+
+ sky->processing_layer++;
+ }
}
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index 83c03399ab..f09f9dde65 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -145,7 +145,7 @@ private:
void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality);
void _create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays);
void _create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer);
- void _update_reflection_mipmaps(ReflectionData &rd);
+ void _update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end);
/* Sky shader */
@@ -261,10 +261,11 @@ private:
int radiance_size = 256;
- RS::SkyMode mode = RS::SKY_MODE_QUALITY;
+ RS::SkyMode mode = RS::SKY_MODE_AUTOMATIC;
ReflectionData reflection;
bool dirty = false;
+ int processing_layer = 0;
Sky *dirty_list = nullptr;
//State to track when radiance cubemap needs updating
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 2e5ceec02f..109e9e53c5 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -720,7 +720,9 @@ public:
/* SKY API */
enum SkyMode {
+ SKY_MODE_AUTOMATIC,
SKY_MODE_QUALITY,
+ SKY_MODE_INCREMENTAL,
SKY_MODE_REALTIME
};