diff options
Diffstat (limited to 'servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp')
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp | 171 |
1 files changed, 138 insertions, 33 deletions
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index bc1603a219..cadf759ec3 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -313,12 +313,16 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { coefficient_buffer = RID(); } -void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers) { +void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { //recreate radiance and all data int mipmaps = p_mipmaps; uint32_t w = p_size, h = p_size; + EffectsRD *effects = p_storage->get_effects(); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + bool prefer_raster_effects = effects->get_prefer_raster_effects(); + if (p_use_array) { int num_layers = p_low_quality ? 8 : p_roughness_layers; @@ -377,9 +381,9 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int } radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, RD::TEXTURE_SLICE_CUBEMAP); - + RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap"); RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.format = p_texture_format; tf.width = 64; // Always 64x64 tf.height = 64; tf.texture_type = RD::TEXTURE_TYPE_CUBE; @@ -388,6 +392,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap"); { uint32_t mmw = 64; uint32_t mmh = 64; @@ -397,6 +402,18 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int mm.size.width = mmw; mm.size.height = mmh; mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, RD::TEXTURE_SLICE_CUBEMAP); + RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip " + itos(j) + " "); + if (prefer_raster_effects) { + // we need a framebuffer for each side of our cubemap + + for (int k = 0; k < 6; k++) { + mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, k, j); + RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip: " + itos(j) + " Face: " + itos(k) + " "); + Vector<RID> fbtex; + fbtex.push_back(mm.views[k]); + mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex); + } + } mmw = MAX(1, mmw >> 1); mmh = MAX(1, mmh >> 1); @@ -405,50 +422,128 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int } void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays) { - p_storage->get_effects()->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); + EffectsRD *effects = p_storage->get_effects(); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + bool prefer_raster_effects = effects->get_prefer_raster_effects(); + + if (prefer_raster_effects) { + RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); + for (int k = 0; k < 6; k++) { + effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); + } - for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { - p_storage->get_effects()->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); - } + for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { + for (int k = 0; k < 6; k++) { + effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); + } + } + RD::get_singleton()->draw_command_end_label(); // Downsample Radiance - Vector<RID> views; - if (p_use_arrays) { - for (int i = 1; i < layers.size(); i++) { - views.push_back(layers[i].views[0]); + if (p_use_arrays) { + RD::get_singleton()->draw_command_begin_label("filter radiance map into array heads"); + for (int i = 0; i < layers.size(); i++) { + for (int k = 0; k < 6; k++) { + effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i); + } + } + } else { + RD::get_singleton()->draw_command_begin_label("filter radiance map into mipmaps directly"); + for (int j = 0; j < layers[0].mipmaps.size(); j++) { + for (int k = 0; k < 6; k++) { + effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j); + } + } } + RD::get_singleton()->draw_command_end_label(); // Filter radiance } else { - for (int i = 1; i < layers[0].views.size(); i++) { - views.push_back(layers[0].views[i]); + effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); + + for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { + effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); + } + + Vector<RID> views; + if (p_use_arrays) { + for (int i = 1; i < layers.size(); i++) { + views.push_back(layers[i].views[0]); + } + } else { + for (int i = 1; i < layers[0].views.size(); i++) { + views.push_back(layers[0].views[i]); + } } - } - p_storage->get_effects()->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays); + effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays); + } } void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { - if (p_use_arrays) { - //render directly to the layers - p_storage->get_effects()->cubemap_roughness(radiance_base_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); + EffectsRD *effects = p_storage->get_effects(); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + bool prefer_raster_effects = effects->get_prefer_raster_effects(); + + if (prefer_raster_effects) { + // Need to ask clayjohn but p_cube_side is set to 10, looks like in the compute shader we're doing all 6 sides in one call + // here we need to do them one by one so ignoring p_cube_side + if (p_use_arrays) { + for (int k = 0; k < 6; k++) { + effects->cubemap_roughness_raster( + radiance_base_cubemap, + layers[p_base_layer].mipmaps[0].framebuffers[k], + k, + p_sky_ggx_samples_quality, + float(p_base_layer) / (layers.size() - 1.0), + layers[p_base_layer].mipmaps[0].size.x); + } + } else { + for (int k = 0; k < 6; k++) { + effects->cubemap_roughness_raster( + layers[0].views[p_base_layer - 1], + layers[0].mipmaps[p_base_layer].framebuffers[k], + k, + p_sky_ggx_samples_quality, + float(p_base_layer) / (layers[0].mipmaps.size() - 1.0), + layers[0].mipmaps[p_base_layer].size.x); + } + } } else { - p_storage->get_effects()->cubemap_roughness( - layers[0].views[p_base_layer - 1], - layers[0].views[p_base_layer], - p_cube_side, - p_sky_ggx_samples_quality, - float(p_base_layer) / (layers[0].mipmaps.size() - 1.0), - layers[0].mipmaps[p_base_layer].size.x); + if (p_use_arrays) { + //render directly to the layers + effects->cubemap_roughness(radiance_base_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); + } else { + effects->cubemap_roughness( + layers[0].views[p_base_layer - 1], + layers[0].views[p_base_layer], + p_cube_side, + p_sky_ggx_samples_quality, + float(p_base_layer) / (layers[0].mipmaps.size() - 1.0), + layers[0].mipmaps[p_base_layer].size.x); + } } } void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) { + EffectsRD *effects = p_storage->get_effects(); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + bool prefer_raster_effects = effects->get_prefer_raster_effects(); + + RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps"); for (int i = p_start; i < p_end; i++) { for (int j = 0; j < layers[i].views.size() - 1; j++) { RID view = layers[i].views[j]; - RID texture = layers[i].views[j + 1]; Size2i size = layers[i].mipmaps[j + 1].size; - p_storage->get_effects()->cubemap_downsample(view, texture, size); + if (prefer_raster_effects) { + for (int k = 0; k < 6; k++) { + RID framebuffer = layers[i].mipmaps[j + 1].framebuffers[k]; + effects->cubemap_downsample_raster(view, framebuffer, k, size); + } + } else { + RID texture = layers[i].views[j + 1]; + effects->cubemap_downsample(view, texture, size); + } } } + RD::get_singleton()->draw_command_end_label(); } //////////////////////////////////////////////////////////////////////////////// @@ -902,6 +997,10 @@ void sky() { } } +void RendererSceneSkyRD::set_texture_format(RD::DataFormat p_texture_format) { + texture_format = p_texture_format; +} + RendererSceneSkyRD::~RendererSceneSkyRD() { // TODO cleanup anything created in init... @@ -1170,6 +1269,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM cm = correction * cm; if (shader_data->uses_quarter_res) { + RD::get_singleton()->draw_command_begin_label("Render Sky to Quarter Res Cubemap"); PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES]; Vector<Color> clear_colors; @@ -1185,9 +1285,11 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM _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.basis, multiplier, p_transform.origin); RD::get_singleton()->draw_list_end(); } + RD::get_singleton()->draw_command_end_label(); } if (shader_data->uses_half_res) { + RD::get_singleton()->draw_command_begin_label("Render Sky to Half Res Cubemap"); PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES]; Vector<Color> clear_colors; @@ -1203,11 +1305,13 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM _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.basis, multiplier, p_transform.origin); RD::get_singleton()->draw_list_end(); } + RD::get_singleton()->draw_command_end_label(); } RD::DrawListID cubemap_draw_list; PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP]; + RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap"); for (int i = 0; i < 6; i++) { Transform3D local_view; local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]); @@ -1217,6 +1321,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM _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.basis, multiplier, p_transform.origin); RD::get_singleton()->draw_list_end(); } + RD::get_singleton()->draw_command_end_label(); if (sky_mode == RS::SKY_MODE_REALTIME) { sky->reflection.create_reflection_fast_filter(storage, sky_use_cubemap_array); @@ -1393,7 +1498,7 @@ void RendererSceneSkyRD::update_dirty_skys() { //array (higher quality, 6 times more memory) RD::TextureFormat tf; tf.array_layers = layers * 6; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.format = texture_format; tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; tf.mipmaps = mipmaps; tf.width = w; @@ -1402,13 +1507,13 @@ void RendererSceneSkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers); + sky->reflection.update_reflection_data(storage, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); } else { //regular cubemap, lower quality (aliasing, less memory) RD::TextureFormat tf; tf.array_layers = 6; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.format = texture_format; tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.mipmaps = MIN(mipmaps, layers); tf.width = w; @@ -1417,7 +1522,7 @@ void RendererSceneSkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers); + sky->reflection.update_reflection_data(storage, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format); } texture_set_dirty = true; } @@ -1425,7 +1530,7 @@ void RendererSceneSkyRD::update_dirty_skys() { // Create subpass buffers if they haven't been created already if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) { RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tformat.format = texture_format; tformat.width = sky->screen_size.x / 2; tformat.height = sky->screen_size.y / 2; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; @@ -1440,7 +1545,7 @@ void RendererSceneSkyRD::update_dirty_skys() { if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) { RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tformat.format = texture_format; tformat.width = sky->screen_size.x / 4; tformat.height = sky->screen_size.y / 4; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; |