diff options
Diffstat (limited to 'servers')
88 files changed, 2251 insertions, 1322 deletions
diff --git a/servers/SCsub b/servers/SCsub index 2ce90e970b..788a368a4f 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -15,6 +15,7 @@ SConscript("text/SCsub") SConscript("debugger/SCsub") SConscript("extensions/SCsub") SConscript("movie_writer/SCsub") +SConscript("navigation/SCsub") lib = env.add_library("servers", env.servers_sources) diff --git a/servers/display_server.cpp b/servers/display_server.cpp index dda8e29b6a..4b97bede56 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -678,6 +678,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_set_flag", "flag", "enabled", "window_id"), &DisplayServer::window_set_flag, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_flag", "flag", "window_id"), &DisplayServer::window_get_flag, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_set_window_buttons_offset", "offset", "window_id"), &DisplayServer::window_set_window_buttons_offset, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_safe_title_margins", "window_id"), &DisplayServer::window_get_safe_title_margins, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_request_attention", "window_id"), &DisplayServer::window_request_attention, DEFVAL(MAIN_WINDOW_ID)); @@ -823,6 +824,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_EVENT_CLOSE_REQUEST); BIND_ENUM_CONSTANT(WINDOW_EVENT_GO_BACK_REQUEST); BIND_ENUM_CONSTANT(WINDOW_EVENT_DPI_CHANGE); + BIND_ENUM_CONSTANT(WINDOW_EVENT_TITLEBAR_CHANGE); BIND_ENUM_CONSTANT(VSYNC_DISABLED); BIND_ENUM_CONSTANT(VSYNC_ENABLED); diff --git a/servers/display_server.h b/servers/display_server.h index ab4f9fc499..8eafccc040 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -336,6 +336,7 @@ public: WINDOW_EVENT_CLOSE_REQUEST, WINDOW_EVENT_GO_BACK_REQUEST, WINDOW_EVENT_DPI_CHANGE, + WINDOW_EVENT_TITLEBAR_CHANGE, }; virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0; @@ -380,7 +381,8 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0; - virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector2i(); }; + virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) {} + virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector2i(); } virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const = 0; diff --git a/servers/extensions/physics_server_2d_extension.cpp b/servers/extensions/physics_server_2d_extension.cpp index 36f3be2468..e5920c78d4 100644 --- a/servers/extensions/physics_server_2d_extension.cpp +++ b/servers/extensions/physics_server_2d_extension.cpp @@ -189,7 +189,10 @@ void PhysicsServer2DExtension::_bind_methods() { GDVIRTUAL_BIND(_area_get_transform, "area"); GDVIRTUAL_BIND(_area_set_collision_layer, "area", "layer"); + GDVIRTUAL_BIND(_area_get_collision_layer, "area"); + GDVIRTUAL_BIND(_area_set_collision_mask, "area", "mask"); + GDVIRTUAL_BIND(_area_get_collision_mask, "area"); GDVIRTUAL_BIND(_area_set_monitorable, "area", "monitorable"); GDVIRTUAL_BIND(_area_set_pickable, "area", "pickable"); @@ -280,7 +283,7 @@ void PhysicsServer2DExtension::_bind_methods() { GDVIRTUAL_BIND(_body_set_omit_force_integration, "body", "enable"); GDVIRTUAL_BIND(_body_is_omitting_force_integration, "body"); - GDVIRTUAL_BIND(_body_set_state_sync_callback, "body", "callback"); + GDVIRTUAL_BIND(_body_set_state_sync_callback, "body", "callable"); GDVIRTUAL_BIND(_body_set_force_integration_callback, "body", "callable", "userdata"); GDVIRTUAL_BIND(_body_collide_shape, "body", "body_shape", "shape", "shape_xform", "motion", "results", "result_max", "result_count"); diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h index 3bd3d642c8..573b51ee12 100644 --- a/servers/extensions/physics_server_2d_extension.h +++ b/servers/extensions/physics_server_2d_extension.h @@ -94,7 +94,6 @@ public: EXBIND1RC(Vector2, get_contact_local_position, int) EXBIND1RC(Vector2, get_contact_local_normal, int) EXBIND1RC(int, get_contact_local_shape, int) - EXBIND1RC(RID, get_contact_collider, int) EXBIND1RC(Vector2, get_contact_collider_position, int) EXBIND1RC(ObjectID, get_contact_collider_id, int) @@ -183,13 +182,7 @@ public: typedef PhysicsServer2D::MotionResult PhysicsServer2DExtensionMotionResult; -struct PhysicsServer2DExtensionStateCallback { - void *instance = nullptr; - void (*callback)(void *p_instance, PhysicsDirectBodyState2D *p_state); -}; - GDVIRTUAL_NATIVE_PTR(PhysicsServer2DExtensionMotionResult) -GDVIRTUAL_NATIVE_PTR(PhysicsServer2DExtensionStateCallback) class PhysicsServer2DExtension : public PhysicsServer2D { GDCLASS(PhysicsServer2DExtension, PhysicsServer2D); @@ -275,8 +268,11 @@ public: EXBIND2RC(Variant, area_get_param, RID, AreaParameter) EXBIND1RC(Transform2D, area_get_transform, RID) - EXBIND2(area_set_collision_mask, RID, uint32_t) EXBIND2(area_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_layer, RID) + + EXBIND2(area_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_mask, RID) EXBIND2(area_set_monitorable, RID, bool) EXBIND2(area_set_pickable, RID, bool) @@ -376,13 +372,7 @@ public: EXBIND2(body_set_omit_force_integration, RID, bool) EXBIND1RC(bool, body_is_omitting_force_integration, RID) - GDVIRTUAL2(_body_set_state_sync_callback, RID, GDNativePtr<PhysicsServer2DExtensionStateCallback>) - void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) override { - PhysicsServer2DExtensionStateCallback callback; - callback.callback = p_callback; - callback.instance = p_instance; - GDVIRTUAL_REQUIRED_CALL(_body_set_state_sync_callback, p_body, &callback); - } + EXBIND2(body_set_state_sync_callback, RID, const Callable &) EXBIND3(body_set_force_integration_callback, RID, const Callable &, const Variant &) virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override { diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp index 800284dc60..27f9ed2cb3 100644 --- a/servers/extensions/physics_server_3d_extension.cpp +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -192,7 +192,10 @@ void PhysicsServer3DExtension::_bind_methods() { GDVIRTUAL_BIND(_area_get_transform, "area"); GDVIRTUAL_BIND(_area_set_collision_layer, "area", "layer"); + GDVIRTUAL_BIND(_area_get_collision_layer, "area"); + GDVIRTUAL_BIND(_area_set_collision_mask, "area", "mask"); + GDVIRTUAL_BIND(_area_get_collision_mask, "area"); GDVIRTUAL_BIND(_area_set_monitorable, "area", "monitorable"); GDVIRTUAL_BIND(_area_set_ray_pickable, "area", "enable"); @@ -284,7 +287,7 @@ void PhysicsServer3DExtension::_bind_methods() { GDVIRTUAL_BIND(_body_set_omit_force_integration, "body", "enable"); GDVIRTUAL_BIND(_body_is_omitting_force_integration, "body"); - GDVIRTUAL_BIND(_body_set_state_sync_callback, "body", "callback"); + GDVIRTUAL_BIND(_body_set_state_sync_callback, "body", "callable"); GDVIRTUAL_BIND(_body_set_force_integration_callback, "body", "callable", "userdata"); GDVIRTUAL_BIND(_body_set_ray_pickable, "body", "enable"); diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index b6ed346a3d..57f2a2d790 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -192,14 +192,8 @@ public: typedef PhysicsServer3D::MotionCollision PhysicsServer3DExtensionMotionCollision; typedef PhysicsServer3D::MotionResult PhysicsServer3DExtensionMotionResult; -struct PhysicsServer3DExtensionStateCallback { - void *instance = nullptr; - void (*callback)(void *p_instance, PhysicsDirectBodyState3D *p_state); -}; - GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionMotionCollision) GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionMotionResult) -GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionStateCallback) class PhysicsServer3DExtension : public PhysicsServer3D { GDCLASS(PhysicsServer3DExtension, PhysicsServer3D); @@ -277,8 +271,11 @@ public: EXBIND2RC(Variant, area_get_param, RID, AreaParameter) EXBIND1RC(Transform3D, area_get_transform, RID) - EXBIND2(area_set_collision_mask, RID, uint32_t) EXBIND2(area_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_layer, RID) + + EXBIND2(area_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_mask, RID) EXBIND2(area_set_monitorable, RID, bool) EXBIND2(area_set_ray_pickable, RID, bool) @@ -380,13 +377,7 @@ public: EXBIND2(body_set_omit_force_integration, RID, bool) EXBIND1RC(bool, body_is_omitting_force_integration, RID) - GDVIRTUAL2(_body_set_state_sync_callback, RID, GDNativePtr<PhysicsServer3DExtensionStateCallback>) - void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) override { - PhysicsServer3DExtensionStateCallback callback; - callback.callback = p_callback; - callback.instance = p_instance; - GDVIRTUAL_REQUIRED_CALL(_body_set_state_sync_callback, p_body, &callback); - } + EXBIND2(body_set_state_sync_callback, RID, const Callable &) EXBIND3(body_set_force_integration_callback, RID, const Callable &, const Variant &) EXBIND2(body_set_ray_pickable, RID, bool) diff --git a/servers/navigation/SCsub b/servers/navigation/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/navigation/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/navigation/navigation_path_query_parameters_2d.cpp b/servers/navigation/navigation_path_query_parameters_2d.cpp new file mode 100644 index 0000000000..574af90be1 --- /dev/null +++ b/servers/navigation/navigation_path_query_parameters_2d.cpp @@ -0,0 +1,144 @@ +/*************************************************************************/ +/* navigation_path_query_parameters_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_path_query_parameters_2d.h" + +void NavigationPathQueryParameters2D::set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm) { + switch (p_pathfinding_algorithm) { + case PATHFINDING_ALGORITHM_ASTAR: { + parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR; + } break; + default: { + WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default"); + parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR; + } break; + } +} + +NavigationPathQueryParameters2D::PathfindingAlgorithm NavigationPathQueryParameters2D::get_pathfinding_algorithm() const { + switch (parameters.pathfinding_algorithm) { + case NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR: + return PATHFINDING_ALGORITHM_ASTAR; + default: + WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default"); + return PATHFINDING_ALGORITHM_ASTAR; + } +} + +void NavigationPathQueryParameters2D::set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing) { + switch (p_path_postprocessing) { + case PATH_POSTPROCESSING_CORRIDORFUNNEL: { + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL; + } break; + case PATH_POSTPROCESSING_EDGECENTERED: { + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED; + } break; + default: { + WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default"); + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL; + } break; + } +} + +NavigationPathQueryParameters2D::PathPostProcessing NavigationPathQueryParameters2D::get_path_postprocessing() const { + switch (parameters.path_postprocessing) { + case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL: + return PATH_POSTPROCESSING_CORRIDORFUNNEL; + case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED: + return PATH_POSTPROCESSING_EDGECENTERED; + default: + WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default"); + return PATH_POSTPROCESSING_CORRIDORFUNNEL; + } +} + +void NavigationPathQueryParameters2D::set_map(const RID &p_map) { + parameters.map = p_map; +} + +const RID &NavigationPathQueryParameters2D::get_map() const { + return parameters.map; +} + +void NavigationPathQueryParameters2D::set_start_position(const Vector2 p_start_position) { + parameters.start_position = Vector3(p_start_position.x, 0.0, p_start_position.y); +} + +Vector2 NavigationPathQueryParameters2D::get_start_position() const { + return Vector2(parameters.start_position.x, parameters.start_position.z); +} + +void NavigationPathQueryParameters2D::set_target_position(const Vector2 p_target_position) { + parameters.target_position = Vector3(p_target_position.x, 0.0, p_target_position.y); +} + +Vector2 NavigationPathQueryParameters2D::get_target_position() const { + return Vector2(parameters.target_position.x, parameters.target_position.z); +} + +void NavigationPathQueryParameters2D::set_navigation_layers(uint32_t p_navigation_layers) { + parameters.navigation_layers = p_navigation_layers; +}; + +uint32_t NavigationPathQueryParameters2D::get_navigation_layers() const { + return parameters.navigation_layers; +}; + +void NavigationPathQueryParameters2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm); + ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters2D::get_pathfinding_algorithm); + + ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationPathQueryParameters2D::set_path_postprocessing); + ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationPathQueryParameters2D::get_path_postprocessing); + + ClassDB::bind_method(D_METHOD("set_map", "map"), &NavigationPathQueryParameters2D::set_map); + ClassDB::bind_method(D_METHOD("get_map"), &NavigationPathQueryParameters2D::get_map); + + ClassDB::bind_method(D_METHOD("set_start_position", "start_position"), &NavigationPathQueryParameters2D::set_start_position); + ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationPathQueryParameters2D::get_start_position); + + ClassDB::bind_method(D_METHOD("set_target_position", "target_position"), &NavigationPathQueryParameters2D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationPathQueryParameters2D::get_target_position); + + ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters2D::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters2D::get_navigation_layers); + + ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing"); + + BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR); + + BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL); + BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED); +} diff --git a/servers/navigation/navigation_path_query_parameters_2d.h b/servers/navigation/navigation_path_query_parameters_2d.h new file mode 100644 index 0000000000..c0ef337a27 --- /dev/null +++ b/servers/navigation/navigation_path_query_parameters_2d.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* navigation_path_query_parameters_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_PATH_QUERY_PARAMETERS_2D_H +#define NAVIGATION_PATH_QUERY_PARAMETERS_2D_H + +#include "core/object/ref_counted.h" +#include "servers/navigation/navigation_utilities.h" + +class NavigationPathQueryParameters2D : public RefCounted { + GDCLASS(NavigationPathQueryParameters2D, RefCounted); + + NavigationUtilities::PathQueryParameters parameters; + +protected: + static void _bind_methods(); + +public: + enum PathfindingAlgorithm { + PATHFINDING_ALGORITHM_ASTAR = 0, + }; + + enum PathPostProcessing { + PATH_POSTPROCESSING_CORRIDORFUNNEL = 0, + PATH_POSTPROCESSING_EDGECENTERED, + }; + + const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; } + + void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm); + PathfindingAlgorithm get_pathfinding_algorithm() const; + + void set_path_postprocessing(const PathPostProcessing p_path_postprocessing); + PathPostProcessing get_path_postprocessing() const; + + void set_map(const RID &p_map); + const RID &get_map() const; + + void set_start_position(const Vector2 p_start_position); + Vector2 get_start_position() const; + + void set_target_position(const Vector2 p_target_position); + Vector2 get_target_position() const; + + void set_navigation_layers(uint32_t p_navigation_layers); + uint32_t get_navigation_layers() const; +}; + +VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm); +VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathPostProcessing); + +#endif // NAVIGATION_PATH_QUERY_PARAMETERS_2D_H diff --git a/servers/navigation/navigation_path_query_parameters_3d.cpp b/servers/navigation/navigation_path_query_parameters_3d.cpp new file mode 100644 index 0000000000..b09448e82e --- /dev/null +++ b/servers/navigation/navigation_path_query_parameters_3d.cpp @@ -0,0 +1,144 @@ +/*************************************************************************/ +/* navigation_path_query_parameters_3d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_path_query_parameters_3d.h" + +void NavigationPathQueryParameters3D::set_pathfinding_algorithm(const NavigationPathQueryParameters3D::PathfindingAlgorithm p_pathfinding_algorithm) { + switch (p_pathfinding_algorithm) { + case PATHFINDING_ALGORITHM_ASTAR: { + parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR; + } break; + default: { + WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default"); + parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR; + } break; + } +} + +NavigationPathQueryParameters3D::PathfindingAlgorithm NavigationPathQueryParameters3D::get_pathfinding_algorithm() const { + switch (parameters.pathfinding_algorithm) { + case NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR: + return PATHFINDING_ALGORITHM_ASTAR; + default: + WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default"); + return PATHFINDING_ALGORITHM_ASTAR; + } +} + +void NavigationPathQueryParameters3D::set_path_postprocessing(const NavigationPathQueryParameters3D::PathPostProcessing p_path_postprocessing) { + switch (p_path_postprocessing) { + case PATH_POSTPROCESSING_CORRIDORFUNNEL: { + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL; + } break; + case PATH_POSTPROCESSING_EDGECENTERED: { + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED; + } break; + default: { + WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default"); + parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL; + } break; + } +} + +NavigationPathQueryParameters3D::PathPostProcessing NavigationPathQueryParameters3D::get_path_postprocessing() const { + switch (parameters.path_postprocessing) { + case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL: + return PATH_POSTPROCESSING_CORRIDORFUNNEL; + case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED: + return PATH_POSTPROCESSING_EDGECENTERED; + default: + WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default"); + return PATH_POSTPROCESSING_CORRIDORFUNNEL; + } +} + +void NavigationPathQueryParameters3D::set_map(const RID &p_map) { + parameters.map = p_map; +} + +const RID &NavigationPathQueryParameters3D::get_map() const { + return parameters.map; +} + +void NavigationPathQueryParameters3D::set_start_position(const Vector3 &p_start_position) { + parameters.start_position = p_start_position; +} + +const Vector3 &NavigationPathQueryParameters3D::get_start_position() const { + return parameters.start_position; +} + +void NavigationPathQueryParameters3D::set_target_position(const Vector3 &p_target_position) { + parameters.target_position = p_target_position; +} + +const Vector3 &NavigationPathQueryParameters3D::get_target_position() const { + return parameters.target_position; +} + +void NavigationPathQueryParameters3D::set_navigation_layers(uint32_t p_navigation_layers) { + parameters.navigation_layers = p_navigation_layers; +} + +uint32_t NavigationPathQueryParameters3D::get_navigation_layers() const { + return parameters.navigation_layers; +} + +void NavigationPathQueryParameters3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters3D::set_pathfinding_algorithm); + ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters3D::get_pathfinding_algorithm); + + ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationPathQueryParameters3D::set_path_postprocessing); + ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationPathQueryParameters3D::get_path_postprocessing); + + ClassDB::bind_method(D_METHOD("set_map", "map"), &NavigationPathQueryParameters3D::set_map); + ClassDB::bind_method(D_METHOD("get_map"), &NavigationPathQueryParameters3D::get_map); + + ClassDB::bind_method(D_METHOD("set_start_position", "start_position"), &NavigationPathQueryParameters3D::set_start_position); + ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationPathQueryParameters3D::get_start_position); + + ClassDB::bind_method(D_METHOD("set_target_position", "target_position"), &NavigationPathQueryParameters3D::set_target_position); + ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationPathQueryParameters3D::get_target_position); + + ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters3D::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters3D::get_navigation_layers); + + ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing"); + + BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR); + + BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL); + BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED); +} diff --git a/servers/navigation/navigation_path_query_parameters_3d.h b/servers/navigation/navigation_path_query_parameters_3d.h new file mode 100644 index 0000000000..b4cf02fc79 --- /dev/null +++ b/servers/navigation/navigation_path_query_parameters_3d.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* navigation_path_query_parameters_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_PATH_QUERY_PARAMETERS_3D_H +#define NAVIGATION_PATH_QUERY_PARAMETERS_3D_H + +#include "core/object/ref_counted.h" +#include "servers/navigation/navigation_utilities.h" + +class NavigationPathQueryParameters3D : public RefCounted { + GDCLASS(NavigationPathQueryParameters3D, RefCounted); + + NavigationUtilities::PathQueryParameters parameters; + +protected: + static void _bind_methods(); + +public: + enum PathfindingAlgorithm { + PATHFINDING_ALGORITHM_ASTAR = 0, + }; + + enum PathPostProcessing { + PATH_POSTPROCESSING_CORRIDORFUNNEL = 0, + PATH_POSTPROCESSING_EDGECENTERED, + }; + + const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; } + + void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm); + PathfindingAlgorithm get_pathfinding_algorithm() const; + + void set_path_postprocessing(const PathPostProcessing p_path_postprocessing); + PathPostProcessing get_path_postprocessing() const; + + void set_map(const RID &p_map); + const RID &get_map() const; + + void set_start_position(const Vector3 &p_start_position); + const Vector3 &get_start_position() const; + + void set_target_position(const Vector3 &p_target_position); + const Vector3 &get_target_position() const; + + void set_navigation_layers(uint32_t p_navigation_layers); + uint32_t get_navigation_layers() const; +}; + +VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathfindingAlgorithm); +VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathPostProcessing); + +#endif // NAVIGATION_PATH_QUERY_PARAMETERS_3D_H diff --git a/servers/navigation/navigation_path_query_result_2d.cpp b/servers/navigation/navigation_path_query_result_2d.cpp new file mode 100644 index 0000000000..23f001057b --- /dev/null +++ b/servers/navigation/navigation_path_query_result_2d.cpp @@ -0,0 +1,46 @@ +/*************************************************************************/ +/* navigation_path_query_result_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_path_query_result_2d.h" + +void NavigationPathQueryResult2D::set_path(const Vector<Vector2> &p_path) { + path = p_path; +} + +const Vector<Vector2> &NavigationPathQueryResult2D::get_path() const { + return path; +} + +void NavigationPathQueryResult2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult2D::set_path); + ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult2D::get_path); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "path"), "set_path", "get_path"); +} diff --git a/servers/navigation/navigation_path_query_result_2d.h b/servers/navigation/navigation_path_query_result_2d.h new file mode 100644 index 0000000000..c98462016e --- /dev/null +++ b/servers/navigation/navigation_path_query_result_2d.h @@ -0,0 +1,50 @@ +/*************************************************************************/ +/* navigation_path_query_result_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_PATH_QUERY_RESULT_2D_H +#define NAVIGATION_PATH_QUERY_RESULT_2D_H + +#include "core/object/ref_counted.h" +#include "servers/navigation/navigation_utilities.h" + +class NavigationPathQueryResult2D : public RefCounted { + GDCLASS(NavigationPathQueryResult2D, RefCounted); + + Vector<Vector2> path; + +protected: + static void _bind_methods(); + +public: + void set_path(const Vector<Vector2> &p_path); + const Vector<Vector2> &get_path() const; +}; + +#endif // NAVIGATION_PATH_QUERY_RESULT_2D_H diff --git a/servers/navigation/navigation_path_query_result_3d.cpp b/servers/navigation/navigation_path_query_result_3d.cpp new file mode 100644 index 0000000000..8335d70c4b --- /dev/null +++ b/servers/navigation/navigation_path_query_result_3d.cpp @@ -0,0 +1,46 @@ +/*************************************************************************/ +/* navigation_path_query_result_3d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_path_query_result_3d.h" + +void NavigationPathQueryResult3D::set_path(const Vector<Vector3> &p_path) { + path = p_path; +} + +const Vector<Vector3> &NavigationPathQueryResult3D::get_path() const { + return path; +} + +void NavigationPathQueryResult3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult3D::set_path); + ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult3D::get_path); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "path"), "set_path", "get_path"); +} diff --git a/servers/navigation/navigation_path_query_result_3d.h b/servers/navigation/navigation_path_query_result_3d.h new file mode 100644 index 0000000000..ff698c285f --- /dev/null +++ b/servers/navigation/navigation_path_query_result_3d.h @@ -0,0 +1,50 @@ +/*************************************************************************/ +/* navigation_path_query_result_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_PATH_QUERY_RESULT_3D_H +#define NAVIGATION_PATH_QUERY_RESULT_3D_H + +#include "core/object/ref_counted.h" +#include "servers/navigation/navigation_utilities.h" + +class NavigationPathQueryResult3D : public RefCounted { + GDCLASS(NavigationPathQueryResult3D, RefCounted); + + Vector<Vector3> path; + +protected: + static void _bind_methods(); + +public: + void set_path(const Vector<Vector3> &p_path); + const Vector<Vector3> &get_path() const; +}; + +#endif // NAVIGATION_PATH_QUERY_RESULT_3D_H diff --git a/servers/navigation/navigation_utilities.h b/servers/navigation/navigation_utilities.h new file mode 100644 index 0000000000..bedcc16a67 --- /dev/null +++ b/servers/navigation/navigation_utilities.h @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* navigation_utilities.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_UTILITIES_H +#define NAVIGATION_UTILITIES_H + +#include "core/math/vector3.h" + +namespace NavigationUtilities { + +enum PathfindingAlgorithm { + PATHFINDING_ALGORITHM_ASTAR = 0, +}; + +enum PathPostProcessing { + PATH_POSTPROCESSING_CORRIDORFUNNEL = 0, + PATH_POSTPROCESSING_EDGECENTERED, +}; + +struct PathQueryParameters { + PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR; + PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL; + RID map; + Vector3 start_position = Vector3(); + Vector3 target_position = Vector3(); + uint32_t navigation_layers = 1; +}; + +struct PathQueryResult { + Vector<Vector3> path; +}; + +} //namespace NavigationUtilities + +#endif // NAVIGATION_UTILITIES_H diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index cec8b95225..04e5d2f6a1 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -243,6 +243,8 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer2D::map_force_update); + ClassDB::bind_method(D_METHOD("query_path", "parameters", "result"), &NavigationServer2D::query_path); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create); ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer2D::region_set_enter_cost); ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer2D::region_get_enter_cost); @@ -409,3 +411,12 @@ bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid); void FORWARD_4_C(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata, rid_to_rid, obj_to_obj, sn_to_sn, var_to_var); void FORWARD_1_C(free, RID, p_object, rid_to_rid); + +void NavigationServer2D::query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const { + ERR_FAIL_COND(!p_query_parameters.is_valid()); + ERR_FAIL_COND(!p_query_result.is_valid()); + + const NavigationUtilities::PathQueryResult _query_result = NavigationServer3D::get_singleton()->_query_path(p_query_parameters->get_parameters()); + + p_query_result->set_path(vector_v3_to_v2(_query_result.path)); +} diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index b2ea4c28a0..54cfc6b14e 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -33,7 +33,10 @@ #include "core/object/class_db.h" #include "core/templates/rid.h" + #include "scene/2d/navigation_region_2d.h" +#include "servers/navigation/navigation_path_query_parameters_2d.h" +#include "servers/navigation/navigation_path_query_result_2d.h" // This server exposes the `NavigationServer3D` features in the 2D world. class NavigationServer2D : public Object { @@ -217,6 +220,8 @@ public: /// Callback called at the end of the RVO process virtual void agent_set_callback(RID p_agent, Object *p_receiver, StringName p_method, Variant p_udata = Variant()) const; + virtual void query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const; + /// Destroy the `RID` virtual void free(RID p_object) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index bc0602e1df..783d32641e 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -62,6 +62,8 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer3D::map_force_update); + ClassDB::bind_method(D_METHOD("query_path", "parameters", "result"), &NavigationServer3D::query_path); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create); ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer3D::region_set_enter_cost); ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer3D::region_get_enter_cost); @@ -485,3 +487,14 @@ bool NavigationServer3D::get_debug_enabled() const { return debug_enabled; } #endif // DEBUG_ENABLED + +/////////////////////////////////////////////////////// + +void NavigationServer3D::query_path(const Ref<NavigationPathQueryParameters3D> &p_query_parameters, Ref<NavigationPathQueryResult3D> p_query_result) const { + ERR_FAIL_COND(!p_query_parameters.is_valid()); + ERR_FAIL_COND(!p_query_result.is_valid()); + + const NavigationUtilities::PathQueryResult _query_result = _query_path(p_query_parameters->get_parameters()); + + p_query_result->set_path(_query_result.path); +} diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 02770794c6..0f537383a2 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -33,7 +33,10 @@ #include "core/object/class_db.h" #include "core/templates/rid.h" + #include "scene/3d/navigation_region_3d.h" +#include "servers/navigation/navigation_path_query_parameters_3d.h" +#include "servers/navigation/navigation_path_query_result_3d.h" /// This server uses the concept of internal mutability. /// All the constant functions can be called in multithread because internally @@ -41,6 +44,7 @@ /// /// Note: All the `set` functions are commands executed during the `sync` phase, /// don't expect that a change is immediately propagated. + class NavigationServer3D : public Object { GDCLASS(NavigationServer3D, Object); @@ -243,6 +247,11 @@ public: /// Note: This function is not thread safe. virtual void process(real_t delta_time) = 0; + /// Returns a customized navigation path using a query parameters object + void query_path(const Ref<NavigationPathQueryParameters3D> &p_query_parameters, Ref<NavigationPathQueryResult3D> p_query_result) const; + + virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const = 0; + NavigationServer3D(); virtual ~NavigationServer3D(); diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp index ef6a6b1ae2..90124cd991 100644 --- a/servers/physics_2d/godot_body_2d.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -615,7 +615,7 @@ void GodotBody2D::integrate_velocities(real_t p_step) { return; } - if (fi_callback_data || body_state_callback) { + if (fi_callback_data || body_state_callback.get_object()) { get_space()->body_add_to_state_query_list(&direct_state_query_list); } @@ -673,11 +673,12 @@ void GodotBody2D::wakeup_neighbours() { } void GodotBody2D::call_queries() { + Variant direct_state_variant = get_direct_state(); + if (fi_callback_data) { if (!fi_callback_data->callable.get_object()) { set_force_integration_callback(Callable()); } else { - Variant direct_state_variant = get_direct_state(); const Variant *vp[2] = { &direct_state_variant, &fi_callback_data->udata }; Callable::CallError ce; @@ -691,8 +692,11 @@ void GodotBody2D::call_queries() { } } - if (body_state_callback) { - (body_state_callback)(body_state_callback_instance, get_direct_state()); + if (body_state_callback.get_object()) { + const Variant *vp[1] = { &direct_state_variant }; + Callable::CallError ce; + Variant rv; + body_state_callback.callp(vp, 1, rv, ce); } } @@ -713,9 +717,8 @@ bool GodotBody2D::sleep_test(real_t p_step) { } } -void GodotBody2D::set_state_sync_callback(void *p_instance, PhysicsServer2D::BodyStateCallback p_callback) { - body_state_callback_instance = p_instance; - body_state_callback = p_callback; +void GodotBody2D::set_state_sync_callback(const Callable &p_callable) { + body_state_callback = p_callable; } void GodotBody2D::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { diff --git a/servers/physics_2d/godot_body_2d.h b/servers/physics_2d/godot_body_2d.h index 409940d4f8..86d42ae7f8 100644 --- a/servers/physics_2d/godot_body_2d.h +++ b/servers/physics_2d/godot_body_2d.h @@ -137,8 +137,7 @@ class GodotBody2D : public GodotCollisionObject2D { Vector<Contact> contacts; //no contacts by default int contact_count = 0; - void *body_state_callback_instance = nullptr; - PhysicsServer2D::BodyStateCallback body_state_callback = nullptr; + Callable body_state_callback; struct ForceIntegrationCallbackData { Callable callable; @@ -156,7 +155,7 @@ class GodotBody2D : public GodotCollisionObject2D { friend class GodotPhysicsDirectBodyState2D; // i give up, too many functions to expose public: - void set_state_sync_callback(void *p_instance, PhysicsServer2D::BodyStateCallback p_callback); + void set_state_sync_callback(const Callable &p_callable); void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); GodotPhysicsDirectBodyState2D *get_direct_state(); diff --git a/servers/physics_2d/godot_collision_solver_2d.cpp b/servers/physics_2d/godot_collision_solver_2d.cpp index 0d7b42b80d..52237539c0 100644 --- a/servers/physics_2d/godot_collision_solver_2d.cpp +++ b/servers/physics_2d/godot_collision_solver_2d.cpp @@ -34,7 +34,7 @@ #define collision_solver sat_2d_calculate_penetration //#define collision_solver gjk_epa_calculate_penetration -bool GodotCollisionSolver2D::solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { +bool GodotCollisionSolver2D::solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin) { const GodotWorldBoundaryShape2D *world_boundary = static_cast<const GodotWorldBoundaryShape2D *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_WORLD_BOUNDARY) { return false; @@ -52,7 +52,9 @@ bool GodotCollisionSolver2D::solve_static_world_boundary(const GodotShape2D *p_s bool found = false; for (int i = 0; i < support_count; i++) { + supports[i] += p_margin * supports[i].normalized(); supports[i] = p_transform_B.xform(supports[i]); + supports[i] += p_motion_B; real_t pd = n.dot(supports[i]); if (pd >= d) { continue; @@ -227,17 +229,19 @@ bool GodotCollisionSolver2D::solve(const GodotShape2D *p_shape_A, const Transfor if (type_A == PhysicsServer2D::SHAPE_WORLD_BOUNDARY) { if (type_B == PhysicsServer2D::SHAPE_WORLD_BOUNDARY) { + WARN_PRINT_ONCE("Collisions between world boundaries are not supported."); return false; } if (swap) { - return solve_static_world_boundary(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); + return solve_static_world_boundary(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_motion_A, p_result_callback, p_userdata, true, p_margin_A); } else { - return solve_static_world_boundary(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); + return solve_static_world_boundary(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, p_margin_B); } } else if (type_A == PhysicsServer2D::SHAPE_SEPARATION_RAY) { if (type_B == PhysicsServer2D::SHAPE_SEPARATION_RAY) { + WARN_PRINT_ONCE("Collisions between two rays are not supported."); return false; //no ray-ray } @@ -249,6 +253,7 @@ bool GodotCollisionSolver2D::solve(const GodotShape2D *p_shape_A, const Transfor } else if (concave_B) { if (concave_A) { + WARN_PRINT_ONCE("Collisions between two concave shapes are not supported."); return false; } diff --git a/servers/physics_2d/godot_collision_solver_2d.h b/servers/physics_2d/godot_collision_solver_2d.h index bd90641f04..3aac2751e0 100644 --- a/servers/physics_2d/godot_collision_solver_2d.h +++ b/servers/physics_2d/godot_collision_solver_2d.h @@ -38,7 +38,7 @@ public: typedef void (*CallbackResult)(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata); private: - static bool solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_static_world_boundary(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin = 0); static bool concave_callback(void *p_userdata, GodotShape2D *p_convex); static bool solve_concave(const GodotShape2D *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); static bool solve_separation_ray(const GodotShape2D *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const GodotShape2D *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *r_sep_axis = nullptr, real_t p_margin = 0); diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index cec31bdc31..6ce8175e6c 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -485,6 +485,20 @@ void GodotPhysicsServer2D::area_set_monitorable(RID p_area, bool p_monitorable) area->set_monitorable(p_monitorable); } +void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_layer(p_layer); +} + +uint32_t GodotPhysicsServer2D::area_get_collision_layer(RID p_area) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_layer(); +} + void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) { GodotArea2D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); @@ -492,11 +506,11 @@ void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) area->set_collision_mask(p_mask); } -void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) { +uint32_t GodotPhysicsServer2D::area_get_collision_mask(RID p_area) const { GodotArea2D *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); + ERR_FAIL_COND_V(!area, 0); - area->set_collision_layer(p_layer); + return area->get_collision_mask(); } void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { @@ -951,10 +965,10 @@ int GodotPhysicsServer2D::body_get_max_contacts_reported(RID p_body) const { return body->get_max_contacts_reported(); } -void GodotPhysicsServer2D::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { +void GodotPhysicsServer2D::body_set_state_sync_callback(RID p_body, const Callable &p_callable) { GodotBody2D *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - body->set_state_sync_callback(p_instance, p_callback); + body->set_state_sync_callback(p_callable); } void GodotPhysicsServer2D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h index 20e492d87a..b96677700c 100644 --- a/servers/physics_2d/godot_physics_server_2d.h +++ b/servers/physics_2d/godot_physics_server_2d.h @@ -151,8 +151,12 @@ public: virtual Variant area_get_param(RID p_area, AreaParameter p_param) const override; virtual Transform2D area_get_transform(RID p_area) const override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; + virtual uint32_t area_get_collision_layer(RID p_area) const override; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual uint32_t area_get_collision_mask(RID p_area) const override; virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; @@ -243,7 +247,7 @@ public: virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override; virtual int body_get_max_contacts_reported(RID p_body) const override; - virtual void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) override; + virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) override; virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) override; virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override; diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index b632f7f461..19f065c319 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -674,7 +674,7 @@ void GodotBody3D::integrate_velocities(real_t p_step) { return; } - if (fi_callback_data || body_state_callback) { + if (fi_callback_data || body_state_callback.get_object()) { get_space()->body_add_to_state_query_list(&direct_state_query_list); } @@ -756,11 +756,12 @@ void GodotBody3D::wakeup_neighbours() { } void GodotBody3D::call_queries() { + Variant direct_state_variant = get_direct_state(); + if (fi_callback_data) { if (!fi_callback_data->callable.get_object()) { set_force_integration_callback(Callable()); } else { - Variant direct_state_variant = get_direct_state(); const Variant *vp[2] = { &direct_state_variant, &fi_callback_data->udata }; Callable::CallError ce; @@ -770,8 +771,11 @@ void GodotBody3D::call_queries() { } } - if (body_state_callback_instance) { - (body_state_callback)(body_state_callback_instance, get_direct_state()); + if (body_state_callback.get_object()) { + const Variant *vp[1] = { &direct_state_variant }; + Callable::CallError ce; + Variant rv; + body_state_callback.callp(vp, 1, rv, ce); } } @@ -792,9 +796,8 @@ bool GodotBody3D::sleep_test(real_t p_step) { } } -void GodotBody3D::set_state_sync_callback(void *p_instance, PhysicsServer3D::BodyStateCallback p_callback) { - body_state_callback_instance = p_instance; - body_state_callback = p_callback; +void GodotBody3D::set_state_sync_callback(const Callable &p_callable) { + body_state_callback = p_callable; } void GodotBody3D::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { diff --git a/servers/physics_3d/godot_body_3d.h b/servers/physics_3d/godot_body_3d.h index 2153ca4e91..412cbebc7d 100644 --- a/servers/physics_3d/godot_body_3d.h +++ b/servers/physics_3d/godot_body_3d.h @@ -131,8 +131,7 @@ class GodotBody3D : public GodotCollisionObject3D { Vector<Contact> contacts; //no contacts by default int contact_count = 0; - void *body_state_callback_instance = nullptr; - PhysicsServer3D::BodyStateCallback body_state_callback = nullptr; + Callable body_state_callback; struct ForceIntegrationCallbackData { Callable callable; @@ -150,7 +149,7 @@ class GodotBody3D : public GodotCollisionObject3D { friend class GodotPhysicsDirectBodyState3D; // i give up, too many functions to expose public: - void set_state_sync_callback(void *p_instance, PhysicsServer3D::BodyStateCallback p_callback); + void set_state_sync_callback(const Callable &p_callable); void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); GodotPhysicsDirectBodyState3D *get_direct_state(); diff --git a/servers/physics_3d/godot_collision_solver_3d.cpp b/servers/physics_3d/godot_collision_solver_3d.cpp index 094d77a582..9fe0e3eb84 100644 --- a/servers/physics_3d/godot_collision_solver_3d.cpp +++ b/servers/physics_3d/godot_collision_solver_3d.cpp @@ -370,12 +370,15 @@ bool GodotCollisionSolver3D::solve_static(const GodotShape3D *p_shape_A, const T if (type_A == PhysicsServer3D::SHAPE_WORLD_BOUNDARY) { if (type_B == PhysicsServer3D::SHAPE_WORLD_BOUNDARY) { + WARN_PRINT_ONCE("Collisions between world boundaries are not supported."); return false; } if (type_B == PhysicsServer3D::SHAPE_SEPARATION_RAY) { + WARN_PRINT_ONCE("Collisions between world boundaries and rays are not supported."); return false; } if (type_B == PhysicsServer3D::SHAPE_SOFT_BODY) { + WARN_PRINT_ONCE("Collisions between world boundaries and soft bodies are not supported."); return false; } @@ -387,6 +390,7 @@ bool GodotCollisionSolver3D::solve_static(const GodotShape3D *p_shape_A, const T } else if (type_A == PhysicsServer3D::SHAPE_SEPARATION_RAY) { if (type_B == PhysicsServer3D::SHAPE_SEPARATION_RAY) { + WARN_PRINT_ONCE("Collisions between rays are not supported."); return false; } @@ -398,7 +402,7 @@ bool GodotCollisionSolver3D::solve_static(const GodotShape3D *p_shape_A, const T } else if (type_B == PhysicsServer3D::SHAPE_SOFT_BODY) { if (type_A == PhysicsServer3D::SHAPE_SOFT_BODY) { - // Soft Body / Soft Body not supported. + WARN_PRINT_ONCE("Collisions between soft bodies are not supported."); return false; } @@ -410,6 +414,7 @@ bool GodotCollisionSolver3D::solve_static(const GodotShape3D *p_shape_A, const T } else if (concave_B) { if (concave_A) { + WARN_PRINT_ONCE("Collisions between two concave shapes are not supported."); return false; } diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index b028c00a31..f3a589d469 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -387,6 +387,13 @@ void GodotPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer area->set_collision_layer(p_layer); } +uint32_t GodotPhysicsServer3D::area_get_collision_layer(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_layer(); +} + void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); @@ -394,6 +401,13 @@ void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) area->set_collision_mask(p_mask); } +uint32_t GodotPhysicsServer3D::area_get_collision_mask(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_mask(); +} + void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); @@ -877,10 +891,10 @@ int GodotPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const { return body->get_max_contacts_reported(); } -void GodotPhysicsServer3D::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { +void GodotPhysicsServer3D::body_set_state_sync_callback(RID p_body, const Callable &p_callable) { GodotBody3D *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - body->set_state_sync_callback(p_instance, p_callback); + body->set_state_sync_callback(p_callable); } void GodotPhysicsServer3D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h index b429f23a0c..e3e649da57 100644 --- a/servers/physics_3d/godot_physics_server_3d.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -148,8 +148,11 @@ public: virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; + virtual uint32_t area_get_collision_layer(RID p_area) const override; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual uint32_t area_get_collision_mask(RID p_area) const override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; @@ -242,7 +245,7 @@ public: virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override; virtual int body_get_max_contacts_reported(RID p_body) const override; - virtual void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) override; + virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) override; virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) override; virtual void body_set_ray_pickable(RID p_body, bool p_enable) override; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index abaa473017..21be311637 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -652,7 +652,10 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer2D::area_clear_shapes); ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer2D::area_set_collision_layer); + ClassDB::bind_method(D_METHOD("area_get_collision_layer", "area"), &PhysicsServer2D::area_get_collision_layer); + ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer2D::area_set_collision_mask); + ClassDB::bind_method(D_METHOD("area_get_collision_mask", "area"), &PhysicsServer2D::area_get_collision_mask); ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer2D::area_set_param); ClassDB::bind_method(D_METHOD("area_set_transform", "area", "transform"), &PhysicsServer2D::area_set_transform); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index d5b4dc05e6..a3feb97d5d 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -332,8 +332,11 @@ public: virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const = 0; virtual Transform2D area_get_transform(RID p_area) const = 0; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0; + virtual uint32_t area_get_collision_layer(RID p_area) const = 0; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; + virtual uint32_t area_get_collision_mask(RID p_area) const = 0; virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; virtual void area_set_pickable(RID p_area, bool p_pickable) = 0; @@ -470,10 +473,7 @@ public: virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0; virtual bool body_is_omitting_force_integration(RID p_body) const = 0; - // Callback for C++ use only. - typedef void (*BodyStateCallback)(void *p_instance, PhysicsDirectBodyState2D *p_state); - virtual void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) = 0; - + virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) = 0; virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) = 0; virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) = 0; @@ -490,7 +490,7 @@ public: bool collide_separation_ray = false; HashSet<RID> exclude_bodies; HashSet<ObjectID> exclude_objects; - bool recovery_as_collision = false; + bool recovery_as_collision = false; // Don't report margin recovery as collision by default, only used for floor snapping. MotionParameters() {} diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index d080aac438..14a6a5c2a1 100644 --- a/servers/physics_server_2d_wrap_mt.h +++ b/servers/physics_server_2d_wrap_mt.h @@ -156,8 +156,11 @@ public: FUNC2RC(Variant, area_get_param, RID, AreaParameter); FUNC1RC(Transform2D, area_get_transform, RID); - FUNC2(area_set_collision_mask, RID, uint32_t); FUNC2(area_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_layer, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_mask, RID); FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_pickable, RID, bool); @@ -249,7 +252,7 @@ public: FUNC2(body_set_omit_force_integration, RID, bool); FUNC1RC(bool, body_is_omitting_force_integration, RID); - FUNC3(body_set_state_sync_callback, RID, void *, BodyStateCallback); + FUNC2(body_set_state_sync_callback, RID, const Callable &); FUNC3(body_set_force_integration_callback, RID, const Callable &, const Variant &); bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override { diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index b4f30d7649..24cc7e8459 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -720,7 +720,10 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer3D::area_clear_shapes); ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer3D::area_set_collision_layer); + ClassDB::bind_method(D_METHOD("area_get_collision_layer", "area"), &PhysicsServer3D::area_get_collision_layer); + ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer3D::area_set_collision_mask); + ClassDB::bind_method(D_METHOD("area_get_collision_mask", "area"), &PhysicsServer3D::area_get_collision_mask); ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer3D::area_set_param); ClassDB::bind_method(D_METHOD("area_set_transform", "area", "transform"), &PhysicsServer3D::area_set_transform); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 1308e4cd36..b21c4e9249 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -364,8 +364,11 @@ public: virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const = 0; virtual Transform3D area_get_transform(RID p_area) const = 0; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0; + virtual uint32_t area_get_collision_layer(RID p_area) const = 0; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; + virtual uint32_t area_get_collision_mask(RID p_area) const = 0; virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; @@ -508,10 +511,7 @@ public: virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0; virtual bool body_is_omitting_force_integration(RID p_body) const = 0; - // Callback for C++ use only. - typedef void (*BodyStateCallback)(void *p_instance, PhysicsDirectBodyState3D *p_state); - virtual void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) = 0; - + virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) = 0; virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) = 0; virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0; @@ -527,7 +527,7 @@ public: bool collide_separation_ray = false; HashSet<RID> exclude_bodies; HashSet<ObjectID> exclude_objects; - bool recovery_as_collision = false; + bool recovery_as_collision = false; // Don't report margin recovery as collision by default, only used for floor snapping. MotionParameters() {} diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index ed4546b240..1d5fa95bfb 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -157,8 +157,11 @@ public: FUNC2RC(Variant, area_get_param, RID, AreaParameter); FUNC1RC(Transform3D, area_get_transform, RID); - FUNC2(area_set_collision_mask, RID, uint32_t); FUNC2(area_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_layer, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_mask, RID); FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_ray_pickable, RID, bool); @@ -252,7 +255,7 @@ public: FUNC2(body_set_omit_force_integration, RID, bool); FUNC1RC(bool, body_is_omitting_force_integration, RID); - FUNC3(body_set_state_sync_callback, RID, void *, BodyStateCallback); + FUNC2(body_set_state_sync_callback, RID, const Callable &); FUNC3(body_set_force_integration_callback, RID, const Callable &, const Variant &); FUNC2(body_set_ray_pickable, RID, bool); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index b9667f338c..1356fedb82 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -145,7 +145,6 @@ void register_server_types() { GDREGISTER_NATIVE_STRUCT(PhysicsServer2DExtensionShapeResult, "RID rid;ObjectID collider_id;Object *collider;int shape"); GDREGISTER_NATIVE_STRUCT(PhysicsServer2DExtensionShapeRestInfo, "Vector2 point;Vector2 normal;RID rid;ObjectID collider_id;int shape;Vector2 linear_velocity"); GDREGISTER_NATIVE_STRUCT(PhysicsServer2DExtensionMotionResult, "Vector2 travel;Vector2 remainder;Vector2 collision_point;Vector2 collision_normal;Vector2 collider_velocity;real_t collision_depth;real_t collision_safe_fraction;real_t collision_unsafe_fraction;int collision_local_shape;ObjectID collider_id;RID collider;int collider_shape"); - GDREGISTER_NATIVE_STRUCT(PhysicsServer2DExtensionStateCallback, "void *instance;void (*callback)(void *p_instance, PhysicsDirectBodyState2D *p_state)"); GDREGISTER_CLASS(PhysicsServer3DManager); Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3DManager", PhysicsServer3DManager::get_singleton(), "PhysicsServer3DManager")); @@ -161,10 +160,14 @@ void register_server_types() { GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionShapeRestInfo, "Vector3 point;Vector3 normal;RID rid;ObjectID collider_id;int shape;Vector3 linear_velocity"); GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionMotionCollision, "Vector3 position;Vector3 normal;Vector3 collider_velocity;real_t depth;int local_shape;ObjectID collider_id;RID collider;int collider_shape"); GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionMotionResult, "Vector3 travel;Vector3 remainder;real_t collision_safe_fraction;real_t collision_unsafe_fraction;PhysicsServer3DExtensionMotionCollision collisions[32];int collision_count"); - GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionStateCallback, "void *instance;void (*callback)(void *p_instance, PhysicsDirectBodyState3D *p_state)"); GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); + GDREGISTER_CLASS(NavigationPathQueryParameters2D); + GDREGISTER_CLASS(NavigationPathQueryParameters3D); + GDREGISTER_CLASS(NavigationPathQueryResult2D); + GDREGISTER_CLASS(NavigationPathQueryResult3D); + GDREGISTER_CLASS(XRServer); GDREGISTER_CLASS(CameraServer); diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index 4a2a947b94..e41373ed37 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -180,7 +180,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override {} - void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {} + void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {} void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {} diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index aa9772a483..c5818d9290 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -189,7 +189,7 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item * RenderingServerDefault::redraw_request(); } - if (ci->commands != nullptr) { + if (ci->commands != nullptr || ci->copy_back_buffer) { ci->final_transform = xform; ci->final_modulate = modulate * ci->self_modulate; ci->global_rect_cache = global_rect; diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index 78d4ded617..8e04191e35 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -34,7 +34,7 @@ #include "servers/rendering/environment/renderer_fog.h" #include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_canvas_render.h" -#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/camera_attributes_storage.h" #include "servers/rendering/storage/light_storage.h" #include "servers/rendering/storage/material_storage.h" diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index ceba43ae8f..307af99e91 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1261,6 +1261,7 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P light_data_dirty = true; for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) { sky_scene_state.directional_lights[i].enabled = false; + sky_scene_state.last_frame_directional_lights[i].enabled = false; } } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index dec5e23558..35953a7120 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -477,6 +477,13 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p prev_material_uniform_set = material_uniform_set; } + if ((surf->owner->base_flags & (INSTANCE_DATA_FLAG_MULTIMESH | INSTANCE_DATA_FLAG_PARTICLES)) == INSTANCE_DATA_FLAG_MULTIMESH) { + mesh_storage->_multimesh_get_motion_vectors_offsets(surf->owner->data->base, push_constant.multimesh_motion_vectors_current_offset, push_constant.multimesh_motion_vectors_previous_offset); + } else { + push_constant.multimesh_motion_vectors_current_offset = 0; + push_constant.multimesh_motion_vectors_previous_offset = 0; + } + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); uint32_t instance_count = surf->owner->instance_count > 1 ? surf->owner->instance_count : element_info.repeat; @@ -574,47 +581,21 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers; + RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID(); + RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID(); - //Projection projection = p_render_data->cam_projection; - //projection.flip_y(); // Vulkan and modern APIs use Y-Down - Projection correction; - correction.set_depth_correction(p_flip_y); - correction.add_jitter_offset(p_render_data->taa_jitter); - Projection projection = correction * p_render_data->cam_projection; - - //store camera into ubo - RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); - RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); - - for (uint32_t v = 0; v < p_render_data->view_count; v++) { - projection = correction * p_render_data->view_projection[v]; - RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); - RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); - - scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x; - scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y; - scene_state.ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z; - scene_state.ubo.eye_offset[v][3] = 0.0; + // May do this earlier in RenderSceneRenderRD::render_scene + if (p_index >= (int)scene_state.uniform_buffers.size()) { + uint32_t from = scene_state.uniform_buffers.size(); + scene_state.uniform_buffers.resize(p_index + 1); + for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { + scene_state.uniform_buffers[i] = p_render_data->scene_data->create_uniform_buffer(); + } } - scene_state.ubo.taa_jitter[0] = p_render_data->taa_jitter.x; - scene_state.ubo.taa_jitter[1] = p_render_data->taa_jitter.y; - - scene_state.ubo.z_far = p_render_data->z_far; - scene_state.ubo.z_near = p_render_data->z_near; + p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers); - scene_state.ubo.pancake_shadows = p_pancake_shadows; - - RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); - - Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); - scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; - scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y; + // now do implementation UBO scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_render_data->cluster_size); scene_state.ubo.max_cluster_element_count_div_32 = p_render_data->cluster_max_elements / 32; @@ -625,22 +606,8 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.cluster_width = cluster_screen_width; } - if (p_render_data->shadow_atlas.is_valid()) { - Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas); - scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x; - scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y; - } - { - Vector2 dss = directional_shadow_get_size(); - scene_state.ubo.directional_shadow_pixel_size[0] = 1.0 / dss.x; - scene_state.ubo.directional_shadow_pixel_size[1] = 1.0 / dss.y; - } - //time global variables - scene_state.ubo.time = time; - scene_state.ubo.gi_upscale_for_msaa = false; scene_state.ubo.volumetric_fog_enabled = false; - scene_state.ubo.fog_enabled = false; if (rd.is_valid()) { if (rd->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) { @@ -668,59 +635,8 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat } if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - scene_state.ubo.use_ambient_light = true; - scene_state.ubo.ambient_light_color_energy[0] = 1; - scene_state.ubo.ambient_light_color_energy[1] = 1; - scene_state.ubo.ambient_light_color_energy[2] = 1; - scene_state.ubo.ambient_light_color_energy[3] = 1.0; - scene_state.ubo.use_ambient_cubemap = false; - scene_state.ubo.use_reflection_cubemap = false; scene_state.ubo.ss_effects_flags = 0; - } else if (is_environment(p_render_data->environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); - RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - - float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); - - scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier; - - scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); - - //ambient - if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); - color = color.srgb_to_linear(); - - scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; - scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; - scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; - scene_state.ubo.use_ambient_light = true; - scene_state.ubo.use_ambient_cubemap = false; - } else { - float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light(p_render_data->environment); - color = color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; - scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; - scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - - Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); - sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; - RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); - - scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; - scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; - } - - //specular - RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); - if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { - scene_state.ubo.use_reflection_cubemap = true; - } else { - scene_state.ubo.use_reflection_cubemap = false; - } - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); uint32_t ss_flags = 0; @@ -729,97 +645,19 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat ss_flags |= environment_get_ssil_enabled(p_render_data->environment) ? 2 : 0; } scene_state.ubo.ss_effects_flags = ss_flags; - - scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); - scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); - scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); - scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); - scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - - Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); - float fog_energy = environment_get_fog_light_energy(p_render_data->environment); - - scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; - scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; - scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - - scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); - } else { - if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { - scene_state.ubo.use_ambient_light = false; - } else { - scene_state.ubo.use_ambient_light = true; - Color clear_color = p_default_bg_color; - clear_color = clear_color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = clear_color.r; - scene_state.ubo.ambient_light_color_energy[1] = clear_color.g; - scene_state.ubo.ambient_light_color_energy[2] = clear_color.b; - scene_state.ubo.ambient_light_color_energy[3] = 1.0; - } - - scene_state.ubo.use_ambient_cubemap = false; - scene_state.ubo.use_reflection_cubemap = false; scene_state.ubo.ss_effects_flags = 0; } - if (p_render_data->camera_attributes.is_valid()) { - scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); - scene_state.ubo.IBL_exposure_normalization = 1.0; - if (is_environment(p_render_data->environment)) { - RID sky_rid = environment_get_sky(p_render_data->environment); - if (sky_rid.is_valid()) { - float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment) / _render_buffers_get_luminance_multiplier(); - scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky.sky_get_baked_exposure(sky_rid)); - } - } - } else if (scene_state.ubo.emissive_exposure_normalization > 0.0) { - // This branch is triggered when using render_material(). - // Emissive is set outside the function, so don't set it. - // IBL isn't used don't set it. - } else { - scene_state.ubo.emissive_exposure_normalization = 1.0; - scene_state.ubo.IBL_exposure_normalization = 1.0; - } - - scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active(); - scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount(); - scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit(); - - if (rd.is_valid()) { - if (rd->get_use_taa() || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) { - memcpy(&scene_state.prev_ubo, &scene_state.ubo, sizeof(SceneState::UBO)); - - Projection prev_correction; - prev_correction.set_depth_correction(true); - prev_correction.add_jitter_offset(p_render_data->prev_taa_jitter); - Projection prev_projection = prev_correction * p_render_data->prev_cam_projection; - - //store camera into ubo - RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix); - RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix); - - for (uint32_t v = 0; v < p_render_data->view_count; v++) { - prev_projection = prev_correction * p_render_data->view_projection[v]; - RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]); - RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]); - } - scene_state.prev_ubo.taa_jitter[0] = p_render_data->prev_taa_jitter.x; - scene_state.prev_ubo.taa_jitter[1] = p_render_data->prev_taa_jitter.y; - scene_state.prev_ubo.time -= time_step; + if (p_index >= (int)scene_state.implementation_uniform_buffers.size()) { + uint32_t from = scene_state.implementation_uniform_buffers.size(); + scene_state.implementation_uniform_buffers.resize(p_index + 1); + for (uint32_t i = from; i < scene_state.implementation_uniform_buffers.size(); i++) { + scene_state.implementation_uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); } } - if (p_index >= (int)scene_state.uniform_buffers.size()) { - uint32_t from = scene_state.uniform_buffers.size(); - scene_state.uniform_buffers.resize(p_index + 1); - for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { - scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO) * 2); - } - } - RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO) * 2, &scene_state.ubo_data, RD::BARRIER_MASK_RASTER); + RD::get_singleton()->buffer_update(scene_state.implementation_uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER); } void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) { @@ -924,7 +762,7 @@ _FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primit static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 }; return (p_indices - subtractor[p_primitive]) / divisor[p_primitive]; } -void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { +void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, uint32_t p_color_pass_flags = 0, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); if (p_render_list == RENDER_LIST_OPAQUE) { @@ -935,9 +773,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con } uint32_t lightmap_captures_used = 0; - Plane near_plane = Plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin); - near_plane.d += p_render_data->cam_projection.get_z_near(); - float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near(); + Plane near_plane = Plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin); + near_plane.d += p_render_data->scene_data->cam_projection.get_z_near(); + float z_max = p_render_data->scene_data->cam_projection.get_z_far() - p_render_data->scene_data->cam_projection.get_z_near(); RenderList *rl = &render_list[p_render_list]; _update_dirty_geometry_instances(); @@ -968,7 +806,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con float fade_alpha = 1.0; if (inst->fade_near || inst->fade_far) { - float fade_dist = inst->transform.origin.distance_to(p_render_data->cam_transform.origin); + float fade_dist = inst->transform.origin.distance_to(p_render_data->scene_data->cam_transform.origin); // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. if (inst->fade_far && fade_dist > inst->fade_far_begin) { fade_alpha = Math::smoothstep(0.0f, 1.0f, 1.0f - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin)); @@ -1063,13 +901,13 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con // LOD - if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { + if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal); - float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); - float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max); + float distance_min = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_min); + float distance_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max); float distance = 0.0; @@ -1082,12 +920,12 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con distance = -distance_max; } - if (p_render_data->cam_orthogonal) { + if (p_render_data->scene_data->cam_orthogonal) { distance = 1.0; } uint32_t indices; - surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices); + surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices); if (p_render_data->render_info) { indices = _indices_to_primitives(surf->primitive, indices); if (p_render_list == RENDER_LIST_OPAQUE) { //opaque @@ -1149,6 +987,12 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con scene_state.used_depth_texture = true; } + if (p_color_pass_flags & COLOR_PASS_FLAG_MOTION_VECTORS) { + if ((flags & (INSTANCE_DATA_FLAG_MULTIMESH | INSTANCE_DATA_FLAG_PARTICLES)) == INSTANCE_DATA_FLAG_MULTIMESH && RendererRD::MeshStorage::get_singleton()->_multimesh_enable_motion_vectors(inst->data->base)) { + inst->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(inst->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET); + } + } + } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) { if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) { rl->add_element(surf); @@ -1220,9 +1064,18 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RENDER_TIMESTAMP("Setup 3D Scene"); - //scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size; - scene_state.ubo.directional_light_count = 0; - scene_state.ubo.opaque_prepass_threshold = 0.99f; + // check if we need motion vectors + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) { + p_render_data->scene_data->calculate_motion_vectors = true; + } else if (rb.is_valid() && rb->get_use_taa()) { + p_render_data->scene_data->calculate_motion_vectors = true; + } else { + p_render_data->scene_data->calculate_motion_vectors = false; + } + + //p_render_data->scene_data->subsurface_scatter_width = subsurface_scatter_size; + p_render_data->scene_data->directional_light_count = 0; + p_render_data->scene_data->opaque_prepass_threshold = 0.99f; Size2i screen_size; RID color_framebuffer; @@ -1285,7 +1138,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co }; } - if (p_render_data->view_count > 1) { + if (p_render_data->scene_data->view_count > 1) { color_pass_flags |= COLOR_PASS_FLAG_MULTIVIEW; } @@ -1309,20 +1162,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co ERR_FAIL(); //bug? } - scene_state.ubo.viewport_size[0] = screen_size.x; - scene_state.ubo.viewport_size[1] = screen_size.y; - - scene_state.ubo.emissive_exposure_normalization = -1.0; + p_render_data->scene_data->emissive_exposure_normalization = -1.0; RD::get_singleton()->draw_command_begin_label("Render Setup"); - _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->cam_transform); + _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform); _setup_voxelgis(*p_render_data->voxel_gi_instances); _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi); + _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, color_pass_flags, using_sdfgi, using_sdfgi || using_voxelgi); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority(); _fill_instance_data(RENDER_LIST_OPAQUE, p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr); @@ -1396,20 +1246,20 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - Projection projection = p_render_data->cam_projection; + Projection projection = p_render_data->scene_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { Projection correction; correction.set_depth_correction(true); - projection = correction * p_render_data->cam_projection; + projection = correction * p_render_data->scene_data->cam_projection; } - sky.setup(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this); sky_energy_multiplier *= bg_energy_multiplier; RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, sky_energy_multiplier); + sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1448,7 +1298,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); @@ -1488,8 +1338,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); - scene_state.ubo.directional_light_count = p_render_data->directional_light_count; - scene_state.ubo.opaque_prepass_threshold = 0.0f; + p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count; + p_render_data->scene_data->opaque_prepass_threshold = 0.0f; _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, rb.is_valid()); @@ -1518,7 +1368,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } } - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, color_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used @@ -1536,7 +1386,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Projection dc; dc.set_depth_correction(true); - Projection cm = (dc * p_render_data->cam_projection) * Projection(p_render_data->cam_transform.affine_inverse()); + Projection cm = (dc * p_render_data->scene_data->cam_projection) * Projection(p_render_data->scene_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs"); for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) { @@ -1554,10 +1404,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Projection dc; dc.set_depth_correction(true); Projection cms[RendererSceneRender::MAX_RENDER_VIEWS]; - for (uint32_t v = 0; v < p_render_data->view_count; v++) { - cms[v] = (dc * p_render_data->view_projection[v]) * Projection(p_render_data->cam_transform.affine_inverse()); + for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) { + cms[v] = (dc * p_render_data->scene_data->view_projection[v]) * Projection(p_render_data->scene_data->cam_transform.affine_inverse()); } - _debug_sdfgi_probes(rb, color_only_framebuffer, p_render_data->view_count, cms, will_continue_color, will_continue_depth); + _debug_sdfgi_probes(rb, color_only_framebuffer, p_render_data->scene_data->view_count, cms, will_continue_color, will_continue_depth); } if (draw_sky || draw_sky_fog_only) { @@ -1568,10 +1418,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (p_render_data->reflection_probe.is_valid()) { Projection correction; correction.set_depth_correction(true); - Projection projection = correction * p_render_data->cam_projection; - sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); + Projection projection = correction * p_render_data->scene_data->cam_projection; + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } else { - sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } RD::get_singleton()->draw_command_end_label(); } @@ -1598,7 +1448,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (using_sss) { RENDER_TIMESTAMP("Sub-Surface Scattering"); RD::get_singleton()->draw_command_begin_label("Process Sub-Surface Scattering"); - _process_sss(rb, p_render_data->cam_projection); + _process_sss(rb, p_render_data->scene_data->cam_projection); RD::get_singleton()->draw_command_end_label(); } @@ -1606,15 +1456,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RENDER_TIMESTAMP("Screen-Space Reflections"); RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections"); RID specular_views[RendererSceneRender::MAX_RENDER_VIEWS]; - for (uint32_t v = 0; v < p_render_data->view_count; v++) { + for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) { specular_views[v] = rb_data->get_specular(v); } - _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->view_projection, p_render_data->view_eye_offset, rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED); + _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED); RD::get_singleton()->draw_command_end_label(); } else { //just mix specular back RENDER_TIMESTAMP("Merge Specular"); - copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? RID() : rb->get_internal_texture(), RID(), p_render_data->view_count); + copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count); } } @@ -1639,7 +1489,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co { uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~(COLOR_PASS_FLAG_SEPARATE_SPECULAR); RID alpha_framebuffer = rb_data.is_valid() ? rb_data->get_color_pass_fb(transparent_color_pass_flags) : color_only_framebuffer; - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -1670,7 +1520,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (rb.is_valid() && taa && rb->get_use_taa()) { RENDER_TIMESTAMP("TAA") - taa->process(rb, _render_buffers_get_color_format(), p_render_data->z_near, p_render_data->z_far); + taa->process(rb, _render_buffers_get_color_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far); } if (rb.is_valid()) { @@ -1691,39 +1541,41 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_projection; + scene_data.cam_transform = p_transform; + scene_data.view_projection[0] = p_projection; + scene_data.z_far = p_zfar; + scene_data.z_near = 0.0; + scene_data.lod_camera_plane = p_camera_plane; + scene_data.lod_distance_multiplier = p_lod_distance_multiplier; + scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; + scene_data.opaque_prepass_threshold = 0.1f; + RenderDataRD render_data; - render_data.cam_projection = p_projection; - render_data.cam_transform = p_transform; - render_data.view_projection[0] = p_projection; - render_data.z_far = p_zfar; - render_data.z_near = 0.0; + render_data.scene_data = &scene_data; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; - render_data.lod_camera_plane = p_camera_plane; - render_data.lod_distance_multiplier = p_lod_distance_multiplier; render_data.render_info = p_render_info; - scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - scene_state.ubo.opaque_prepass_threshold = 0.1f; - _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - render_data.screen_mesh_lod_threshold = 0.0; + scene_data.screen_mesh_lod_threshold = 0.0; } else { - render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; + scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; } PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); - _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, false, false, true); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, 0, false, false, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); _fill_instance_data(RENDER_LIST_SECONDARY, p_render_info ? p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW] : (int *)nullptr, render_list_from, render_list_size, false); @@ -1742,8 +1594,8 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete shadow_pass.camera_plane = p_camera_plane; - shadow_pass.screen_mesh_lod_threshold = render_data.screen_mesh_lod_threshold; - shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier; + shadow_pass.screen_mesh_lod_threshold = scene_data.screen_mesh_lod_threshold; + shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier; shadow_pass.framebuffer = p_framebuffer; shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); @@ -1786,19 +1638,22 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_cam_projection; + scene_data.cam_transform = p_cam_transform; + scene_data.view_projection[0] = p_cam_projection; + scene_data.z_near = 0.0; + scene_data.z_far = p_cam_projection.get_z_far(); + scene_data.dual_paraboloid_side = 0; + scene_data.opaque_prepass_threshold = 0.0; + RenderDataRD render_data; - render_data.cam_projection = p_cam_projection; - render_data.cam_transform = p_cam_transform; - render_data.view_projection[0] = p_cam_projection; - render_data.z_near = 0.0; - render_data.z_far = p_cam_projection.get_z_far(); + render_data.scene_data = &scene_data; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.opaque_prepass_threshold = 0.0; _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false); @@ -1825,21 +1680,23 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RD::get_singleton()->draw_command_begin_label("Render 3D Material"); + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_cam_projection; + scene_data.cam_transform = p_cam_transform; + scene_data.view_projection[0] = p_cam_projection; + scene_data.dual_paraboloid_side = 0; + scene_data.material_uv2_mode = false; + scene_data.opaque_prepass_threshold = 0.0f; + scene_data.emissive_exposure_normalization = p_exposure_normalization; + RenderDataRD render_data; - render_data.cam_projection = p_cam_projection; - render_data.cam_transform = p_cam_transform; - render_data.view_projection[0] = p_cam_projection; + render_data.scene_data = &scene_data; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.material_uv2_mode = false; - scene_state.ubo.opaque_prepass_threshold = 0.0f; - scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; - _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; @@ -1875,18 +1732,20 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance RD::get_singleton()->draw_command_begin_label("Render UV2"); + RenderSceneDataRD scene_data; + scene_data.dual_paraboloid_side = 0; + scene_data.material_uv2_mode = true; + scene_data.opaque_prepass_threshold = 0.0; + scene_data.emissive_exposure_normalization = -1.0; + RenderDataRD render_data; + render_data.scene_data = &scene_data; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.material_uv2_mode = true; - scene_state.ubo.opaque_prepass_threshold = 0.0; - scene_state.ubo.emissive_exposure_normalization = -1.0; - _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; @@ -1946,7 +1805,10 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); + RenderSceneDataRD scene_data; + RenderDataRD render_data; + render_data.scene_data = &scene_data; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; @@ -1987,26 +1849,26 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu fb_size.x = p_size[right_axis]; fb_size.y = p_size[up_axis]; - render_data.cam_transform.origin = center + axis * half_extents; - render_data.cam_transform.basis.set_column(0, right); - render_data.cam_transform.basis.set_column(1, up); - render_data.cam_transform.basis.set_column(2, axis); + scene_data.cam_transform.origin = center + axis * half_extents; + scene_data.cam_transform.basis.set_column(0, right); + scene_data.cam_transform.basis.set_column(1, up); + scene_data.cam_transform.basis.set_column(2, axis); - //print_line("pass: " + itos(i) + " xform " + render_data.cam_transform); + //print_line("pass: " + itos(i) + " xform " + scene_data.cam_transform); float h_size = half_extents[right_axis]; float v_size = half_extents[up_axis]; float d_size = half_extents[i] * 2.0; - render_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size); + scene_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size); //print_line("pass: " + itos(i) + " cam hsize: " + rtos(h_size) + " vsize: " + rtos(v_size) + " dsize " + rtos(d_size)); Transform3D to_bounds; to_bounds.origin = p_bounds.position; to_bounds.basis.scale(p_bounds.size); - RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds); + RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * scene_data.cam_transform, scene_state.ubo.sdf_to_bounds); - scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; + scene_data.emissive_exposure_normalization = p_exposure_normalization; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); @@ -2248,6 +2110,13 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend { RD::Uniform u; u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(scene_state.implementation_uniform_buffers[p_index]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID instance_buffer = scene_state.instance_buffer[p_render_list]; if (instance_buffer == RID()) { @@ -2264,16 +2133,15 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; - u.binding = 2; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.append_id(radiance_texture); uniforms.push_back(u); } - { RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID(); RD::Uniform u; - u.binding = 3; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { u.append_id(ref_texture); @@ -2282,10 +2150,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } uniforms.push_back(u); } - { RD::Uniform u; - u.binding = 4; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; if (p_render_data && p_render_data->shadow_atlas.is_valid()) { @@ -2299,7 +2166,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { RD::Uniform u; - u.binding = 5; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { u.append_id(directional_shadow_get_texture()); @@ -2310,7 +2177,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { RD::Uniform u; - u.binding = 6; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2329,7 +2196,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { RD::Uniform u; - u.binding = 7; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { @@ -2349,7 +2216,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend { RD::Uniform u; - u.binding = 8; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = (p_render_data && p_render_data->cluster_buffer.is_valid()) ? p_render_data->cluster_buffer : scene_shader.default_vec4_xform_buffer; u.append_id(cb); @@ -2358,7 +2225,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend { RD::Uniform u; - u.binding = 9; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; if (rb.is_valid() && rb->has_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH)) { @@ -2371,7 +2238,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { RD::Uniform u; - u.binding = 10; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb_data.is_valid() ? rb->get_back_buffer_texture() : RID(); RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); @@ -2380,110 +2247,108 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { - { - RD::Uniform u; - u.binding = 11; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb_data.is_valid() && rb_data->has_normal_roughness() ? rb_data->get_normal_roughness() : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_NORMAL); - u.append_id(texture); - uniforms.push_back(u); - } + RD::Uniform u; + u.binding = 12; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb_data.is_valid() && rb_data->has_normal_roughness() ? rb_data->get_normal_roughness() : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_NORMAL); + u.append_id(texture); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 12; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID aot = rb_data.is_valid() ? rb->get_ao_texture() : RID(); - RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); - u.append_id(texture); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 13; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID aot = rb_data.is_valid() ? rb->get_ao_texture() : RID(); + RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 13; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb_data.is_valid() && rb->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT) ? rb->get_texture(RB_SCOPE_GI, RB_TEX_AMBIENT) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); - u.append_id(texture); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 14; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb_data.is_valid() && rb->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT) ? rb->get_texture(RB_SCOPE_GI, RB_TEX_AMBIENT) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 14; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb_data.is_valid() && rb->has_texture(RB_SCOPE_GI, RB_TEX_REFLECTION) ? rb->get_texture(RB_SCOPE_GI, RB_TEX_REFLECTION) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); - u.append_id(texture); - uniforms.push_back(u); + { + RD::Uniform u; + u.binding = 15; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = rb_data.is_valid() && rb->has_texture(RB_SCOPE_GI, RB_TEX_REFLECTION) ? rb->get_texture(RB_SCOPE_GI, RB_TEX_REFLECTION) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 16; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID t; + if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { + Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); + t = sdfgi->lightprobe_texture; } - { - RD::Uniform u; - u.binding = 15; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID t; - if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { - Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); - t = sdfgi->lightprobe_texture; - } - if (t.is_null()) { - t = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); - } - u.append_id(t); - uniforms.push_back(u); + if (t.is_null()) { + t = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } - { - RD::Uniform u; - u.binding = 16; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID t; - if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { - Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); - t = sdfgi->occlusion_texture; - } - if (t.is_null()) { - t = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); - } - u.append_id(t); - uniforms.push_back(u); + u.append_id(t); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 17; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID t; + if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { + Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); + t = sdfgi->occlusion_texture; } - { - RD::Uniform u; - u.binding = 17; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - RID voxel_gi; - if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_GI)) { - Ref<RendererRD::GI::RenderBuffersGI> rbgi = rb->get_custom_data(RB_SCOPE_GI); - voxel_gi = rbgi->get_voxel_gi_buffer(); - } - u.append_id(voxel_gi.is_valid() ? voxel_gi : render_buffers_get_default_voxel_gi_buffer()); - uniforms.push_back(u); + if (t.is_null()) { + t = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } - { - RD::Uniform u; - u.binding = 18; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID vfog = RID(); - if (rb_data.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) { - Ref<RendererRD::Fog::VolumetricFog> fog = rb->get_custom_data(RB_SCOPE_FOG); - vfog = fog->fog_map; - if (vfog.is_null()) { - vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); - } - } else { + u.append_id(t); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 18; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + RID voxel_gi; + if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_GI)) { + Ref<RendererRD::GI::RenderBuffersGI> rbgi = rb->get_custom_data(RB_SCOPE_GI); + voxel_gi = rbgi->get_voxel_gi_buffer(); + } + u.append_id(voxel_gi.is_valid() ? voxel_gi : render_buffers_get_default_voxel_gi_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 19; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID vfog = RID(); + if (rb_data.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) { + Ref<RendererRD::Fog::VolumetricFog> fog = rb->get_custom_data(RB_SCOPE_FOG); + vfog = fog->fog_map; + if (vfog.is_null()) { vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } - u.append_id(vfog); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 19; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID ssil = rb_data.is_valid() ? rb->get_ssil_texture() : RID(); - RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); - u.append_id(texture); - uniforms.push_back(u); + } else { + vfog = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); } + u.append_id(vfog); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 20; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID ssil = rb_data.is_valid() ? rb->get_ssil_texture() : RID(); + RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); + uniforms.push_back(u); } return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, uniforms); @@ -2503,6 +2368,13 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { RD::Uniform u; u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(scene_state.implementation_uniform_buffers[0]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID instance_buffer = scene_state.instance_buffer[RENDER_LIST_SECONDARY]; if (instance_buffer == RID()) { @@ -2515,7 +2387,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te // No radiance texture. RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RD::Uniform u; - u.binding = 2; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.append_id(radiance_texture); uniforms.push_back(u); @@ -2525,7 +2397,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te // No reflection atlas. RID ref_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); RD::Uniform u; - u.binding = 3; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.append_id(ref_texture); uniforms.push_back(u); @@ -2534,7 +2406,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { // No shadow atlas. RD::Uniform u; - u.binding = 4; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); @@ -2544,7 +2416,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { // No directional shadow atlas. RD::Uniform u; - u.binding = 5; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH); u.append_id(texture); @@ -2554,7 +2426,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { // No Lightmaps RD::Uniform u; - u.binding = 6; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2568,7 +2440,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { // No VoxelGIs RD::Uniform u; - u.binding = 7; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2581,7 +2453,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { RD::Uniform u; - u.binding = 8; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = scene_shader.default_vec4_xform_buffer; u.append_id(cb); @@ -2593,28 +2465,28 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; + u.binding = 10; u.append_id(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 10; + u.binding = 11; u.append_id(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 11; + u.binding = 12; u.append_id(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 12; + u.binding = 13; u.append_id(p_geom_facing_texture); uniforms.push_back(u); } @@ -2925,6 +2797,7 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p ginstance->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET); } else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_PARTICLES; ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; @@ -3195,6 +3068,9 @@ RenderForwardClustered::~RenderForwardClustered() { for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) { RD::get_singleton()->free(scene_state.uniform_buffers[i]); } + for (uint32_t i = 0; i < scene_state.implementation_uniform_buffers.size(); i++) { + RD::get_singleton()->free(scene_state.implementation_uniform_buffers[i]); + } RD::get_singleton()->free(scene_state.lightmap_buffer); RD::get_singleton()->free(scene_state.lightmap_capture_buffer); for (uint32_t i = 0; i < RENDER_LIST_MAX; i++) { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 35379cd69b..cde241f231 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -37,7 +37,7 @@ #include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/utilities.h" #define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered") @@ -231,13 +231,14 @@ class RenderForwardClustered : public RendererSceneRenderRD { }; enum { - INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5, - INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6, - INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7, - INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, - INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, - INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, - INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11, + INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, + INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, + INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 6, + INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 7, + INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 8, + INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 9, + INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 10, + INSTANCE_DATA_FLAG_PARTICLES = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -249,61 +250,22 @@ class RenderForwardClustered : public RendererSceneRenderRD { }; struct SceneState { - // This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code + // This struct is loaded into Set 1 - Binding 1, populated at start of rendering a frame, must match with shader code struct UBO { - float projection_matrix[16]; - float inv_projection_matrix[16]; - float inv_view_matrix[16]; - float view_matrix[16]; - - float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; - float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; - float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4]; - - float viewport_size[2]; - float screen_pixel_size[2]; - uint32_t cluster_shift; uint32_t cluster_width; uint32_t cluster_type_size; uint32_t max_cluster_element_count_div_32; - float directional_penumbra_shadow_kernel[128]; //32 vec4s - float directional_soft_shadow_kernel[128]; - float penumbra_shadow_kernel[128]; - float soft_shadow_kernel[128]; - - float ambient_light_color_energy[4]; - - float ambient_color_sky_mix; - uint32_t use_ambient_light; - uint32_t use_ambient_cubemap; - uint32_t use_reflection_cubemap; - - float radiance_inverse_xform[12]; - - float shadow_atlas_pixel_size[2]; - float directional_shadow_pixel_size[2]; - - uint32_t directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; - uint32_t ss_effects_flags; float ssao_light_affect; float ssao_ao_affect; - uint32_t roughness_limiter_enabled; - - float roughness_limiter_amount; - float roughness_limiter_limit; - float opaque_prepass_threshold; - uint32_t roughness_limiter_pad; + uint32_t pad1; float sdf_to_bounds[16]; int32_t sdf_offset[3]; - uint32_t material_uv2_mode; + uint32_t pad2; int32_t sdf_size[3]; uint32_t gi_upscale_for_msaa; @@ -312,32 +274,13 @@ class RenderForwardClustered : public RendererSceneRenderRD { float volumetric_fog_inv_length; float volumetric_fog_detail_spread; uint32_t volumetric_fog_pad; - - // Fog - uint32_t fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; - - float fog_light_color[3]; - float fog_sun_scatter; - - float fog_aerial_perspective; - - float time; - float reflection_multiplier; - - uint32_t pancake_shadows; - - float taa_jitter[2]; - float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. - float IBL_exposure_normalization; }; struct PushConstant { uint32_t base_index; // uint32_t uv_offset; //packed - uint32_t pad[2]; + uint32_t multimesh_motion_vectors_current_offset; + uint32_t multimesh_motion_vectors_previous_offset; }; struct InstanceData { @@ -350,11 +293,10 @@ class RenderForwardClustered : public RendererSceneRenderRD { float lightmap_uv_scale[4]; }; - UBO ubo_data[2]; - UBO &ubo = ubo_data[0]; - UBO &prev_ubo = ubo_data[1]; + UBO ubo; LocalVector<RID> uniform_buffers; + LocalVector<RID> implementation_uniform_buffers; LightmapData lightmaps[MAX_LIGHTMAPS]; RID lightmap_ids[MAX_LIGHTMAPS]; @@ -429,7 +371,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _update_instance_data_buffer(RenderListType p_render_list); void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); - void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); + void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); HashMap<Size2i, RID> sdfgi_framebuffer_size_cache; @@ -622,7 +564,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index c2f56eb164..a9a9fa94de 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -32,7 +32,7 @@ #define SCENE_SHADER_FORWARD_CLUSTERED_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h" namespace RendererSceneRenderImplementation { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 46d90e75fb..6c1b69148c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -504,8 +504,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RENDER_TIMESTAMP("Setup 3D Scene"); - scene_state.ubo.directional_light_count = 0; - scene_state.ubo.opaque_prepass_threshold = 0.0; + /* TODO + // check if we need motion vectors + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) { + p_render_data->scene_data->calculate_motion_vectors = true; + } else if (render target has velocity override) { // TODO + p_render_data->scene_data->calculate_motion_vectors = true; + } else { + p_render_data->scene_data->calculate_motion_vectors = false; + } + */ + p_render_data->scene_data->calculate_motion_vectors = false; // for now, not yet supported... + + p_render_data->scene_data->directional_light_count = 0; + p_render_data->scene_data->opaque_prepass_threshold = 0.0; // We can only use our full subpass approach if we're: // - not reading from SCREEN_TEXTURE/DEPTH_TEXTURE @@ -581,13 +593,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color ERR_FAIL(); //bug? } - scene_state.ubo.viewport_size[0] = screen_size.x; - scene_state.ubo.viewport_size[1] = screen_size.y; - scene_state.ubo.emissive_exposure_normalization = -1.0; + p_render_data->scene_data->emissive_exposure_normalization = -1.0; RD::get_singleton()->draw_command_begin_label("Render Setup"); - _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->cam_transform); + _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform); _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) @@ -658,20 +668,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - Projection projection = p_render_data->cam_projection; + Projection projection = p_render_data->scene_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { Projection correction; correction.set_depth_correction(true); - projection = correction * p_render_data->cam_projection; + projection = correction * p_render_data->scene_data->cam_projection; } - sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this); sky_energy_multiplier *= bg_energy_multiplier; RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, sky_energy_multiplier); + sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -694,10 +704,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (p_render_data->reflection_probe.is_valid()) { Projection correction; correction.set_depth_correction(true); - Projection projection = correction * p_render_data->cam_projection; - sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); + Projection projection = correction * p_render_data->scene_data->cam_projection; + sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } else { - sky.update_res_buffers(p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); + sky.update_res_buffers(p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers @@ -719,7 +729,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; } - if (!is_environment(p_render_data->environment) || environment_get_fog_enabled(p_render_data->environment)) { + if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) { spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; } } @@ -734,7 +744,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Opaque Subpass"); - scene_state.ubo.directional_light_count = p_render_data->directional_light_count; + p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count; _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid()); @@ -765,7 +775,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -793,10 +803,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (p_render_data->reflection_probe.is_valid()) { Projection correction; correction.set_depth_correction(true); - Projection projection = correction * p_render_data->cam_projection; - sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); + Projection projection = correction * p_render_data->scene_data->cam_projection; + sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } else { - sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); + sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier); } RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass @@ -832,7 +842,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (using_subpass_transparent) { RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -871,7 +881,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color // _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -919,7 +929,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -928,26 +938,29 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size(); p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size(); } + + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_projection; + scene_data.cam_transform = p_transform; + scene_data.view_projection[0] = p_projection; + scene_data.z_near = 0.0; + scene_data.z_far = p_zfar; + scene_data.lod_camera_plane = p_camera_plane; + scene_data.lod_distance_multiplier = p_lod_distance_multiplier; + scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; + scene_data.opaque_prepass_threshold = 0.1; + RenderDataRD render_data; - render_data.cam_projection = p_projection; - render_data.cam_transform = p_transform; - render_data.view_projection[0] = p_projection; - render_data.z_near = 0.0; - render_data.z_far = p_zfar; + render_data.scene_data = &scene_data; render_data.instances = &p_instances; render_data.render_info = p_render_info; - render_data.lod_camera_plane = p_camera_plane; - render_data.lod_distance_multiplier = p_lod_distance_multiplier; - - scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - scene_state.ubo.opaque_prepass_threshold = 0.1; _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - render_data.screen_mesh_lod_threshold = 0.0; + scene_data.screen_mesh_lod_threshold = 0.0; } else { - render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; + scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; } PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; @@ -972,8 +985,8 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete shadow_pass.camera_plane = p_camera_plane; - shadow_pass.screen_mesh_lod_threshold = render_data.screen_mesh_lod_threshold; - shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier; + shadow_pass.screen_mesh_lod_threshold = scene_data.screen_mesh_lod_threshold; + shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier; shadow_pass.framebuffer = p_framebuffer; shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); @@ -1020,15 +1033,17 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.material_uv2_mode = false; - scene_state.ubo.opaque_prepass_threshold = 0.0f; - scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_cam_projection; + scene_data.cam_transform = p_cam_transform; + scene_data.view_projection[0] = p_cam_projection; + scene_data.dual_paraboloid_side = 0; + scene_data.material_uv2_mode = false; + scene_data.opaque_prepass_threshold = 0.0f; + scene_data.emissive_exposure_normalization = p_exposure_normalization; RenderDataRD render_data; - render_data.cam_projection = p_cam_projection; - render_data.cam_transform = p_cam_transform; - render_data.view_projection[0] = p_cam_projection; + render_data.scene_data = &scene_data; render_data.instances = &p_instances; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -1067,11 +1082,13 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.material_uv2_mode = true; - scene_state.ubo.emissive_exposure_normalization = -1.0; + RenderSceneDataRD scene_data; + scene_data.dual_paraboloid_side = 0; + scene_data.material_uv2_mode = true; + scene_data.emissive_exposure_normalization = -1.0; RenderDataRD render_data; + render_data.scene_data = &scene_data; render_data.instances = &p_instances; _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -1138,15 +1155,18 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); _update_render_base_uniform_set(); - scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.opaque_prepass_threshold = 0.0; + + RenderSceneDataRD scene_data; + scene_data.cam_projection = p_cam_projection; + scene_data.cam_transform = p_cam_transform; + scene_data.view_projection[0] = p_cam_projection; + scene_data.z_near = 0.0; + scene_data.z_far = p_cam_projection.get_z_far(); + scene_data.dual_paraboloid_side = 0; + scene_data.opaque_prepass_threshold = 0.0; RenderDataRD render_data; - render_data.cam_projection = p_cam_projection; - render_data.cam_transform = p_cam_transform; - render_data.view_projection[0] = p_cam_projection; - render_data.z_near = 0.0; - render_data.z_far = p_cam_projection.get_z_far(); + render_data.scene_data = &scene_data; render_data.instances = &p_instances; _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false); @@ -1385,9 +1405,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const } uint32_t lightmap_captures_used = 0; - Plane near_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin); - near_plane.d += p_render_data->cam_projection.get_z_near(); - float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near(); + Plane near_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin); + near_plane.d += p_render_data->scene_data->cam_projection.get_z_near(); + float z_max = p_render_data->scene_data->cam_projection.get_z_far() - p_render_data->scene_data->cam_projection.get_z_near(); RenderList *rl = &render_list[p_render_list]; @@ -1466,13 +1486,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const // LOD - if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { + if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal); - float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); - float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max); + float distance_min = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_min); + float distance_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max); float distance = 0.0; @@ -1485,12 +1505,12 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const distance = -distance_max; } - if (p_render_data->cam_orthogonal) { + if (p_render_data->scene_data->cam_orthogonal) { distance = 1.0; } uint32_t indices; - surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices); + surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices); if (p_render_data->render_info) { indices = _indices_to_primitives(surf->primitive, indices); if (p_render_list == RENDER_LIST_OPAQUE) { //opaque @@ -1562,184 +1582,20 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const } void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { - //!BAS! need to go through this and find out what we don't need anymore - - // This populates our UBO with main scene data that is pushed into set 1 - - //Projection projection = p_render_data->cam_projection; - //projection.flip_y(); // Vulkan and modern APIs use Y-Down - Projection correction; - correction.set_depth_correction(p_flip_y); - Projection projection = correction * p_render_data->cam_projection; - - //store camera into ubo - RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); - RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); - RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix); - - for (uint32_t v = 0; v < p_render_data->view_count; v++) { - projection = correction * p_render_data->view_projection[v]; - RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); - RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); - - scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x; - scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y; - scene_state.ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z; - scene_state.ubo.eye_offset[v][3] = 0.0; - } - - scene_state.ubo.z_far = p_render_data->z_far; - scene_state.ubo.z_near = p_render_data->z_near; - - scene_state.ubo.pancake_shadows = p_pancake_shadows; - - RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); - RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); - - Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); - scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; - scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y; - - if (p_render_data->shadow_atlas.is_valid()) { - Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas); - scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x; - scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y; - } - { - Vector2 dss = directional_shadow_get_size(); - scene_state.ubo.directional_shadow_pixel_size[0] = 1.0 / dss.x; - scene_state.ubo.directional_shadow_pixel_size[1] = 1.0 / dss.y; - } - - //time global variables - scene_state.ubo.time = time; - - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - scene_state.ubo.use_ambient_light = true; - scene_state.ubo.ambient_light_color_energy[0] = 1; - scene_state.ubo.ambient_light_color_energy[1] = 1; - scene_state.ubo.ambient_light_color_energy[2] = 1; - scene_state.ubo.ambient_light_color_energy[3] = 1.0; - scene_state.ubo.use_ambient_cubemap = false; - scene_state.ubo.use_reflection_cubemap = false; - scene_state.ubo.ssao_enabled = false; - - } else if (is_environment(p_render_data->environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); - RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - - float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); - - scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier; - - scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); - - //ambient - if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); - color = color.srgb_to_linear(); - - scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; - scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; - scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; - scene_state.ubo.use_ambient_light = true; - scene_state.ubo.use_ambient_cubemap = false; - } else { - float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light(p_render_data->environment); - color = color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; - scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; - scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - - Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); - sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; - RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); - - scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; - scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; - } - - //specular - RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); - if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { - scene_state.ubo.use_reflection_cubemap = true; - } else { - scene_state.ubo.use_reflection_cubemap = false; - } - - scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_get_ssao_enabled(p_render_data->environment); - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); - - scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); - scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); - scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); - scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); - scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - - Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); - float fog_energy = environment_get_fog_light_energy(p_render_data->environment); - - scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; - scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; - scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - - scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); - - } else { - if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { - scene_state.ubo.use_ambient_light = false; - } else { - scene_state.ubo.use_ambient_light = true; - Color clear_color = p_default_bg_color; - clear_color = clear_color.srgb_to_linear(); - scene_state.ubo.ambient_light_color_energy[0] = clear_color.r; - scene_state.ubo.ambient_light_color_energy[1] = clear_color.g; - scene_state.ubo.ambient_light_color_energy[2] = clear_color.b; - scene_state.ubo.ambient_light_color_energy[3] = 1.0; - } - - scene_state.ubo.use_ambient_cubemap = false; - scene_state.ubo.use_reflection_cubemap = false; - scene_state.ubo.ssao_enabled = false; - } - - if (p_render_data->camera_attributes.is_valid()) { - scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); - scene_state.ubo.IBL_exposure_normalization = 1.0; - if (is_environment(p_render_data->environment)) { - RID sky_rid = environment_get_sky(p_render_data->environment); - if (sky_rid.is_valid()) { - float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment) / _render_buffers_get_luminance_multiplier(); - scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky.sky_get_baked_exposure(sky_rid)); - } - } - } else if (scene_state.ubo.emissive_exposure_normalization > 0.0) { - // This branch is triggered when using render_material(). - // Emissive is set outside the function, so don't set it. - // IBL isn't used don't set it. - } else { - scene_state.ubo.emissive_exposure_normalization = 1.0; - scene_state.ubo.IBL_exposure_normalization = 1.0; - } - - scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active(); - scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount(); - scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit(); + Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers; + RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID(); + RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID(); + // May do this earlier in RenderSceneRenderRD::render_scene if (p_index >= (int)scene_state.uniform_buffers.size()) { uint32_t from = scene_state.uniform_buffers.size(); scene_state.uniform_buffers.resize(p_index + 1); - render_pass_uniform_sets.resize(p_index + 1); for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { - scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); + scene_state.uniform_buffers[i] = p_render_data->scene_data->create_uniform_buffer(); } } - RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER); + + p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers); } void RenderForwardMobile::_fill_element_info(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements) { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index da1cd85fb3..1b31d2749d 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -209,7 +209,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; @@ -252,75 +252,6 @@ protected: /* Scene state */ struct SceneState { - // This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code - struct UBO { - float projection_matrix[16]; - float inv_projection_matrix[16]; - float inv_view_matrix[16]; - float view_matrix[16]; - - float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; - float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; - float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4]; - - float viewport_size[2]; - float screen_pixel_size[2]; - - float directional_penumbra_shadow_kernel[128]; //32 vec4s - float directional_soft_shadow_kernel[128]; - float penumbra_shadow_kernel[128]; - float soft_shadow_kernel[128]; - - float ambient_light_color_energy[4]; - - float ambient_color_sky_mix; - uint32_t use_ambient_light; - uint32_t use_ambient_cubemap; - uint32_t use_reflection_cubemap; - - float radiance_inverse_xform[12]; - - float shadow_atlas_pixel_size[2]; - float directional_shadow_pixel_size[2]; - - uint32_t directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; - - uint32_t ssao_enabled; - float ssao_light_affect; - float ssao_ao_affect; - uint32_t roughness_limiter_enabled; - - float roughness_limiter_amount; - float roughness_limiter_limit; - float opaque_prepass_threshold; - uint32_t roughness_limiter_pad; - - // Fog - uint32_t fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; - - float fog_light_color[3]; - float fog_sun_scatter; - - float fog_aerial_perspective; - uint32_t material_uv2_mode; - - float time; - float reflection_multiplier; - - uint32_t pancake_shadows; - float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. - float IBL_exposure_normalization; // Adjusts for baked exposure. - uint32_t pad3; - }; - - UBO ubo; - LocalVector<RID> uniform_buffers; // !BAS! We need to change lightmaps, we're not going to do this with a buffer but pushing the used lightmap in @@ -442,13 +373,14 @@ protected: // check which ones of these apply, probably all except GI and SDFGI enum { - INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5, - INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6, - INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7, - INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, - INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, - INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, - INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11, + INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4, + INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5, + INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 6, + INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 7, + INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 8, + INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 9, + INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 10, + INSTANCE_DATA_FLAG_PARTICLES = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 21270d7c62..f67665a02f 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -32,7 +32,7 @@ #define SCENE_SHADER_FORWARD_MOBILE_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" -#include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl.gen.h" namespace RendererSceneRenderImplementation { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index ab3e3ebe51..0210151420 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1362,9 +1362,12 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p default_repeat = p_default_repeat; } - //fill the list until rendering is possible. - bool material_screen_texture_found = false; Item *ci = p_item_list; + + //fill the list until rendering is possible. + bool material_screen_texture_cached = false; + bool material_screen_texture_mipmaps_cached = false; + Rect2 back_buffer_rect; bool backbuffer_copy = false; bool backbuffer_gen_mipmaps = false; @@ -1393,10 +1396,12 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p CanvasMaterialData *md = static_cast<CanvasMaterialData *>(material_storage->material_get_data(material, RendererRD::MaterialStorage::SHADER_TYPE_2D)); if (md && md->shader_data->valid) { if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) { - if (!material_screen_texture_found) { + if (!material_screen_texture_cached) { backbuffer_copy = true; back_buffer_rect = Rect2(); backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps; + } else if (!material_screen_texture_mipmaps_cached) { + backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps; } } @@ -1486,7 +1491,15 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p backbuffer_copy = false; backbuffer_gen_mipmaps = false; - material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies + material_screen_texture_cached = true; // After a backbuffer copy, screen texture makes no further copies. + material_screen_texture_mipmaps_cached = backbuffer_gen_mipmaps; + } + + if (backbuffer_gen_mipmaps) { + texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, back_buffer_rect); + + backbuffer_gen_mipmaps = false; + material_screen_texture_mipmaps_cached = true; } items[item_count++] = ci; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index e7abcf5674..f169692ea0 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -299,14 +299,19 @@ RendererCompositorRD::RendererCompositorRD() { fog = memnew(RendererRD::Fog); canvas = memnew(RendererCanvasRenderRD()); - back_end = (bool)(int)GLOBAL_GET("rendering/vulkan/rendering/back_end"); + String rendering_method = GLOBAL_GET("rendering/renderer/rendering_method"); uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); - if (back_end || textures_per_stage < 48) { + if (rendering_method == "mobile" || textures_per_stage < 48) { scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile()); - } else { // back_end == false + if (rendering_method == "forward_plus") { + WARN_PRINT_ONCE("Platform supports less than 48 textures per stage which is less than required by the Clustered renderer. Defaulting to Mobile renderer."); + } + } else if (rendering_method == "forward_plus") { // default to our high end renderer scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered()); + } else { + ERR_FAIL_MSG("Cannot instantiate RenderingDevice-based renderer with renderer type " + rendering_method); } scene->init(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index e2b06bc92f..ac1daad05c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1492,7 +1492,7 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR bool can_use_storage = _render_buffers_can_be_storage(); Size2i size = rb->get_internal_size(); - for (uint32_t v = 0; v < p_render_data->view_count; v++) { + for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) { RID depth_texture = rb->get_depth_texture(v); RID depth_back_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, v, 0); @@ -1544,9 +1544,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende buffers.depth_texture = rb->get_depth_texture(i); // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum - float z_near = p_render_data->view_projection[i].get_z_near(); - float z_far = p_render_data->view_projection[i].get_z_far(); - bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal); + float z_near = p_render_data->scene_data->view_projection[i].get_z_near(); + float z_far = p_render_data->scene_data->view_projection[i].get_z_far(); + bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal); }; } else { // Set framebuffers. @@ -1567,9 +1567,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum - float z_near = p_render_data->view_projection[i].get_z_near(); - float z_far = p_render_data->view_projection[i].get_z_far(); - bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal); + float z_near = p_render_data->scene_data->view_projection[i].get_z_near(); + float z_far = p_render_data->scene_data->view_projection[i].get_z_far(); + bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal); } } RD::get_singleton()->draw_command_end_label(); @@ -2901,8 +2901,8 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool render_state.shadows.clear(); render_state.directional_shadows.clear(); - Plane camera_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin); - float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); + Plane camera_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin); + float lod_distance_multiplier = p_render_data->scene_data->cam_projection.get_lod_multiplier(); { for (int i = 0; i < render_state.render_shadow_count; i++) { LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light); @@ -2918,7 +2918,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //cube shadows are rendered in their own way for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info); + _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info); } if (render_state.directional_shadows.size()) { @@ -2948,11 +2948,11 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //render directional shadows for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info); + _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info); } //render positional shadows for (uint32_t i = 0; i < render_state.shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info); + _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info); } _render_shadow_process(); @@ -2960,7 +2960,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //start GI if (render_gi) { - gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances); + gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances); } //Do shadow rendering (in parallel with GI) @@ -2999,17 +2999,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } RID depth_texture = rb->get_depth_texture(); - ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->cam_projection); + ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->scene_data->cam_projection); } if (p_use_ssao) { // TODO make these proper stereo - _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection); + _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection); } if (p_use_ssil) { // TODO make these proper stereo - _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection, p_render_data->cam_transform); + _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform); } } @@ -3017,7 +3017,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); if (current_cluster_builder) { - current_cluster_builder->begin(p_render_data->cam_transform, p_render_data->cam_projection, !p_render_data->reflection_probe.is_valid()); + current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid()); } bool using_shadows = true; @@ -3028,13 +3028,13 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } else { //do not render reflections when rendering a reflection probe - _setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->cam_transform.affine_inverse(), p_render_data->environment); + _setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment); } uint32_t directional_light_count = 0; uint32_t positional_light_count = 0; - _setup_lights(p_render_data, *p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows); - _setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse()); + _setup_lights(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows); + _setup_decals(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse()); p_render_data->directional_light_count = directional_light_count; @@ -3051,12 +3051,12 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } if (is_volumetric_supported()) { - _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes); + _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes); } } } -void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { +void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); // getting this here now so we can direct call a bunch of things more easily @@ -3066,33 +3066,62 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render ERR_FAIL_COND(rb.is_null()); } - //assign render data - RenderDataRD render_data; + // setup scene data + RenderSceneDataRD scene_data; { - render_data.render_buffers = rb; - // Our first camera is used by default - render_data.cam_transform = p_camera_data->main_transform; - render_data.cam_projection = p_camera_data->main_projection; - render_data.cam_orthogonal = p_camera_data->is_orthogonal; - render_data.taa_jitter = p_camera_data->taa_jitter; + scene_data.cam_transform = p_camera_data->main_transform; + scene_data.cam_projection = p_camera_data->main_projection; + scene_data.cam_orthogonal = p_camera_data->is_orthogonal; + scene_data.taa_jitter = p_camera_data->taa_jitter; - render_data.view_count = p_camera_data->view_count; + scene_data.view_count = p_camera_data->view_count; for (uint32_t v = 0; v < p_camera_data->view_count; v++) { - render_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin; - render_data.view_projection[v] = p_camera_data->view_projection[v]; + scene_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin; + scene_data.view_projection[v] = p_camera_data->view_projection[v]; } - render_data.prev_cam_transform = p_prev_camera_data->main_transform; - render_data.prev_cam_projection = p_prev_camera_data->main_projection; - render_data.prev_taa_jitter = p_prev_camera_data->taa_jitter; + scene_data.prev_cam_transform = p_prev_camera_data->main_transform; + scene_data.prev_cam_projection = p_prev_camera_data->main_projection; + scene_data.prev_taa_jitter = p_prev_camera_data->taa_jitter; for (uint32_t v = 0; v < p_camera_data->view_count; v++) { - render_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v]; + scene_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v]; + } + + scene_data.z_near = p_camera_data->main_projection.get_z_near(); + scene_data.z_far = p_camera_data->main_projection.get_z_far(); + + // this should be the same for all cameras.. + scene_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier(); + scene_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin()); + + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { + scene_data.screen_mesh_lod_threshold = 0.0; + } else { + scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; + } + + if (p_shadow_atlas.is_valid()) { + Vector2 sas = shadow_atlas_get_size(p_shadow_atlas); + scene_data.shadow_atlas_pixel_size.x = 1.0 / sas.x; + scene_data.shadow_atlas_pixel_size.y = 1.0 / sas.y; } + { + Vector2 dss = directional_shadow_get_size(); + scene_data.directional_shadow_pixel_size.x = 1.0 / dss.x; + scene_data.directional_shadow_pixel_size.y = 1.0 / dss.y; + } + + scene_data.time = time; + scene_data.time_step = time_step; + } - render_data.z_near = p_camera_data->main_projection.get_z_near(); - render_data.z_far = p_camera_data->main_projection.get_z_far(); + //assign render data + RenderDataRD render_data; + { + render_data.render_buffers = rb; + render_data.scene_data = &scene_data; render_data.instances = &p_instances; render_data.lights = &p_lights; @@ -3108,16 +3137,6 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render render_data.reflection_probe = p_reflection_probe; render_data.reflection_probe_pass = p_reflection_probe_pass; - // this should be the same for all cameras.. - render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier(); - render_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin()); - - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - render_data.screen_mesh_lod_threshold = 0.0; - } else { - render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; - } - render_state.render_shadows = p_render_shadows; render_state.render_shadow_count = p_render_shadow_count; render_state.render_sdfgi_regions = p_render_sdfgi_regions; @@ -3134,7 +3153,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render render_data.voxel_gi_instances = ∅ } - //sdfgi first + // sdfgi first if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); float exposure_normalization = 1.0; @@ -3191,12 +3210,12 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); if (sdfgi.is_valid()) { sdfgi->update_cascades(); - sdfgi->pre_process_gi(render_data.cam_transform, &render_data, this); + sdfgi->pre_process_gi(scene_data.cam_transform, &render_data, this); sdfgi->update_light(); } } - gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, render_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this); + gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, scene_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this); } render_state.depth_prepass_used = false; @@ -3246,7 +3265,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render view_rids.push_back(rb->get_internal_texture(v)); } - sdfgi->debug_draw(render_data.view_count, render_data.view_projection, render_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids); + sdfgi->debug_draw(scene_data.view_count, scene_data.view_projection, scene_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids); } } } @@ -3278,12 +3297,12 @@ void RendererSceneRenderRD::_debug_draw_cluster(Ref<RenderSceneBuffersRD> p_rend } } -void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; - uint32_t atlas_size; + uint32_t atlas_size = 1; RID atlas_fb; bool using_dual_paraboloid = false; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index d47394989f..82dc2fd09f 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -46,30 +46,14 @@ #include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_rd/framebuffer_cache_rd.h" #include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h" -#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/rendering_method.h" struct RenderDataRD { Ref<RenderSceneBuffersRD> render_buffers; - - Transform3D cam_transform; - Projection cam_projection; - Vector2 taa_jitter; - bool cam_orthogonal = false; - - // For stereo rendering - uint32_t view_count = 1; - Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; - - Transform3D prev_cam_transform; - Projection prev_cam_projection; - Vector2 prev_taa_jitter; - Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; - - float z_near = 0.0; - float z_far = 0.0; + RenderSceneDataRD *scene_data; const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; @@ -85,10 +69,6 @@ struct RenderDataRD { RID reflection_probe; int reflection_probe_pass = 0; - float lod_distance_multiplier = 0.0; - Plane lod_camera_plane; - float screen_mesh_lod_threshold = 0.0; - RID cluster_buffer; uint32_t cluster_size = 0; uint32_t cluster_max_elements = 0; @@ -96,7 +76,7 @@ struct RenderDataRD { uint32_t directional_light_count = 0; bool directional_light_soft_shadows = false; - RendererScene::RenderInfo *render_info = nullptr; + RenderingMethod::RenderInfo *render_info = nullptr; }; class RendererSceneRenderRD : public RendererSceneRender { @@ -121,7 +101,7 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; @@ -598,16 +578,9 @@ private: uint64_t scene_pass = 0; uint64_t shadow_atlas_realloc_tolerance_msec = 500; - /* !BAS! is this used anywhere? - struct SDFGICosineNeighbour { - uint32_t neighbour; - float weight; - }; - */ - uint32_t max_cluster_elements = 512; - void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr); /* Volumetric Fog */ @@ -627,6 +600,10 @@ public: RendererRD::GI *get_gi() { return &gi; } + /* SKY */ + + RendererRD::SkyRD *get_sky() { return &sky; } + /* SHADOW ATLAS API */ virtual RID shadow_atlas_create() override; @@ -969,7 +946,7 @@ public: virtual void update_uniform_sets(){}; - virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; + virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override; virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index d352743908..5405985741 100644 --- a/servers/rendering/renderer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub @@ -18,3 +18,5 @@ if "RD_GLSL" in env["BUILDERS"]: SConscript("effects/SCsub") SConscript("environment/SCsub") +SConscript("forward_clustered/SCsub") +SConscript("forward_mobile/SCsub") diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 459d798a80..a3734a7218 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -597,7 +597,7 @@ void main() { #ifdef MODE_LIGHT_ONLY color = vec4(0.0); -#else +#elif !defined(MODE_UNSHADED) color *= canvas_data.canvas_modulation; #endif diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/SCsub +++ b/servers/rendering/renderer_rd/shaders/effects/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl index bdf84bb03a..fe770ac065 100644 --- a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl @@ -186,6 +186,7 @@ void main() { uv += pixel_size * 0.5; //half pixel to read centers vec4 color = texture(color_texture, uv); + float initial_blur = color.a; float accum = 1.0; float radius = params.blur_scale; @@ -193,8 +194,8 @@ void main() { vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; vec4 sample_color = texture(color_texture, suv); float sample_size = abs(sample_color.a); - if (sample_color.a > color.a) { - sample_size = clamp(sample_size, 0.0, abs(color.a) * 2.0); + if (sample_color.a > initial_blur) { + sample_size = clamp(sample_size, 0.0, abs(initial_blur) * 2.0); } float m = smoothstep(radius - 0.5, radius + 0.5, sample_size); diff --git a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl index a2bdc2e90e..1b487835d2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl @@ -221,12 +221,9 @@ void main() { vec4 sample_color = texture(source_color, uv_adj); sample_color.a = texture(source_weight, uv_adj).r; - float limit; - - if (sample_color.a < color.a) { - limit = abs(sample_color.a); - } else { - limit = abs(color.a); + float limit = abs(sample_color.a); + if (sample_color.a > color.a) { + limit = clamp(limit, 0.0, abs(color.a) * 2.0); } limit -= DEPTH_GAP; diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/environment/SCsub +++ b/servers/rendering/renderer_rd/shaders/environment/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub new file mode 100644 index 0000000000..f06a2d86e2 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +Import("env") + +if "RD_GLSL" in env["BUILDERS"]: + # find all include files + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] + + # find all shader code(all glsl files excluding our include files) + glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] + + # make sure we recompile shaders if include files change + env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"]) + + # compile shaders + for glsl_file in glsl_files: + env.RD_GLSL(glsl_file) diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 26b96b358f..d41474118d 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -129,7 +129,7 @@ invariant gl_Position; #GLOBALS -void vertex_shader(in uint instance_index, in bool is_multimesh, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { +void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; @@ -208,7 +208,7 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in SceneData sc } } - uint offset = stride * gl_InstanceIndex; + uint offset = stride * (gl_InstanceIndex + multimesh_offset); if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); @@ -326,10 +326,6 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in SceneData sc vertex_interp = vertex; -#ifdef MOTION_VECTORS - screen_pos = projection_matrix * vec4(vertex_interp, 1.0); -#endif - #ifdef NORMAL_USED normal_interp = normal; #endif @@ -367,6 +363,10 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in SceneData sc gl_Position = projection_matrix * vec4(vertex_interp, 1.0); #endif +#ifdef MOTION_VECTORS + screen_pos = gl_Position; +#endif + #ifdef MODE_RENDER_DEPTH if (scene_data.pancake_shadows) { if (gl_Position.z <= 0.00001) { @@ -397,13 +397,13 @@ void main() { mat4 model_matrix = instances.data[instance_index].transform; #if defined(MOTION_VECTORS) global_time = scene_data_block.prev_data.time; - vertex_shader(instance_index, is_multimesh, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); + vertex_shader(instance_index, is_multimesh, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); global_time = scene_data_block.data.time; - vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position); + vertex_shader(instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); #else global_time = scene_data_block.data.time; vec4 screen_position; - vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position); + vertex_shader(instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); #endif } @@ -553,7 +553,7 @@ layout(location = 0) out vec4 frag_color; layout(location = 2) out vec2 motion_vector; #endif -#include "scene_forward_aa_inc.glsl" +#include "../scene_forward_aa_inc.glsl" #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) @@ -562,20 +562,20 @@ layout(location = 2) out vec2 motion_vector; #define SPECULAR_SCHLICK_GGX #endif -#include "scene_forward_lights_inc.glsl" +#include "../scene_forward_lights_inc.glsl" -#include "scene_forward_gi_inc.glsl" +#include "../scene_forward_gi_inc.glsl" #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #ifndef MODE_RENDER_DEPTH vec4 volumetric_fog_process(vec2 screen_uv, float z) { - vec3 fog_pos = vec3(screen_uv, z * scene_data_block.data.volumetric_fog_inv_length); + vec3 fog_pos = vec3(screen_uv, z * implementation_data.volumetric_fog_inv_length); if (fog_pos.z < 0.0) { return vec4(0.0); } else if (fog_pos.z < 1.0) { - fog_pos.z = pow(fog_pos.z, scene_data_block.data.volumetric_fog_detail_spread); + fog_pos.z = pow(fog_pos.z, implementation_data.volumetric_fog_detail_spread); } return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos); @@ -821,7 +821,7 @@ void fragment_shader(in SceneData scene_data) { fog = fog_process(vertex); } - if (scene_data.volumetric_fog_enabled) { + if (implementation_data.volumetric_fog_enabled) { vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z); if (scene_data.fog_enabled) { //must use the full blending equation here to blend fogs @@ -849,8 +849,8 @@ void fragment_shader(in SceneData scene_data) { #ifndef MODE_RENDER_DEPTH - uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> scene_data.cluster_shift; - uint cluster_offset = (scene_data.cluster_width * cluster_pos.y + cluster_pos.x) * (scene_data.max_cluster_element_count_div_32 + 32); + uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> implementation_data.cluster_shift; + uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32); uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0)); @@ -860,14 +860,14 @@ void fragment_shader(in SceneData scene_data) { { // process decals - uint cluster_decal_offset = cluster_offset + scene_data.cluster_type_size * 2; + uint cluster_decal_offset = cluster_offset + implementation_data.cluster_type_size * 2; uint item_min; uint item_max; uint item_from; uint item_to; - cluster_get_item_range(cluster_decal_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_decal_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS item_from = subgroupBroadcastFirst(subgroupMin(item_from)); @@ -1256,7 +1256,7 @@ void fragment_shader(in SceneData scene_data) { vec2 coord; - if (scene_data.gi_upscale_for_msaa) { + if (implementation_data.gi_upscale_for_msaa) { vec2 base_coord = screen_uv; vec2 closest_coord = base_coord; #ifdef USE_MULTIVIEW @@ -1298,10 +1298,10 @@ void fragment_shader(in SceneData scene_data) { } #endif // !USE_LIGHTMAP - if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) { + if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) { float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; ao = min(ao, ssao); - ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect); + ao_light_affect = mix(ao_light_affect, max(ao_light_affect, implementation_data.ssao_light_affect), implementation_data.ssao_ao_affect); } { // process reflections @@ -1309,14 +1309,14 @@ void fragment_shader(in SceneData scene_data) { vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); - uint cluster_reflection_offset = cluster_offset + scene_data.cluster_type_size * 3; + uint cluster_reflection_offset = cluster_offset + implementation_data.cluster_type_size * 3; uint item_min; uint item_max; uint item_from; uint item_to; - cluster_get_item_range(cluster_reflection_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_reflection_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS item_from = subgroupBroadcastFirst(subgroupMin(item_from)); @@ -1380,7 +1380,7 @@ void fragment_shader(in SceneData scene_data) { // convert ao to direct light ao ao = mix(1.0, ao, ao_light_affect); - if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { + if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); ambient_light *= 1.0 - ssil.a; ambient_light += ssil.rgb * albedo.rgb; @@ -1748,7 +1748,7 @@ void fragment_shader(in SceneData scene_data) { uint item_from; uint item_to; - cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_omni_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS item_from = subgroupBroadcastFirst(subgroupMin(item_from)); @@ -1812,14 +1812,14 @@ void fragment_shader(in SceneData scene_data) { { //spot lights - uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size; + uint cluster_spot_offset = cluster_offset + implementation_data.cluster_type_size; uint item_min; uint item_max; uint item_from; uint item_to; - cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_spot_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS item_from = subgroupBroadcastFirst(subgroupMin(item_from)); @@ -1909,8 +1909,8 @@ void fragment_shader(in SceneData scene_data) { #ifdef MODE_RENDER_SDF { - vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; - ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); + vec3 local_pos = (implementation_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; + ivec3 grid_pos = implementation_data.sdf_offset + ivec3(local_pos * vec3(implementation_data.sdf_size)); uint albedo16 = 0x1; //solid flag albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index 45484b8c47..e8e2dce990 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -17,8 +17,9 @@ #extension GL_EXT_multiview : enable #endif -#include "cluster_data_inc.glsl" -#include "decal_data_inc.glsl" +#include "../cluster_data_inc.glsl" +#include "../decal_data_inc.glsl" +#include "../scene_data_inc.glsl" #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED @@ -29,8 +30,8 @@ layout(push_constant, std430) uniform DrawCall { uint instance_index; uint uv_offset; - uint pad0; - uint pad1; + uint multimesh_motion_vectors_current_offset; + uint multimesh_motion_vectors_previous_offset; } draw_call; @@ -38,7 +39,7 @@ draw_call; /* Set 0: Base Pass (never changes) */ -#include "light_data_inc.glsl" +#include "../light_data_inc.glsl" #define SAMPLER_NEAREST_CLAMP 0 #define SAMPLER_LINEAR_CLAMP 1 @@ -175,62 +176,27 @@ sdfgi; /* Set 1: Render Pass (changes per render pass) */ -struct SceneData { - mat4 projection_matrix; - mat4 inv_projection_matrix; - mat4 inv_view_matrix; - mat4 view_matrix; - - // only used for multiview - mat4 projection_matrix_view[MAX_VIEWS]; - mat4 inv_projection_matrix_view[MAX_VIEWS]; - vec4 eye_offset[MAX_VIEWS]; - - vec2 viewport_size; - vec2 screen_pixel_size; +layout(set = 1, binding = 0, std140) uniform SceneDataBlock { + SceneData data; + SceneData prev_data; +} +scene_data_block; +struct ImplementationData { uint cluster_shift; uint cluster_width; uint cluster_type_size; uint max_cluster_element_count_div_32; - // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. - vec4 directional_penumbra_shadow_kernel[32]; - vec4 directional_soft_shadow_kernel[32]; - vec4 penumbra_shadow_kernel[32]; - vec4 soft_shadow_kernel[32]; - - vec4 ambient_light_color_energy; - - float ambient_color_sky_mix; - bool use_ambient_light; - bool use_ambient_cubemap; - bool use_reflection_cubemap; - - mat3 radiance_inverse_xform; - - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; - - uint directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; - uint ss_effects_flags; float ssao_light_affect; float ssao_ao_affect; - bool roughness_limiter_enabled; - - float roughness_limiter_amount; - float roughness_limiter_limit; - float opaque_prepass_threshold; - uint roughness_limiter_pad; + uint pad1; mat4 sdf_to_bounds; ivec3 sdf_offset; - bool material_uv2_mode; + uint pad2; ivec3 sdf_size; bool gi_upscale_for_msaa; @@ -239,31 +205,14 @@ struct SceneData { float volumetric_fog_inv_length; float volumetric_fog_detail_spread; uint volumetric_fog_pad; - - bool fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; - - vec3 fog_light_color; - float fog_sun_scatter; - - float fog_aerial_perspective; - - float time; - float reflection_multiplier; // one normally, zero when rendering reflections - - bool pancake_shadows; - vec2 taa_jitter; - float emissive_exposure_normalization; - float IBL_exposure_normalization; }; -layout(set = 1, binding = 0, std140) uniform SceneDataBlock { - SceneData data; - SceneData prev_data; +layout(set = 1, binding = 1, std140) uniform ImplementationDataBlock { + ImplementationData data; } -scene_data_block; +implementation_data_block; + +#define implementation_data implementation_data_block.data struct InstanceData { mat4 transform; @@ -275,42 +224,42 @@ struct InstanceData { vec4 lightmap_uv_scale; }; -layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer { +layout(set = 1, binding = 2, std430) buffer restrict readonly InstanceDataBuffer { InstanceData data[]; } instances; #ifdef USE_RADIANCE_CUBEMAP_ARRAY -layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; +layout(set = 1, binding = 3) uniform textureCubeArray radiance_cubemap; #else -layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; +layout(set = 1, binding = 3) uniform textureCube radiance_cubemap; #endif -layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; +layout(set = 1, binding = 4) uniform textureCubeArray reflection_atlas; -layout(set = 1, binding = 4) uniform texture2D shadow_atlas; +layout(set = 1, binding = 5) uniform texture2D shadow_atlas; -layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; +layout(set = 1, binding = 6) uniform texture2D directional_shadow_atlas; -layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +layout(set = 1, binding = 7) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -layout(set = 1, binding = 7) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; +layout(set = 1, binding = 8) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; -layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer { +layout(set = 1, binding = 9, std430) buffer restrict readonly ClusterBuffer { uint data[]; } cluster_buffer; #ifdef MODE_RENDER_SDF -layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid; -layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid; -layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid; -layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; +layout(r16ui, set = 1, binding = 10) uniform restrict writeonly uimage3D albedo_volume_grid; +layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_grid; +layout(r32ui, set = 1, binding = 12) uniform restrict writeonly uimage3D emission_aniso_grid; +layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid; //still need to be present for shaders that use it, so remap them to something #define depth_buffer shadow_atlas @@ -319,21 +268,21 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; #else -layout(set = 1, binding = 9) uniform texture2D depth_buffer; -layout(set = 1, binding = 10) uniform texture2D color_buffer; +layout(set = 1, binding = 10) uniform texture2D depth_buffer; +layout(set = 1, binding = 11) uniform texture2D color_buffer; #ifdef USE_MULTIVIEW -layout(set = 1, binding = 11) uniform texture2DArray normal_roughness_buffer; -layout(set = 1, binding = 13) uniform texture2DArray ambient_buffer; -layout(set = 1, binding = 14) uniform texture2DArray reflection_buffer; +layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer; +layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer; +layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer; #else // USE_MULTIVIEW -layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 13) uniform texture2D ambient_buffer; -layout(set = 1, binding = 14) uniform texture2D reflection_buffer; +layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer; +layout(set = 1, binding = 14) uniform texture2D ambient_buffer; +layout(set = 1, binding = 15) uniform texture2D reflection_buffer; #endif -layout(set = 1, binding = 12) uniform texture2D ao_buffer; -layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; -layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; +layout(set = 1, binding = 13) uniform texture2D ao_buffer; +layout(set = 1, binding = 16) uniform texture2DArray sdfgi_lightprobe_texture; +layout(set = 1, binding = 17) uniform texture3D sdfgi_occlusion_cascades; struct VoxelGIData { mat4 xform; // 64 - 64 @@ -350,14 +299,14 @@ struct VoxelGIData { float exposure_normalization; // 4 - 112 }; -layout(set = 1, binding = 17, std140) uniform VoxelGIs { +layout(set = 1, binding = 18, std140) uniform VoxelGIs { VoxelGIData data[MAX_VOXEL_GI_INSTANCES]; } voxel_gi_instances; -layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture; +layout(set = 1, binding = 19) uniform texture3D volumetric_fog_texture; -layout(set = 1, binding = 19) uniform texture2D ssil_buffer; +layout(set = 1, binding = 20) uniform texture2D ssil_buffer; #endif diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub new file mode 100644 index 0000000000..f06a2d86e2 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +Import("env") + +if "RD_GLSL" in env["BUILDERS"]: + # find all include files + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] + + # find all shader code(all glsl files excluding our include files) + glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] + + # make sure we recompile shaders if include files change + env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"]) + + # compile shaders + for glsl_file in glsl_files: + env.RD_GLSL(glsl_file) diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 5a5ada7231..a109fd4d75 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -101,7 +101,7 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms #ifdef MODE_DUAL_PARABOLOID -layout(location = 8) out highp float dp_clip; +layout(location = 9) out highp float dp_clip; #endif @@ -450,7 +450,7 @@ layout(location = 6) mediump in vec3 binormal_interp; #ifdef MODE_DUAL_PARABOLOID -layout(location = 8) highp in float dp_clip; +layout(location = 9) highp in float dp_clip; #endif @@ -519,7 +519,7 @@ layout(location = 0) out mediump vec4 frag_color; #endif // RENDER DEPTH -#include "scene_forward_aa_inc.glsl" +#include "../scene_forward_aa_inc.glsl" #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) @@ -528,7 +528,7 @@ layout(location = 0) out mediump vec4 frag_color; #define SPECULAR_SCHLICK_GGX #endif -#include "scene_forward_lights_inc.glsl" +#include "../scene_forward_lights_inc.glsl" #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 3a9c52f5bc..5e4999fa0f 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -5,7 +5,8 @@ #extension GL_EXT_multiview : enable #endif -#include "decal_data_inc.glsl" +#include "../decal_data_inc.glsl" +#include "../scene_data_inc.glsl" #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED @@ -32,7 +33,7 @@ draw_call; /* Set 0: Base Pass (never changes) */ -#include "light_data_inc.glsl" +#include "../light_data_inc.glsl" #define SAMPLER_NEAREST_CLAMP 0 #define SAMPLER_LINEAR_CLAMP 1 @@ -127,75 +128,9 @@ global_shader_uniforms; /* Set 1: Render Pass (changes per render pass) */ -struct SceneData { - highp mat4 projection_matrix; - highp mat4 inv_projection_matrix; - highp mat4 inv_view_matrix; - highp mat4 view_matrix; - - // only used for multiview - highp mat4 projection_matrix_view[MAX_VIEWS]; - highp mat4 inv_projection_matrix_view[MAX_VIEWS]; - highp vec4 eye_offset[MAX_VIEWS]; - - highp vec2 viewport_size; - highp vec2 screen_pixel_size; - - // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. - highp vec4 directional_penumbra_shadow_kernel[32]; - highp vec4 directional_soft_shadow_kernel[32]; - highp vec4 penumbra_shadow_kernel[32]; - highp vec4 soft_shadow_kernel[32]; - - mediump vec4 ambient_light_color_energy; - - mediump float ambient_color_sky_mix; - bool use_ambient_light; - bool use_ambient_cubemap; - bool use_reflection_cubemap; - - mediump mat3 radiance_inverse_xform; - - highp vec2 shadow_atlas_pixel_size; - highp vec2 directional_shadow_pixel_size; - - uint directional_light_count; - mediump float dual_paraboloid_side; - highp float z_far; - highp float z_near; - - bool ssao_enabled; - mediump float ssao_light_affect; - mediump float ssao_ao_affect; - bool roughness_limiter_enabled; - - mediump float roughness_limiter_amount; - mediump float roughness_limiter_limit; - mediump float opaque_prepass_threshold; - uint roughness_limiter_pad; - - bool fog_enabled; - highp float fog_density; - highp float fog_height; - highp float fog_height_density; - - mediump vec3 fog_light_color; - mediump float fog_sun_scatter; - - mediump float fog_aerial_perspective; - bool material_uv2_mode; - - highp float time; - mediump float reflection_multiplier; // one normally, zero when rendering reflections - - bool pancake_shadows; - float emissive_exposure_normalization; - float IBL_exposure_normalization; - uint pad3; -}; - layout(set = 1, binding = 0, std140) uniform SceneDataBlock { SceneData data; + SceneData prev_data; } scene_data_block; diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl new file mode 100644 index 0000000000..048257e9ef --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl @@ -0,0 +1,69 @@ +// Scene data stores all our 3D rendering globals for a frame such as our matrices +// where this information is independent of the different RD implementations. +// This enables us to use this UBO in our main scene render shaders but also in +// effects that need access to this data. + +struct SceneData { + highp mat4 projection_matrix; + highp mat4 inv_projection_matrix; + highp mat4 inv_view_matrix; + highp mat4 view_matrix; + + // only used for multiview + highp mat4 projection_matrix_view[MAX_VIEWS]; + highp mat4 inv_projection_matrix_view[MAX_VIEWS]; + highp vec4 eye_offset[MAX_VIEWS]; + + highp vec2 viewport_size; + highp vec2 screen_pixel_size; + + // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. + highp vec4 directional_penumbra_shadow_kernel[32]; + highp vec4 directional_soft_shadow_kernel[32]; + highp vec4 penumbra_shadow_kernel[32]; + highp vec4 soft_shadow_kernel[32]; + + mediump mat3 radiance_inverse_xform; + + mediump vec4 ambient_light_color_energy; + + mediump float ambient_color_sky_mix; + bool use_ambient_light; + bool use_ambient_cubemap; + bool use_reflection_cubemap; + + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; + + uint directional_light_count; + mediump float dual_paraboloid_side; + highp float z_far; + highp float z_near; + + bool roughness_limiter_enabled; + mediump float roughness_limiter_amount; + mediump float roughness_limiter_limit; + mediump float opaque_prepass_threshold; + + bool fog_enabled; + highp float fog_density; + highp float fog_height; + highp float fog_height_density; + + mediump vec3 fog_light_color; + mediump float fog_sun_scatter; + + mediump float fog_aerial_perspective; + highp float time; + mediump float reflection_multiplier; // one normally, zero when rendering reflections + bool material_uv2_mode; + + vec2 taa_jitter; + float emissive_exposure_normalization; + float IBL_exposure_normalization; + + bool pancake_shadows; + uint pad1; + uint pad2; + uint pad3; +}; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 82d609291c..4b34cc74cb 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -34,6 +34,7 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/storage/light_storage.h" #include "servers/rendering/storage/utilities.h" @@ -235,7 +236,7 @@ public: const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); - return light_owner.owns(light->projector); + return TextureStorage::get_singleton()->owns_texture(light->projector); } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 49e3543ba5..1827b73507 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "mesh_storage.h" +#include "../../rendering_server_globals.h" using namespace RendererRD; @@ -1211,7 +1212,13 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS:: if (multimesh->data_cache_dirty_regions) { memdelete_arr(multimesh->data_cache_dirty_regions); multimesh->data_cache_dirty_regions = nullptr; - multimesh->data_cache_used_dirty_regions = 0; + multimesh->data_cache_dirty_region_count = 0; + } + + if (multimesh->previous_data_cache_dirty_regions) { + memdelete_arr(multimesh->previous_data_cache_dirty_regions); + multimesh->previous_data_cache_dirty_regions = nullptr; + multimesh->previous_data_cache_dirty_region_count = 0; } multimesh->instances = p_instances; @@ -1228,14 +1235,67 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS:: multimesh->aabb = AABB(); multimesh->aabb_dirty = false; multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances); + multimesh->motion_vectors_current_offset = 0; + multimesh->motion_vectors_previous_offset = 0; + multimesh->motion_vectors_last_change = -1; if (multimesh->instances) { - multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4); + uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float); + if (multimesh->motion_vectors_enabled) { + buffer_size *= 2; + } + multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size); } multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH); } +bool MeshStorage::_multimesh_enable_motion_vectors(RID p_multimesh) { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + ERR_FAIL_COND_V(!multimesh, false); + + if (multimesh->motion_vectors_enabled) { + return false; + } + + multimesh->motion_vectors_enabled = true; + + multimesh->motion_vectors_current_offset = 0; + multimesh->motion_vectors_previous_offset = 0; + multimesh->motion_vectors_last_change = -1; + + if (!multimesh->data_cache.is_empty()) { + multimesh->data_cache.append_array(multimesh->data_cache); + } + + if (multimesh->buffer_set) { + RD::get_singleton()->barrier(); + Vector<uint8_t> buffer_data = RD::get_singleton()->buffer_get_data(multimesh->buffer); + if (!multimesh->data_cache.is_empty()) { + memcpy(buffer_data.ptrw(), multimesh->data_cache.ptr(), buffer_data.size()); + } + + RD::get_singleton()->free(multimesh->buffer); + uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float) * 2; + multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size); + RD::get_singleton()->buffer_update(multimesh->buffer, 0, buffer_data.size(), buffer_data.ptr(), RD::BARRIER_MASK_NO_BARRIER); + RD::get_singleton()->buffer_update(multimesh->buffer, buffer_data.size(), buffer_data.size(), buffer_data.ptr()); + multimesh->uniform_set_3d = RID(); // Cleared by dependency + return true; + } + return false; // Update the transforms uniform set cache +} + +void MeshStorage::_multimesh_get_motion_vectors_offsets(RID p_multimesh, uint32_t &r_current_offset, uint32_t &r_prev_offset) { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + ERR_FAIL_COND(!multimesh); + r_current_offset = multimesh->motion_vectors_current_offset; + if (RSG::rasterizer->get_frame_number() - multimesh->motion_vectors_last_change >= 2) { + multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset; + } + r_prev_offset = multimesh->motion_vectors_previous_offset; +} + int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); @@ -1261,7 +1321,7 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { //need to re-create AABB unfortunately, calling this has a penalty if (multimesh->buffer_set) { Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer); - const uint8_t *r = buffer.ptr(); + const uint8_t *r = buffer.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float); const float *data = reinterpret_cast<const float *>(r); _multimesh_re_create_aabb(multimesh, data, multimesh->instances); } @@ -1276,10 +1336,14 @@ void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const { if (multimesh->data_cache.size() > 0) { return; //already local } - ERR_FAIL_COND(multimesh->data_cache.size() > 0); + // this means that the user wants to load/save individual elements, // for this, the data must reside on CPU, so just copy it there. - multimesh->data_cache.resize(multimesh->instances * multimesh->stride_cache); + uint32_t buffer_size = multimesh->instances * multimesh->stride_cache; + if (multimesh->motion_vectors_enabled) { + buffer_size *= 2; + } + multimesh->data_cache.resize(buffer_size); { float *w = multimesh->data_cache.ptrw(); @@ -1290,15 +1354,48 @@ void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const { memcpy(w, r, buffer.size()); } } else { - memset(w, 0, (size_t)multimesh->instances * multimesh->stride_cache * sizeof(float)); + memset(w, 0, buffer_size * sizeof(float)); } } uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count); - for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = false; + memset(multimesh->data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool)); + multimesh->data_cache_dirty_region_count = 0; + + multimesh->previous_data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count); + memset(multimesh->previous_data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool)); + multimesh->previous_data_cache_dirty_region_count = 0; +} + +void MeshStorage::_multimesh_update_motion_vectors_data_cache(MultiMesh *multimesh) { + ERR_FAIL_COND(multimesh->data_cache.is_empty()); + + if (!multimesh->motion_vectors_enabled) { + return; + } + + uint32_t frame = RSG::rasterizer->get_frame_number(); + if (multimesh->motion_vectors_last_change != frame) { + multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset; + multimesh->motion_vectors_current_offset = multimesh->instances - multimesh->motion_vectors_current_offset; + multimesh->motion_vectors_last_change = frame; + + if (multimesh->previous_data_cache_dirty_region_count > 0) { + uint8_t *data = (uint8_t *)multimesh->data_cache.ptrw(); + uint32_t current_ofs = multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float); + uint32_t previous_ofs = multimesh->motion_vectors_previous_offset * multimesh->stride_cache * sizeof(float); + uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; + uint32_t visible_region_count = visible_instances == 0 ? 0 : (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; + uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float); + uint32_t size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float); + for (uint32_t i = 0; i < visible_region_count; i++) { + if (multimesh->previous_data_cache_dirty_regions[i]) { + uint32_t offset = i * region_size; + memcpy(data + current_ofs + offset, data + previous_ofs + offset, MIN(region_size, size - offset)); + } + } + } } - multimesh->data_cache_used_dirty_regions = 0; } void MeshStorage::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) { @@ -1309,7 +1406,7 @@ void MeshStorage::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool #endif if (!multimesh->data_cache_dirty_regions[region_index]) { multimesh->data_cache_dirty_regions[region_index] = true; - multimesh->data_cache_used_dirty_regions++; + multimesh->data_cache_dirty_region_count++; } if (p_aabb) { @@ -1330,7 +1427,7 @@ void MeshStorage::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, b for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { if (!multimesh->data_cache_dirty_regions[i]) { multimesh->data_cache_dirty_regions[i] = true; - multimesh->data_cache_used_dirty_regions++; + multimesh->data_cache_dirty_region_count++; } } } @@ -1395,11 +1492,12 @@ void MeshStorage::multimesh_instance_set_transform(RID p_multimesh, int p_index, ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D); _multimesh_make_local(multimesh); + _multimesh_update_motion_vectors_data_cache(multimesh); { float *w = multimesh->data_cache.ptrw(); - float *dataptr = w + p_index * multimesh->stride_cache; + float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache; dataptr[0] = p_transform.basis.rows[0][0]; dataptr[1] = p_transform.basis.rows[0][1]; @@ -1425,11 +1523,12 @@ void MeshStorage::multimesh_instance_set_transform_2d(RID p_multimesh, int p_ind ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D); _multimesh_make_local(multimesh); + _multimesh_update_motion_vectors_data_cache(multimesh); { float *w = multimesh->data_cache.ptrw(); - float *dataptr = w + p_index * multimesh->stride_cache; + float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache; dataptr[0] = p_transform.columns[0][0]; dataptr[1] = p_transform.columns[1][0]; @@ -1451,11 +1550,12 @@ void MeshStorage::multimesh_instance_set_color(RID p_multimesh, int p_index, con ERR_FAIL_COND(!multimesh->uses_colors); _multimesh_make_local(multimesh); + _multimesh_update_motion_vectors_data_cache(multimesh); { float *w = multimesh->data_cache.ptrw(); - float *dataptr = w + p_index * multimesh->stride_cache + multimesh->color_offset_cache; + float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->color_offset_cache; dataptr[0] = p_color.r; dataptr[1] = p_color.g; @@ -1473,11 +1573,12 @@ void MeshStorage::multimesh_instance_set_custom_data(RID p_multimesh, int p_inde ERR_FAIL_COND(!multimesh->uses_custom_data); _multimesh_make_local(multimesh); + _multimesh_update_motion_vectors_data_cache(multimesh); { float *w = multimesh->data_cache.ptrw(); - float *dataptr = w + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache; + float *dataptr = w + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->custom_data_offset_cache; dataptr[0] = p_color.r; dataptr[1] = p_color.g; @@ -1514,7 +1615,7 @@ Transform3D MeshStorage::multimesh_instance_get_transform(RID p_multimesh, int p { const float *r = multimesh->data_cache.ptr(); - const float *dataptr = r + p_index * multimesh->stride_cache; + const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache; t.basis.rows[0][0] = dataptr[0]; t.basis.rows[0][1] = dataptr[1]; @@ -1545,7 +1646,7 @@ Transform2D MeshStorage::multimesh_instance_get_transform_2d(RID p_multimesh, in { const float *r = multimesh->data_cache.ptr(); - const float *dataptr = r + p_index * multimesh->stride_cache; + const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache; t.columns[0][0] = dataptr[0]; t.columns[1][0] = dataptr[1]; @@ -1570,7 +1671,7 @@ Color MeshStorage::multimesh_instance_get_color(RID p_multimesh, int p_index) co { const float *r = multimesh->data_cache.ptr(); - const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->color_offset_cache; + const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->color_offset_cache; c.r = dataptr[0]; c.g = dataptr[1]; @@ -1593,7 +1694,7 @@ Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_ind { const float *r = multimesh->data_cache.ptr(); - const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache; + const float *dataptr = r + (multimesh->motion_vectors_current_offset + p_index) * multimesh->stride_cache + multimesh->custom_data_offset_cache; c.r = dataptr[0]; c.g = dataptr[1]; @@ -1609,25 +1710,26 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache)); + if (multimesh->motion_vectors_enabled) { + uint32_t frame = RSG::rasterizer->get_frame_number(); + + if (multimesh->motion_vectors_last_change != frame) { + multimesh->motion_vectors_previous_offset = multimesh->motion_vectors_current_offset; + multimesh->motion_vectors_current_offset = multimesh->instances - multimesh->motion_vectors_current_offset; + multimesh->motion_vectors_last_change = frame; + } + } + { const float *r = p_buffer.ptr(); - RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r); + RD::get_singleton()->buffer_update(multimesh->buffer, multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float), p_buffer.size() * sizeof(float), r); multimesh->buffer_set = true; } if (multimesh->data_cache.size()) { - //if we have a data cache, just update it - multimesh->data_cache = p_buffer; - { - //clear dirty since nothing will be dirty anymore - uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; - for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = false; - } - multimesh->data_cache_used_dirty_regions = 0; - } - - _multimesh_mark_all_dirty(multimesh, false, true); //update AABB + float *cache_data = multimesh->data_cache.ptrw(); + memcpy(cache_data + (multimesh->motion_vectors_current_offset * multimesh->stride_cache), p_buffer.ptr(), p_buffer.size() * sizeof(float)); + _multimesh_mark_all_dirty(multimesh, true, true); //update AABB } else if (multimesh->mesh.is_valid()) { //if we have a mesh set, we need to re-generate the AABB from the new data const float *data = p_buffer.ptr(); @@ -1642,20 +1744,19 @@ Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const { ERR_FAIL_COND_V(!multimesh, Vector<float>()); if (multimesh->buffer.is_null()) { return Vector<float>(); - } else if (multimesh->data_cache.size()) { - return multimesh->data_cache; } else { - //get from memory - - Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer); Vector<float> ret; ret.resize(multimesh->instances * multimesh->stride_cache); - { - float *w = ret.ptrw(); - const uint8_t *r = buffer.ptr(); - memcpy(w, r, buffer.size()); - } + float *w = ret.ptrw(); + if (multimesh->data_cache.size()) { + const uint8_t *r = (uint8_t *)multimesh->data_cache.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float); + memcpy(w, r, ret.size() * sizeof(float)); + } else { + Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer); + const uint8_t *r = buffer.ptr() + multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float); + memcpy(w, r, ret.size() * sizeof(float)); + } return ret; } } @@ -1698,36 +1799,38 @@ void MeshStorage::_update_dirty_multimeshes() { MultiMesh *multimesh = multimesh_dirty_list; if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists - const float *data = multimesh->data_cache.ptr(); uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; + uint32_t buffer_offset = multimesh->motion_vectors_current_offset * multimesh->stride_cache; + const float *data = multimesh->data_cache.ptr() + buffer_offset; - if (multimesh->data_cache_used_dirty_regions) { + uint32_t total_dirty_regions = multimesh->data_cache_dirty_region_count + multimesh->previous_data_cache_dirty_region_count; + if (total_dirty_regions != 0) { uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; uint32_t visible_region_count = visible_instances == 0 ? 0 : (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float); - - if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) { + if (total_dirty_regions > 32 || total_dirty_regions > visible_region_count / 2) { //if there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much - RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * (uint32_t)multimesh->stride_cache * (uint32_t)sizeof(float)), data); + RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float), MIN(visible_region_count * region_size, multimesh->instances * (uint32_t)multimesh->stride_cache * (uint32_t)sizeof(float)), data); } else { //not that many regions? update them all for (uint32_t i = 0; i < visible_region_count; i++) { - if (multimesh->data_cache_dirty_regions[i]) { + if (multimesh->data_cache_dirty_regions[i] || multimesh->previous_data_cache_dirty_regions[i]) { uint32_t offset = i * region_size; uint32_t size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float); uint32_t region_start_index = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * i; - RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[region_start_index]); + RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index], RD::BARRIER_MASK_NO_BARRIER); } } + RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL); } - for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = false; - } + memcpy(multimesh->previous_data_cache_dirty_regions, multimesh->data_cache_dirty_regions, data_cache_dirty_region_count * sizeof(bool)); + memset(multimesh->data_cache_dirty_regions, 0, data_cache_dirty_region_count * sizeof(bool)); - multimesh->data_cache_used_dirty_regions = 0; + multimesh->previous_data_cache_dirty_region_count = multimesh->data_cache_dirty_region_count; + multimesh->data_cache_dirty_region_count = 0; } if (multimesh->aabb_dirty) { diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 5c0d019c15..622f3911c7 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -205,13 +205,19 @@ private: AABB aabb; bool aabb_dirty = false; bool buffer_set = false; + bool motion_vectors_enabled = false; + uint32_t motion_vectors_current_offset = 0; + uint32_t motion_vectors_previous_offset = 0; + uint64_t motion_vectors_last_change = -1; uint32_t stride_cache = 0; uint32_t color_offset_cache = 0; uint32_t custom_data_offset_cache = 0; Vector<float> data_cache; //used if individual setting is used bool *data_cache_dirty_regions = nullptr; - uint32_t data_cache_used_dirty_regions = 0; + uint32_t data_cache_dirty_region_count = 0; + bool *previous_data_cache_dirty_regions = nullptr; + uint32_t previous_data_cache_dirty_region_count = 0; RID buffer; //storage buffer RID uniform_set_3d; @@ -228,6 +234,7 @@ private: MultiMesh *multimesh_dirty_list = nullptr; _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const; + _FORCE_INLINE_ void _multimesh_update_motion_vectors_data_cache(MultiMesh *multimesh); _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb); _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb); _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances); @@ -579,6 +586,8 @@ public: virtual AABB multimesh_get_aabb(RID p_multimesh) const override; void _update_dirty_multimeshes(); + bool _multimesh_enable_motion_vectors(RID p_multimesh); + void _multimesh_get_motion_vectors_offsets(RID p_multimesh, uint32_t &r_current_offset, uint32_t &r_prev_offset); _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h index adaf075f80..1975eec7b0 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h @@ -35,8 +35,8 @@ #include "servers/rendering/renderer_rd/effects/vrs.h" #include "servers/rendering/renderer_rd/framebuffer_cache_rd.h" #include "servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h" -#include "servers/rendering/renderer_scene.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/render_scene_buffers.h" // These can be retired in due time diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp new file mode 100644 index 0000000000..f925f87cbe --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -0,0 +1,246 @@ +/*************************************************************************/ +/* render_scene_data_rd.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "render_scene_data_rd.h" +#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/light_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/rendering_server_default.h" + +RID RenderSceneDataRD::create_uniform_buffer() { + return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA)); +} + +void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers) { + RendererSceneRenderRD *render_scene_render = RendererSceneRenderRD::get_singleton(); + + UBODATA ubo_data; + memset(&ubo_data, 0, sizeof(UBODATA)); + + // just for easy access.. + UBO &ubo = ubo_data.ubo; + UBO &prev_ubo = ubo_data.prev_ubo; + + Projection correction; + correction.set_depth_correction(p_flip_y); + correction.add_jitter_offset(taa_jitter); + Projection projection = correction * cam_projection; + + //store camera into ubo + RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix); + RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix); + RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix); + RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix); + + for (uint32_t v = 0; v < view_count; v++) { + projection = correction * view_projection[v]; + RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix_view[v]); + + ubo.eye_offset[v][0] = view_eye_offset[v].x; + ubo.eye_offset[v][1] = view_eye_offset[v].y; + ubo.eye_offset[v][2] = view_eye_offset[v].z; + ubo.eye_offset[v][3] = 0.0; + } + + ubo.taa_jitter[0] = taa_jitter.x; + ubo.taa_jitter[1] = taa_jitter.y; + + ubo.z_far = z_far; + ubo.z_near = z_near; + + ubo.pancake_shadows = p_pancake_shadows; + + RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel); + RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel); + + ubo.viewport_size[0] = p_screen_size.x; + ubo.viewport_size[1] = p_screen_size.y; + + Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); + ubo.screen_pixel_size[0] = screen_pixel_size.x; + ubo.screen_pixel_size[1] = screen_pixel_size.y; + + ubo.shadow_atlas_pixel_size[0] = shadow_atlas_pixel_size.x; + ubo.shadow_atlas_pixel_size[1] = shadow_atlas_pixel_size.y; + + ubo.directional_shadow_pixel_size[0] = directional_shadow_pixel_size.x; + ubo.directional_shadow_pixel_size[1] = directional_shadow_pixel_size.y; + + ubo.time = time; + + ubo.directional_light_count = directional_light_count; + ubo.dual_paraboloid_side = dual_paraboloid_side; + ubo.opaque_prepass_threshold = opaque_prepass_threshold; + ubo.material_uv2_mode = material_uv2_mode; + + ubo.fog_enabled = false; + + if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + ubo.use_ambient_light = true; + ubo.ambient_light_color_energy[0] = 1; + ubo.ambient_light_color_energy[1] = 1; + ubo.ambient_light_color_energy[2] = 1; + ubo.ambient_light_color_energy[3] = 1.0; + ubo.use_ambient_cubemap = false; + ubo.use_reflection_cubemap = false; + } else if (p_env.is_valid()) { + RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env); + RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env); + + float bg_energy_multiplier = render_scene_render->environment_get_bg_energy_multiplier(p_env); + + ubo.ambient_light_color_energy[3] = bg_energy_multiplier; + + ubo.ambient_color_sky_mix = render_scene_render->environment_get_ambient_sky_contribution(p_env); + + //ambient + if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { + Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : render_scene_render->environment_get_bg_color(p_env); + color = color.srgb_to_linear(); + + ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; + ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; + ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; + ubo.use_ambient_light = true; + ubo.use_ambient_cubemap = false; + } else { + float energy = render_scene_render->environment_get_ambient_light_energy(p_env); + Color color = render_scene_render->environment_get_ambient_light(p_env); + color = color.srgb_to_linear(); + ubo.ambient_light_color_energy[0] = color.r * energy; + ubo.ambient_light_color_energy[1] = color.g * energy; + ubo.ambient_light_color_energy[2] = color.b * energy; + + Basis sky_transform = render_scene_render->environment_get_sky_orientation(p_env); + sky_transform = sky_transform.inverse() * cam_transform.basis; + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform); + + ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; + ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; + } + + //specular + RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env); + if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { + ubo.use_reflection_cubemap = true; + } else { + ubo.use_reflection_cubemap = false; + } + + ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env); + ubo.fog_density = render_scene_render->environment_get_fog_density(p_env); + ubo.fog_height = render_scene_render->environment_get_fog_height(p_env); + ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env); + ubo.fog_aerial_perspective = render_scene_render->environment_get_fog_aerial_perspective(p_env); + + Color fog_color = render_scene_render->environment_get_fog_light_color(p_env).srgb_to_linear(); + float fog_energy = render_scene_render->environment_get_fog_light_energy(p_env); + + ubo.fog_light_color[0] = fog_color.r * fog_energy; + ubo.fog_light_color[1] = fog_color.g * fog_energy; + ubo.fog_light_color[2] = fog_color.b * fog_energy; + + ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env); + } else { + if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) { + ubo.use_ambient_light = false; + } else { + ubo.use_ambient_light = true; + Color clear_color = p_default_bg_color; + clear_color = clear_color.srgb_to_linear(); + ubo.ambient_light_color_energy[0] = clear_color.r; + ubo.ambient_light_color_energy[1] = clear_color.g; + ubo.ambient_light_color_energy[2] = clear_color.b; + ubo.ambient_light_color_energy[3] = 1.0; + } + + ubo.use_ambient_cubemap = false; + ubo.use_reflection_cubemap = false; + } + + if (p_camera_attributes.is_valid()) { + ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes); + ubo.IBL_exposure_normalization = 1.0; + if (p_env.is_valid()) { + RID sky_rid = render_scene_render->environment_get_sky(p_env); + if (sky_rid.is_valid()) { + float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes) * render_scene_render->environment_get_bg_intensity(p_env) / p_luminance_multiplier; + ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, render_scene_render->get_sky()->sky_get_baked_exposure(sky_rid)); + } + } + } else if (emissive_exposure_normalization > 0.0) { + // This branch is triggered when using render_material(). + // Emissive is set outside the function. + ubo.emissive_exposure_normalization = emissive_exposure_normalization; + // IBL isn't used don't set it. + } else { + ubo.emissive_exposure_normalization = 1.0; + ubo.IBL_exposure_normalization = 1.0; + } + + ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active(); + ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount(); + ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit(); + + if (calculate_motion_vectors) { + // Q : Should we make a complete copy or should we define a separate UBO with just the components we need? + memcpy(&prev_ubo, &ubo, sizeof(UBO)); + + Projection prev_correction; + prev_correction.set_depth_correction(true); + prev_correction.add_jitter_offset(prev_taa_jitter); + Projection prev_projection = prev_correction * prev_cam_projection; + + //store camera into ubo + RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix); + RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix); + RendererRD::MaterialStorage::store_transform(prev_cam_transform, prev_ubo.inv_view_matrix); + RendererRD::MaterialStorage::store_transform(prev_cam_transform.affine_inverse(), prev_ubo.view_matrix); + + for (uint32_t v = 0; v < view_count; v++) { + prev_projection = prev_correction * view_projection[v]; + RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix_view[v]); + RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix_view[v]); + } + prev_ubo.taa_jitter[0] = prev_taa_jitter.x; + prev_ubo.taa_jitter[1] = prev_taa_jitter.y; + prev_ubo.time -= time_step; + } + + uniform_buffer = p_uniform_buffer; + RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo, RD::BARRIER_MASK_RASTER); +} + +RID RenderSceneDataRD::get_uniform_buffer() { + return uniform_buffer; +} diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h new file mode 100644 index 0000000000..c2dc7d5f4c --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -0,0 +1,157 @@ +/*************************************************************************/ +/* render_scene_data_rd.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RENDER_SCENE_DATA_RD_H +#define RENDER_SCENE_DATA_RD_H + +#include "render_scene_buffers_rd.h" +#include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering/rendering_device.h" + +// This is a container for data related to rendering a single frame of a viewport where we load this data into a UBO +// that can be used by the main scene shader but also by various effects. + +class RenderSceneDataRD { +public: + bool calculate_motion_vectors = false; + + Transform3D cam_transform; + Projection cam_projection; + Vector2 taa_jitter; + bool cam_orthogonal = false; + + // For stereo rendering + uint32_t view_count = 1; + Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + + Transform3D prev_cam_transform; + Projection prev_cam_projection; + Vector2 prev_taa_jitter; + Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + + float z_near = 0.0; + float z_far = 0.0; + + float lod_distance_multiplier = 0.0; + Plane lod_camera_plane; + float screen_mesh_lod_threshold = 0.0; + + uint32_t directional_light_count = 0; + float dual_paraboloid_side = 0.0; + float opaque_prepass_threshold = 0.0; + bool material_uv2_mode = false; + float emissive_exposure_normalization = 0.0; + + Size2 shadow_atlas_pixel_size; + Size2 directional_shadow_pixel_size; + + float time; + float time_step; + + RID create_uniform_buffer(); + void update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers); + RID get_uniform_buffer(); + +private: + RID uniform_buffer; // loaded into this uniform buffer (supplied externally) + + // This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code + struct UBO { + float projection_matrix[16]; + float inv_projection_matrix[16]; + float inv_view_matrix[16]; + float view_matrix[16]; + + float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; + float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; + float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4]; + + float viewport_size[2]; + float screen_pixel_size[2]; + + float directional_penumbra_shadow_kernel[128]; //32 vec4s + float directional_soft_shadow_kernel[128]; + float penumbra_shadow_kernel[128]; + float soft_shadow_kernel[128]; + + float radiance_inverse_xform[12]; + + float ambient_light_color_energy[4]; + + float ambient_color_sky_mix; + uint32_t use_ambient_light; + uint32_t use_ambient_cubemap; + uint32_t use_reflection_cubemap; + + float shadow_atlas_pixel_size[2]; + float directional_shadow_pixel_size[2]; + + uint32_t directional_light_count; + float dual_paraboloid_side; + float z_far; + float z_near; + + uint32_t roughness_limiter_enabled; + float roughness_limiter_amount; + float roughness_limiter_limit; + float opaque_prepass_threshold; + + // Fog + uint32_t fog_enabled; + float fog_density; + float fog_height; + float fog_height_density; + + float fog_light_color[3]; + float fog_sun_scatter; + + float fog_aerial_perspective; + float time; + float reflection_multiplier; + uint32_t material_uv2_mode; + + float taa_jitter[2]; + float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. + float IBL_exposure_normalization; // Adjusts for baked exposure. + + uint32_t pancake_shadows; + uint32_t pad1; + uint32_t pad2; + uint32_t pad3; + }; + + struct UBODATA { + UBO ubo; + UBO prev_ubo; + }; +}; + +#endif // RENDER_SCENE_DATA_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index b87b4d4a0f..800a742cb6 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -795,6 +795,8 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; } break; + default: + ERR_FAIL(); // Shouldn't happen, silence warnings. } texture.rd_format = ret_format.format; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 04dedc0646..c2dece8b46 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2910,7 +2910,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } -void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RendererScene::RenderInfo *r_render_info) { +void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) { Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it Scenario *scenario = scenario_owner.get_or_null(p_scenario); diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index c799553f87..fedaac99b1 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -39,13 +39,13 @@ #include "core/templates/pass_func.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" -#include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_occlusion_cull.h" #include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/utilities.h" #include "servers/xr/xr_interface.h" -class RendererSceneCull : public RendererScene { +class RendererSceneCull : public RenderingMethod { public: RendererSceneRender *scene_render = nullptr; @@ -1058,7 +1058,7 @@ public: void _render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr); void render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas); - void render_camera(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RendererScene::RenderInfo *r_render_info = nullptr); + void render_camera(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderingMethod::RenderInfo *r_render_info = nullptr); void update_dirty_instances(); void render_particle_colliders(); diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 9aa4108412..34f4980f05 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -34,7 +34,7 @@ #include "core/math/projection.h" #include "core/templates/paged_array.h" #include "servers/rendering/renderer_geometry_instance.h" -#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/environment_storage.h" #include "storage/render_scene_buffers.h" #include "storage/utilities.h" @@ -320,7 +320,7 @@ public: void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); }; - virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0; + virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0; virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index eacd9bbbc2..2b05e23a96 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -179,7 +179,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { // to compensate for the loss of sharpness. const float texture_mipmap_bias = log2f(MIN(scaling_3d_scale, 1.0)) + p_viewport->texture_mipmap_bias; - p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count()); + p_viewport->render_buffers->configure(p_viewport->render_target, Size2i(render_width, render_height), Size2(width, height), p_viewport->fsr_sharpness, texture_mipmap_bias, p_viewport->msaa_3d, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->view_count); } } } @@ -220,7 +220,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { timestamp_vp_map[rt_id] = p_viewport->self; } - if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") { + if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") { // This is currently needed for GLES to keep the current window being rendered to up to date DisplayServer::get_singleton()->gl_window_make_current(p_viewport->viewport_to_screen); } @@ -616,14 +616,7 @@ void RendererViewport::draw_viewports() { if (xr_interface.is_valid()) { // Override our size, make sure it matches our required size and is created as a stereo target Size2 xr_size = xr_interface->get_render_target_size(); - - // Would have been nice if we could call viewport_set_size here, - // but alas that takes our RID and we now have our pointer, - // also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change - vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size); - vp->size = xr_size; - uint32_t view_count = xr_interface->get_view_count(); - RSG::texture_storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count); + _viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count()); // Inform xr interface we're about to render its viewport, if this returns false we don't render visible = xr_interface->pre_draw_viewport(vp->render_target); @@ -686,12 +679,17 @@ void RendererViewport::draw_viewports() { // commit our eyes Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect); if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && blits.size() > 0) { - if (!blit_to_screen_list.has(vp->viewport_to_screen)) { - blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>(); - } + if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") { + RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size()); + RSG::rasterizer->end_frame(true); + } else { + if (!blit_to_screen_list.has(vp->viewport_to_screen)) { + blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>(); + } - for (int b = 0; b < blits.size(); b++) { - blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]); + for (int b = 0; b < blits.size(); b++) { + blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]); + } } } } else { @@ -777,7 +775,13 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { } viewport->use_xr = p_use_xr; - _configure_3d_render_buffers(viewport); + + // Re-configure the 3D render buffers when disabling XR. They'll get + // re-configured when enabling XR in draw_viewports(). + if (!p_use_xr) { + viewport->view_count = 1; + _configure_3d_render_buffers(viewport); + } } void RendererViewport::viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode) { @@ -823,34 +827,27 @@ void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_sca _configure_3d_render_buffers(viewport); } -uint32_t RendererViewport::Viewport::get_view_count() { - uint32_t view_count = 1; - - if (use_xr && XRServer::get_singleton() != nullptr) { - Ref<XRInterface> xr_interface; - - xr_interface = XRServer::get_singleton()->get_primary_interface(); - if (xr_interface.is_valid()) { - view_count = xr_interface->get_view_count(); - } - } - - return view_count; -} - void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { ERR_FAIL_COND(p_width < 0 && p_height < 0); Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); + ERR_FAIL_COND_MSG(viewport->use_xr, "Cannot set viewport size when using XR"); - viewport->size = Size2(p_width, p_height); + _viewport_set_size(viewport, p_width, p_height, 1); +} - uint32_t view_count = viewport->get_view_count(); - RSG::texture_storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count); - _configure_3d_render_buffers(viewport); +void RendererViewport::_viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count) { + Size2i new_size(p_width, p_height); + if (p_viewport->size != new_size || p_viewport->view_count != p_view_count) { + p_viewport->size = new_size; + p_viewport->view_count = p_view_count; - viewport->occlusion_buffer_dirty = true; + RSG::texture_storage->render_target_set_size(p_viewport->render_target, p_width, p_height, p_view_count); + _configure_3d_render_buffers(p_viewport); + + p_viewport->occlusion_buffer_dirty = true; + } } void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) { @@ -890,7 +887,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_ // If using OpenGL we can optimize this operation by rendering directly to system_fbo // instead of rendering to fbo and copying to system_fbo after if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count()); + RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->view_count); RSG::texture_storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y); } @@ -900,7 +897,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_ // if render_direct_to_screen was used, reset size and position if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0); - RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count()); + RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->view_count); } viewport->viewport_to_screen_rect = Rect2(); @@ -919,7 +916,7 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool // if disabled, reset render_target size and position if (!p_enable) { RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0); - RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count()); + RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->view_count); } RSG::texture_storage->render_target_set_direct_to_screen(viewport->render_target, p_enable); @@ -927,7 +924,7 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) { - RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count()); + RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->view_count); RSG::texture_storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y); } } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index a123c70372..55058a30b8 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -34,8 +34,8 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" -#include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" #include "storage/render_scene_buffers.h" @@ -54,6 +54,7 @@ public: Size2i internal_size; Size2i size; + uint32_t view_count; RID camera; RID scenario; @@ -147,9 +148,10 @@ public: HashMap<RID, CanvasData> canvas_map; - RendererScene::RenderInfo render_info; + RenderingMethod::RenderInfo render_info; Viewport() { + view_count = 1; update_mode = RS::VIEWPORT_UPDATE_WHEN_VISIBLE; clear_mode = RS::VIEWPORT_CLEAR_ALWAYS; transparent_bg = false; @@ -176,8 +178,6 @@ public: time_gpu_begin = 0; time_gpu_end = 0; } - - uint32_t get_view_count(); }; HashMap<String, RID> timestamp_vp_map; @@ -196,6 +196,7 @@ public: private: Vector<Viewport *> _sort_active_viewports(); + void _viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count); void _configure_3d_render_buffers(Viewport *p_viewport); void _draw_3d(Viewport *p_viewport); void _draw_viewport(Viewport *p_viewport); diff --git a/servers/rendering/renderer_scene.cpp b/servers/rendering/rendering_method.cpp index b3fdd88626..16a4e35ad3 100644 --- a/servers/rendering/renderer_scene.cpp +++ b/servers/rendering/rendering_method.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene.cpp */ +/* rendering_method.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "renderer_scene.h" +#include "rendering_method.h" -RendererScene::RendererScene() { +RenderingMethod::RenderingMethod() { } -RendererScene::~RendererScene() { +RenderingMethod::~RenderingMethod() { } diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/rendering_method.h index 29c65fcffb..a178b00424 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/rendering_method.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene.h */ +/* rendering_method.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERER_SCENE_H -#define RENDERER_SCENE_H +#ifndef RENDERING_METHOD_H +#define RENDERING_METHOD_H #include "servers/rendering/storage/render_scene_buffers.h" #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" -class RendererScene { +class RenderingMethod { public: virtual RID camera_allocate() = 0; virtual void camera_initialize(RID p_rid) = 0; @@ -318,8 +318,8 @@ public: virtual bool free(RID p_rid) = 0; - RendererScene(); - virtual ~RendererScene(); + RenderingMethod(); + virtual ~RenderingMethod(); }; -#endif // RENDERER_SCENE_H +#endif // RENDERING_METHOD_H diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index dfe16431bd..5ee29d5e2a 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -550,7 +550,7 @@ public: #undef server_name #undef ServerName //from now on, calls forwarded to this singleton -#define ServerName RendererScene +#define ServerName RenderingMethod #define server_name RSG::scene /* CAMERA API */ @@ -649,7 +649,7 @@ public: #undef server_name #undef ServerName //from now on, calls forwarded to this singleton -#define ServerName RendererScene +#define ServerName RenderingMethod #define server_name RSG::scene FUNC2(directional_shadow_atlas_set_size, int, bool) @@ -739,7 +739,7 @@ public: #undef server_name #undef ServerName -#define ServerName RendererScene +#define ServerName RenderingMethod #define server_name RSG::scene FUNCRIDSPLIT(scenario) diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp index ce7383a03f..ca24042ef9 100644 --- a/servers/rendering/rendering_server_globals.cpp +++ b/servers/rendering/rendering_server_globals.cpp @@ -46,4 +46,4 @@ RendererCompositor *RenderingServerGlobals::rasterizer = nullptr; RendererCanvasCull *RenderingServerGlobals::canvas = nullptr; RendererViewport *RenderingServerGlobals::viewport = nullptr; -RendererScene *RenderingServerGlobals::scene = nullptr; +RenderingMethod *RenderingServerGlobals::scene = nullptr; diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h index 6c4ab5a26e..23f3810ce8 100644 --- a/servers/rendering/rendering_server_globals.h +++ b/servers/rendering/rendering_server_globals.h @@ -35,7 +35,7 @@ #include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_canvas_cull.h" #include "servers/rendering/renderer_canvas_render.h" -#include "servers/rendering/renderer_scene.h" +#include "servers/rendering/rendering_method.h" #include "servers/rendering/storage/camera_attributes_storage.h" #include "servers/rendering/storage/light_storage.h" #include "servers/rendering/storage/material_storage.h" @@ -46,7 +46,7 @@ class RendererCanvasCull; class RendererViewport; -class RendererScene; +class RenderingMethod; class RenderingServerGlobals { public: @@ -66,7 +66,7 @@ public: static RendererCanvasCull *canvas; static RendererViewport *viewport; - static RendererScene *scene; + static RenderingMethod *scene; }; #define RSG RenderingServerGlobals diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 47cb38f268..cd063f91ac 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -340,6 +340,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_UINT); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["FLAG_EMIT_ROT_SCALE"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["FLAG_EMIT_VELOCITY"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["FLAG_EMIT_COLOR"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["FLAG_EMIT_CUSTOM"] = constt(ShaderLanguage::TYPE_UINT); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["RESTART_POSITION"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["RESTART_ROT_SCALE"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["RESTART_VELOCITY"] = constt(ShaderLanguage::TYPE_BOOL); @@ -385,6 +390,7 @@ ShaderTypes::ShaderTypes() { emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4)); emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT)); emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit + shader_modes[RS::SHADER_PARTICLES].functions["start"].stage_functions["emit_subparticle"] = emit_vertex_func; shader_modes[RS::SHADER_PARTICLES].functions["process"].stage_functions["emit_subparticle"] = emit_vertex_func; } diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index aa3351c815..57378708ba 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -743,7 +743,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i r_attrib_element_size = 0; r_skin_element_size = 0; - uint32_t *size_accum; + uint32_t *size_accum = nullptr; for (int i = 0; i < RS::ARRAY_MAX; i++) { r_offsets[i] = 0; // Reset @@ -847,8 +847,12 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i } } - r_offsets[i] = (*size_accum); - (*size_accum) += elem_size; + if (size_accum != nullptr) { + r_offsets[i] = (*size_accum); + (*size_accum) += elem_size; + } else { + r_offsets[i] = 0; + } } } @@ -1114,7 +1118,8 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t for (int j = 0; j < p_vertex_len; j++) { const uint32_t v = *(const uint32_t *)&r[j * vertex_elem_size + offsets[i]]; - w[j] = Vector3((v & 0x3FF) / 1023.0, ((v >> 10) & 0x3FF) / 1023.0, ((v >> 20) & 0x3FF) / 1023.0) * Vector3(2, 2, 2) - Vector3(1, 1, 1); + + w[j] = Vector3::octahedron_decode(Vector2((v & 0xFFFF) / 65535.0, ((v >> 16) & 0xFFFF) / 65535.0)); } ret[i] = arr; @@ -1129,11 +1134,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t for (int j = 0; j < p_vertex_len; j++) { const uint32_t v = *(const uint32_t *)&r[j * vertex_elem_size + offsets[i]]; - - w[j * 4 + 0] = ((v & 0x3FF) / 1023.0) * 2.0 - 1.0; - w[j * 4 + 1] = (((v >> 10) & 0x3FF) / 1023.0) * 2.0 - 1.0; - w[j * 4 + 2] = (((v >> 20) & 0x3FF) / 1023.0) * 2.0 - 1.0; - w[j * 4 + 3] = ((v >> 30) / 3.0) * 2.0 - 1.0; + float tangent_sign; + Vector3 res = Vector3::octahedron_tangent_decode(Vector2((v & 0xFFFF) / 65535.0, ((v >> 16) & 0xFFFF) / 65535.0), &tangent_sign); + w[j * 4 + 0] = res.x; + w[j * 4 + 1] = res.y; + w[j * 4 + 2] = res.z; + w[j * 4 + 3] = tangent_sign; } ret[i] = arr; @@ -2861,18 +2867,12 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048); - GLOBAL_DEF_RST_BASIC("rendering/vulkan/rendering/back_end", 0); - GLOBAL_DEF_RST_BASIC("rendering/vulkan/rendering/back_end.mobile", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/vulkan/rendering/back_end", - PropertyInfo(Variant::INT, - "rendering/vulkan/rendering/back_end", - PROPERTY_HINT_ENUM, "Forward Clustered (Supports Desktop Only),Forward Mobile (Supports Desktop and Mobile)")); // Already defined in RenderingDeviceVulkan::initialize which runs before this code. // We re-define them here just for doctool's sake. Make sure to keep default values in sync. - GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); - GLOBAL_DEF("rendering/vulkan/staging_buffer/max_size_mb", 128); - GLOBAL_DEF("rendering/vulkan/staging_buffer/texture_upload_region_size_px", 64); - GLOBAL_DEF("rendering/vulkan/descriptor_pools/max_descriptors_per_pool", 64); + GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); + GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); + GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); + GLOBAL_DEF("rendering/rendering_device/descriptor_pools/max_descriptors_per_pool", 64); GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true); GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true); diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index ebd35b0f75..7a8a298dbd 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -1550,8 +1550,8 @@ PackedInt32Array TextServerExtension::string_get_word_breaks(const String &p_str return PackedInt32Array(); } -int TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { - int ret; +int64_t TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { + int64_t ret; if (GDVIRTUAL_CALL(is_confusable, p_string, p_dict, ret)) { return ret; } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 700d08f7d7..fbaa4961e1 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -508,9 +508,9 @@ public: TypedArray<Vector2i> parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; GDVIRTUAL3RC(TypedArray<Vector2i>, parse_structured_text, StructuredTextParser, const Array &, const String &); - virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; + virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; virtual bool spoof_check(const String &p_string) const override; - GDVIRTUAL2RC(int, is_confusable, const String &, const PackedStringArray &); + GDVIRTUAL2RC(int64_t, is_confusable, const String &, const PackedStringArray &); GDVIRTUAL1RC(bool, spoof_check, const String &); TextServerExtension(); diff --git a/servers/text_server.h b/servers/text_server.h index b62d418fc8..a0624c2c05 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -485,7 +485,7 @@ public: // String functions. virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const = 0; - virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; + virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; virtual bool spoof_check(const String &p_string) const { return false; }; virtual String strip_diacritics(const String &p_string) const; |