diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp | 83 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.h | 5 | ||||
-rw-r--r-- | servers/rendering_server.h | 2 |
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 }; |