summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/register_core_types.cpp4
-rw-r--r--core/register_core_types.h1
-rw-r--r--doc/classes/ProjectSettings.xml4
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp4
-rw-r--r--drivers/vulkan/vulkan_context.cpp158
-rw-r--r--drivers/vulkan/vulkan_context.h5
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp3
-rw-r--r--editor/script_create_dialog.cpp1
-rw-r--r--main/main.cpp7
-rw-r--r--platform/windows/display_server_windows.cpp11
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp3
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp44
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl26
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl21
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl24
-rw-r--r--servers/rendering_server.cpp6
18 files changed, 225 insertions, 101 deletions
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index a4b6a589f3..7ebffdb459 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -316,9 +316,11 @@ void register_core_extensions() {
native_extension_manager->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_CORE);
}
-void unregister_core_types() {
+void unregister_core_extensions() {
native_extension_manager->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_CORE);
+}
+void unregister_core_types() {
memdelete(native_extension_manager);
memdelete(resource_uid);
diff --git a/core/register_core_types.h b/core/register_core_types.h
index 0fd4e73c40..dfb2d8ac80 100644
--- a/core/register_core_types.h
+++ b/core/register_core_types.h
@@ -36,5 +36,6 @@ void register_core_settings();
void register_core_extensions();
void register_core_singletons();
void unregister_core_types();
+void unregister_core_extensions();
#endif // REGISTER_CORE_TYPES_H
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 805f897b63..0a695414ee 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1776,10 +1776,10 @@
<member name="rendering/reflections/sky_reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false">
Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed.
</member>
- <member name="rendering/reflections/sky_reflections/ggx_samples" type="int" setter="" getter="" default="1024">
+ <member name="rendering/reflections/sky_reflections/ggx_samples" type="int" setter="" getter="" default="32">
Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail.
</member>
- <member name="rendering/reflections/sky_reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128">
+ <member name="rendering/reflections/sky_reflections/ggx_samples.mobile" type="int" setter="" getter="" default="16">
Lower-end override for [member rendering/reflections/sky_reflections/ggx_samples] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/reflections/sky_reflections/roughness_layers" type="int" setter="" getter="" default="8">
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 247961b358..ddeac220ec 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -6652,6 +6652,10 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di
VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
+ if (!context->window_is_valid_swapchain(p_screen)) {
+ return INVALID_ID;
+ }
+
Size2i size = Size2i(context->window_get_width(p_screen), context->window_get_height(p_screen));
_draw_list_allocate(Rect2i(Vector2i(), size), 0, 0);
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 1aa1bfddc8..db3517ac97 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -514,45 +514,62 @@ Error VulkanContext::_check_capabilities() {
subgroup_capabilities.supportedStages = 0;
subgroup_capabilities.supportedOperations = 0;
subgroup_capabilities.quadOperationsInAllStages = false;
+ shader_capabilities.shader_float16_is_supported = false;
+ shader_capabilities.shader_int8_is_supported = false;
+ storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false;
+ storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = false;
+ storage_buffer_capabilities.storage_push_constant_16_is_supported = false;
+ storage_buffer_capabilities.storage_input_output_16 = false;
// check for extended features
- PFN_vkGetPhysicalDeviceFeatures2 device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
- if (device_features_func == nullptr) {
+ PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
+ if (vkGetPhysicalDeviceFeatures2_func == nullptr) {
// In Vulkan 1.0 might be accessible under its original extension name
- device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
+ vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
}
- if (device_features_func != nullptr) {
+ if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
// check our extended features
- VkPhysicalDeviceMultiviewFeatures multiview_features;
- multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
- multiview_features.pNext = nullptr;
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+ /*pNext*/ nullptr,
+ /*shaderFloat16*/ false,
+ /*shaderInt8*/ false,
+ };
+
+ VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
+ /*pNext*/ &shader_features,
+ /*storageBuffer16BitAccess*/ false,
+ /*uniformAndStorageBuffer16BitAccess*/ false,
+ /*storagePushConstant16*/ false,
+ /*storageInputOutput16*/ false,
+ };
+
+ VkPhysicalDeviceMultiviewFeatures multiview_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+ /*pNext*/ &storage_feature,
+ /*multiview*/ false,
+ /*multiviewGeometryShader*/ false,
+ /*multiviewTessellationShader*/ false,
+ };
VkPhysicalDeviceFeatures2 device_features;
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
device_features.pNext = &multiview_features;
- device_features_func(gpu, &device_features);
+ vkGetPhysicalDeviceFeatures2_func(gpu, &device_features);
+
multiview_capabilities.is_supported = multiview_features.multiview;
multiview_capabilities.geometry_shader_is_supported = multiview_features.multiviewGeometryShader;
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features;
- shader_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
- shader_features.pNext = nullptr;
-
- device_features.pNext = &shader_features;
-
- device_features_func(gpu, &device_features);
shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
+ shader_capabilities.shader_int8_is_supported = shader_features.shaderInt8;
- VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
- storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
- storage_feature.pNext = nullptr;
-
- device_features.pNext = &storage_feature;
-
- device_features_func(gpu, &device_features);
storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = storage_feature.storageBuffer16BitAccess;
+ storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = storage_feature.uniformAndStorageBuffer16BitAccess;
+ storage_buffer_capabilities.storage_push_constant_16_is_supported = storage_feature.storagePushConstant16;
+ storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
}
// check extended properties
@@ -1057,9 +1074,61 @@ Error VulkanContext::_create_device() {
queues[0].pQueuePriorities = queue_priorities;
queues[0].flags = 0;
+ // Before we retrieved what is supported, here we tell Vulkan we want to enable these features using the same structs.
+ void *nextptr = nullptr;
+
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+ /*pNext*/ nextptr,
+ /*shaderFloat16*/ shader_capabilities.shader_float16_is_supported,
+ /*shaderInt8*/ shader_capabilities.shader_int8_is_supported,
+ };
+ nextptr = &shader_features;
+
+ VkPhysicalDeviceVulkan11Features vulkan11features;
+ VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
+ VkPhysicalDeviceMultiviewFeatures multiview_features;
+ if (vulkan_major > 1 || vulkan_minor >= 2) {
+ // In Vulkan 1.2 and newer we use a newer struct to enable various features
+
+ vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+ vulkan11features.pNext = nextptr;
+ vulkan11features.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
+ vulkan11features.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
+ vulkan11features.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
+ vulkan11features.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
+ vulkan11features.multiview = multiview_capabilities.is_supported;
+ vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
+ vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
+ vulkan11features.variablePointersStorageBuffer = 0;
+ vulkan11features.variablePointers = 0;
+ vulkan11features.protectedMemory = 0;
+ vulkan11features.samplerYcbcrConversion = 0;
+ vulkan11features.shaderDrawParameters = 0;
+ nextptr = &vulkan11features;
+ } else {
+ // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features
+ storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
+ storage_feature.pNext = nextptr;
+ storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
+ storage_feature.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
+ storage_feature.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
+ storage_feature.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
+ nextptr = &storage_feature;
+
+ if (vulkan_major == 1 && vulkan_minor == 1) {
+ multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
+ multiview_features.pNext = nextptr;
+ multiview_features.multiview = multiview_capabilities.is_supported;
+ multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
+ multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
+ nextptr = &multiview_features;
+ }
+ }
+
VkDeviceCreateInfo sdevice = {
/*sType*/ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- /*pNext*/ nullptr,
+ /*pNext*/ nextptr,
/*flags*/ 0,
/*queueCreateInfoCount*/ 1,
/*pQueueCreateInfos*/ queues,
@@ -1068,7 +1137,6 @@ Error VulkanContext::_create_device() {
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
/*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here
-
};
if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -1080,36 +1148,6 @@ Error VulkanContext::_create_device() {
sdevice.queueCreateInfoCount = 2;
}
- VkPhysicalDeviceVulkan11Features vulkan11features;
- VkPhysicalDeviceMultiviewFeatures multiview_features;
- if (vulkan_major > 1 || vulkan_minor >= 2) {
- vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
- vulkan11features.pNext = nullptr;
- // !BAS! Need to figure out which ones of these we want enabled...
- vulkan11features.storageBuffer16BitAccess = 0;
- vulkan11features.uniformAndStorageBuffer16BitAccess = 0;
- vulkan11features.storagePushConstant16 = 0;
- vulkan11features.storageInputOutput16 = 0;
- vulkan11features.multiview = multiview_capabilities.is_supported;
- vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
- vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
- vulkan11features.variablePointersStorageBuffer = 0;
- vulkan11features.variablePointers = 0;
- vulkan11features.protectedMemory = 0;
- vulkan11features.samplerYcbcrConversion = 0;
- vulkan11features.shaderDrawParameters = 0;
-
- sdevice.pNext = &vulkan11features;
- } else if (vulkan_major == 1 && vulkan_minor == 1) {
- multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
- multiview_features.pNext = nullptr;
- multiview_features.multiview = multiview_capabilities.is_supported;
- multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
- multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
-
- sdevice.pNext = &multiview_features;
- }
-
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1348,6 +1386,12 @@ int VulkanContext::window_get_height(DisplayServer::WindowID p_window) {
return windows[p_window].height;
}
+bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window) {
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ Window *w = &windows[p_window];
+ return w->swapchain_image_resources != VK_NULL_HANDLE;
+}
+
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window];
@@ -1360,7 +1404,11 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window];
//vulkan use of currentbuffer
- return w->swapchain_image_resources[w->current_buffer].framebuffer;
+ if (w->swapchain_image_resources != VK_NULL_HANDLE) {
+ return w->swapchain_image_resources[w->current_buffer].framebuffer;
+ } else {
+ return VK_NULL_HANDLE;
+ }
}
void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 67a675f6c6..d4052666e3 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -69,10 +69,14 @@ public:
struct ShaderCapabilities {
bool shader_float16_is_supported;
+ bool shader_int8_is_supported;
};
struct StorageBufferCapabilities {
bool storage_buffer_16_bit_access_is_supported;
+ bool uniform_and_storage_buffer_16_bit_access_is_supported;
+ bool storage_push_constant_16_is_supported;
+ bool storage_input_output_16;
};
private:
@@ -266,6 +270,7 @@ public:
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);
int window_get_height(DisplayServer::WindowID p_window = 0);
+ bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0);
void window_destroy(DisplayServer::WindowID p_window_id);
VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0);
VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index a10eecbca1..cda5e6b537 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2908,7 +2908,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
command_palette->open_popup();
} break;
case HELP_DOCS: {
- OS::get_singleton()->shell_open("https://docs.godotengine.org/");
+ OS::get_singleton()->shell_open(VERSION_DOCS_URL "/");
} break;
case HELP_QA: {
OS::get_singleton()->shell_open("https://godotengine.org/qa/");
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 205464daee..bd4064708b 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -36,6 +36,7 @@
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
+#include "core/version.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_file_dialog.h"
@@ -1281,7 +1282,7 @@ void ScriptEditor::_menu_option(int p_option) {
help_search_dialog->popup_dialog();
} break;
case SEARCH_WEBSITE: {
- OS::get_singleton()->shell_open("https://docs.godotengine.org/");
+ OS::get_singleton()->shell_open(VERSION_DOCS_URL "/");
} break;
case WINDOW_NEXT: {
_history_forward();
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index c60c253a65..4a6c014942 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -1038,6 +1038,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
internal_name = memnew(LineEdit);
internal_name->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ internal_name->connect("text_submitted", callable_mp(this, &ScriptCreateDialog::_path_submitted));
label = memnew(Label(TTR("Name:")));
gc->add_child(label);
gc->add_child(internal_name);
diff --git a/main/main.cpp b/main/main.cpp
index 21199fe227..f8877d0717 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -487,6 +487,7 @@ void Main::test_cleanup() {
}
unregister_core_driver_types();
+ unregister_core_extensions();
unregister_core_types();
OS::get_singleton()->finalize_core();
@@ -554,6 +555,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
globals = memnew(ProjectSettings);
register_core_settings(); //here globals are present
+ register_core_extensions(); // core extensions must be registered after core settings and before display
translation_server = memnew(TranslationServer);
performance = memnew(Performance);
@@ -634,7 +636,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
continue;
}
#endif
-
List<String>::Element *N = I->next();
if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help
@@ -1271,8 +1272,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Logger::set_flush_stdout_on_print(ProjectSettings::get_singleton()->get("application/run/flush_stdout_on_print"));
OS::get_singleton()->set_cmdline(execpath, main_args);
-
- register_core_extensions(); //before display
// possibly be worth changing the default from vulkan to something lower spec,
// for the project manager, depending on how smooth the fallback is.
GLOBAL_DEF_RST("rendering/driver/driver_name", "vulkan");
@@ -1529,6 +1528,7 @@ error:
}
unregister_core_driver_types();
+ unregister_core_extensions();
unregister_core_types();
OS::get_singleton()->_cmdline.clear();
@@ -2888,6 +2888,7 @@ void Main::cleanup(bool p_force) {
memdelete(message_queue);
unregister_core_driver_types();
+ unregister_core_extensions();
unregister_core_types();
OS::get_singleton()->finalize_core();
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 2f0b3b4490..41295d41d2 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2778,13 +2778,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
window.width = window_client_rect.size.width;
window.height = window_client_rect.size.height;
-#if defined(VULKAN_ENABLED)
- if (context_vulkan && window_created) {
- context_vulkan->window_resize(window_id, window.width, window.height);
- }
-#endif
rect_changed = true;
}
+#if defined(VULKAN_ENABLED)
+ if (context_vulkan && window_created) {
+ // Note: Trigger resize event to update swapchains when window is minimized/restored, even if size is not changed.
+ context_vulkan->window_resize(window_id, window.width, window.height);
+ }
+#endif
}
if (!window.minimized && (!(window_pos_params->flags & SWP_NOMOVE) || window_pos_params->flags & SWP_FRAMECHANGED)) {
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 02a0b6f184..6c28cfd134 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -2040,7 +2040,7 @@ void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, u
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture, true), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 2f8ef696cd..606527ed24 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -39,6 +39,9 @@ void RendererCompositorRD::prepare_for_blitting_render_targets() {
void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
+ if (draw_list == RD::INVALID_ID) {
+ return; // Window is minimized and does not have valid swapchain, skip drawing without printing errors.
+ }
for (int i = 0; i < p_amount; i++) {
RID texture = storage->render_target_get_texture(p_render_targets[i].render_target);
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 354516ae87..b44ae6cf8d 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -473,12 +473,13 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS
}
RD::get_singleton()->draw_command_end_label(); // Filter radiance
} else {
+ RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
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);
}
-
+ RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
Vector<RID> views;
if (p_use_arrays) {
for (int i = 1; i < layers.size(); i++) {
@@ -489,8 +490,9 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS
views.push_back(layers[0].views[i]);
}
}
-
+ RD::get_singleton()->draw_command_begin_label("Fast filter radiance");
effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays);
+ RD::get_singleton()->draw_command_end_label(); // Filter radiance
}
}
@@ -500,12 +502,25 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
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_base_layer == 1) {
+ 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++) {
+ 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
+ }
+
+ RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
if (p_use_arrays) {
for (int k = 0; k < 6; k++) {
effects->cubemap_roughness_raster(
- radiance_base_cubemap,
+ downsampled_radiance_cubemap,
layers[p_base_layer].mipmaps[0].framebuffers[k],
k,
p_sky_ggx_samples_quality,
@@ -515,7 +530,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
} else {
for (int k = 0; k < 6; k++) {
effects->cubemap_roughness_raster(
- layers[0].views[p_base_layer - 1],
+ downsampled_radiance_cubemap,
layers[0].mipmaps[p_base_layer].framebuffers[k],
k,
p_sky_ggx_samples_quality,
@@ -524,12 +539,22 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
}
}
} else {
+ if (p_base_layer == 1) {
+ RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
+ 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);
+ }
+ RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
+ }
+
+ RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
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);
+ effects->cubemap_roughness(downsampled_radiance_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],
+ downsampled_radiance_cubemap,
layers[0].views[p_base_layer],
p_cube_side,
p_sky_ggx_samples_quality,
@@ -537,6 +562,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
layers[0].mipmaps[p_base_layer].size.x);
}
}
+ RD::get_singleton()->draw_command_end_label(); // Filter radiance
}
void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) {
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
index 28f4dc59ec..1d46f59408 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
@@ -21,24 +21,38 @@ void main() {
vec2 uv = ((vec2(id.xy) * 2.0 + 1.0) / (params.face_size) - 1.0);
vec3 N = texelCoordToVec(uv, id.z);
- //vec4 color = color_interp;
-
if (params.use_direct_write) {
imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0));
} else {
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
+ float solid_angle_texel = 4.0 * M_PI / (6.0 * params.face_size * params.face_size);
+ float roughness2 = params.roughness * params.roughness;
+ float roughness4 = roughness2 * roughness2;
+ vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ mat3 T;
+ T[0] = normalize(cross(UpVector, N));
+ T[1] = cross(N, T[0]);
+ T[2] = N;
+
for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
vec2 xi = Hammersley(sampleNum, params.sample_count);
- vec3 H = ImportanceSampleGGX(xi, params.roughness, N);
- vec3 V = N;
- vec3 L = (2.0 * dot(V, H) * H - V);
+ vec3 H = T * ImportanceSampleGGX(xi, roughness4);
+ float NdotH = dot(N, H);
+ vec3 L = (2.0 * NdotH * H - N);
float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl > 0.0) {
- sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
+ float D = DistributionGGX(NdotH, roughness4);
+ float pdf = D * NdotH / (4.0 * NdotH) + 0.0001;
+
+ float solid_angle_sample = 1.0 / (float(params.sample_count) * pdf + 0.0001);
+
+ float mipLevel = params.roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel);
+
+ sum.rgb += textureLod(source_cube, L, mipLevel).rgb * ndotl;
sum.a += ndotl;
}
}
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
index ce0a25e12f..1bee428a6f 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
@@ -47,12 +47,10 @@ vec3 texelCoordToVec(vec2 uv, uint faceID) {
return normalize(result);
}
-vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
- float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
-
+vec3 ImportanceSampleGGX(vec2 xi, float roughness4) {
// Compute distribution direction
- float Phi = 2.0 * M_PI * Xi.x;
- float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
+ float Phi = 2.0 * M_PI * xi.x;
+ float CosTheta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y));
float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
// Convert to spherical direction
@@ -61,12 +59,15 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
H.y = SinTheta * sin(Phi);
H.z = CosTheta;
- vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- vec3 TangentX = normalize(cross(UpVector, N));
- vec3 TangentY = cross(N, TangentX);
+ return H;
+}
+
+float DistributionGGX(float NdotH, float roughness4) {
+ float NdotH2 = NdotH * NdotH;
+ float denom = (NdotH2 * (roughness4 - 1.0) + 1.0);
+ denom = M_PI * denom * denom;
- // Tangent to world space
- return TangentX * H.x + TangentY * H.y + N * H.z;
+ return roughness4 / denom;
}
// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl
index 2570308816..c29accd8a7 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl
@@ -42,17 +42,33 @@ void main() {
} else {
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
+ float solid_angle_texel = 4.0 * M_PI / (6.0 * params.face_size * params.face_size);
+ float roughness2 = params.roughness * params.roughness;
+ float roughness4 = roughness2 * roughness2;
+ vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ mat3 T;
+ T[0] = normalize(cross(UpVector, N));
+ T[1] = cross(N, T[0]);
+ T[2] = N;
+
for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
vec2 xi = Hammersley(sampleNum, params.sample_count);
- vec3 H = ImportanceSampleGGX(xi, params.roughness, N);
- vec3 V = N;
- vec3 L = (2.0 * dot(V, H) * H - V);
+ vec3 H = T * ImportanceSampleGGX(xi, roughness4);
+ float NdotH = dot(N, H);
+ vec3 L = (2.0 * NdotH * H - N);
float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl > 0.0) {
- sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
+ float D = DistributionGGX(NdotH, roughness4);
+ float pdf = D * NdotH / (4.0 * NdotH) + 0.0001;
+
+ float solid_angle_sample = 1.0 / (float(params.sample_count) * pdf + 0.0001);
+
+ float mipLevel = params.roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel);
+
+ sum.rgb += textureLod(source_cube, L, mipLevel).rgb * ndotl;
sum.a += ndotl;
}
}
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index a7fcbcce42..820aeab5b7 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2860,11 +2860,11 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug", false);
GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug.release", true);
- GLOBAL_DEF("rendering/reflections/sky_reflections/roughness_layers", 8);
+ GLOBAL_DEF_RST("rendering/reflections/sky_reflections/roughness_layers", 8); // Assumes a 256x256 cubemap
GLOBAL_DEF_RST("rendering/reflections/sky_reflections/texture_array_reflections", true);
GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections.mobile", false);
- GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples", 1024);
- GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 128);
+ GLOBAL_DEF_RST("rendering/reflections/sky_reflections/ggx_samples", 32);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 16);
GLOBAL_DEF("rendering/reflections/sky_reflections/fast_filter_high_quality", false);
GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size", 256);
GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size.mobile", 128);