diff options
Diffstat (limited to 'servers')
114 files changed, 3816 insertions, 1208 deletions
diff --git a/servers/SCsub b/servers/SCsub index 7080a110da..121990f2e1 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -5,7 +5,7 @@ Import("env") env.servers_sources = [] env.add_source_files(env.servers_sources, "*.cpp") -SConscript("arvr/SCsub") +SConscript("xr/SCsub") SConscript("camera/SCsub") SConscript("physics_3d/SCsub") SConscript("physics_2d/SCsub") diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 69b098edfc..ed67e8902a 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -38,7 +38,7 @@ Error AudioDriverDummy::init() { active = false; thread_exited = false; exit_thread = false; - samples_in = NULL; + samples_in = nullptr; mix_rate = DEFAULT_MIX_RATE; speaker_mode = SPEAKER_MODE_STEREO; @@ -119,12 +119,12 @@ void AudioDriverDummy::finish() { }; memdelete(thread); - thread = NULL; + thread = nullptr; }; AudioDriverDummy::AudioDriverDummy() { - thread = NULL; + thread = nullptr; }; AudioDriverDummy::~AudioDriverDummy(){ diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp index c0bf4f3a55..2771fc177b 100644 --- a/servers/audio/audio_filter_sw.cpp +++ b/servers/audio/audio_filter_sw.cpp @@ -237,7 +237,7 @@ AudioFilterSW::AudioFilterSW() { AudioFilterSW::Processor::Processor() { - set_filter(NULL); + set_filter(nullptr); } void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_history) { diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index 092c3315ee..0ac7ddc7a9 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -203,18 +203,18 @@ void AudioRBResampler::clear() { //should be stopped at this point but just in case memdelete_arr(rb); memdelete_arr(read_buf); - rb = NULL; + rb = nullptr; offset = 0; rb_read_pos = 0; rb_write_pos = 0; - read_buf = NULL; + read_buf = nullptr; } AudioRBResampler::AudioRBResampler() { - rb = NULL; + rb = nullptr; offset = 0; - read_buf = NULL; + read_buf = nullptr; rb_read_pos = 0; rb_write_pos = 0; diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h index 8cd9714d57..40cf3e4cd7 100644 --- a/servers/audio/audio_rb_resampler.h +++ b/servers/audio/audio_rb_resampler.h @@ -69,7 +69,7 @@ public: } _FORCE_INLINE_ bool is_ready() const { - return rb != NULL; + return rb != nullptr; } _FORCE_INLINE_ int get_total() const { diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp index 8f0c55ad83..f2784679b5 100644 --- a/servers/audio/effects/audio_effect_record.cpp +++ b/servers/audio/effects/audio_effect_record.cpp @@ -178,14 +178,14 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() { void AudioEffectRecord::ensure_thread_stopped() { recording_active = false; - if (current_instance != 0) { + if (current_instance != nullptr) { current_instance->finish(); } } void AudioEffectRecord::set_recording_active(bool p_record) { if (p_record) { - if (current_instance == 0) { + if (current_instance == nullptr) { WARN_PRINT("Recording should not be set as active before Godot has initialized."); recording_active = false; return; @@ -217,8 +217,8 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { Vector<uint8_t> dst_data; - ERR_FAIL_COND_V(current_instance.is_null(), NULL); - ERR_FAIL_COND_V(current_instance->recording_data.size() == 0, NULL); + ERR_FAIL_COND_V(current_instance.is_null(), nullptr); + ERR_FAIL_COND_V(current_instance->recording_data.size() == 0, nullptr); if (dst_format == AudioStreamSample::FORMAT_8_BITS) { int data_size = current_instance->recording_data.size(); diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index 5f24cf3d6b..d272a2cdf7 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -205,7 +205,7 @@ void AudioStreamGeneratorPlayback::_bind_methods() { } AudioStreamGeneratorPlayback::AudioStreamGeneratorPlayback() { - generator = NULL; + generator = nullptr; skips = 0; active = false; mixed = 0; diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index 9946a5eeef..ea2174f1d4 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -314,7 +314,7 @@ void Reverb::clear_buffers() { if (comb[i].buffer) memdelete_arr(comb[i].buffer); - comb[i].buffer = 0; + comb[i].buffer = nullptr; } for (int i = 0; i < MAX_ALLPASS; i++) { @@ -322,7 +322,7 @@ void Reverb::clear_buffers() { if (allpass[i].buffer) memdelete_arr(allpass[i].buffer); - allpass[i].buffer = 0; + allpass[i].buffer = nullptr; } } @@ -342,7 +342,7 @@ Reverb::Reverb() { hpf_h2 = 0; input_buffer = memnew_arr(float, INPUT_BUFFER_MAX_SIZE); - echo_buffer = 0; + echo_buffer = nullptr; configure_buffers(); update_parameters(); diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 02e6d0f2d4..90033d4a87 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -45,7 +45,7 @@ #define MARK_EDITED #endif -AudioDriver *AudioDriver::singleton = NULL; +AudioDriver *AudioDriver::singleton = nullptr; AudioDriver *AudioDriver::get_singleton() { return singleton; @@ -215,7 +215,7 @@ void AudioDriverManager::initialize(int p_driver) { AudioDriver *AudioDriverManager::get_driver(int p_driver) { - ERR_FAIL_INDEX_V(p_driver, driver_count, NULL); + ERR_FAIL_INDEX_V(p_driver, driver_count, nullptr); return drivers[p_driver]; } @@ -322,7 +322,7 @@ void AudioServer::_mix_step() { bus->soloed = true; } else { - bus = NULL; + bus = nullptr; } } while (bus); @@ -388,7 +388,7 @@ void AudioServer::_mix_step() { //process send - Bus *send = NULL; + Bus *send = nullptr; if (i > 0) { //everything has a send save for master bus @@ -476,8 +476,8 @@ bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const { AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) { - ERR_FAIL_INDEX_V(p_bus, buses.size(), NULL); - ERR_FAIL_INDEX_V(p_buffer, buses[p_bus]->channels.size(), NULL); + ERR_FAIL_INDEX_V(p_bus, buses.size(), nullptr); + ERR_FAIL_INDEX_V(p_buffer, buses[p_bus]->channels.size(), nullptr); AudioFrame *data = buses.write[p_bus]->channels.write[p_buffer].buffer.ptrw(); @@ -1129,7 +1129,7 @@ double AudioServer::get_time_since_last_mix() const { return AudioDriver::get_singleton()->get_time_since_last_mix(); } -AudioServer *AudioServer::singleton = NULL; +AudioServer *AudioServer::singleton = nullptr; void AudioServer::add_callback(AudioCallback p_callback, void *p_userdata) { lock(); @@ -1372,7 +1372,7 @@ AudioServer::AudioServer() { AudioServer::~AudioServer() { - singleton = NULL; + singleton = nullptr; } ///////////////////////////////// diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp index 1a86ff1af4..3caea6b7c3 100644 --- a/servers/camera_server.cpp +++ b/servers/camera_server.cpp @@ -35,7 +35,7 @@ //////////////////////////////////////////////////////// // CameraServer -CameraServer::CreateFunc CameraServer::create_func = NULL; +CameraServer::CreateFunc CameraServer::create_func = nullptr; void CameraServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_feed", "index"), &CameraServer::get_feed); @@ -54,7 +54,7 @@ void CameraServer::_bind_methods() { BIND_ENUM_CONSTANT(FEED_CBCR_IMAGE); }; -CameraServer *CameraServer::singleton = NULL; +CameraServer *CameraServer::singleton = nullptr; CameraServer *CameraServer::get_singleton() { return singleton; @@ -92,7 +92,7 @@ Ref<CameraFeed> CameraServer::get_feed_by_id(int p_id) { int index = get_feed_index(p_id); if (index == -1) { - return NULL; + return nullptr; } else { return feeds[index]; } @@ -132,7 +132,7 @@ void CameraServer::remove_feed(const Ref<CameraFeed> &p_feed) { }; Ref<CameraFeed> CameraServer::get_feed(int p_index) { - ERR_FAIL_INDEX_V(p_index, feeds.size(), NULL); + ERR_FAIL_INDEX_V(p_index, feeds.size(), nullptr); return feeds[p_index]; }; @@ -167,5 +167,5 @@ CameraServer::CameraServer() { }; CameraServer::~CameraServer() { - singleton = NULL; + singleton = nullptr; }; diff --git a/servers/display_server.h b/servers/display_server.h index 1956bcafca..93db7ef844 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -180,7 +180,7 @@ public: }; virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW); - ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; virtual void screen_set_keep_on(bool p_enable); //disable screensaver virtual bool screen_is_kept_on() const; diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index fe9eaa5736..17f2232c72 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -37,7 +37,7 @@ @author AndreaCatania */ -NavigationServer2D *NavigationServer2D::singleton = NULL; +NavigationServer2D *NavigationServer2D::singleton = nullptr; #define FORWARD_0_C(FUNC_NAME) \ NavigationServer2D::FUNC_NAME() \ @@ -167,7 +167,7 @@ NavigationServer2D::NavigationServer2D() { } NavigationServer2D::~NavigationServer2D() { - singleton = NULL; + singleton = nullptr; } RID FORWARD_0_C(map_create); diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 3e7a8e816e..67a4d0e413 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -34,7 +34,7 @@ #include "navigation_server_3d.h" -NavigationServer3D *NavigationServer3D::singleton = NULL; +NavigationServer3D *NavigationServer3D::singleton = nullptr; void NavigationServer3D::_bind_methods() { @@ -87,21 +87,21 @@ NavigationServer3D *NavigationServer3D::get_singleton_mut() { } NavigationServer3D::NavigationServer3D() { - ERR_FAIL_COND(singleton != NULL); + ERR_FAIL_COND(singleton != nullptr); singleton = this; } NavigationServer3D::~NavigationServer3D() { - singleton = NULL; + singleton = nullptr; } -NavigationServer3DCallback NavigationServer3DManager::create_callback = NULL; +NavigationServer3DCallback NavigationServer3DManager::create_callback = nullptr; void NavigationServer3DManager::set_default_server(NavigationServer3DCallback p_callback) { create_callback = p_callback; } NavigationServer3D *NavigationServer3DManager::new_default_server() { - ERR_FAIL_COND_V(create_callback == NULL, NULL); + ERR_FAIL_COND_V(create_callback == nullptr, nullptr); return create_callback(); } diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 669f27bcc8..0e70a626c2 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -37,7 +37,7 @@ bool AreaPair2DSW::setup(real_t p_step) { if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) { result = false; - } else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this)) { + } else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) { result = true; } @@ -100,7 +100,7 @@ bool Area2Pair2DSW::setup(real_t p_step) { bool result = false; if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) { result = false; - } else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this)) { + } else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) { result = true; } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 11cf1339bc..39e28fd002 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -538,8 +538,8 @@ void Body2DSW::integrate_forces(real_t p_step) { _update_shapes_with_motion(motion); } - // damp_area=NULL; // clear the area, so it is set in the next frame - def_area = NULL; // clear the area, so it is set in the next frame + // damp_area=nullptr; // clear the area, so it is set in the next frame + def_area = nullptr; // clear the area, so it is set in the next frame contact_count = 0; } @@ -650,7 +650,7 @@ void Body2DSW::set_force_integration_callback(ObjectID p_id, const StringName &p if (fi_callback) { memdelete(fi_callback); - fi_callback = NULL; + fi_callback = nullptr; } if (p_id.is_valid()) { @@ -682,8 +682,8 @@ Body2DSW::Body2DSW() : omit_force_integration = false; applied_torque = 0; island_step = 0; - island_next = NULL; - island_list_next = NULL; + island_next = nullptr; + island_list_next = nullptr; _set_static(false); first_time_kinematic = false; linear_damp = -1; @@ -697,7 +697,7 @@ Body2DSW::Body2DSW() : still_time = 0; continuous_cd_mode = PhysicsServer2D::CCD_MODE_DISABLED; can_sleep = true; - fi_callback = NULL; + fi_callback = nullptr; } Body2DSW::~Body2DSW() { @@ -706,7 +706,7 @@ Body2DSW::~Body2DSW() { memdelete(fi_callback); } -PhysicsDirectBodyState2DSW *PhysicsDirectBodyState2DSW::singleton = NULL; +PhysicsDirectBodyState2DSW *PhysicsDirectBodyState2DSW::singleton = nullptr; PhysicsDirectSpaceState2D *PhysicsDirectBodyState2DSW::get_space_state() { diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index e463377c7b..0514b263b4 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -419,7 +419,7 @@ public: virtual real_t get_step() const { return step; } PhysicsDirectBodyState2DSW() { singleton = this; - body = NULL; + body = nullptr; } }; diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp index 11bf8712ac..5e3a13f4dd 100644 --- a/servers/physics_2d/broad_phase_2d_basic.cpp +++ b/servers/physics_2d/broad_phase_2d_basic.cpp @@ -65,7 +65,7 @@ void BroadPhase2DBasic::remove(ID p_id) { CollisionObject2DSW *BroadPhase2DBasic::get_object(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, NULL); + ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } bool BroadPhase2DBasic::is_static(ID p_id) const { @@ -158,7 +158,7 @@ void BroadPhase2DBasic::update() { if (pair_ok && !E) { - void *data = NULL; + void *data = nullptr; if (pair_callback) data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); pair_map.insert(key, data); @@ -175,8 +175,8 @@ BroadPhase2DSW *BroadPhase2DBasic::_create() { BroadPhase2DBasic::BroadPhase2DBasic() { current = 1; - unpair_callback = NULL; - unpair_userdata = NULL; - pair_callback = NULL; - pair_userdata = NULL; + unpair_callback = nullptr; + unpair_userdata = nullptr; + pair_callback = nullptr; + pair_userdata = nullptr; } diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h index fea5668c89..7d02590af9 100644 --- a/servers/physics_2d/broad_phase_2d_basic.h +++ b/servers/physics_2d/broad_phase_2d_basic.h @@ -91,8 +91,8 @@ public: virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp index 711ff9f1f7..2cb021258a 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp @@ -394,7 +394,7 @@ void BroadPhase2DHashGrid::remove(ID p_id) { CollisionObject2DSW *BroadPhase2DHashGrid::get_object(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, NULL); + ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } bool BroadPhase2DHashGrid::is_static(ID p_id) const { @@ -646,7 +646,7 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() { ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/large_object_surface_threshold_in_cells", PropertyInfo(Variant::INT, "physics/2d/large_object_surface_threshold_in_cells", PROPERTY_HINT_RANGE, "0,1024,1,or_greater")); for (uint32_t i = 0; i < hash_table_size; i++) - hash_table[i] = NULL; + hash_table[i] = nullptr; pass = 1; current = 0; diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h index e75b51c19d..dc29d0c619 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.h +++ b/servers/physics_2d/broad_phase_2d_hash_grid.h @@ -44,7 +44,7 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { PairData() { colliding = false; rc = 1; - ud = NULL; + ud = nullptr; } }; @@ -177,8 +177,8 @@ public: virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics_2d/broad_phase_2d_sw.cpp b/servers/physics_2d/broad_phase_2d_sw.cpp index c9e1dd8758..5ba557e70a 100644 --- a/servers/physics_2d/broad_phase_2d_sw.cpp +++ b/servers/physics_2d/broad_phase_2d_sw.cpp @@ -30,7 +30,7 @@ #include "broad_phase_2d_sw.h" -BroadPhase2DSW::CreateFunction BroadPhase2DSW::create_func = NULL; +BroadPhase2DSW::CreateFunction BroadPhase2DSW::create_func = nullptr; BroadPhase2DSW::~BroadPhase2DSW() { } diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h index c7777d9d92..5e42c72d83 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/broad_phase_2d_sw.h @@ -58,8 +58,8 @@ public: virtual bool is_static(ID p_id) const = 0; virtual int get_subindex(ID p_id) const = 0; - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; + virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index a6891372c2..0ec293c042 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -266,7 +266,7 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) : _static = true; type = p_type; - space = NULL; + space = nullptr; collision_mask = 1; collision_layer = 1; pickable = true; diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp index 217c93c6da..a954cb3de3 100644 --- a/servers/physics_2d/collision_solver_2d_sat.cpp +++ b/servers/physics_2d/collision_solver_2d_sat.cpp @@ -145,7 +145,7 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po _generate_contacts_point_edge, }, { - 0, + nullptr, _generate_contacts_edge_edge, } }; @@ -1060,25 +1060,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<false, false, false>, _collision_segment_capsule<false, false, false>, _collision_segment_convex_polygon<false, false, false> }, - { 0, + { nullptr, _collision_circle_circle<false, false, false>, _collision_circle_rectangle<false, false, false>, _collision_circle_capsule<false, false, false>, _collision_circle_convex_polygon<false, false, false> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<false, false, false>, _collision_rectangle_capsule<false, false, false>, _collision_rectangle_convex_polygon<false, false, false> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<false, false, false>, _collision_capsule_convex_polygon<false, false, false> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<false, false, false> } }; @@ -1089,25 +1089,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<true, false, false>, _collision_segment_capsule<true, false, false>, _collision_segment_convex_polygon<true, false, false> }, - { 0, + { nullptr, _collision_circle_circle<true, false, false>, _collision_circle_rectangle<true, false, false>, _collision_circle_capsule<true, false, false>, _collision_circle_convex_polygon<true, false, false> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<true, false, false>, _collision_rectangle_capsule<true, false, false>, _collision_rectangle_convex_polygon<true, false, false> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<true, false, false>, _collision_capsule_convex_polygon<true, false, false> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<true, false, false> } }; @@ -1118,25 +1118,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<false, true, false>, _collision_segment_capsule<false, true, false>, _collision_segment_convex_polygon<false, true, false> }, - { 0, + { nullptr, _collision_circle_circle<false, true, false>, _collision_circle_rectangle<false, true, false>, _collision_circle_capsule<false, true, false>, _collision_circle_convex_polygon<false, true, false> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<false, true, false>, _collision_rectangle_capsule<false, true, false>, _collision_rectangle_convex_polygon<false, true, false> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<false, true, false>, _collision_capsule_convex_polygon<false, true, false> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<false, true, false> } }; @@ -1147,25 +1147,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<true, true, false>, _collision_segment_capsule<true, true, false>, _collision_segment_convex_polygon<true, true, false> }, - { 0, + { nullptr, _collision_circle_circle<true, true, false>, _collision_circle_rectangle<true, true, false>, _collision_circle_capsule<true, true, false>, _collision_circle_convex_polygon<true, true, false> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<true, true, false>, _collision_rectangle_capsule<true, true, false>, _collision_rectangle_convex_polygon<true, true, false> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<true, true, false>, _collision_capsule_convex_polygon<true, true, false> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<true, true, false> } }; @@ -1176,25 +1176,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<false, false, true>, _collision_segment_capsule<false, false, true>, _collision_segment_convex_polygon<false, false, true> }, - { 0, + { nullptr, _collision_circle_circle<false, false, true>, _collision_circle_rectangle<false, false, true>, _collision_circle_capsule<false, false, true>, _collision_circle_convex_polygon<false, false, true> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<false, false, true>, _collision_rectangle_capsule<false, false, true>, _collision_rectangle_convex_polygon<false, false, true> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<false, false, true>, _collision_capsule_convex_polygon<false, false, true> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<false, false, true> } }; @@ -1205,25 +1205,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<true, false, true>, _collision_segment_capsule<true, false, true>, _collision_segment_convex_polygon<true, false, true> }, - { 0, + { nullptr, _collision_circle_circle<true, false, true>, _collision_circle_rectangle<true, false, true>, _collision_circle_capsule<true, false, true>, _collision_circle_convex_polygon<true, false, true> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<true, false, true>, _collision_rectangle_capsule<true, false, true>, _collision_rectangle_convex_polygon<true, false, true> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<true, false, true>, _collision_capsule_convex_polygon<true, false, true> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<true, false, true> } }; @@ -1234,25 +1234,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<false, true, true>, _collision_segment_capsule<false, true, true>, _collision_segment_convex_polygon<false, true, true> }, - { 0, + { nullptr, _collision_circle_circle<false, true, true>, _collision_circle_rectangle<false, true, true>, _collision_circle_capsule<false, true, true>, _collision_circle_convex_polygon<false, true, true> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<false, true, true>, _collision_rectangle_capsule<false, true, true>, _collision_rectangle_convex_polygon<false, true, true> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<false, true, true>, _collision_capsule_convex_polygon<false, true, true> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<false, true, true> } }; @@ -1263,25 +1263,25 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D _collision_segment_rectangle<true, true, true>, _collision_segment_capsule<true, true, true>, _collision_segment_convex_polygon<true, true, true> }, - { 0, + { nullptr, _collision_circle_circle<true, true, true>, _collision_circle_rectangle<true, true, true>, _collision_circle_capsule<true, true, true>, _collision_circle_convex_polygon<true, true, true> }, - { 0, - 0, + { nullptr, + nullptr, _collision_rectangle_rectangle<true, true, true>, _collision_rectangle_capsule<true, true, true>, _collision_rectangle_convex_polygon<true, true, true> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_capsule_capsule<true, true, true>, _collision_capsule_convex_polygon<true, true, true> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<true, true, true> } }; diff --git a/servers/physics_2d/collision_solver_2d_sat.h b/servers/physics_2d/collision_solver_2d_sat.h index 105cb9104d..6bb485f561 100644 --- a/servers/physics_2d/collision_solver_2d_sat.h +++ b/servers/physics_2d/collision_solver_2d_sat.h @@ -33,6 +33,6 @@ #include "collision_solver_2d_sw.h" -bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); +bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector2 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); #endif // COLLISION_SOLVER_2D_SAT_H diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h index e73ee8fd7e..f39cfee0a9 100644 --- a/servers/physics_2d/collision_solver_2d_sw.h +++ b/servers/physics_2d/collision_solver_2d_sw.h @@ -40,11 +40,11 @@ public: private: static bool solve_static_line(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); static void concave_callback(void *p_userdata, Shape2DSW *p_convex); - static bool solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *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 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL); + static bool solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *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 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = nullptr); public: - static bool solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); }; #endif // COLLISION_SOLVER_2D_SW_H diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/constraint_2d_sw.h index b5c994cbdd..f8eb16214f 100644 --- a/servers/physics_2d/constraint_2d_sw.h +++ b/servers/physics_2d/constraint_2d_sw.h @@ -45,7 +45,7 @@ class Constraint2DSW { RID self; protected: - Constraint2DSW(Body2DSW **p_body_ptr = NULL, int p_body_count = 0) { + Constraint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) { _body_ptr = p_body_ptr; _body_count = p_body_count; island_step = 0; diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h index f4aeb6e3c8..a0d25dc70d 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/joints_2d_sw.h @@ -51,7 +51,7 @@ public: _FORCE_INLINE_ real_t get_max_bias() const { return max_bias; } virtual PhysicsServer2D::JointType get_type() const = 0; - Joint2DSW(Body2DSW **p_body_ptr = NULL, int p_body_count = 0) : + Joint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint2DSW(p_body_ptr, p_body_count) { bias = 0; max_force = max_bias = 3.40282e+38; @@ -86,7 +86,7 @@ public: void set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value); real_t get_param(PhysicsServer2D::PinJointParam p_param) const; - PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b = NULL); + PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b = nullptr); ~PinJoint2DSW(); }; diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index e2a482e960..871e2aba1d 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -42,7 +42,7 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { - Shape2DSW *shape = NULL; + Shape2DSW *shape = nullptr; switch (p_shape) { case SHAPE_LINE: { @@ -227,7 +227,7 @@ bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_ if (p_result_max == 0) { - return CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, NULL, NULL); + return CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr); } CollCbkData cbk; @@ -313,8 +313,8 @@ int PhysicsServer2DSW::space_get_contact_count(RID p_space) const { PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space) { Space2DSW *space = space_owner.getornull(p_space); - ERR_FAIL_COND_V(!space, NULL); - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), NULL, "Space state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V(!space, nullptr); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); return space->get_direct_state(); } @@ -332,7 +332,7 @@ void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - Space2DSW *space = NULL; + Space2DSW *space = nullptr; if (p_space.is_valid()) { space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -596,7 +596,7 @@ void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); - Space2DSW *space = NULL; + Space2DSW *space = nullptr; if (p_space.is_valid()) { space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -1069,15 +1069,15 @@ int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); if (!body_owner.owns(p_body)) - return NULL; + return nullptr; Body2DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, NULL); - ERR_FAIL_COND_V(!body->get_space(), NULL); - ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V(!body, nullptr); + ERR_FAIL_COND_V(!body->get_space(), nullptr); + ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); direct_state->body = body; return direct_state; @@ -1142,7 +1142,7 @@ RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID Body2DSW *A = body_owner.getornull(p_body_a); ERR_FAIL_COND_V(!A, RID()); - Body2DSW *B = NULL; + Body2DSW *B = nullptr; if (body_owner.owns(p_body_b)) { B = body_owner.getornull(p_body_b); ERR_FAIL_COND_V(!B, RID()); @@ -1276,7 +1276,7 @@ void PhysicsServer2DSW::free(RID p_rid) { _clear_query(area->get_monitor_query()); */ - area->set_space(NULL); + area->set_space(nullptr); while (area->get_shape_count()) { @@ -1291,7 +1291,7 @@ void PhysicsServer2DSW::free(RID p_rid) { while (space->get_objects().size()) { CollisionObject2DSW *co = (CollisionObject2DSW *)space->get_objects().front()->get(); - co->set_space(NULL); + co->set_space(nullptr); } active_spaces.erase(space); @@ -1444,7 +1444,7 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { return 0; } -PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = NULL; +PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; PhysicsServer2DSW::PhysicsServer2DSW() { diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 9dfa8bf474..918958ffe2 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -249,7 +249,7 @@ public: virtual void body_set_pickable(RID p_body, bool p_pickable); - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true); + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true); virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001); // this function only works on physics process, errors and returns null otherwise diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 5f65e296fd..0a89a76615 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -126,7 +126,7 @@ void PhysicsServer2DWrapMT::finish() { Thread::wait_to_finish(thread); memdelete(thread); - thread = NULL; + thread = nullptr; } else { physics_2d_server->finish(); } @@ -150,7 +150,7 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool physics_2d_server = p_contained; create_thread = p_create_thread; - thread = NULL; + thread = nullptr; step_pending = 0; step_thread_up = false; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index ffd46feebd..7e61927378 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -112,7 +112,7 @@ public: // this function only works on physics process, errors and returns null otherwise PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), NULL); + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->space_get_direct_state(p_space); } @@ -255,7 +255,7 @@ public: FUNC2(body_set_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) { + bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); @@ -270,7 +270,7 @@ public: // this function only works on physics process, errors and returns null otherwise PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), NULL); + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->body_get_direct_state(p_body); } diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 5fefb9595f..06096d674a 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -643,7 +643,7 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { if (points) memdelete_arr(points); - points = NULL; + points = nullptr; point_count = 0; if (p_data.get_type() == Variant::PACKED_VECTOR2_ARRAY) { @@ -706,7 +706,7 @@ Variant ConvexPolygonShape2DSW::get_data() const { ConvexPolygonShape2DSW::ConvexPolygonShape2DSW() { - points = NULL; + points = nullptr; point_count = 0; } diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index cba190995f..7ae2e9769f 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -222,7 +222,7 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), NULL, NULL, NULL, p_margin)) + if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) continue; r_results[cc].collider_id = col_obj->get_instance_id(); @@ -265,12 +265,12 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) { + if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } //test initial overlap - if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) { + if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { return false; } @@ -285,7 +285,7 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor real_t ofs = (low + hi) * 0.5; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, &sep, p_margin); + bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); if (collided) { @@ -348,7 +348,7 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & cbk.valid_dir = Vector2(); cbk.valid_depth = 0; - if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { + if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, nullptr, p_margin)) { collided = cbk.amount > 0; } } @@ -415,7 +415,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh _RestCallbackData2D rcd; rcd.best_len = 0; - rcd.best_object = NULL; + rcd.best_object = nullptr; rcd.best_shape = 0; rcd.min_allowed_depth = space->test_motion_min_contact_depth; @@ -435,7 +435,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh rcd.object = col_obj; rcd.shape = shape_idx; rcd.local_shape = 0; - bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) continue; } @@ -464,7 +464,7 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh PhysicsDirectSpaceState2DSW::PhysicsDirectSpaceState2DSW() { - space = NULL; + space = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -613,7 +613,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t */ Shape2DSW *against_shape = col_obj->get_shape(shape_idx); - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, NULL, p_margin)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_margin)) { if (cbk.amount > 0) { collided = true; } @@ -818,7 +818,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co bool did_collide = false; Shape2DSW *against_shape = col_obj->get_shape(shape_idx); - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, NULL, separation_margin)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, separation_margin)) { did_collide = cbk.passed > current_passed; //more passed, so collision actually existed } @@ -925,12 +925,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { continue; } //test initial overlap - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { continue; @@ -950,7 +950,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co real_t ofs = (low + hi) * 0.5; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, &sep, 0); + bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); if (collided) { @@ -1018,7 +1018,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co _RestCallbackData2D rcd; rcd.best_len = 0; - rcd.best_object = NULL; + rcd.best_object = nullptr; rcd.best_shape = 0; rcd.min_allowed_depth = test_motion_min_contact_depth; @@ -1081,7 +1081,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co rcd.object = col_obj; rcd.shape = shape_idx; rcd.local_shape = j; - bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) continue; } @@ -1156,7 +1156,7 @@ void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, Coll return b; } - return NULL; + return nullptr; } void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_self) { @@ -1351,7 +1351,7 @@ Space2DSW::Space2DSW() { broadphase = BroadPhase2DSW::create_func(); broadphase->set_pair_callback(_broadphase_pair, this); broadphase->set_unpair_callback(_broadphase_unpair, this); - area = NULL; + area = nullptr; direct_access = memnew(PhysicsDirectSpaceState2DSW); direct_access->space = this; diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp index 198fccdb80..6f3bcfec13 100644 --- a/servers/physics_2d/step_2d_sw.cpp +++ b/servers/physics_2d/step_2d_sw.cpp @@ -60,7 +60,7 @@ void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constrain bool Step2DSW::_setup_island(Constraint2DSW *p_island, real_t p_delta) { Constraint2DSW *ci = p_island; - Constraint2DSW *prev_ci = NULL; + Constraint2DSW *prev_ci = nullptr; bool removed_root = false; while (ci) { bool process = ci->setup(p_delta); @@ -164,8 +164,8 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { /* GENERATE CONSTRAINT ISLANDS */ - Body2DSW *island_list = NULL; - Constraint2DSW *constraint_island_list = NULL; + Body2DSW *island_list = nullptr; + Constraint2DSW *constraint_island_list = nullptr; b = body_list->first(); int island_count = 0; @@ -175,8 +175,8 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { if (body->get_island_step() != _step) { - Body2DSW *island = NULL; - Constraint2DSW *constraint_island = NULL; + Body2DSW *island = nullptr; + Constraint2DSW *constraint_island = nullptr; _populate_island(body, &island, &constraint_island); island->set_island_list_next(island_list); @@ -202,7 +202,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { if (c->get_island_step() == _step) continue; c->set_island_step(_step); - c->set_island_next(NULL); + c->set_island_next(nullptr); c->set_island_list_next(constraint_island_list); constraint_island_list = c; } @@ -219,7 +219,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { { Constraint2DSW *ci = constraint_island_list; - Constraint2DSW *prev_ci = NULL; + Constraint2DSW *prev_ci = nullptr; while (ci) { if (_setup_island(ci, p_delta)) { diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/area_pair_3d_sw.cpp index e92a3a0dd1..fa2fb2dabb 100644 --- a/servers/physics_3d/area_pair_3d_sw.cpp +++ b/servers/physics_3d/area_pair_3d_sw.cpp @@ -37,7 +37,7 @@ bool AreaPair3DSW::setup(real_t p_step) { if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) { result = false; - } else if (area->test_collision_mask(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), NULL, this)) { + } else if (area->test_collision_mask(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) { result = true; } @@ -100,7 +100,7 @@ bool Area2Pair3DSW::setup(real_t p_step) { bool result = false; if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) { result = false; - } else if (area_a->test_collision_mask(area_b) && CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), NULL, this)) { + } else if (area_a->test_collision_mask(area_b) && CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) { result = true; } diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp index 6a00e4f471..fea5aed6ad 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/body_3d_sw.cpp @@ -569,7 +569,7 @@ void Body3DSW::integrate_forces(real_t p_step) { _update_shapes_with_motion(motion); } - def_area = NULL; // clear the area, so it is set in the next frame + def_area = nullptr; // clear the area, so it is set in the next frame contact_count = 0; } @@ -746,7 +746,7 @@ void Body3DSW::set_force_integration_callback(ObjectID p_id, const StringName &p if (fi_callback) { memdelete(fi_callback); - fi_callback = NULL; + fi_callback = nullptr; } if (p_id.is_valid()) { @@ -781,8 +781,8 @@ Body3DSW::Body3DSW() : omit_force_integration = false; //applied_torque=0; island_step = 0; - island_next = NULL; - island_list_next = NULL; + island_next = nullptr; + island_list_next = nullptr; first_time_kinematic = false; first_integration = false; _set_static(false); @@ -797,7 +797,7 @@ Body3DSW::Body3DSW() : still_time = 0; continuous_cd = false; can_sleep = true; - fi_callback = NULL; + fi_callback = nullptr; } Body3DSW::~Body3DSW() { @@ -806,7 +806,7 @@ Body3DSW::~Body3DSW() { memdelete(fi_callback); } -PhysicsDirectBodyState3DSW *PhysicsDirectBodyState3DSW::singleton = NULL; +PhysicsDirectBodyState3DSW *PhysicsDirectBodyState3DSW::singleton = nullptr; PhysicsDirectSpaceState3D *PhysicsDirectBodyState3DSW::get_space_state() { diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index 368dd59b06..b553cf0670 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -468,7 +468,7 @@ public: virtual real_t get_step() const { return step; } PhysicsDirectBodyState3DSW() { singleton = this; - body = NULL; + body = nullptr; } }; diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp index bea87a45ca..08ea219869 100644 --- a/servers/physics_3d/broad_phase_3d_basic.cpp +++ b/servers/physics_3d/broad_phase_3d_basic.cpp @@ -34,7 +34,7 @@ BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int p_subindex) { - ERR_FAIL_COND_V(p_object == NULL, 0); + ERR_FAIL_COND_V(p_object == nullptr, 0); current++; @@ -88,7 +88,7 @@ void BroadPhase3DBasic::remove(ID p_id) { CollisionObject3DSW *BroadPhase3DBasic::get_object(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, NULL); + ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } bool BroadPhase3DBasic::is_static(ID p_id) const { @@ -201,7 +201,7 @@ void BroadPhase3DBasic::update() { if (pair_ok && !E) { - void *data = NULL; + void *data = nullptr; if (pair_callback) data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); pair_map.insert(key, data); @@ -218,8 +218,8 @@ BroadPhase3DSW *BroadPhase3DBasic::_create() { BroadPhase3DBasic::BroadPhase3DBasic() { current = 1; - unpair_callback = NULL; - unpair_userdata = NULL; - pair_callback = NULL; - pair_userdata = NULL; + unpair_callback = nullptr; + unpair_userdata = nullptr; + pair_callback = nullptr; + pair_userdata = nullptr; } diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/servers/physics_3d/broad_phase_3d_basic.h index 9b20b7619a..563dda6931 100644 --- a/servers/physics_3d/broad_phase_3d_basic.h +++ b/servers/physics_3d/broad_phase_3d_basic.h @@ -92,9 +92,9 @@ public: virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics_3d/broad_phase_3d_sw.cpp b/servers/physics_3d/broad_phase_3d_sw.cpp index 5e367a7736..1a20fdd0cb 100644 --- a/servers/physics_3d/broad_phase_3d_sw.cpp +++ b/servers/physics_3d/broad_phase_3d_sw.cpp @@ -30,7 +30,7 @@ #include "broad_phase_3d_sw.h" -BroadPhase3DSW::CreateFunction BroadPhase3DSW::create_func = NULL; +BroadPhase3DSW::CreateFunction BroadPhase3DSW::create_func = nullptr; BroadPhase3DSW::~BroadPhase3DSW() { } diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/broad_phase_3d_sw.h index 47d09a8b1d..5950489619 100644 --- a/servers/physics_3d/broad_phase_3d_sw.h +++ b/servers/physics_3d/broad_phase_3d_sw.h @@ -58,9 +58,9 @@ public: virtual bool is_static(ID p_id) const = 0; virtual int get_subindex(ID p_id) const = 0; - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; + virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; + virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; diff --git a/servers/physics_3d/broad_phase_octree.cpp b/servers/physics_3d/broad_phase_octree.cpp index 50ac17e027..264ab21e1e 100644 --- a/servers/physics_3d/broad_phase_octree.cpp +++ b/servers/physics_3d/broad_phase_octree.cpp @@ -55,7 +55,7 @@ void BroadPhaseOctree::remove(ID p_id) { CollisionObject3DSW *BroadPhaseOctree::get_object(ID p_id) const { CollisionObject3DSW *it = octree.get(p_id); - ERR_FAIL_COND_V(!it, NULL); + ERR_FAIL_COND_V(!it, nullptr); return it; } bool BroadPhaseOctree::is_static(ID p_id) const { @@ -86,7 +86,7 @@ void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, Collisio BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self); if (!bpo->pair_callback) - return NULL; + return nullptr; return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); } @@ -123,7 +123,7 @@ BroadPhase3DSW *BroadPhaseOctree::_create() { BroadPhaseOctree::BroadPhaseOctree() { octree.set_pair_callback(_pair_callback, this); octree.set_unpair_callback(_unpair_callback, this); - pair_callback = NULL; - pair_userdata = NULL; - unpair_userdata = NULL; + pair_callback = nullptr; + pair_userdata = nullptr; + unpair_userdata = nullptr; } diff --git a/servers/physics_3d/broad_phase_octree.h b/servers/physics_3d/broad_phase_octree.h index 25cf5b32da..0ad59d8b0c 100644 --- a/servers/physics_3d/broad_phase_octree.h +++ b/servers/physics_3d/broad_phase_octree.h @@ -57,9 +57,9 @@ public: virtual bool is_static(ID p_id) const; virtual int get_subindex(ID p_id) const; - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); + virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index ba13d70e4f..24715d211d 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -231,7 +231,7 @@ CollisionObject3DSW::CollisionObject3DSW(Type p_type) : _static = true; type = p_type; - space = NULL; + space = nullptr; collision_layer = 1; collision_mask = 1; diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index 0a7a9caf91..5096b080ab 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -241,13 +241,13 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po _generate_contacts_point_face, }, { - 0, + nullptr, _generate_contacts_edge_edge, _generate_contacts_face_face, }, { - 0, - 0, + nullptr, + nullptr, _generate_contacts_face_face, } }; @@ -1483,36 +1483,36 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_tr _collision_sphere_cylinder<false>, _collision_sphere_convex_polygon<false>, _collision_sphere_face<false> }, - { 0, + { nullptr, _collision_box_box<false>, _collision_box_capsule<false>, _collision_box_cylinder<false>, _collision_box_convex_polygon<false>, _collision_box_face<false> }, - { 0, - 0, + { nullptr, + nullptr, _collision_capsule_capsule<false>, _collision_capsule_cylinder<false>, _collision_capsule_convex_polygon<false>, _collision_capsule_face<false> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_cylinder_cylinder<false>, _collision_cylinder_convex_polygon<false>, _collision_cylinder_face<false> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<false>, _collision_convex_polygon_face<false> }, - { 0, - 0, - 0, - 0, - 0, - 0 }, + { nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }, }; static const CollisionFunc collision_table_margin[6][6] = { @@ -1522,36 +1522,36 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_tr _collision_sphere_cylinder<true>, _collision_sphere_convex_polygon<true>, _collision_sphere_face<true> }, - { 0, + { nullptr, _collision_box_box<true>, _collision_box_capsule<true>, _collision_box_cylinder<true>, _collision_box_convex_polygon<true>, _collision_box_face<true> }, - { 0, - 0, + { nullptr, + nullptr, _collision_capsule_capsule<true>, _collision_capsule_cylinder<true>, _collision_capsule_convex_polygon<true>, _collision_capsule_face<true> }, - { 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, _collision_cylinder_cylinder<true>, _collision_cylinder_convex_polygon<true>, _collision_cylinder_face<true> }, - { 0, - 0, - 0, - 0, + { nullptr, + nullptr, + nullptr, + nullptr, _collision_convex_polygon_convex_polygon<true>, _collision_convex_polygon_face<true> }, - { 0, - 0, - 0, - 0, - 0, - 0 }, + { nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }, }; _CollectorCallback callback; diff --git a/servers/physics_3d/collision_solver_3d_sat.h b/servers/physics_3d/collision_solver_3d_sat.h index c8ffd8e660..5eccfda9ac 100644 --- a/servers/physics_3d/collision_solver_3d_sat.h +++ b/servers/physics_3d/collision_solver_3d_sat.h @@ -33,6 +33,6 @@ #include "collision_solver_3d_sw.h" -bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = NULL, real_t p_margin_a = 0, real_t p_margin_b = 0); +bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); #endif // COLLISION_SOLVER_SAT_H diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index 26de49c96f..5d31e1f546 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -125,7 +125,7 @@ void CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; - bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, NULL, cinfo.margin_A, cinfo.margin_B); + bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, nullptr, cinfo.margin_A, cinfo.margin_B); if (!collided) return; @@ -316,8 +316,8 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans cinfo.transform_A = &p_transform_A; cinfo.shape_A = p_shape_A; cinfo.transform_B = &p_transform_B; - cinfo.result_callback = NULL; - cinfo.userdata = NULL; + cinfo.result_callback = nullptr; + cinfo.userdata = nullptr; cinfo.swap_result = false; cinfo.collided = false; cinfo.collisions = 0; diff --git a/servers/physics_3d/collision_solver_3d_sw.h b/servers/physics_3d/collision_solver_3d_sw.h index ec76a4217e..13f54ca8fb 100644 --- a/servers/physics_3d/collision_solver_3d_sw.h +++ b/servers/physics_3d/collision_solver_3d_sw.h @@ -46,8 +46,8 @@ private: static bool solve_distance_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B); public: - static bool solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = NULL); + static bool solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = nullptr); }; #endif // COLLISION_SOLVER__SW_H diff --git a/servers/physics_3d/constraint_3d_sw.h b/servers/physics_3d/constraint_3d_sw.h index b9d3ac4f12..5e2b00404b 100644 --- a/servers/physics_3d/constraint_3d_sw.h +++ b/servers/physics_3d/constraint_3d_sw.h @@ -46,7 +46,7 @@ class Constraint3DSW { RID self; protected: - Constraint3DSW(Body3DSW **p_body_ptr = NULL, int p_body_count = 0) { + Constraint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) { _body_ptr = p_body_ptr; _body_count = p_body_count; island_step = 0; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index bd0d429e7b..db37f261ce 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -515,14 +515,14 @@ struct GJK { sFace* root; U count; - sList() : root(0),count(0) {} + sList() : root(nullptr),count(0) {} }; struct sHorizon { sFace* cf; sFace* ff; U nf; - sHorizon() : cf(0),ff(0),nf(0) {} + sHorizon() : cf(nullptr),ff(nullptr),nf(0) {} }; struct eStatus { enum _ { Valid, @@ -559,7 +559,7 @@ struct GJK } static inline void append(sList& list,sFace* face) { - face->l[0] = 0; + face->l[0] = nullptr; face->l[1] = list.root; if(list.root) list.root->l[0]=face; list.root = face; @@ -720,13 +720,13 @@ struct GJK } else m_status=eStatus::Degenerated; remove(m_hull,face); append(m_stock,face); - return(0); + return(nullptr); } // -- GODOT start -- //m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces; m_status=eStatus::OutOfFaces; // -- GODOT end -- - return(0); + return(nullptr); } sFace* findbest() { diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h index 435ee2301d..0f2d4892a8 100644 --- a/servers/physics_3d/joints_3d_sw.h +++ b/servers/physics_3d/joints_3d_sw.h @@ -38,7 +38,7 @@ class Joint3DSW : public Constraint3DSW { public: virtual PhysicsServer3D::JointType get_type() const = 0; - _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = NULL, int p_body_count = 0) : + _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint3DSW(p_body_ptr, p_body_count) { } }; diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index 11a3b7bbb8..bc42c2fd9e 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -45,7 +45,7 @@ RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { - Shape3DSW *shape = NULL; + Shape3DSW *shape = nullptr; switch (p_shape) { case SHAPE_PLANE: { @@ -195,8 +195,8 @@ real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) c PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { Space3DSW *space = space_owner.getornull(p_space); - ERR_FAIL_COND_V(!space, NULL); - ERR_FAIL_COND_V_MSG(!doing_sync || space->is_locked(), NULL, "Space state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V(!space, nullptr); + ERR_FAIL_COND_V_MSG(!doing_sync || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); return space->get_direct_state(); } @@ -235,7 +235,7 @@ void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - Space3DSW *space = NULL; + Space3DSW *space = nullptr; if (p_space.is_valid()) { space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -492,7 +492,7 @@ void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); - Space3DSW *space = NULL; + Space3DSW *space = nullptr; if (p_space.is_valid()) { space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -978,8 +978,8 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, NULL); - ERR_FAIL_COND_V_MSG(!doing_sync || body->get_space()->is_locked(), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V(!body, nullptr); + ERR_FAIL_COND_V_MSG(!doing_sync || body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); direct_state->body = body; return direct_state; @@ -1341,7 +1341,7 @@ void PhysicsServer3DSW::free(RID p_rid) { _clear_query(body->get_direct_state_query()); */ - body->set_space(NULL); + body->set_space(nullptr); while (body->get_shape_count()) { @@ -1360,7 +1360,7 @@ void PhysicsServer3DSW::free(RID p_rid) { _clear_query(area->get_monitor_query()); */ - area->set_space(NULL); + area->set_space(nullptr); while (area->get_shape_count()) { @@ -1375,7 +1375,7 @@ void PhysicsServer3DSW::free(RID p_rid) { while (space->get_objects().size()) { CollisionObject3DSW *co = (CollisionObject3DSW *)space->get_objects().front()->get(); - co->set_space(NULL); + co->set_space(nullptr); } active_spaces.erase(space); @@ -1572,7 +1572,7 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 & } } -PhysicsServer3DSW *PhysicsServer3DSW::singleton = NULL; +PhysicsServer3DSW *PhysicsServer3DSW::singleton = nullptr; PhysicsServer3DSW::PhysicsServer3DSW() { singleton = this; BroadPhase3DSW::create_func = BroadPhaseOctree::_create; diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 67123084c1..6e79d9eceb 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -237,7 +237,7 @@ public: virtual void body_set_ray_pickable(RID p_body, bool p_enable); virtual bool body_is_ray_pickable(RID p_body) const; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true); + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true); virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001); // this function only works on physics process, errors and returns null otherwise diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 52253d615a..61c32b779a 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -1385,8 +1385,8 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz if (p_size == 1) { //leaf bvh->aabb = p_elements[0].aabb; - bvh->left = NULL; - bvh->right = NULL; + bvh->left = nullptr; + bvh->right = nullptr; bvh->face_index = p_elements->face_index; count++; return bvh; diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 9bd507e178..bd8e89a8f5 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -83,7 +83,7 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe if (r_results[cc].collider_id.is_valid()) r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); else - r_results[cc].collider = NULL; + r_results[cc].collider = nullptr; r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; @@ -162,7 +162,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec if (r_result.collider_id.is_valid()) r_result.collider = ObjectDB::get_instance(r_result.collider_id); else - r_result.collider = NULL; + r_result.collider = nullptr; r_result.normal = res_normal; r_result.position = res_point; r_result.rid = res_obj->get_self(); @@ -203,7 +203,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL, NULL, NULL, p_margin, 0)) + if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) continue; if (r_results) { @@ -211,7 +211,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans if (r_results[cc].collider_id.is_valid()) r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); else - r_results[cc].collider = NULL; + r_results[cc].collider = nullptr; r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; } @@ -364,7 +364,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ continue; } - if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) { + if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { collided = true; } } @@ -415,7 +415,7 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap _RestCallbackData rcd; rcd.best_len = 0; - rcd.best_object = NULL; + rcd.best_object = nullptr; rcd.best_shape = 0; rcd.min_allowed_depth = space->test_motion_min_contact_depth; @@ -432,7 +432,7 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) continue; } @@ -501,7 +501,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob PhysicsDirectSpaceState3DSW::PhysicsDirectSpaceState3DSW() { - space = NULL; + space = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -621,7 +621,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra } Shape3DSW *against_shape = col_obj->get_shape(shape_idx); - if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) { + if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { if (cbk.amount > 0) { collided = true; } @@ -775,7 +775,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons const CollisionObject3DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; - if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) { + if (CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { collided = cbk.amount > 0; } } @@ -935,7 +935,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons _RestCallbackData rcd; rcd.best_len = 0; - rcd.best_object = NULL; + rcd.best_object = nullptr; rcd.best_shape = 0; rcd.min_allowed_depth = test_motion_min_contact_depth; @@ -953,7 +953,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); if (!sc) continue; } @@ -1030,7 +1030,7 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll return b; } - return NULL; + return nullptr; } void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_self) { @@ -1226,7 +1226,7 @@ Space3DSW::Space3DSW() { broadphase = BroadPhase3DSW::create_func(); broadphase->set_pair_callback(_broadphase_pair, this); broadphase->set_unpair_callback(_broadphase_unpair, this); - area = NULL; + area = nullptr; direct_access = memnew(PhysicsDirectSpaceState3DSW); direct_access->space = this; diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h index fb4fb6aa1f..3634834952 100644 --- a/servers/physics_3d/space_3d_sw.h +++ b/servers/physics_3d/space_3d_sw.h @@ -51,7 +51,7 @@ public: virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false); virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL); + virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr); virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const; diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp index dda88b45c6..1a7d5f8cec 100644 --- a/servers/physics_3d/step_3d_sw.cpp +++ b/servers/physics_3d/step_3d_sw.cpp @@ -88,7 +88,7 @@ void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t { Constraint3DSW *ci = p_island; - Constraint3DSW *prev = NULL; + Constraint3DSW *prev = nullptr; while (ci) { if (ci->get_priority() < at_priority) { if (prev) { @@ -177,8 +177,8 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { /* GENERATE CONSTRAINT ISLANDS */ - Body3DSW *island_list = NULL; - Constraint3DSW *constraint_island_list = NULL; + Body3DSW *island_list = nullptr; + Constraint3DSW *constraint_island_list = nullptr; b = body_list->first(); int island_count = 0; @@ -188,8 +188,8 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { if (body->get_island_step() != _step) { - Body3DSW *island = NULL; - Constraint3DSW *constraint_island = NULL; + Body3DSW *island = nullptr; + Constraint3DSW *constraint_island = nullptr; _populate_island(body, &island, &constraint_island); island->set_island_list_next(island_list); @@ -215,7 +215,7 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { if (c->get_island_step() == _step) continue; c->set_island_step(_step); - c->set_island_next(NULL); + c->set_island_next(nullptr); c->set_island_list_next(constraint_island_list); constraint_island_list = c; } diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 11fa2acc1a..48c51b5350 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -34,7 +34,7 @@ #include "core/print_string.h" #include "core/project_settings.h" -PhysicsServer2D *PhysicsServer2D::singleton = NULL; +PhysicsServer2D *PhysicsServer2D::singleton = nullptr; void PhysicsDirectBodyState2D::integrate_forces() { @@ -531,7 +531,7 @@ PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() { bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { - MotionResult *r = NULL; + MotionResult *r = nullptr; if (p_result.is_valid()) r = p_result->get_result_ptr(); return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r); @@ -771,7 +771,7 @@ PhysicsServer2D::PhysicsServer2D() { PhysicsServer2D::~PhysicsServer2D() { - singleton = NULL; + singleton = nullptr; } Vector<PhysicsServer2DManager::ClassInfo> PhysicsServer2DManager::physics_2d_servers; @@ -826,14 +826,14 @@ String PhysicsServer2DManager::get_server_name(int p_id) { } PhysicsServer2D *PhysicsServer2DManager::new_default_server() { - ERR_FAIL_COND_V(default_server_id == -1, NULL); + ERR_FAIL_COND_V(default_server_id == -1, nullptr); return physics_2d_servers[default_server_id].create_callback(); } PhysicsServer2D *PhysicsServer2DManager::new_server(const String &p_name) { int id = find_server_id(p_name); if (id == -1) { - return NULL; + return nullptr; } else { return physics_2d_servers[id].create_callback(); } diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 632371565c..8c833b390f 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -513,7 +513,7 @@ public: } }; - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) = 0; + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { @@ -644,7 +644,7 @@ class PhysicsServer2DManager { ClassInfo() : name(""), - create_callback(NULL) {} + create_callback(nullptr) {} ClassInfo(String p_name, CreatePhysicsServer2DCallback p_create_callback) : name(p_name), diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 0ee471231b..a5a02fd1bd 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -34,7 +34,7 @@ #include "core/print_string.h" #include "core/project_settings.h" -PhysicsServer3D *PhysicsServer3D::singleton = NULL; +PhysicsServer3D *PhysicsServer3D::singleton = nullptr; void PhysicsDirectBodyState3D::integrate_forces() { @@ -725,13 +725,13 @@ void PhysicsServer3D::_bind_methods() { PhysicsServer3D::PhysicsServer3D() { - ERR_FAIL_COND(singleton != NULL); + ERR_FAIL_COND(singleton != nullptr); singleton = this; } PhysicsServer3D::~PhysicsServer3D() { - singleton = NULL; + singleton = nullptr; } Vector<PhysicsServer3DManager::ClassInfo> PhysicsServer3DManager::physics_servers; @@ -786,14 +786,14 @@ String PhysicsServer3DManager::get_server_name(int p_id) { } PhysicsServer3D *PhysicsServer3DManager::new_default_server() { - ERR_FAIL_COND_V(default_server_id == -1, NULL); + ERR_FAIL_COND_V(default_server_id == -1, nullptr); return physics_servers[default_server_id].create_callback(); } PhysicsServer3D *PhysicsServer3DManager::new_server(const String &p_name) { int id = find_server_id(p_name); if (id == -1) { - return NULL; + return nullptr; } else { return physics_servers[id].create_callback(); } diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index ddef8a9b20..a2f08b3ed8 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -189,7 +189,7 @@ public: Vector3 linear_velocity; //velocity at contact point }; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; @@ -500,7 +500,7 @@ public: } }; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) = 0; + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { @@ -785,7 +785,7 @@ class PhysicsServer3DManager { ClassInfo() : name(""), - create_callback(NULL) {} + create_callback(nullptr) {} ClassInfo(String p_name, CreatePhysicsServer3DCallback p_create_callback) : name(p_name), diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index f96752813d..dadd26dade 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -33,9 +33,6 @@ #include "core/engine.h" #include "core/project_settings.h" -#include "arvr/arvr_interface.h" -#include "arvr/arvr_positional_tracker.h" -#include "arvr_server.h" #include "audio/audio_effect.h" #include "audio/audio_stream.h" #include "audio/effects/audio_effect_amplify.h" @@ -67,8 +64,11 @@ #include "physics_server_3d.h" #include "rendering_server.h" #include "servers/rendering/shader_types.h" +#include "xr/xr_interface.h" +#include "xr/xr_positional_tracker.h" +#include "xr_server.h" -ShaderTypes *shader_types = NULL; +ShaderTypes *shader_types = nullptr; PhysicsServer3D *_createGodotPhysics3DCallback() { return memnew(PhysicsServer3DSW); @@ -102,11 +102,15 @@ void register_server_types() { ClassDB::register_class<AudioServer>(); ClassDB::register_virtual_class<PhysicsServer3D>(); ClassDB::register_virtual_class<PhysicsServer2D>(); - ClassDB::register_class<ARVRServer>(); + ClassDB::register_class<XRServer>(); ClassDB::register_class<CameraServer>(); - ClassDB::register_virtual_class<ARVRInterface>(); - ClassDB::register_class<ARVRPositionalTracker>(); + ClassDB::register_virtual_class<XRInterface>(); + ClassDB::register_class<XRPositionalTracker>(); + + ClassDB::add_compatibility_class("ARVRServer", "XRServer"); + ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); + ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); ClassDB::register_virtual_class<AudioStream>(); ClassDB::register_virtual_class<AudioStreamPlayback>(); @@ -198,6 +202,6 @@ void register_server_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut())); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut())); - Engine::get_singleton()->add_singleton(Engine::Singleton("ARVRServer", ARVRServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton())); } diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/rasterizer.cpp index a3f93a3f8c..f62e0a43a6 100644 --- a/servers/rendering/rasterizer.cpp +++ b/servers/rendering/rasterizer.cpp @@ -33,7 +33,7 @@ #include "core/os/os.h" #include "core/print_string.h" -Rasterizer *(*Rasterizer::_create_func)() = NULL; +Rasterizer *(*Rasterizer::_create_func)() = nullptr; void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) { for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { @@ -67,9 +67,9 @@ Rasterizer *Rasterizer::create() { return _create_func(); } -RasterizerCanvas *RasterizerCanvas::singleton = NULL; +RasterizerCanvas *RasterizerCanvas::singleton = nullptr; -RasterizerStorage *RasterizerStorage::base_singleton = NULL; +RasterizerStorage *RasterizerStorage::base_singleton = nullptr; RasterizerStorage::RasterizerStorage() { diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index eb33db04fc..cf0afe6097 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -79,7 +79,9 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0; - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0; + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0; virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0; @@ -104,10 +106,11 @@ public: virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + virtual void shadow_filter_set(RS::ShadowFilter p_filter) = 0; + struct InstanceBase; struct InstanceDependency { - void instance_notify_changed(bool p_aabb, bool p_dependencies); void instance_notify_deleted(RID p_deleted); @@ -119,7 +122,6 @@ public: }; struct InstanceBase { - RS::InstanceType base_type; RID base; @@ -219,7 +221,7 @@ public: baked_light = false; dynamic_gi = false; redraw_if_visible = false; - lightmap_capture = NULL; + lightmap_capture = nullptr; } virtual ~InstanceBase() { @@ -229,9 +231,11 @@ public: virtual RID light_instance_create(RID p_light) = 0; virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; - virtual bool light_instances_can_render_shadow_cube() const { return true; } + virtual bool light_instances_can_render_shadow_cube() const { + return true; + } virtual RID reflection_atlas_create() = 0; virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0; @@ -264,6 +268,9 @@ public: virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0; virtual bool screen_space_roughness_limiter_is_active() const = 0; + virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; + virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + virtual bool free(RID p_rid) = 0; virtual void update() = 0; @@ -751,10 +758,10 @@ public: energy = 1.0; item_shadow_mask = -1; mode = RS::CANVAS_LIGHT_MODE_ADD; - // texture_cache = NULL; - next_ptr = NULL; - mask_next_ptr = NULL; - filter_next_ptr = NULL; + // texture_cache = nullptr; + next_ptr = nullptr; + mask_next_ptr = nullptr; + filter_next_ptr = nullptr; use_shadow = false; shadow_buffer_size = 2048; shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE; @@ -1005,7 +1012,7 @@ public: //must update rect - if (commands == NULL) { + if (commands == nullptr) { rect = Rect2(); rect_dirty = false; @@ -1115,12 +1122,12 @@ public: template <class T> T *alloc_command() { T *command; - if (commands == NULL) { + if (commands == nullptr) { // As the most common use case of canvas items is to // use only one command, the first is done with it's // own allocation. The rest of them use blocks. command = memnew(T); - command->next = NULL; + command->next = nullptr; commands = command; last_command = command; } else { @@ -1147,7 +1154,7 @@ public: //allocate block and add to the linked list void *memory = c->memory + c->usage; command = memnew_placement(memory, T); - command->next = NULL; + command->next = nullptr; last_command->next = command; last_command = command; c->usage += sizeof(T); @@ -1172,7 +1179,7 @@ public: Command *n = c->next; if (c == commands) { memdelete(commands); - commands = NULL; + commands = nullptr; } else { c->~Command(); } @@ -1186,36 +1193,36 @@ public: } } - last_command = NULL; - commands = NULL; + last_command = nullptr; + commands = nullptr; current_block = 0; clip = false; rect_dirty = true; - final_clip_owner = NULL; - material_owner = NULL; + final_clip_owner = nullptr; + material_owner = nullptr; light_masked = false; } Item() { - commands = NULL; - last_command = NULL; + commands = nullptr; + last_command = nullptr; current_block = 0; light_mask = 1; - vp_render = NULL; - next = NULL; - final_clip_owner = NULL; + vp_render = nullptr; + next = nullptr; + final_clip_owner = nullptr; clip = false; final_modulate = Color(1, 1, 1, 1); visible = true; rect_dirty = true; custom_rect = false; behind = false; - material_owner = NULL; - copy_back_buffer = NULL; + material_owner = nullptr; + copy_back_buffer = nullptr; distance_field = false; light_masked = false; update_when_visible = false; z_final = 0; - custom_data = NULL; + custom_data = nullptr; } virtual ~Item() { clear(); @@ -1248,7 +1255,7 @@ public: LightOccluderInstance() { enabled = true; - next = NULL; + next = nullptr; light_mask = 1; cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h index 3411ed07a0..50a68e03cb 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.h +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h @@ -170,17 +170,15 @@ public: _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count); } break; case LIGHT_TYPE_SPOT: { - Vector3 v(0, 0, -1); - v.rotated(Vector3(0, 1, 0), Math::deg2rad(ld.spot_aperture)); //rotate in x-z - v.normalize(); - v *= ld.radius; - v.y = v.x; + + float r = ld.radius; + real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r; aabb.position = xform.origin; - aabb.expand_to(xform.xform(v)); - aabb.expand_to(xform.xform(Vector3(-v.x, v.y, v.z))); - aabb.expand_to(xform.xform(Vector3(-v.x, -v.y, v.z))); - aabb.expand_to(xform.xform(Vector3(v.x, -v.y, v.z))); + aabb.expand_to(xform.xform(Vector3(len, len, -r))); + aabb.expand_to(xform.xform(Vector3(-len, len, -r))); + aabb.expand_to(xform.xform(Vector3(-len, -len, -r))); + aabb.expand_to(xform.xform(Vector3(len, -len, -r))); _add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count); } break; } diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index 8d52ffd7b9..ba4f4c4acb 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -1220,7 +1220,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 5)); glVertexAttribDivisor(10, 1); glEnableVertexAttribArray(11); //color - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, NULL); + glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, nullptr); glVertexAttribDivisor(11, 1); glEnableVertexAttribArray(12); //custom glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 2)); @@ -1262,7 +1262,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 5)); glVertexAttribDivisor(10, 1); glEnableVertexAttribArray(11); //color - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, NULL); + glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, nullptr); glVertexAttribDivisor(11, 1); glEnableVertexAttribArray(12); //custom glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 2)); @@ -1314,13 +1314,13 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ if (current_clip && reclip) { //will make it re-enable clipping if needed afterwards - current_clip = NULL; + current_clip = nullptr; } } void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set) { - Item *current_clip = NULL; + Item *current_clip = nullptr; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; @@ -1369,7 +1369,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, if (ci->material != prev_material) { - MaterialData *material_data = NULL; + MaterialData *material_data = nullptr; if (ci->material.is_valid()) { material_data = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); } @@ -2532,7 +2532,7 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { //anything remains? if (bindings.texture_bindings.size()) { ERR_PRINT("Some texture bindings were not properly freed (leaked canvasitems?"); - const TextureBindingID *key = NULL; + const TextureBindingID *key = nullptr; while ((key = bindings.texture_bindings.next(key))) { TextureBinding *tb = bindings.texture_bindings[*key]; tb->reference_count = 1; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 0c151975bc..83b431eaf6 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -383,7 +383,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) { light_cache[i].light_version = 0; - light_cache[i].light = NULL; + light_cache[i].light = nullptr; } light_cache_count = 0xFFFFFFFF; } diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index 9ccc1f172e..79b1686232 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -50,6 +50,16 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } +static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + + p_array[i * 4 + j] = p_mtx.matrix[i][j]; + } + } +} + RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { if (image_to_uniform_set_cache.has(p_image)) { @@ -120,6 +130,99 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo return uniform_set; } +RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { + + TexturePair tp; + tp.texture1 = p_texture1; + tp.texture2 = p_texture2; + + if (texture_pair_to_compute_uniform_set_cache.has(tp)) { + RID uniform_set = texture_pair_to_compute_uniform_set_cache[tp]; + if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { + return uniform_set; + } + } + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 0; + u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.ids.push_back(p_texture1); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 1; + u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.ids.push_back(p_texture2); + uniforms.push_back(u); + } + //any thing with the same configuration (one texture in binding 0 for set 0), is good + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 1); + + texture_pair_to_compute_uniform_set_cache[tp] = uniform_set; + + return uniform_set; +} + +RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { + + TexturePair tp; + tp.texture1 = p_texture1; + tp.texture2 = p_texture2; + + if (image_pair_to_compute_uniform_set_cache.has(tp)) { + RID uniform_set = image_pair_to_compute_uniform_set_cache[tp]; + if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { + return uniform_set; + } + } + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.ids.push_back(p_texture1); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 1; + u.ids.push_back(p_texture2); + uniforms.push_back(u); + } + //any thing with the same configuration (one texture in binding 0 for set 0), is good + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 3); + + image_pair_to_compute_uniform_set_cache[tp] = uniform_set; + + return uniform_set; +} + +void RasterizerEffectsRD::copy_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { + + zeromem(&blur.push_constant, sizeof(BlurPushConstant)); + if (p_flip_y) { + blur.push_constant.flags |= BLUR_FLAG_FLIP_Y; + } + + blur.push_constant.camera_z_near = p_z_near; + blur.push_constant.camera_z_far = p_z_far; + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_LINEARIZE_DEPTH].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, bool p_force_luminance) { zeromem(&blur.push_constant, sizeof(BlurPushConstant)); @@ -218,6 +321,7 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuff blur.push_constant.glow_exposure = p_exposure; blur.push_constant.glow_white = 0; //actually unused blur.push_constant.glow_luminance_cap = p_luminance_cap; + blur.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also //HORIZONTAL @@ -250,6 +354,212 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuff RD::get_singleton()->draw_list_end(); } +void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; + int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; + + { //scale color and depth to half + ssr_scale.push_constant.camera_z_far = p_camera.get_z_far(); + ssr_scale.push_constant.camera_z_near = p_camera.get_z_near(); + ssr_scale.push_constant.orthogonal = p_camera.is_orthogonal(); + ssr_scale.push_constant.filter = false; //enabling causes arctifacts + ssr_scale.push_constant.screen_size[0] = p_screen_size.x; + ssr_scale.push_constant.screen_size[1] = p_screen_size.y; + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipeline); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_depth, p_normal), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output_blur), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_scale_depth, p_scale_normal), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + + { + + ssr.push_constant.camera_z_far = p_camera.get_z_far(); + ssr.push_constant.camera_z_near = p_camera.get_z_near(); + ssr.push_constant.orthogonal = p_camera.is_orthogonal(); + ssr.push_constant.screen_size[0] = p_screen_size.x; + ssr.push_constant.screen_size[1] = p_screen_size.y; + ssr.push_constant.curve_fade_in = p_fade_in; + ssr.push_constant.distance_fade = p_fade_out; + ssr.push_constant.num_steps = p_max_steps; + ssr.push_constant.depth_tolerance = p_tolerance; + ssr.push_constant.use_half_res = true; + ssr.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]); + ssr.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]); + ssr.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; + ssr.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; + ssr.push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255); + ssr.push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255); + ssr.push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255); + ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255); + store_camera(p_camera, ssr.push_constant.projection); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant)); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0); + + if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_metallic, p_roughness), 3); + } else { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3); + } + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + } + + if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + + //blurr + + RD::get_singleton()->compute_list_add_barrier(compute_list); + + ssr_filter.push_constant.orthogonal = p_camera.is_orthogonal(); + ssr_filter.push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0)); + ssr_filter.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]); + ssr_filter.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]); + ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; + ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; + ssr_filter.push_constant.vertical = 0; + if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_LOW) { + ssr_filter.push_constant.steps = p_max_steps / 3; + ssr_filter.push_constant.increment = 3; + } else if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_MEDIUM) { + ssr_filter.push_constant.steps = p_max_steps / 2; + ssr_filter.push_constant.increment = 2; + } else { + ssr_filter.push_constant.steps = p_max_steps; + ssr_filter.push_constant.increment = 1; + } + + ssr_filter.push_constant.screen_size[0] = p_screen_size.width; + ssr_filter.push_constant.screen_size[1] = p_screen_size.height; + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + + RD::get_singleton()->compute_list_add_barrier(compute_list); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_VERTICAL]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3); + + ssr_filter.push_constant.vertical = 1; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + } + + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; + int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; + + Plane p = p_camera.xform4(Plane(1, 0, -1, 1)); + p.normal /= p.d; + float unit_size = p.normal.x; + + { //scale color and depth to half + sss.push_constant.camera_z_far = p_camera.get_z_far(); + sss.push_constant.camera_z_near = p_camera.get_z_near(); + sss.push_constant.orthogonal = p_camera.is_orthogonal(); + sss.push_constant.unit_size = unit_size; + sss.push_constant.screen_size[0] = p_screen_size.x; + sss.push_constant.screen_size[1] = p_screen_size.y; + sss.push_constant.vertical = false; + sss.push_constant.scale = p_scale; + sss.push_constant.depth_scale = p_depth_scale; + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sss.pipelines[p_quality - 1]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_diffuse2), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth), 2); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + + RD::get_singleton()->compute_list_add_barrier(compute_list); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse2), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_diffuse), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth), 2); + + sss.push_constant.vertical = true; + RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + + RD::get_singleton()->compute_list_end(); + } +} + +void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>()); + + if (p_reflection.is_valid()) { + + if (p_base.is_valid()) { + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); + } else { + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + } + + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1); + + } else { + + if (p_base.is_valid()) { + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); + } else { + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + } + + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0); + } + + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) { zeromem(&blur.push_constant, sizeof(BlurPushConstant)); @@ -819,8 +1129,7 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ RasterizerEffectsRD::RasterizerEffectsRD() { - { - // Initialize blur + { // Initialize blur Vector<String> blur_modes; blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); @@ -837,6 +1146,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() { blur_modes.push_back("\n#define MODE_SSAO_MERGE\n"); blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); blur_modes.push_back("\n#define MODE_MIPMAP\n"); + blur_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); blur.shader.initialize(blur_modes); zeromem(&blur.push_constant, sizeof(BlurPushConstant)); @@ -970,6 +1280,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() { for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_UPSCALE; i++) { ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS)); + pipeline++; } } @@ -1035,6 +1346,97 @@ RasterizerEffectsRD::RasterizerEffectsRD() { filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); } + { + Vector<String> specular_modes; + specular_modes.push_back("\n#define MODE_MERGE\n"); + specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); + specular_modes.push_back("\n"); + specular_modes.push_back("\n#define MODE_SSR\n"); + + specular_merge.shader.initialize(specular_modes); + + specular_merge.shader_version = specular_merge.shader.version_create(); + + //use additive + + RD::PipelineColorBlendState::Attachment ba; + ba.enable_blend = true; + ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE; + ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE; + ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.color_blend_op = RD::BLEND_OP_ADD; + ba.alpha_blend_op = RD::BLEND_OP_ADD; + + RD::PipelineColorBlendState blend_additive; + blend_additive.attachments.push_back(ba); + + for (int i = 0; i < SPECULAR_MERGE_MAX; i++) { + + RD::PipelineColorBlendState blend_state; + if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) { + blend_state = blend_additive; + } else { + blend_state = RD::PipelineColorBlendState::create_disabled(); + } + specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); + } + } + + { + Vector<String> ssr_modes; + ssr_modes.push_back("\n"); + ssr_modes.push_back("\n#define MODE_ROUGH\n"); + + ssr.shader.initialize(ssr_modes); + + ssr.shader_version = ssr.shader.version_create(); + + for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) { + ssr.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i)); + } + } + + { + Vector<String> ssr_filter_modes; + ssr_filter_modes.push_back("\n"); + ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n"); + + ssr_filter.shader.initialize(ssr_filter_modes); + + ssr_filter.shader_version = ssr_filter.shader.version_create(); + + for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) { + ssr_filter.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i)); + } + } + + { + Vector<String> ssr_scale_modes; + ssr_scale_modes.push_back("\n"); + + ssr_scale.shader.initialize(ssr_scale_modes); + + ssr_scale.shader_version = ssr_scale.shader.version_create(); + + ssr_scale.pipeline = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0)); + } + + { + Vector<String> sss_modes; + sss_modes.push_back("\n#define USE_11_SAMPLES\n"); + sss_modes.push_back("\n#define USE_17_SAMPLES\n"); + sss_modes.push_back("\n#define USE_25_SAMPLES\n"); + + sss.shader.initialize(sss_modes); + + sss.shader_version = sss.shader.version_create(); + + for (int i = 0; i < sss_modes.size(); i++) { + sss.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sss.shader.version_get_shader(sss.shader_version, i)); + } + } + RD::SamplerState sampler; sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; @@ -1079,16 +1481,22 @@ RasterizerEffectsRD::~RasterizerEffectsRD() { RD::get_singleton()->free(default_mipmap_sampler); RD::get_singleton()->free(index_buffer); //array gets freed as dependency RD::get_singleton()->free(filter.coefficient_buffer); + blur.shader.version_free(blur.shader_version); - roughness.shader.version_free(roughness.shader_version); - tonemap.shader.version_free(tonemap.shader_version); - luminance_reduce.shader.version_free(luminance_reduce.shader_version); - copy.shader.version_free(copy.shader_version); bokeh.shader.version_free(bokeh.shader_version); - ssao.minify_shader.version_free(ssao.minify_shader_version); - ssao.gather_shader.version_free(ssao.gather_shader_version); - ssao.blur_shader.version_free(ssao.blur_shader_version); - roughness_limiter.shader.version_free(roughness_limiter.shader_version); + copy.shader.version_free(copy.shader_version); cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version); filter.shader.version_free(filter.shader_version); + luminance_reduce.shader.version_free(luminance_reduce.shader_version); + roughness.shader.version_free(roughness.shader_version); + roughness_limiter.shader.version_free(roughness_limiter.shader_version); + specular_merge.shader.version_free(specular_merge.shader_version); + ssao.blur_shader.version_free(ssao.blur_shader_version); + ssao.gather_shader.version_free(ssao.gather_shader_version); + ssao.minify_shader.version_free(ssao.minify_shader_version); + ssr.shader.version_free(ssr.shader_version); + ssr_filter.shader.version_free(ssr_filter.shader_version); + ssr_scale.shader.version_free(ssr_scale.shader_version); + sss.shader.version_free(sss.shader_version); + tonemap.shader.version_free(tonemap.shader_version); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index 69da5dc6d4..c0c62eb0be 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -41,9 +41,14 @@ #include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/specular_merge.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/ssao.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/tonemap.glsl.gen.h" #include "servers/rendering_server.h" @@ -66,6 +71,7 @@ class RasterizerEffectsRD { BLUR_MODE_SSAO_MERGE, BLUR_MODE_SIMPLY_COPY, BLUR_MODE_MIPMAP, + BLUR_MODE_LINEARIZE_DEPTH, BLUR_MODE_MAX, }; @@ -378,6 +384,127 @@ class RasterizerEffectsRD { float pad[3]; }; + enum SpecularMergeMode { + SPECULAR_MERGE_ADD, + SPECULAR_MERGE_SSR, + SPECULAR_MERGE_ADDITIVE_ADD, + SPECULAR_MERGE_ADDITIVE_SSR, + SPECULAR_MERGE_MAX + }; + + struct SpecularMerge { + + SpecularMergeShaderRD shader; + RID shader_version; + RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX]; + + } specular_merge; + + enum ScreenSpaceReflectionMode { + SCREEN_SPACE_REFLECTION_NORMAL, + SCREEN_SPACE_REFLECTION_ROUGH, + SCREEN_SPACE_REFLECTION_MAX, + }; + + struct ScreenSpaceReflectionPushConstant { + + float proj_info[4]; + + int32_t screen_size[2]; + float camera_z_near; + float camera_z_far; + + int32_t num_steps; + float depth_tolerance; + float distance_fade; + float curve_fade_in; + + uint32_t orthogonal; + float filter_mipmap_levels; + uint32_t use_half_res; + uint8_t metallic_mask[4]; + + float projection[16]; + }; + + struct ScreenSpaceReflection { + + ScreenSpaceReflectionPushConstant push_constant; + ScreenSpaceReflectionShaderRD shader; + RID shader_version; + RID pipelines[SCREEN_SPACE_REFLECTION_MAX]; + + } ssr; + + struct ScreenSpaceReflectionFilterPushConstant { + + float proj_info[4]; + + uint32_t orthogonal; + float edge_tolerance; + int32_t increment; + uint32_t pad; + + int32_t screen_size[2]; + uint32_t vertical; + uint32_t steps; + }; + enum { + SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL, + SCREEN_SPACE_REFLECTION_FILTER_VERTICAL, + SCREEN_SPACE_REFLECTION_FILTER_MAX, + }; + + struct ScreenSpaceReflectionFilter { + + ScreenSpaceReflectionFilterPushConstant push_constant; + ScreenSpaceReflectionFilterShaderRD shader; + RID shader_version; + RID pipelines[SCREEN_SPACE_REFLECTION_FILTER_MAX]; + } ssr_filter; + + struct ScreenSpaceReflectionScalePushConstant { + + int32_t screen_size[2]; + float camera_z_near; + float camera_z_far; + + uint32_t orthogonal; + uint32_t filter; + uint32_t pad[2]; + }; + + struct ScreenSpaceReflectionScale { + + ScreenSpaceReflectionScalePushConstant push_constant; + ScreenSpaceReflectionScaleShaderRD shader; + RID shader_version; + RID pipeline; + } ssr_scale; + + struct SubSurfaceScatteringPushConstant { + + int32_t screen_size[2]; + float camera_z_far; + float camera_z_near; + + uint32_t vertical; + uint32_t orthogonal; + float unit_size; + float scale; + + float depth_scale; + uint32_t pad[3]; + }; + + struct SubSurfaceScattering { + + SubSurfaceScatteringPushConstant push_constant; + SubsurfaceScatteringShaderRD shader; + RID shader_version; + RID pipelines[3]; //3 quality levels + } sss; + RID default_sampler; RID default_mipmap_sampler; RID index_buffer; @@ -386,17 +513,35 @@ class RasterizerEffectsRD { Map<RID, RID> texture_to_uniform_set_cache; Map<RID, RID> image_to_uniform_set_cache; + + struct TexturePair { + RID texture1; + RID texture2; + _FORCE_INLINE_ bool operator<(const TexturePair &p_pair) const { + if (texture1 == p_pair.texture1) { + return texture2 < p_pair.texture2; + } else { + return texture1 < p_pair.texture1; + } + } + }; + Map<RID, RID> texture_to_compute_uniform_set_cache; + Map<TexturePair, RID> texture_pair_to_compute_uniform_set_cache; + Map<TexturePair, RID> image_pair_to_compute_uniform_set_cache; RID _get_uniform_set_from_image(RID p_texture); RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false); RID _get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false); + RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false); + RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2); public: //TODO must re-do most of the shaders in compute void region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region); void copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y = false, bool p_force_luminance = false); + void copy_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, float p_z_near, float p_z_far); void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region); void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); @@ -450,6 +595,10 @@ public: void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array); void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position); + void screen_space_reflection(RID p_diffuse, RID p_normal, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera); + void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); + void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); + RasterizerEffectsRD(); ~RasterizerEffectsRD(); }; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index bf3cd045f1..ec05c9e964 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -109,6 +109,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { unshaded = false; uses_vertex = false; uses_sss = false; + uses_transmittance = false; uses_screen_texture = false; uses_depth_texture = false; uses_normal_texture = false; @@ -142,6 +143,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; + actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance; actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture; actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture; @@ -321,7 +323,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL) { blend_state = blend_state_depth_normal; } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { - blend_state = blend_state_depth_normal; + blend_state = blend_state_depth_normal_roughness; } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) { blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way @@ -537,12 +539,20 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { specular = RD::get_singleton()->texture_create(tf, RD::TextureView()); - Vector<RID> fb; - fb.push_back(color); - fb.push_back(specular); - fb.push_back(depth); + { + Vector<RID> fb; + fb.push_back(color); + fb.push_back(specular); + fb.push_back(depth); - color_specular_fb = RD::get_singleton()->framebuffer_create(fb); + color_specular_fb = RD::get_singleton()->framebuffer_create(fb); + } + { + Vector<RID> fb; + fb.push_back(specular); + + specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + } } } @@ -554,6 +564,7 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { } color_specular_fb = RID(); + specular_only_fb = RID(); color_fb = RID(); if (normal_buffer.is_valid()) { @@ -935,7 +946,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } } -void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers) { +void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down @@ -951,6 +962,10 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.z_far = p_zfar; scene_state.ubo.z_near = p_znear; + scene_state.ubo.shadow_filter_mode = shadow_filter_get(); + + scene_state.ubo.pancake_shadows = p_pancake_shadows; + scene_state.ubo.shadow_blocker_count = 16; scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x; scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y; @@ -1074,12 +1089,12 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t } } - MaterialData *material = NULL; + MaterialData *material = nullptr; if (m_src.is_valid()) { material = (MaterialData *)storage->material_get_data(m_src, RasterizerStorageRD::SHADER_TYPE_3D); if (!material || !material->shader_data->valid) { - material = NULL; + material = nullptr; } } @@ -1203,7 +1218,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i case RS::INSTANCE_MESH: { - const RID *materials = NULL; + const RID *materials = nullptr; uint32_t surface_count; materials = storage->mesh_get_surface_count_and_materials(inst->base, surface_count); @@ -1237,7 +1252,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i continue; } - const RID *materials = NULL; + const RID *materials = nullptr; uint32_t surface_count; materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count); @@ -1258,7 +1273,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base); ERR_CONTINUE(!immediate); - _add_geometry(immediate, inst, NULL, -1, p_depth_pass, p_shadow_pass); + _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass); } break; case RS::INSTANCE_PARTICLES: { @@ -1470,11 +1485,49 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.specular = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); light_data.mask = storage->light_get_cull_mask(base); + float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + + light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset + Color shadow_col = storage->light_get_shadow_color(base).to_linear(); - light_data.shadow_color[0] = shadow_col.r; - light_data.shadow_color[1] = shadow_col.g; - light_data.shadow_color[2] = shadow_col.b; + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { + light_data.shadow_color1[0] = 1.0; + light_data.shadow_color1[1] = 0.0; + light_data.shadow_color1[2] = 0.0; + light_data.shadow_color1[3] = 1.0; + light_data.shadow_color2[0] = 0.0; + light_data.shadow_color2[1] = 1.0; + light_data.shadow_color2[2] = 0.0; + light_data.shadow_color2[3] = 1.0; + light_data.shadow_color3[0] = 0.0; + light_data.shadow_color3[1] = 0.0; + light_data.shadow_color3[2] = 1.0; + light_data.shadow_color3[3] = 1.0; + light_data.shadow_color4[0] = 1.0; + light_data.shadow_color4[1] = 1.0; + light_data.shadow_color4[2] = 0.0; + light_data.shadow_color4[3] = 1.0; + + } else { + + light_data.shadow_color1[0] = shadow_col.r; + light_data.shadow_color1[1] = shadow_col.g; + light_data.shadow_color1[2] = shadow_col.b; + light_data.shadow_color1[3] = 1.0; + light_data.shadow_color2[0] = shadow_col.r; + light_data.shadow_color2[1] = shadow_col.g; + light_data.shadow_color2[2] = shadow_col.b; + light_data.shadow_color2[3] = 1.0; + light_data.shadow_color3[0] = shadow_col.r; + light_data.shadow_color3[1] = shadow_col.g; + light_data.shadow_color3[2] = shadow_col.b; + light_data.shadow_color3[3] = 1.0; + light_data.shadow_color4[0] = shadow_col.r; + light_data.shadow_color4[1] = shadow_col.g; + light_data.shadow_color4[2] = shadow_col.b; + light_data.shadow_color4[3] = 1.0; + } light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); @@ -1498,12 +1551,49 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; + float bias_scale = light_instance_get_shadow_bias_scale(li, j); + light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale; + light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * light_instance_get_directional_shadow_texel_size(li, j); + light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; + light_data.shadow_transmittance_z_scale[j] = light_instance_get_shadow_range(li, j); + light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j); store_camera(shadow_mtx, light_data.shadow_matrices[j]); + + Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j); + uv_scale *= atlas_rect.size; //adapt to atlas size + switch (j) { + case 0: { + light_data.uv_scale1[0] = uv_scale.x; + light_data.uv_scale1[1] = uv_scale.y; + } break; + case 1: { + light_data.uv_scale2[0] = uv_scale.x; + light_data.uv_scale2[1] = uv_scale.y; + } break; + case 2: { + light_data.uv_scale3[0] = uv_scale.x; + light_data.uv_scale3[1] = uv_scale.y; + } break; + case 3: { + light_data.uv_scale4[0] = uv_scale.x; + light_data.uv_scale4[1] = uv_scale.y; + } break; + } } float fade_start = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START); light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; + + float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + if (softshadow_angle > 0.0) { + // I know tan(0) is 0, but let's not risk it with numerical precision. + // technically this will keep expanding until reaching the sun, but all we care + // is expand until we reach the radius of the near plane (there can't be more occluders than that) + light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle)); + } else { + light_data.softshadow_angle = 0; + } } // Copy to SkyDirectionalLightData @@ -1566,20 +1656,16 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.direction[1] = direction.y; light_data.direction[2] = direction.z; + float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + + light_data.size = size; + light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION)); float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(spot_angle))); light_data.mask = storage->light_get_cull_mask(base); - Color shadow_color = storage->light_get_shadow_color(base); - - bool has_shadow = p_using_shadows && storage->light_has_shadow(base); - light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); - light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); - light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); - light_data.shadow_color_enabled[3] = has_shadow ? 255 : 0; - light_data.atlas_rect[0] = 0; light_data.atlas_rect[1] = 0; light_data.atlas_rect[2] = 0; @@ -1588,20 +1674,55 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig if (p_using_shadows && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) { // fill in the shadow information + Color shadow_color = storage->light_get_shadow_color(base); + + light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); + light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); + light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); + light_data.shadow_color_enabled[3] = 255; + + if (type == RS::LIGHT_SPOT) { + light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); + float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; + shadow_texel_size *= light_instance_get_shadow_texel_size(li, p_shadow_atlas); + + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; + + } else { //omni + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; + float shadow_texel_size = light_instance_get_shadow_texel_size(li, p_shadow_atlas); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space + } + + light_data.transmittance_bias = storage->light_get_transmittance_bias(base); + Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas); - if (type == RS::LIGHT_OMNI) { + light_data.atlas_rect[0] = rect.position.x; + light_data.atlas_rect[1] = rect.position.y; + light_data.atlas_rect[2] = rect.size.width; + light_data.atlas_rect[3] = rect.size.height; - light_data.atlas_rect[0] = rect.position.x; - light_data.atlas_rect[1] = rect.position.y; - light_data.atlas_rect[2] = rect.size.width; - light_data.atlas_rect[3] = rect.size.height * 0.5; + if (type == RS::LIGHT_OMNI) { + light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform proj = (p_camera_inverse_transform * light_transform).inverse(); store_transform(proj, light_data.shadow_matrix); + + if (size > 0.0) { + + light_data.soft_shadow_size = size; + } else { + light_data.soft_shadow_size = 0.0; + } + } else if (type == RS::LIGHT_SPOT) { + //used for clamping in this light type + light_data.atlas_rect[2] += light_data.atlas_rect[0]; + light_data.atlas_rect[3] += light_data.atlas_rect[1]; + Transform modelview = (p_camera_inverse_transform * light_transform).inverse(); CameraMatrix bias; bias.set_light_bias(); @@ -1610,7 +1731,17 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig CameraMatrix shadow_mtx = rectm * bias * light_instance_get_shadow_camera(li, 0) * modelview; store_camera(shadow_mtx, light_data.shadow_matrix); + + if (size > 0.0) { + CameraMatrix cm = light_instance_get_shadow_camera(li, 0); + float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); + light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; + } else { + light_data.soft_shadow_size = 0.0; + } } + } else { + light_data.shadow_color_enabled[3] = 0; } light_instance_set_index(li, light_count); @@ -1637,7 +1768,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { - RenderBufferDataHighEnd *render_buffer = NULL; + RenderBufferDataHighEnd *render_buffer = nullptr; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer); } @@ -1689,9 +1820,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor //scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size; - scene_state.ubo.shadow_z_offset = 0; - scene_state.ubo.shadow_z_slope_scale = 0; - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; @@ -1699,11 +1827,14 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor Size2 screen_pixel_size; Size2i screen_size; RID opaque_framebuffer; + RID opaque_specular_framebuffer; RID depth_framebuffer; RID alpha_framebuffer; PassMode depth_pass_mode = PASS_MODE_DEPTH; Vector<Color> depth_pass_clear; + bool using_separate_specular = false; + bool using_ssr = false; if (render_buffer) { screen_pixel_size.width = 1.0 / render_buffer->width; @@ -1715,6 +1846,10 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (p_environment.is_valid() && environment_is_ssr_enabled(p_environment)) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS; + render_buffer->ensure_specular(); + using_separate_specular = true; + using_ssr = true; + opaque_specular_framebuffer = render_buffer->color_specular_fb; } else if (screen_space_roughness_limiter_is_active()) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL; //we need to allocate both these, if not allocated @@ -1779,6 +1914,14 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor render_list.clear(); _fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, render_buffer == nullptr); + bool using_sss = render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED; + + if (using_sss) { + using_separate_specular = true; + render_buffer->ensure_specular(); + using_separate_specular = true; + opaque_specular_framebuffer = render_buffer->color_specular_fb; + } RID radiance_uniform_set; bool draw_sky = false; @@ -1845,22 +1988,22 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor _fill_instances(render_list.elements, render_list.element_count, false); - bool can_continue = true; //unless the middle buffers are needed bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION; - bool using_separate_specular = false; bool depth_pre_pass = depth_framebuffer.is_valid(); RID render_buffers_uniform_set; + bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment); + if (depth_pre_pass) { //depth pre pass RENDER_TIMESTAMP("Render Depth Pre-Pass"); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, using_ssao ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID()); RD::get_singleton()->draw_list_end(); } - if (p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment)) { + if (using_ssao) { _process_ssao(p_render_buffer, p_environment, render_buffer->normal_buffer, p_cam_projection); } @@ -1878,23 +2021,46 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor RENDER_TIMESTAMP("Render Opaque Pass"); + bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; + bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; + { - bool will_continue = (can_continue || draw_sky || debug_giprobes); + + bool will_continue_color = (can_continue_color || draw_sky || debug_giprobes); + bool will_continue_depth = (can_continue_depth || draw_sky || debug_giprobes); + //regular forward for now Vector<Color> c; - c.push_back(clear_color.to_linear()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); + if (using_separate_specular) { + Color cc = clear_color.to_linear(); + cc.a = 0; //subsurf scatter must be 0 + c.push_back(cc); + c.push_back(Color(0, 0, 0, 0)); + } else { + c.push_back(clear_color.to_linear()); + } + + RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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 ? (using_ssao ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); RD::get_singleton()->draw_list_end(); + + if (will_continue_color && using_separate_specular) { + // close the specular framebuffer, as it's no longer used + draw_list = RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE); + RD::get_singleton()->draw_list_end(); + } } if (debug_giprobes) { //debug giprobes - bool will_continue = (can_continue || draw_sky); + bool will_continue_color = (can_continue_color || draw_sky); + bool will_continue_depth = (can_continue_depth || draw_sky); + CameraMatrix dc; dc.set_depth_correction(true); CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_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); for (int i = 0; i < p_gi_probe_cull_count; i++) { _debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); } @@ -1911,12 +2077,23 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor projection = correction * p_cam_projection; } - _draw_sky(can_continue, opaque_framebuffer, p_environment, projection, p_cam_transform); + _draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform); + } + + if (using_separate_specular) { + + if (using_sss) { + RENDER_TIMESTAMP("Sub Surface Scattering"); + _process_sss(p_render_buffer, p_cam_projection); + } - if (using_separate_specular && !can_continue) { - //can't continue, so close the buffers - //RD::get_singleton()->draw_list_begin(render_buffer->color_specular_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c); - //RD::get_singleton()->draw_list_end(); + if (using_ssr) { + RENDER_TIMESTAMP("Screen Space Reflection"); + _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, true); + } else { + //just mix specular back + RENDER_TIMESTAMP("Merge Specular"); + storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, RID(), RID()); } } @@ -1929,7 +2106,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor _fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false); { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(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); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); RD::get_singleton()->draw_list_end(); } @@ -1937,13 +2114,13 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor //_render_list #if 0 if (state.directional_light_count == 0) { - directional_light = NULL; - _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, false, shadow_atlas != NULL); + directional_light = nullptr; + _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, false, shadow_atlas != nullptr); } else { for (int i = 0; i < state.directional_light_count; i++) { directional_light = directional_lights[i]; - _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL && shadow_atlas->size > 0); - _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != NULL); + _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != nullptr && shadow_atlas->size > 0); + _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != nullptr); } } #endif @@ -2005,7 +2182,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor //disable all stuff #endif } -void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip) { +void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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) { RENDER_TIMESTAMP("Setup Rendering Shadow"); @@ -2013,11 +2190,9 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase ** render_pass++; - scene_state.ubo.shadow_z_offset = p_bias; - scene_state.ubo.shadow_z_slope_scale = p_normal_bias; scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar); + _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake); render_list.clear(); @@ -2048,8 +2223,6 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform render_pass++; - scene_state.ubo.shadow_z_offset = 0; - scene_state.ubo.shadow_z_slope_scale = 0; scene_state.ubo.dual_paraboloid_side = 0; _setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); @@ -2146,7 +2319,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.light_buffer); uniforms.push_back(u); } @@ -2366,7 +2539,7 @@ void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_b } } -RasterizerSceneHighEndRD *RasterizerSceneHighEndRD::singleton = NULL; +RasterizerSceneHighEndRD *RasterizerSceneHighEndRD::singleton = nullptr; void RasterizerSceneHighEndRD::set_time(double p_time, double p_step) { time = p_time; @@ -2405,11 +2578,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } { //lights - scene_state.max_lights = MIN(65536, uniform_max_size) / sizeof(LightData); + scene_state.max_lights = MIN(1024 * 1024, uniform_max_size) / sizeof(LightData); //1mb of lights uint32_t light_buffer_size = scene_state.max_lights * sizeof(LightData); scene_state.lights = memnew_arr(LightData, scene_state.max_lights); - scene_state.light_buffer = RD::get_singleton()->uniform_buffer_create(light_buffer_size); - defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n"; + scene_state.light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size); + //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n"; scene_state.max_directional_lights = 8; uint32_t directional_light_buffer_size = scene_state.max_directional_lights * sizeof(DirectionalLightData); @@ -2511,7 +2684,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; - actions.renames["TRANSMISSION"] = "transmission"; + actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; + actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; + actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve"; + actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; + actions.renames["BACKLIGHT"] = "backlight"; actions.renames["AO"] = "ao"; actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; actions.renames["EMISSION"] = "emission"; @@ -2551,7 +2728,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; - actions.usage_defines["TRANSMISSION"] = "#define LIGHT_TRANSMISSION_USED\n"; + actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n"; + actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n"; actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; @@ -2574,6 +2752,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; + actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; + bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx"); if (!force_blinn) { diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index 4c3422cedb..b4f5d25afd 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -138,6 +138,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool unshaded; bool uses_vertex; bool uses_sss; + bool uses_transmittance; bool uses_screen_texture; bool uses_depth_texture; bool uses_normal_texture; @@ -207,6 +208,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID depth_normal_roughness_fb; RID color_fb; RID color_specular_fb; + RID specular_only_fb; int width, height; void ensure_specular(); @@ -252,13 +254,19 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float position[3]; float inv_radius; float direction[3]; + float size; uint16_t attenuation_energy[2]; //16 bits attenuation, then energy uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm) uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float) - uint32_t mask; uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm) float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv float shadow_matrix[16]; + float shadow_bias; + float shadow_normal_bias; + float transmittance_bias; + float soft_shadow_size; + uint32_t mask; + uint32_t pad[3]; }; struct DirectionalLightData { @@ -266,15 +274,30 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float direction[3]; float energy; float color[3]; + float size; float specular; - float shadow_color[3]; uint32_t mask; + float softshadow_angle; + uint32_t pad[1]; uint32_t blend_splits; uint32_t shadow_enabled; float fade_from; float fade_to; + float shadow_bias[4]; + float shadow_normal_bias[4]; + float shadow_transmittance_bias[4]; + float shadow_transmittance_z_scale[4]; + float shadow_range_begin[4]; float shadow_split_offsets[4]; float shadow_matrices[4][16]; + float shadow_color1[4]; + float shadow_color2[4]; + float shadow_color3[4]; + float shadow_color4[4]; + float uv_scale1[2]; + float uv_scale2[2]; + float uv_scale3[2]; + float uv_scale4[2]; }; struct GIProbeData { @@ -323,12 +346,15 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float viewport_size[2]; float screen_pixel_size[2]; - float shadow_z_offset; - float shadow_z_slope_scale; - float time; float reflection_multiplier; + uint32_t pancake_shadows; + uint32_t shadow_filter_mode; + + uint32_t shadow_blocker_count; + uint32_t shadow_pad[3]; + float ambient_light_color_energy[4]; float ambient_color_sky_mix; @@ -489,7 +515,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { _FORCE_INLINE_ Element *add_element() { if (element_count + alpha_element_count >= max_elements) - return NULL; + return nullptr; elements[element_count] = &base_elements[element_count]; return elements[element_count++]; } @@ -497,7 +523,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { _FORCE_INLINE_ Element *add_alpha_element() { if (element_count + alpha_element_count >= max_elements) - return NULL; + return nullptr; int idx = max_elements - alpha_element_count - 1; elements[idx] = &base_elements[idx]; alpha_element_count++; @@ -557,7 +583,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { PASS_MODE_DEPTH_MATERIAL, }; - void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false); + void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false); void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows); void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform); @@ -571,7 +597,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { protected: virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); - virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip); + virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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); virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); public: diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 517eea12f4..a0bbf8bd43 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -456,7 +456,7 @@ RID RasterizerSceneRD::sky_get_material(RID p_sky) const { return sky->material; } -void RasterizerSceneRD::_draw_sky(bool p_can_continue, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { +void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { ERR_FAIL_COND(!is_environment(p_environment)); @@ -465,12 +465,12 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue, RID p_fb, RID p_environme RID sky_material = sky_get_material(environment_get_sky(p_environment)); - SkyMaterialData *material = NULL; + SkyMaterialData *material = nullptr; if (sky_material.is_valid()) { material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { - material = NULL; + material = nullptr; } } @@ -537,7 +537,7 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue, RID p_fb, RID p_environme RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_BACKGROUND); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); storage->get_effects()->render_sky(draw_list, time, p_fb, sky_scene_state.sampler_uniform_set, sky_scene_state.light_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin); RD::get_singleton()->draw_list_end(); } @@ -551,12 +551,12 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, RID sky_material = sky_get_material(environment_get_sky(p_environment)); - SkyMaterialData *material = NULL; + SkyMaterialData *material = nullptr; if (sky_material.is_valid()) { material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { - material = NULL; + material = nullptr; } } @@ -688,12 +688,12 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro RID sky_material = sky_get_material(environment_get_sky(p_environment)); - SkyMaterialData *material = NULL; + SkyMaterialData *material = nullptr; if (sky_material.is_valid()) { material = (SkyMaterialData *)storage->material_get_data(sky_material, RasterizerStorageRD::SHADER_TYPE_SKY); if (!material || !material->shader_data->valid) { - material = NULL; + material = nullptr; } } @@ -1231,6 +1231,26 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) glow_bicubic_upscale = p_enable; } +void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { + + Environent *env = environment_owner.getornull(p_env); + ERR_FAIL_COND(!env); + + env->ssr_enabled = p_enable; + env->ssr_max_steps = p_max_steps; + env->ssr_fade_in = p_fade_int; + env->ssr_fade_out = p_fade_out; + env->ssr_depth_tolerance = p_depth_tolerance; +} + +void RasterizerSceneRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { + ssr_roughness_quality = p_quality; +} + +RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughness_quality() const { + return ssr_roughness_quality; +} + void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environent *env = environment_owner.getornull(p_env); @@ -1272,7 +1292,7 @@ bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); - return false; + return env->ssr_enabled; } bool RasterizerSceneRD::is_environment(RID p_env) const { @@ -2012,7 +2032,7 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const light_instance->transform = p_transform; } -void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) { +void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2028,6 +2048,9 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance light_instance->shadow_transform[p_pass].farplane = p_far; light_instance->shadow_transform[p_pass].split = p_split; light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale; + light_instance->shadow_transform[p_pass].range_begin = p_range_begin; + light_instance->shadow_transform[p_pass].shadow_texel_size = p_shadow_texel_size; + light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale; } void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { @@ -3167,6 +3190,94 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { rb->ssao.ao_full = RID(); rb->ssao.depth_slices.clear(); } + + if (rb->ssr.blur_radius[0].is_valid()) { + RD::get_singleton()->free(rb->ssr.blur_radius[0]); + RD::get_singleton()->free(rb->ssr.blur_radius[1]); + rb->ssr.blur_radius[0] = RID(); + rb->ssr.blur_radius[1] = RID(); + } + + if (rb->ssr.depth_scaled.is_valid()) { + RD::get_singleton()->free(rb->ssr.depth_scaled); + rb->ssr.depth_scaled = RID(); + RD::get_singleton()->free(rb->ssr.normal_scaled); + rb->ssr.normal_scaled = RID(); + } +} + +void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { + + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(!rb); + + bool can_use_effects = rb->width >= 8 && rb->height >= 8; + + if (!can_use_effects) { + //just copy + return; + } + + if (rb->blur[0].texture.is_null()) { + _allocate_blur_textures(rb); + _render_buffers_uniform_set_changed(p_render_buffers); + } + + storage->get_effects()->sub_surface_scattering(rb->texture, rb->blur[0].mipmaps[0].texture, rb->depth_texture, p_camera, Size2i(rb->width, rb->height), sss_scale, sss_depth_scale, sss_quality); +} + +void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { + + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(!rb); + + bool can_use_effects = rb->width >= 8 && rb->height >= 8; + + if (!can_use_effects) { + //just copy + storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, RID()); + return; + } + + Environent *env = environment_owner.getornull(p_environment); + ERR_FAIL_COND(!env); + + ERR_FAIL_COND(!env->ssr_enabled); + + if (rb->ssr.depth_scaled.is_null()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + tf.width = rb->width / 2; + tf.height = rb->height / 2; + tf.type = RD::TEXTURE_TYPE_2D; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; + + rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + + rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); + } + + if (ssr_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = rb->width / 2; + tf.height = rb->height / 2; + tf.type = RD::TEXTURE_TYPE_2D; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + + rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ssr.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + } + + if (rb->blur[0].texture.is_null()) { + _allocate_blur_textures(rb); + _render_buffers_uniform_set_changed(p_render_buffers); + } + + storage->get_effects()->screen_space_reflection(rb->texture, p_normal_buffer, ssr_roughness_quality, p_roughness_buffer, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].mipmaps[1].texture, rb->blur[1].mipmaps[0].texture, Size2i(rb->width / 2, rb->height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); + storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->texture, rb->blur[0].mipmaps[1].texture); } void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { @@ -3459,6 +3570,23 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren _render_buffers_uniform_set_changed(p_render_buffers); } +void RasterizerSceneRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) { + sss_quality = p_quality; +} + +RS::SubSurfaceScatteringQuality RasterizerSceneRD::sub_surface_scattering_get_quality() const { + return sss_quality; +} + +void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) { + sss_scale = p_scale; + sss_depth_scale = p_depth_scale; +} + +void RasterizerSceneRD::shadow_filter_set(RS::ShadowFilter p_filter) { + shadow_filter = p_filter; +} + int RasterizerSceneRD::get_roughness_layers() const { return roughness_layers; } @@ -3469,7 +3597,7 @@ bool RasterizerSceneRD::is_using_radiance_cubemap_array() const { RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); - ERR_FAIL_COND_V(!rb, NULL); + ERR_FAIL_COND_V(!rb, nullptr); return rb->data; } @@ -3504,12 +3632,15 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; + float znear = 0; float zfar = 0; RID render_fb; RID render_texture; float bias = 0; float normal_bias = 0; + bool use_pancake = false; + bool use_linear_depth = false; bool render_cubemap = false; bool finalize_cubemap = false; @@ -3524,6 +3655,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas light_instance->last_scene_shadow_pass = scene_pass; } + use_pancake = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0; light_projection = light_instance->shadow_transform[p_pass].camera; light_transform = light_instance->shadow_transform[p_pass].transform; @@ -3562,7 +3694,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size; light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size; - float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE)); + float bias_mult = light_instance->shadow_transform[p_pass].bias_scale; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult; normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult; @@ -3641,26 +3773,33 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); render_fb = shadow_map->fb; render_texture = shadow_map->depth; + + znear = light_instance->shadow_transform[0].camera.get_z_near(); + use_linear_depth = true; } } if (render_cubemap) { //rendering to cubemap - _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false); + _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake); if (finalize_cubemap) { //reblit atlas_rect.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, false); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false); atlas_rect.position.y += atlas_rect.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, true); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true); } } else { //render shadow - _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip); + _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake); //copy to atlas - storage->get_effects()->copy_to_rect(render_texture, atlas_fb, atlas_rect, true); + if (use_linear_depth) { + storage->get_effects()->copy_to_rect_and_linearize(render_texture, atlas_fb, atlas_rect, true, znear, zfar); + } else { + storage->get_effects()->copy_to_rect(render_texture, atlas_fb, atlas_rect, true); + } //does not work from depth to color //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true); @@ -3798,7 +3937,7 @@ float RasterizerSceneRD::screen_space_roughness_limiter_get_curve() const { return screen_space_roughness_limiter_curve; } -RasterizerSceneRD *RasterizerSceneRD::singleton = NULL; +RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr; RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { storage = p_storage; @@ -4012,6 +4151,11 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter"); screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve"); glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; + ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); + sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality"))); + sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); + sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); + shadow_filter = RS::ShadowFilter(int(GLOBAL_GET("rendering/quality/shadows/filter_mode"))); } RasterizerSceneRD::~RasterizerSceneRD() { diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index dbdaf2f447..3478c05fb1 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -79,7 +79,7 @@ protected: virtual RenderBufferData *_create_render_buffer_data() = 0; virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0; - virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip) = 0; + virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0; virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); @@ -92,10 +92,12 @@ protected: virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0; void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection); + void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive); + void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera); void _setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size); void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); - void _draw_sky(bool p_can_continue, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); + void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); private: RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; @@ -525,6 +527,8 @@ private: bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); + RS::ShadowFilter shadow_filter = RS::SHADOW_FILTER_NONE; + /* DIRECTIONAL SHADOW */ struct DirectionalShadow { @@ -568,7 +572,10 @@ private: float farplane; float split; float bias_scale; + float shadow_texel_size; + float range_begin; Rect2 atlas_rect; + Vector2 uv_scale; }; RS::LightType light_type = RS::LIGHT_DIRECTIONAL; @@ -657,11 +664,20 @@ private: float ssao_ao_channel_affect = 0.0; float ssao_blur_edge_sharpness = 4.0; RS::EnvironmentSSAOBlur ssao_blur = RS::ENV_SSAO_BLUR_3x3; + + /// SSR + /// + bool ssr_enabled = false; + int ssr_max_steps = 64; + float ssr_fade_in = 0.15; + float ssr_fade_out = 2.0; + float ssr_depth_tolerance = 0.2; }; RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; bool ssao_half_size = false; bool glow_bicubic_upscale = false; + RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW; static uint64_t auto_exposure_counter; @@ -688,6 +704,9 @@ private: RS::DOFBlurQuality dof_blur_quality = RS::DOF_BLUR_QUALITY_MEDIUM; RS::DOFBokehShape dof_blur_bokeh_shape = RS::DOF_BOKEH_HEXAGON; bool dof_blur_use_jitter = false; + RS::SubSurfaceScatteringQuality sss_quality = RS::SUB_SURFACE_SCATTERING_QUALITY_MEDIUM; + float sss_scale = 0.05; + float sss_depth_scale = 0.01; mutable RID_Owner<CameraEffects> camera_effects_owner; @@ -733,6 +752,12 @@ private: RID ao[2]; RID ao_full; //when using half-size } ssao; + + struct SSR { + RID normal_scaled; + RID depth_scaled; + RID blur_radius[2]; + } ssr; }; bool screen_space_roughness_limiter = false; @@ -832,7 +857,7 @@ public: void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {} - void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) {} + void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size); bool environment_is_ssao_enabled(RID p_env) const; @@ -840,6 +865,9 @@ public: float environment_get_ssao_light_affect(RID p_env) const; bool environment_is_ssr_enabled(RID p_env) const; + void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality); + RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const; + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {} @@ -857,7 +885,7 @@ public: RID light_instance_create(RID p_light); void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0); + void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()); void light_instance_mark_visible(RID p_light_instance); _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { @@ -903,11 +931,55 @@ public: return li->shadow_transform[p_index].camera; } - _FORCE_INLINE_ Transform light_instance_get_shadow_transform(RID p_light_instance, int p_index) { + _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) { + +#ifdef DEBUG_ENABLED + LightInstance *li = light_instance_owner.getornull(p_light_instance); + ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0); +#endif + ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ERR_FAIL_COND_V(!shadow_atlas, 0); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0); +#endif + uint32_t key = shadow_atlas->shadow_owners[p_light_instance]; + + uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; + + uint32_t quadrant_size = shadow_atlas->size >> 1; + + uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision); + + return float(1.0) / shadow_size; + } + + _FORCE_INLINE_ Transform + light_instance_get_shadow_transform(RID p_light_instance, int p_index) { LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].transform; } + _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].bias_scale; + } + _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].farplane; + } + _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].range_begin; + } + + _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].uv_scale; + } _FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) { @@ -921,6 +993,12 @@ public: return li->shadow_transform[p_index].split; } + _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].shadow_texel_size; + } + _FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) { LightInstance *li = light_instance_owner.getornull(p_light_instance); li->last_pass = p_pass; @@ -1084,13 +1162,24 @@ public: void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); - virtual void set_scene_pass(uint64_t p_pass) { scene_pass = p_pass; } - _FORCE_INLINE_ uint64_t get_scene_pass() { return scene_pass; } + virtual void set_scene_pass(uint64_t p_pass) { + scene_pass = p_pass; + } + _FORCE_INLINE_ uint64_t get_scene_pass() { + return scene_pass; + } virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve); virtual bool screen_space_roughness_limiter_is_active() const; virtual float screen_space_roughness_limiter_get_curve() const; + virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality); + RS::SubSurfaceScatteringQuality sub_surface_scattering_get_quality() const; + virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale); + + virtual void shadow_filter_set(RS::ShadowFilter p_filter); + _FORCE_INLINE_ RS::ShadowFilter shadow_filter_get() const { return shadow_filter; } + int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; @@ -1099,7 +1188,9 @@ public: virtual void update(); virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw); - _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const { return debug_draw; } + _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const { + return debug_draw; + } virtual void set_time(double p_time, double p_step); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index b6b6b5a040..0b26ec1be6 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -862,7 +862,7 @@ Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) { RID RasterizerStorageRD::shader_create() { Shader shader; - shader.data = NULL; + shader.data = nullptr; shader.type = SHADER_TYPE_MAX; return shader_owner.make_rid(shader); @@ -890,7 +890,7 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { if (new_type != shader->type) { if (shader->data) { memdelete(shader->data); - shader->data = NULL; + shader->data = nullptr; } for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { @@ -899,7 +899,7 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { material->shader_type = new_type; if (material->data) { memdelete(material->data); - material->data = NULL; + material->data = nullptr; } } @@ -991,10 +991,10 @@ void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_t RID RasterizerStorageRD::material_create() { Material material; - material.data = NULL; - material.shader = NULL; + material.data = nullptr; + material.shader = nullptr; material.shader_type = SHADER_TYPE_MAX; - material.update_next = NULL; + material.update_next = nullptr; material.update_requested = false; material.uniform_dirty = false; material.texture_dirty = false; @@ -1026,12 +1026,12 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { if (material->data) { memdelete(material->data); - material->data = NULL; + material->data = nullptr; } if (material->shader) { material->shader->owners.erase(material); - material->shader = NULL; + material->shader = nullptr; material->shader_type = SHADER_TYPE_MAX; } @@ -1050,7 +1050,7 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { return; } - ERR_FAIL_COND(shader->data == NULL); + ERR_FAIL_COND(shader->data == nullptr); material->data = material_data_request_func[shader->type](shader->data); material->data->set_next_pass(material->next_pass); @@ -1770,10 +1770,10 @@ void RasterizerStorageRD::_update_queued_materials() { material->update_requested = false; material->texture_dirty = false; material->uniform_dirty = false; - material->update_next = NULL; + material->update_next = nullptr; material = next; } - material_update_list = NULL; + material_update_list = nullptr; } /* MESH API */ @@ -3104,15 +3104,17 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; + light.param[RS::LIGHT_PARAM_SIZE] = 0.0; light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45; - light.param[RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] = 45; light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6; light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8; - light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1; - light.param[RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1; + light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; + light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; + light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; return light_owner.make_rid(light); } @@ -3138,6 +3140,7 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET: case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET: case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: + case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; @@ -4453,10 +4456,10 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const RasterizerStorageRD::RasterizerStorageRD() { for (int i = 0; i < SHADER_TYPE_MAX; i++) { - shader_data_request_func[i] = NULL; + shader_data_request_func[i] = nullptr; } - material_update_list = NULL; + material_update_list = nullptr; { //create default textures RD::TextureFormat tformat; diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index ab02ca1331..7573a0d70c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -604,7 +604,7 @@ public: _FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) { Material *material = material_owner.getornull(p_material); if (!material || material->shader_type != p_shader_type) { - return NULL; + return nullptr; } else { return material->data; } @@ -640,10 +640,10 @@ public: _FORCE_INLINE_ const RID *mesh_get_surface_count_and_materials(RID p_mesh, uint32_t &r_surface_count) { Mesh *mesh = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!mesh, NULL); + ERR_FAIL_COND_V(!mesh, nullptr); r_surface_count = mesh->surface_count; if (r_surface_count == 0) { - return NULL; + return nullptr; } if (mesh->material_cache.empty()) { mesh->material_cache.resize(mesh->surface_count); @@ -926,6 +926,14 @@ public: return light->negative; } + _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const { + + const Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, 0.0); + + return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; + } + bool light_get_use_gi(RID p_light); uint64_t light_get_version(RID p_light) const; @@ -1037,7 +1045,7 @@ public: void lightmap_capture_set_energy(RID p_capture, float p_energy) {} float lightmap_capture_get_energy(RID p_capture) const { return 0.0; } const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const { - return NULL; + return nullptr; } /* PARTICLES */ diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp index 4ee020aa69..2bfdb7fffe 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp @@ -57,7 +57,7 @@ void RenderPipelineVertexFormatCacheRD::_clear() { } version_count = 0; memfree(versions); - versions = NULL; + versions = nullptr; } } @@ -88,7 +88,7 @@ void RenderPipelineVertexFormatCacheRD::clear() { RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() { version_count = 0; - versions = NULL; + versions = nullptr; input_mask = 0; } diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index b3a4b0ede8..4a0b4f02b1 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -303,7 +303,7 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, added); - SL::FunctionNode *fnode = NULL; + SL::FunctionNode *fnode = nullptr; for (int i = 0; i < p_node->functions.size(); i++) { if (p_node->functions[i].name == E->get()) { @@ -572,7 +572,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge function = fnode; current_func_name = fnode->name; function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); - function = NULL; + function = nullptr; } //place functions in actual code @@ -605,7 +605,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); r_gen_code.light = function_code[light_name]; } - function = NULL; + function = nullptr; } //code+=dump_node_code(pnode->body,p_level); @@ -798,12 +798,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge else code = _mkid(anode->name); - if (anode->call_expression != NULL) { + if (anode->call_expression != nullptr) { code += "."; code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); } - if (anode->index_expression != NULL) { + if (anode->index_expression != nullptr) { code += "["; code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "]"; @@ -1025,7 +1025,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge case SL::Node::TYPE_MEMBER: { SL::MemberNode *mnode = (SL::MemberNode *)p_node; code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + mnode->name; - if (mnode->index_expression != NULL) { + if (mnode->index_expression != nullptr) { code += "["; code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "]"; @@ -1048,7 +1048,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide print_line(itos(i + 1) + " " + shader[i]); } - _err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER); + _err_print_error(nullptr, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER); return err; } @@ -1066,7 +1066,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide used_flag_pointers.clear(); shader = parser.get_shader(); - function = NULL; + function = nullptr; _dump_node_code(shader, 1, r_gen_code, *p_actions, actions, false); return OK; diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/rasterizer_rd/shader_rd.cpp index 3dcfd0faf9..d60a58813e 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_rd.cpp @@ -191,7 +191,7 @@ RID ShaderRD::version_create() { version.dirty = true; version.valid = false; version.initialize_needed = true; - version.variants = NULL; + version.variants = nullptr; return version_owner.make_rid(version); } @@ -203,7 +203,7 @@ void ShaderRD::_clear_version(Version *p_version) { } memdelete_arr(p_version->variants); - p_version->variants = NULL; + p_version->variants = nullptr; } } @@ -394,7 +394,7 @@ void ShaderRD::_compile_version(Version *p_version) { } } memdelete_arr(p_version->variants); - p_version->variants = NULL; + p_version->variants = nullptr; return; } diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub index 6e852e2dc5..04a43e3251 100644 --- a/servers/rendering/rasterizer_rd/shaders/SCsub +++ b/servers/rendering/rasterizer_rd/shaders/SCsub @@ -22,3 +22,8 @@ if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("ssao_minify.glsl") env.RD_GLSL("ssao_blur.glsl") env.RD_GLSL("roughness_limiter.glsl") + env.RD_GLSL("screen_space_reflection.glsl") + env.RD_GLSL("screen_space_reflection_filter.glsl") + env.RD_GLSL("screen_space_reflection_scale.glsl") + env.RD_GLSL("subsurface_scattering.glsl") + env.RD_GLSL("specular_merge.glsl") diff --git a/servers/rendering/rasterizer_rd/shaders/blur.glsl b/servers/rendering/rasterizer_rd/shaders/blur.glsl index 87c20ebaef..5dfdc614a4 100644 --- a/servers/rendering/rasterizer_rd/shaders/blur.glsl +++ b/servers/rendering/rasterizer_rd/shaders/blur.glsl @@ -285,6 +285,13 @@ void main() { frag_color = color; #endif +#ifdef MODE_LINEARIZE_DEPTH_COPY + float depth = texture(source_color, uv_interp, 0.0).r; + depth = depth * 2.0 - 1.0; + depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); + frag_color = vec4(depth / blur.camera_z_far); +#endif + #ifdef MODE_SSAO_MERGE vec4 color = texture(source_color, uv_interp, 0.0); float ssao = texture(source_ssao, uv_interp, 0.0).r; diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index cbb9b546a3..2b541f2660 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -57,6 +57,7 @@ void main() { } float depth = texture(source_cube, normal).r; + depth_buffer = depth; // absolute values for direction cosines, bigger value equals closer to basis axis vec3 unorm = abs(normal); @@ -80,7 +81,7 @@ void main() { depth = 2.0 * depth - 1.0; float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); - depth_buffer = (linear_depth * depth_fix + params.bias) / params.z_far; + depth_buffer = (linear_depth * depth_fix) / params.z_far; #endif } diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 07f4770b14..70ce8d61e4 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -244,19 +244,13 @@ VERTEX_SHADER_CODE //for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges - vec3 vtx = vertex_interp + normalize(vertex_interp) * scene_data.z_offset; + vec3 vtx = vertex_interp; float distance = length(vtx); vtx = normalize(vtx); vtx.xy /= 1.0 - vtx.z; vtx.z = (distance / scene_data.z_far); vtx.z = vtx.z * 2.0 - 1.0; - vertex_interp = vtx; -#else - - float z_ofs = scene_data.z_offset; - z_ofs += max(0.0, 1.0 - abs(normalize(normal_interp).z)) * scene_data.z_slope_scale; - vertex_interp.z -= z_ofs; #endif @@ -267,6 +261,14 @@ VERTEX_SHADER_CODE #else gl_Position = projection_matrix * vec4(vertex_interp, 1.0); #endif + +#ifdef MODE_RENDER_DEPTH + if (scene_data.pancake_shadows) { + if (gl_Position.z <= 0.00001) { + gl_Position.z = 0.00001; + } + } +#endif } /* clang-format off */ @@ -315,6 +317,11 @@ layout(location = 8) in float dp_clip; #define world_normal_matrix instances.data[instance_index].normal_transform #define projection_matrix scene_data.projection_matrix +#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) +//both required for transmittance to be enabled +#define LIGHT_TRANSMITTANCE_USED +#endif + #ifdef USE_MATERIAL_UNIFORMS layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ @@ -434,9 +441,16 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, vec3 attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 shadow_attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, + float transmittance_z, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -467,7 +481,7 @@ LIGHT_SHADER_CODE /* clang-format on */ #else - float NdotL = dot(N, L); + float NdotL = min(A + dot(N, L), 1.0); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); @@ -477,11 +491,11 @@ LIGHT_SHADER_CODE #endif #if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) - float cNdotH = max(dot(N, H), 0.0); + float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); #endif #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) - float cLdotH = max(dot(L, H), 0.0); + float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); #endif if (metallic < 1.0) { @@ -538,16 +552,48 @@ LIGHT_SHADER_CODE diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif - diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation; + diffuse_light += light_color * diffuse_color * shadow_attenuation * diffuse_brdf_NL * attenuation; -#if defined(LIGHT_TRANSMISSION_USED) - diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation; +#if defined(LIGHT_BACKLIGHT_USED) + diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; #endif #if defined(LIGHT_RIM_USED) float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color; #endif + +#ifdef LIGHT_TRANSMITTANCE_USED + +#ifdef SSS_MODE_SKIN + + { + float scale = 8.25 / transmittance_depth; + float d = scale * abs(transmittance_z); + float dd = -d * d; + vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); + + diffuse_light += profile * transmittance_color.a * diffuse_color * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI) * attenuation; + } +#else + + if (transmittance_depth > 0.0) { + float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0); + + fade = pow(max(0.0, 1.0 - fade), transmittance_curve); + fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0); + + diffuse_light += diffuse_color * transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade * attenuation; + } + +#endif //SSS_MODE_SKIN + +#endif //LIGHT_TRANSMITTANCE_USED } if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely @@ -562,18 +608,18 @@ LIGHT_SHADER_CODE blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = blinn; - specular_light += light_color * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_PHONG) vec3 R = normalize(-reflect(L, N)); - float cRdotV = max(0.0, dot(R, V)); + float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); - specular_light += light_color * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_TOON) @@ -582,7 +628,7 @@ LIGHT_SHADER_CODE float mid = 1.0 - roughness; mid *= mid; float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; - diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection + diffuse_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection #elif defined(SPECULAR_DISABLED) // none.. @@ -613,7 +659,7 @@ LIGHT_SHADER_CODE vec3 specular_brdf_NL = cNdotL * D * F * G; - specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; + specular_light += specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; #endif #if defined(LIGHT_CLEARCOAT_USED) @@ -627,12 +673,12 @@ LIGHT_SHADER_CODE float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; - specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation; + specular_light += clearcoat_specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; #endif } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0)); + alpha = min(alpha, clamp(1.0 - length(shadow_attenuation * attenuation), 0.0, 1.0)); #endif #endif //defined(USE_LIGHT_SHADER_CODE) @@ -640,53 +686,119 @@ LIGHT_SHADER_CODE #ifndef USE_NO_SHADOWS +const vec2 shadow_poisson_disk[16] = vec2[]( + vec2(-0.94201624, -0.39906216), + vec2(0.94558609, -0.76890725), + vec2(-0.094184101, -0.92938870), + vec2(0.34495938, 0.29387760), + vec2(-0.91588581, 0.45771432), + vec2(-0.81544232, -0.87912464), + vec2(-0.38277543, 0.27676845), + vec2(0.97484398, 0.75648379), + vec2(0.44323325, -0.97511554), + vec2(0.53742981, -0.47373420), + vec2(-0.26496911, -0.41893023), + vec2(0.79197514, 0.19090188), + vec2(-0.24188840, 0.99706507), + vec2(-0.81409955, 0.91437590), + vec2(0.19984126, 0.78641367), + vec2(0.14383161, -0.14100790)); + float sample_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - //todo optimize vec2 pos = coord.xy; float depth = coord.z; -#ifdef SHADOW_MODE_PCF_13 + switch (scene_data.shadow_filter_mode) { + case SHADOW_MODE_NO_FILTER: { + return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + }; + case SHADOW_MODE_PCF5: { + float avg = textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); + return avg * (1.0 / 5.0); + }; + case SHADOW_MODE_PCF13: { + + float avg = textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0)); + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0)); + return avg * (1.0 / 13.0); + }; + } - float avg = textureProj(shadow, vec4(pos, depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0)); - return avg * (1.0 / 13.0); -#endif + return 0; +} -#ifdef SHADOW_MODE_PCF_5 +float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { - float avg = textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); - return avg * (1.0 / 5.0); + //find blocker + float blocker_count = 0.0; + float blocker_average = 0.0; -#endif + mat2 poisson_rotate; -#if !defined(SHADOW_MODE_PCF_5) || !defined(SHADOW_MODE_PCF_13) + { + float r = dot(vec2(gl_FragCoord.xy), vec2(131.234, 583.123)); + float sr = sin(r); + float cr = cos(r); + poisson_rotate = mat2(vec2(cr, -sr), vec2(sr, cr)); + } - return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + vec2 suv = pssm_coord.xy + (poisson_rotate * shadow_poisson_disk[i]) * tex_scale; + float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; + if (d < pssm_coord.z) { + blocker_average += d; + blocker_count += 1.0; + } + } -#endif + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (pssm_coord.z - blocker_average) / blocker_average; + tex_scale *= penumbra; + + float s = 0.0; + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + vec2 suv = pssm_coord.xy + (poisson_rotate * shadow_poisson_disk[i]) * tex_scale; + s += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(suv, pssm_coord.z, 1.0)); + } + + return s / float(scene_data.shadow_blocker_count); + + } else { + //no blockers found, so no shadow + return 1.0; + } } #endif //USE_NO_SHADOWS void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -707,45 +819,203 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a float normalized_distance = light_length * lights.data[idx].inv_radius; vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x); - vec3 light_attenuation = vec3(omni_attenuation); + float light_attenuation = omni_attenuation; + vec3 shadow_attenuation = vec3(1.0); vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); color_specular.rgb *= attenuation_energy.y; + float size_A = 0.0; + + if (lights.data[idx].size > 0.0) { + + float t = lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } + +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; //no transmittance by default +#endif #ifndef USE_NO_SHADOWS vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); if (shadow_color_enabled.w > 0.5) { // there is a shadowmap - vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); - float shadow_len = length(splane); - splane = normalize(splane); - vec4 clamp_rect = lights.data[idx].atlas_rect; + vec4 v = vec4(vertex, 1.0); + + vec4 splane = (lights.data[idx].shadow_matrix * v); + float shadow_len = length(splane.xyz); //need to remember shadow len from here + + { + vec3 nofs = normal_interp * lights.data[idx].shadow_normal_bias / lights.data[idx].inv_radius; + nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp)))); + v.xyz += nofs; + splane = (lights.data[idx].shadow_matrix * v); + } + + float shadow; + + if (lights.data[idx].soft_shadow_size > 0.0) { + //soft shadow + + //find blocker - if (splane.z >= 0.0) { + float blocker_count = 0.0; + float blocker_average = 0.0; - splane.z += 1.0; + mat2 poisson_rotate; - clamp_rect.y += clamp_rect.w; + { + float r = dot(vec2(gl_FragCoord.xy), vec2(131.234, 583.123)); + float sr = sin(r); + float cr = cos(r); + poisson_rotate = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + vec3 normal = normalize(splane.xyz); + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, normal)); + vec3 bitangent = normalize(cross(tangent, normal)); + float z_norm = shadow_len * lights.data[idx].inv_radius; + + tangent *= lights.data[idx].soft_shadow_size; + bitangent *= lights.data[idx].soft_shadow_size; + + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + vec2 poisson = (poisson_rotate * shadow_poisson_disk[i]); + vec3 pos = splane.xyz + tangent * poisson.x + bitangent * poisson.y; + + pos = normalize(pos); + vec4 uv_rect = lights.data[idx].atlas_rect; + + if (pos.z >= 0.0) { + + pos.z += 1.0; + uv_rect.y += uv_rect.w; + } else { + + pos.z = 1.0 - pos.z; + } + + pos.xy /= pos.z; + + pos.xy = pos.xy * 0.5 + 0.5; + pos.xy = uv_rect.xy + pos.xy * uv_rect.zw; + + float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), pos.xy, 0.0).r; + if (d < z_norm) { + blocker_average += d; + blocker_count += 1.0; + } + } + + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (z_norm - blocker_average) / blocker_average; + tangent *= penumbra; + bitangent *= penumbra; + + z_norm -= lights.data[idx].inv_radius * lights.data[idx].shadow_bias; + + shadow = 0.0; + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + + vec2 poisson = (poisson_rotate * shadow_poisson_disk[i]); + vec3 pos = splane.xyz + tangent * poisson.x + bitangent * poisson.y; + + pos = normalize(pos); + vec4 uv_rect = lights.data[idx].atlas_rect; + + if (pos.z >= 0.0) { + + pos.z += 1.0; + uv_rect.y += uv_rect.w; + } else { + pos.z = 1.0 - pos.z; + } + + pos.xy /= pos.z; + + pos.xy = pos.xy * 0.5 + 0.5; + pos.xy = uv_rect.xy + pos.xy * uv_rect.zw; + shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(pos.xy, z_norm, 1.0)); + } + + shadow /= float(scene_data.shadow_blocker_count); + + } else { + //no blockers found, so no shadow + shadow = 1.0; + } } else { - splane.z = 1.0 - splane.z; + splane.xyz = normalize(splane.xyz); + vec4 clamp_rect = lights.data[idx].atlas_rect; + + if (splane.z >= 0.0) { + + splane.z += 1.0; + + clamp_rect.y += clamp_rect.w; + + } else { + splane.z = 1.0 - splane.z; + } + + splane.xy /= splane.z; + + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = (shadow_len - lights.data[idx].shadow_bias) * lights.data[idx].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already + shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); } - splane.xy /= splane.z; - splane.xy = splane.xy * 0.5 + 0.5; - splane.z = shadow_len * lights.data[idx].inv_radius; - splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; - splane.w = 1.0; //needed? i think it should be 1 already - float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); +#ifdef LIGHT_TRANSMITTANCE_USED + { + + //redo shadowmapping, but shrink the model a bit to avoid arctifacts + splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); + + shadow_len = length(splane); + splane = normalize(splane); + + if (splane.z >= 0.0) { + + splane.z += 1.0; + + } else { + + splane.z = 1.0 - splane.z; + } + + splane.xy /= splane.z; + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = shadow_len * lights.data[idx].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already + + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + transmittance_z = (splane.z - shadow_z) / lights.data[idx].inv_radius; + } +#endif - light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); } #endif //USE_NO_SHADOWS - light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim * omni_attenuation, rim_tint, @@ -764,8 +1034,14 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a } void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -792,31 +1068,135 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y); float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y)); spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x); - vec3 light_attenuation = vec3(spot_attenuation); + float light_attenuation = spot_attenuation; + vec3 shadow_attenuation = vec3(1.0); vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); color_specular.rgb *= attenuation_energy.y; + float size_A = 0.0; + + if (lights.data[idx].size > 0.0) { + + float t = lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } /* if (lights.data[idx].atlas_rect!=vec4(0.0)) { //use projector texture } */ +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; +#endif + #ifndef USE_NO_SHADOWS vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); if (shadow_color_enabled.w > 0.5) { //there is a shadowmap - vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + + v.xyz -= spot_dir * lights.data[idx].shadow_bias; + + float z_norm = dot(spot_dir, -light_rel_vec) * lights.data[idx].inv_radius; + + float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map + vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * lights.data[idx].shadow_normal_bias * depth_bias_scale; + normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z + v.xyz += normal_bias; + + //adjust with bias + z_norm = dot(spot_dir, v.xyz - lights.data[idx].position) * lights.data[idx].inv_radius; + + float shadow; + + vec4 splane = (lights.data[idx].shadow_matrix * v); splane /= splane.w; - float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); - light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + if (lights.data[idx].soft_shadow_size > 0.0) { + //soft shadow + + //find blocker + + float blocker_count = 0.0; + float blocker_average = 0.0; + + mat2 poisson_rotate; + + { + float r = dot(vec2(gl_FragCoord.xy), vec2(131.234, 583.123)); + float sr = sin(r); + float cr = cos(r); + poisson_rotate = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + float uv_size = lights.data[idx].soft_shadow_size * z_norm; + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + vec2 suv = splane.xy + (poisson_rotate * shadow_poisson_disk[i]) * uv_size; + suv = clamp(suv, lights.data[idx].atlas_rect.xy, lights.data[idx].atlas_rect.zw); + float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; + if (d < z_norm) { + blocker_average += d; + blocker_count += 1.0; + } + } + + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (z_norm - blocker_average) / blocker_average; + uv_size *= penumbra; + + shadow = 0.0; + for (uint i = 0; i < scene_data.shadow_blocker_count; i++) { + vec2 suv = splane.xy + (poisson_rotate * shadow_poisson_disk[i]) * uv_size; + suv = clamp(suv, lights.data[idx].atlas_rect.xy, lights.data[idx].atlas_rect.zw); + shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0)); + } + + shadow /= float(scene_data.shadow_blocker_count); + + } else { + //no blockers found, so no shadow + shadow = 1.0; + } + + } else { + //hard shadow + splane.z = z_norm; + shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); + } + + shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + +#ifdef LIGHT_TRANSMITTANCE_USED + { + + vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); + splane /= splane.w; + + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + //reconstruct depth + shadow_z / lights.data[idx].inv_radius; + //distance to light plane + float z = dot(spot_dir, -light_rel_vec); + transmittance_z = z - shadow_z; + } +#endif //LIGHT_TRANSMITTANCE_USED } #endif //USE_NO_SHADOWS - light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim * spot_attenuation, rim_tint, @@ -1185,7 +1565,11 @@ void main() { vec3 vertex = vertex_interp; vec3 view = -normalize(vertex_interp); vec3 albedo = vec3(1.0); - vec3 transmission = vec3(0.0); + vec3 backlight = vec3(0.0); + vec4 transmittance_color = vec4(0.0); + float transmittance_depth = 0.0; + float transmittance_curve = 1.0; + float transmittance_boost = 0.0; float metallic = 0.0; float specular = 0.5; vec3 emission = vec3(0.0); @@ -1254,6 +1638,14 @@ FRAGMENT_SHADER_CODE /* clang-format on */ } +#if defined(LIGHT_TRANSMITTANCE_USED) +#ifdef SSS_MODE_SKIN + transmittance_color.a = sss_strength; +#else + transmittance_color.a *= sss_strength; +#endif +#endif + #if !defined(USE_SHADOW_TO_OPACITY) #if defined(ALPHA_SCISSOR_USED) @@ -1462,58 +1854,250 @@ FRAGMENT_SHADER_CODE continue; //not masked } - vec3 light_attenuation = vec3(1.0); + vec3 shadow_attenuation = vec3(1.0); + +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; +#endif if (directional_lights.data[i].shadow_enabled) { float depth_z = -vertex.z; vec4 pssm_coord; + vec3 shadow_color = vec3(0.0); + vec3 light_dir = directional_lights.data[i].direction; + +#define BIAS_FUNC(m_var, m_idx) \ + m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ + vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))) * directional_lights.data[i].shadow_normal_bias[m_idx]; \ + normal_bias -= light_dir * dot(light_dir, normal_bias); \ + m_var.xyz += normal_bias; + + float shadow = 0.0; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix1 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 0) + + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.x; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color1.rgb; + +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; + + transmittance_z = z - shadow_z; + } +#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0)); + + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 1) + + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.y; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color2.rgb; +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; + + transmittance_z = z - shadow_z; + } +#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0)); + + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 2) + + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.z; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color3.rgb; +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; + + transmittance_z = z - shadow_z; + } +#endif + } else { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0)); - } - pssm_coord /= pssm_coord.w; + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 3) + + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.w; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color4.rgb; + +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; - float shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + transmittance_z = z - shadow_z; + } +#endif + } if (directional_lights.data[i].blend_splits) { + vec3 shadow_color_blend = vec3(0.0); float pssm_blend; + float shadow2; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 1) + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.y; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); + shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 2) + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.z; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + + shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 3) + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.w; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale); + } else { + shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + } + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); + shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; } else { pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } - pssm_coord /= pssm_coord.w; + pssm_blend = sqrt(pssm_blend); - float shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); shadow = mix(shadow, shadow2, pssm_blend); + shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); } shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance - light_attenuation = mix(directional_lights.data[i].shadow_color, vec3(1.0), shadow); + shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); + +#undef BIAS_FUNC } - light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, light_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].size, directional_lights.data[i].color * directional_lights.data[i].energy, 1.0, shadow_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim, rim_tint, @@ -1546,8 +2130,14 @@ FRAGMENT_SHADER_CODE } light_process_omni(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED rim, @@ -1579,8 +2169,14 @@ FRAGMENT_SHADER_CODE } light_process_spot(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED rim, @@ -1697,6 +2293,9 @@ FRAGMENT_SHADER_CODE #else +#ifdef SSS_MODE_SKIN + sss_strength = -sss_strength; +#endif diffuse_buffer = vec4(emission + diffuse_light + ambient_light, sss_strength); specular_buffer = vec4(specular_light, metallic); diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl index baef1e060f..59f326bc9b 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -22,6 +22,10 @@ draw_call; #define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10 #define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11 +#define SHADOW_MODE_NO_FILTER 0 +#define SHADOW_MODE_PCF5 1 +#define SHADOW_MODE_PCF13 2 + layout(set = 0, binding = 1) uniform sampler material_samplers[12]; layout(set = 0, binding = 2) uniform sampler shadow_sampler; @@ -37,13 +41,17 @@ layout(set = 0, binding = 3, std140) uniform SceneData { vec2 viewport_size; vec2 screen_pixel_size; - //used for shadow mapping only - float z_offset; - float z_slope_scale; - float time; float reflection_multiplier; // one normally, zero when rendering reflections + bool pancake_shadows; + uint shadow_filter_mode; + + uint shadow_blocker_count; + uint shadow_pad0; + uint shadow_pad1; + uint shadow_pad2; + vec4 ambient_light_color_energy; float ambient_color_sky_mix; @@ -134,21 +142,27 @@ layout(set = 0, binding = 4, std430) buffer Instances { } instances; -struct LightData { //this structure needs to be 128 bits +struct LightData { //this structure needs to be as packed as possible vec3 position; float inv_radius; vec3 direction; + float size; uint attenuation_energy; //attenuation uint color_specular; //rgb color, a specular (8 bit unorm) uint cone_attenuation_angle; // attenuation and angle, (16bit float) - uint mask; uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm) - vec4 atlas_rect; //used for shadow atlas uv on omni, and for projection atlas on spot + vec4 atlas_rect; // used for spot mat4 shadow_matrix; + float shadow_bias; + float shadow_normal_bias; + float transmittance_bias; + float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle + uint mask; + uint pad[3]; }; -layout(set = 0, binding = 5, std140) uniform Lights { - LightData data[MAX_LIGHT_DATA_STRUCTS]; +layout(set = 0, binding = 5, std430) buffer Lights { + LightData data[]; } lights; @@ -173,18 +187,33 @@ struct DirectionalLightData { vec3 direction; float energy; vec3 color; + float size; float specular; - vec3 shadow_color; uint mask; + float softshadow_angle; + uint pad1; bool blend_splits; bool shadow_enabled; float fade_from; float fade_to; + vec4 shadow_bias; + vec4 shadow_normal_bias; + vec4 shadow_transmittance_bias; + vec4 shadow_transmittance_z_scale; + vec4 shadow_range_begin; vec4 shadow_split_offsets; mat4 shadow_matrix1; mat4 shadow_matrix2; mat4 shadow_matrix3; mat4 shadow_matrix4; + vec4 shadow_color1; + vec4 shadow_color2; + vec4 shadow_color3; + vec4 shadow_color4; + vec2 uv_scale1; + vec2 uv_scale2; + vec2 uv_scale3; + vec2 uv_scale4; }; layout(set = 0, binding = 7, std140) uniform DirectionalLights { diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl new file mode 100644 index 0000000000..e3c26c9b72 --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl @@ -0,0 +1,262 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + + + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +/* clang-format on */ + +layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_diffuse; +layout(r32f, set = 0, binding = 1) uniform restrict readonly image2D source_depth; +layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D ssr_image; +#ifdef MODE_ROUGH +layout(r8, set = 1, binding = 1) uniform restrict writeonly image2D blur_radius_image; +#endif +layout(rgba8, set = 2, binding = 0) uniform restrict readonly image2D source_normal; +layout(set = 3, binding = 0) uniform sampler2D source_metallic; +#ifdef MODE_ROUGH +layout(set = 3, binding = 1) uniform sampler2D source_roughness; +#endif + +layout(push_constant, binding = 2, std430) uniform Params { + + vec4 proj_info; + + ivec2 screen_size; + float camera_z_near; + float camera_z_far; + + int num_steps; + float depth_tolerance; + float distance_fade; + float curve_fade_in; + + bool orthogonal; + float filter_mipmap_levels; + bool use_half_res; + uint metallic_mask; + + mat4 projection; +} +params; + +vec2 view_to_screen(vec3 view_pos, out float w) { + vec4 projected = params.projection * vec4(view_pos, 1.0); + projected.xyz /= projected.w; + projected.xy = projected.xy * 0.5 + 0.5; + w = projected.w; + return projected.xy; +} + +#define M_PI 3.14159265359 + +vec3 reconstructCSPosition(vec2 S, float z) { + if (params.orthogonal) { + return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z); + } else { + return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z); + } +} + +void main() { + + // Pixel being shaded + ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); + + if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + return; + } + + vec2 pixel_size = 1.0 / vec2(params.screen_size); + vec2 uv = vec2(ssC) * pixel_size; + + uv += pixel_size * 0.5; + + float base_depth = imageLoad(source_depth, ssC).r; + + // World space point being shaded + vec3 vertex = reconstructCSPosition(uv * vec2(params.screen_size), base_depth); + + vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0; + normal = normalize(normal); + normal.y = -normal.y; //because this code reads flipped + + vec3 view_dir = normalize(vertex); + vec3 ray_dir = normalize(reflect(view_dir, normal)); + + if (dot(ray_dir, normal) < 0.001) { + imageStore(ssr_image, ssC, vec4(0.0)); + return; + } + //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); + //ray_dir = normalize(vec3(1.0, 1.0, -1.0)); + + //////////////// + + // make ray length and clip it against the near plane (don't want to trace beyond visible) + float ray_len = (vertex.z + ray_dir.z * params.camera_z_far) > -params.camera_z_near ? (-params.camera_z_near - vertex.z) / ray_dir.z : params.camera_z_far; + vec3 ray_end = vertex + ray_dir * ray_len; + + float w_begin; + vec2 vp_line_begin = view_to_screen(vertex, w_begin); + float w_end; + vec2 vp_line_end = view_to_screen(ray_end, w_end); + vec2 vp_line_dir = vp_line_end - vp_line_begin; + + // we need to interpolate w along the ray, to generate perspective correct reflections + w_begin = 1.0 / w_begin; + w_end = 1.0 / w_end; + + float z_begin = vertex.z * w_begin; + float z_end = ray_end.z * w_end; + + vec2 line_begin = vp_line_begin / pixel_size; + vec2 line_dir = vp_line_dir / pixel_size; + float z_dir = z_end - z_begin; + float w_dir = w_end - w_begin; + + // clip the line to the viewport edges + + float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x)); + float scale_max_y = min(1.0, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y)); + float scale_min_x = min(1.0, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x)); + float scale_min_y = min(1.0, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y)); + float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y); + line_dir *= line_clip; + z_dir *= line_clip; + w_dir *= line_clip; + + // clip z and w advance to line advance + vec2 line_advance = normalize(line_dir); // down to pixel + float step_size = length(line_advance) / length(line_dir); + float z_advance = z_dir * step_size; // adapt z advance to line advance + float w_advance = w_dir * step_size; // adapt w advance to line advance + + // make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice) + float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y)); + line_advance *= advance_angle_adj; // adapt z advance to line advance + z_advance *= advance_angle_adj; + w_advance *= advance_angle_adj; + + vec2 pos = line_begin; + float z = z_begin; + float w = w_begin; + float z_from = z / w; + float z_to = z_from; + float depth; + vec2 prev_pos = pos; + + bool found = false; + + float steps_taken = 0.0; + + for (int i = 0; i < params.num_steps; i++) { + + pos += line_advance; + z += z_advance; + w += w_advance; + + // convert to linear depth + + depth = imageLoad(source_depth, ivec2(pos - 0.5)).r; + + if (-depth >= params.camera_z_far) { //went beyond camera + break; + } + + z_from = z_to; + z_to = z / w; + + if (depth > z_to) { + // if depth was surpassed + if (depth <= max(z_to, z_from) + params.depth_tolerance) { + // check the depth tolerance + //check that normal is valid + found = true; + } + break; + } + + steps_taken += 1.0; + prev_pos = pos; + } + + if (found) { + + float margin_blend = 1.0; + + vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin + if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, params.screen_size + margin)))) { + // clip outside screen + margin + imageStore(ssr_image, ssC, vec4(0.0)); + return; + } + + { + //blend fading out towards external margin + vec2 margin_grad = mix(pos - params.screen_size, -pos, lessThan(pos, vec2(0.0))); + margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y)); + //margin_blend = 1.0; + } + + vec2 final_pos; + float grad; + grad = steps_taken / float(params.num_steps); + float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in); + float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade; + final_pos = pos; + + vec4 final_color; + +#ifdef MODE_ROUGH + + // if roughness is enabled, do screen space cone tracing + float blur_radius = 0.0; + float roughness = texelFetch(source_roughness, ssC << 1, 0).r; + + if (roughness > 0.001) { + + float cone_angle = min(roughness, 0.999) * M_PI * 0.5; + float cone_len = length(final_pos - line_begin); + float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle + { + // fit to sphere inside cone (sphere ends at end of cone), something like this: + // ___ + // \O/ + // V + // + // as it avoids bleeding from beyond the reflection as much as possible. As a plus + // it also makes the rough reflection more elongated. + float a = op_len; + float h = cone_len; + float a2 = a * a; + float fh2 = 4.0f * h * h; + blur_radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); + } + } + + final_color = imageLoad(source_diffuse, ivec2((final_pos - 0.5) * pixel_size)); + + imageStore(blur_radius_image, ssC, vec4(blur_radius / 255.0)); //stored in r8 + +#endif + + final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend); + //change blend by metallic + vec4 metallic_mask = unpackUnorm4x8(params.metallic_mask); + final_color.a *= dot(metallic_mask, texelFetch(source_metallic, ssC << 1, 0)); + + imageStore(ssr_image, ssC, final_color); + + } else { +#ifdef MODE_ROUGH + imageStore(blur_radius_image, ssC, vec4(0.0)); +#endif + imageStore(ssr_image, ssC, vec4(0.0)); + } +} diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl new file mode 100644 index 0000000000..1a5dd5ab55 --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl @@ -0,0 +1,164 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + + + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +/* clang-format on */ + +layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_ssr; +layout(r8, set = 0, binding = 1) uniform restrict readonly image2D source_radius; +layout(rgba8, set = 1, binding = 0) uniform restrict readonly image2D source_normal; + +layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly image2D dest_ssr; +#ifndef VERTICAL_PASS +layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius; +#endif +layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth; + +layout(push_constant, binding = 2, std430) uniform Params { + + vec4 proj_info; + + bool orthogonal; + float edge_tolerance; + int increment; + uint pad; + + ivec2 screen_size; + bool vertical; + uint steps; +} +params; + +#define GAUSS_TABLE_SIZE 15 + +const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[]( + 0.1847392078702266, + 0.16595854345772326, + 0.12031364177766891, + 0.07038755277896766, + 0.03322925565155569, + 0.012657819729901945, + 0.0038903040680094217, + 0.0009646503390864025, + 0.00019297087402915717, + 0.000031139936308099136, + 0.000004053309048174758, + 4.255228059965837e-7, + 3.602517634249573e-8, + 2.4592560765896795e-9, + 1.3534945386863618e-10, + 0.0 //one more for interpolation +); + +float gauss_weight(float p_val) { + + float idxf; + float c = modf(max(0.0, p_val * float(GAUSS_TABLE_SIZE)), idxf); + int idx = int(idxf); + if (idx >= GAUSS_TABLE_SIZE + 1) { + return 0.0; + } + + return mix(gauss_table[idx], gauss_table[idx + 1], c); +} + +#define M_PI 3.14159265359 + +vec3 reconstructCSPosition(vec2 S, float z) { + if (params.orthogonal) { + return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z); + } else { + return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z); + } +} + +void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) { + + for (int i = 1; i < params.steps; i++) { + float d = float(i * params.increment); + ivec2 tc = texcoord + increment * i; + float depth = imageLoad(source_depth, tc).r; + vec3 view_pos = reconstructCSPosition(vec2(tc) + 0.5, depth); + vec3 view_normal = normalize(imageLoad(source_normal, tc).rgb * 2.0 - 1.0); + view_normal.y = -view_normal.y; + + float r = imageLoad(source_radius, tc).r; + float radius = round(r * 255.0); + + float angle_n = 1.0 - abs(dot(normal, view_normal)); + if (angle_n > params.edge_tolerance) { + break; + } + + float angle = abs(dot(normal, normalize(view_pos - p_pos))); + + if (angle > params.edge_tolerance) { + break; + } + + if (d < radius) { + + float w = gauss_weight(d / radius); + accum += imageLoad(source_ssr, tc) * w; +#ifndef VERTICAL_PASS + accum_radius += r * w; +#endif + divisor += w; + } + } +} + +void main() { + + // Pixel being shaded + ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); + + if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + return; + } + + float base_contrib = gauss_table[0]; + + vec4 accum = imageLoad(source_ssr, ssC); + + float accum_radius = imageLoad(source_radius, ssC).r; + float radius = accum_radius * 255.0; + + float divisor = gauss_table[0]; + accum *= divisor; + accum_radius *= divisor; +#ifdef VERTICAL_PASS + ivec2 direction = ivec2(0, params.increment); +#else + ivec2 direction = ivec2(params.increment, 0); +#endif + float depth = imageLoad(source_depth, ssC).r; + vec3 pos = reconstructCSPosition(vec2(ssC) + 0.5, depth); + vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0; + normal = normalize(normal); + normal.y = -normal.y; + + do_filter(accum, accum_radius, divisor, ssC, direction, pos, normal, radius); + do_filter(accum, accum_radius, divisor, ssC, -direction, pos, normal, radius); + + if (divisor > 0.0) { + accum /= divisor; + accum_radius /= divisor; + } else { + accum = vec4(0.0); + accum_radius = 0.0; + } + + imageStore(dest_ssr, ssC, accum); + +#ifndef VERTICAL_PASS + imageStore(dest_radius, ssC, vec4(accum_radius)); +#endif +} diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl new file mode 100644 index 0000000000..cec6c14c76 --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl @@ -0,0 +1,96 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D source_ssr; +layout(set = 1, binding = 0) uniform sampler2D source_depth; +layout(set = 1, binding = 1) uniform sampler2D source_normal; +layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly image2D dest_ssr; +layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth; +layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal; + +layout(push_constant, binding = 1, std430) uniform Params { + + ivec2 screen_size; + float camera_z_near; + float camera_z_far; + + bool orthogonal; + bool filtered; + uint pad[2]; +} +params; + +void main() { + + // Pixel being shaded + ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); + + if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + return; + } + //do not filter, SSR will generate arctifacts if this is done + + float divisor = 0.0; + vec4 color; + float depth; + vec3 normal; + + if (params.filtered) { + + color = vec4(0.0); + depth = 0.0; + normal = vec3(0.0); + + for (int i = 0; i < 4; i++) { + + ivec2 ofs = ssC << 1; + if (bool(i & 1)) { + ofs.x += 1; + } + if (bool(i & 2)) { + ofs.y += 1; + } + color += texelFetch(source_ssr, ofs, 0); + float d = texelFetch(source_depth, ofs, 0).r; + normal += texelFetch(source_normal, ofs, 0).xyz * 2.0 - 1.0; + + d = d * 2.0 - 1.0; + if (params.orthogonal) { + d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + } else { + d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near)); + } + depth += -d; + } + + color /= 4.0; + depth /= 4.0; + normal = normalize(normal / 4.0) * 0.5 + 0.5; + + } else { + color = texelFetch(source_ssr, ssC << 1, 0); + depth = texelFetch(source_depth, ssC << 1, 0).r; + normal = texelFetch(source_normal, ssC << 1, 0).xyz; + + depth = depth * 2.0 - 1.0; + if (params.orthogonal) { + depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + } else { + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + } + depth = -depth; + } + + imageStore(dest_ssr, ssC, color); + imageStore(dest_depth, ssC, vec4(depth)); + imageStore(dest_normal, ssC, vec4(normal, 0.0)); +} diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl index 3f433eb2ee..469925839a 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl @@ -141,15 +141,15 @@ void main() { vec4 quarter_res_color = vec4(1.0); #ifdef USE_CUBEMAP_PASS - float using_cubemap = 1.0; + vec3 inverted_cube_normal = cube_normal; + inverted_cube_normal.z *= -1.0; #ifdef USES_HALF_RES_COLOR - half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal); + half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal); #endif #ifdef USES_QUARTER_RES_COLOR - quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal); + quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal); #endif #else - float using_cubemap = 0.0; #ifdef USES_HALF_RES_COLOR half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0); #endif diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl new file mode 100644 index 0000000000..b28250318e --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl @@ -0,0 +1,59 @@ +/* clang-format off */ +[vertex] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +void main() { + + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); +} + +/* clang-format off */ +[fragment] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D specular; + +#ifdef MODE_SSR + +layout(set = 1, binding = 0) uniform sampler2D ssr; + +#endif + +#ifdef MODE_MERGE + +layout(set = 2, binding = 0) uniform sampler2D diffuse; + +#endif + +layout(location = 0) out vec4 frag_color; + +void main() { + + frag_color.rgb = texture(specular, uv_interp).rgb; + frag_color.a = 0.0; +#ifdef MODE_SSR + + vec4 ssr = texture(ssr, uv_interp); + frag_color.rgb = mix(frag_color.rgb, ssr.rgb, ssr.a); +#endif + +#ifdef MODE_MERGE + frag_color += texture(diffuse, uv_interp); +#endif + //added using additive blend +} diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl new file mode 100644 index 0000000000..41f8fde3ca --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl @@ -0,0 +1,198 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + + + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +/* clang-format on */ + +#ifdef USE_25_SAMPLES +const int kernel_size = 13; + +const vec2 kernel[kernel_size] = vec2[]( + vec2(0.530605, 0.0), + vec2(0.0211412, 0.0208333), + vec2(0.0402784, 0.0833333), + vec2(0.0493588, 0.1875), + vec2(0.0410172, 0.333333), + vec2(0.0263642, 0.520833), + vec2(0.017924, 0.75), + vec2(0.0128496, 1.02083), + vec2(0.0094389, 1.33333), + vec2(0.00700976, 1.6875), + vec2(0.00500364, 2.08333), + vec2(0.00333804, 2.52083), + vec2(0.000973794, 3.0)); + +const vec4 skin_kernel[kernel_size] = vec4[]( + vec4(0.530605, 0.613514, 0.739601, 0), + vec4(0.0211412, 0.0459286, 0.0378196, 0.0208333), + vec4(0.0402784, 0.0657244, 0.04631, 0.0833333), + vec4(0.0493588, 0.0367726, 0.0219485, 0.1875), + vec4(0.0410172, 0.0199899, 0.0118481, 0.333333), + vec4(0.0263642, 0.0119715, 0.00684598, 0.520833), + vec4(0.017924, 0.00711691, 0.00347194, 0.75), + vec4(0.0128496, 0.00356329, 0.00132016, 1.02083), + vec4(0.0094389, 0.00139119, 0.000416598, 1.33333), + vec4(0.00700976, 0.00049366, 0.000151938, 1.6875), + vec4(0.00500364, 0.00020094, 5.28848e-005, 2.08333), + vec4(0.00333804, 7.85443e-005, 1.2945e-005, 2.52083), + vec4(0.000973794, 1.11862e-005, 9.43437e-007, 3)); + +#endif //USE_25_SAMPLES + +#ifdef USE_17_SAMPLES +const int kernel_size = 9; +const vec2 kernel[kernel_size] = vec2[]( + vec2(0.536343, 0.0), + vec2(0.0324462, 0.03125), + vec2(0.0582416, 0.125), + vec2(0.0571056, 0.28125), + vec2(0.0347317, 0.5), + vec2(0.0216301, 0.78125), + vec2(0.0144609, 1.125), + vec2(0.0100386, 1.53125), + vec2(0.00317394, 2.0)); + +const vec4 skin_kernel[kernel_size] = vec4[]( + vec4(0.536343, 0.624624, 0.748867, 0), + vec4(0.0324462, 0.0656718, 0.0532821, 0.03125), + vec4(0.0582416, 0.0659959, 0.0411329, 0.125), + vec4(0.0571056, 0.0287432, 0.0172844, 0.28125), + vec4(0.0347317, 0.0151085, 0.00871983, 0.5), + vec4(0.0216301, 0.00794618, 0.00376991, 0.78125), + vec4(0.0144609, 0.00317269, 0.00106399, 1.125), + vec4(0.0100386, 0.000914679, 0.000275702, 1.53125), + vec4(0.00317394, 0.000134823, 3.77269e-005, 2)); +#endif //USE_17_SAMPLES + +#ifdef USE_11_SAMPLES +const int kernel_size = 6; +const vec2 kernel[kernel_size] = vec2[]( + vec2(0.560479, 0.0), + vec2(0.0771802, 0.08), + vec2(0.0821904, 0.32), + vec2(0.03639, 0.72), + vec2(0.0192831, 1.28), + vec2(0.00471691, 2.0)); + +const vec4 skin_kernel[kernel_size] = vec4[]( + + vec4(0.560479, 0.669086, 0.784728, 0), + vec4(0.0771802, 0.113491, 0.0793803, 0.08), + vec4(0.0821904, 0.0358608, 0.0209261, 0.32), + vec4(0.03639, 0.0130999, 0.00643685, 0.72), + vec4(0.0192831, 0.00282018, 0.00084214, 1.28), + vec4(0.00471691, 0.000184771, 5.07565e-005, 2)); + +#endif //USE_11_SAMPLES + +layout(push_constant, binding = 1, std430) uniform Params { + + ivec2 screen_size; + float camera_z_far; + float camera_z_near; + + bool vertical; + bool orthogonal; + float unit_size; + float scale; + + float depth_scale; + uint pad[3]; +} +params; + +layout(set = 0, binding = 0) uniform sampler2D source_image; +layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D dest_image; +layout(set = 2, binding = 0) uniform sampler2D source_depth; + +void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, bool p_skin) { + + // Accumulate the other samples: + for (int i = 1; i < kernel_size; i++) { + // Fetch color and depth for current sample: + vec2 offset = uv + kernel[i].y * step; + vec4 color = texture(source_image, offset); + + if (abs(color.a) < 0.001) { + break; //mix no more + } + + vec3 w; + if (p_skin) { + //skin + w = skin_kernel[i].rgb; + } else { + w = vec3(kernel[i].x); + } + + color_accum += color.rgb * w; + divisor += w; + } +} + +void main() { + + // Pixel being shaded + ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); + + if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + return; + } + + vec2 uv = (vec2(ssC) + 0.5) / vec2(params.screen_size); + + // Fetch color of current pixel: + vec4 base_color = texture(source_image, uv); + float strength = abs(base_color.a); + + if (strength > 0.0) { + + vec2 dir = params.vertical ? vec2(0.0, 1.0) : vec2(1.0, 0.0); + + // Fetch linear depth of current pixel: + float depth = texture(source_depth, uv).r * 2.0 - 1.0; + float depth_scale; + + if (params.orthogonal) { + depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + depth_scale = params.unit_size; //remember depth is negative by default in OpenGL + } else { + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + depth_scale = params.unit_size / depth; //remember depth is negative by default in OpenGL + } + + float scale = mix(params.scale, depth_scale, params.depth_scale); + + // Calculate the final step to fetch the surrounding pixels: + vec2 step = scale * dir; + step *= strength; + step /= 3.0; + // Accumulate the center sample: + + vec3 divisor; + bool skin = bool(base_color.a < 0.0); + + if (skin) { + //skin + divisor = skin_kernel[0].rgb; + } else { + divisor = vec3(kernel[0].x); + } + + vec3 color = base_color.rgb * divisor; + + do_filter(color, divisor, uv, step, skin); + do_filter(color, divisor, uv, -step, skin); + + base_color.rgb = color / divisor; + } + + imageStore(dest_image, ssC, base_color); +} diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 3c1795161d..a3799b0e4d 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -30,14 +30,14 @@ #include "rendering_device.h" -RenderingDevice *RenderingDevice::singleton = NULL; +RenderingDevice *RenderingDevice::singleton = nullptr; RenderingDevice *RenderingDevice::get_singleton() { return singleton; } -RenderingDevice::ShaderCompileFunction RenderingDevice::compile_function = NULL; -RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = NULL; +RenderingDevice::ShaderCompileFunction RenderingDevice::compile_function = nullptr; +RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr; void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { compile_function = p_function; diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 4705bcaa75..a639ff3641 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -563,7 +563,7 @@ public: /**** SHADER ****/ /****************/ - virtual Vector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = NULL, bool p_allow_cache = true); + virtual Vector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true); static void shader_set_compile_function(ShaderCompileFunction p_function); static void shader_set_cache_function(ShaderCacheFunction p_function); diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index 261bd4c275..5d6dcfd2c1 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -43,14 +43,14 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can memset(z_last_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); for (int i = 0; i < p_child_item_count; i++) { - _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, NULL, NULL); + _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); } if (p_canvas_item) { - _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, NULL, NULL); + _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); } - RasterizerCanvas::Item *list = NULL; - RasterizerCanvas::Item *list_end = NULL; + RasterizerCanvas::Item *list = nullptr; + RasterizerCanvas::Item *list_end = nullptr; for (int i = 0; i < z_range; i++) { if (!z_list[i]) @@ -78,7 +78,7 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo r_items[r_index] = child_items[i]; child_items[i]->ysort_xform = p_transform; child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); - child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL; + child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr; } r_index++; @@ -92,7 +92,7 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<RenderingServerCanvas::Item> &canvas_item_owner) { do { ysort_owner->ysort_children_count = -1; - ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL; + ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr; } while (ysort_owner && ysort_owner->sort_y); } @@ -118,7 +118,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo ci->material_owner = p_material_owner; else { p_material_owner = ci; - ci->material_owner = NULL; + ci->material_owner = nullptr; } Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a); @@ -130,7 +130,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo Item **child_items = ci->child_items.ptrw(); if (ci->clip) { - if (p_canvas_clip != NULL) { + if (p_canvas_clip != nullptr) { ci->final_clip_rect = p_canvas_clip->final_clip_rect.clip(global_rect); } else { ci->final_clip_rect = global_rect; @@ -145,7 +145,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count); + _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count); } child_item_count = ci->ysort_children_count; @@ -183,7 +183,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo RenderingServerRaster::redraw_request(); } - if ((ci->commands != NULL && p_clip_rect.intersects(global_rect, true)) || ci->vp_render || ci->copy_back_buffer) { + if ((ci->commands != nullptr && p_clip_rect.intersects(global_rect, true)) || ci->vp_render || ci->copy_back_buffer) { //something to draw? ci->final_transform = xform; ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a); @@ -204,7 +204,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo ci->z_final = p_z; - ci->next = NULL; + ci->next = nullptr; } for (int i = 0; i < child_item_count; i++) { @@ -265,30 +265,30 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, NULL, p_transform, p_clip_rect, p_canvas->modulate, p_lights); + _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; - _render_canvas_item_tree(p_render_target, NULL, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); - _render_canvas_item_tree(p_render_target, NULL, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); - _render_canvas_item_tree(p_render_target, NULL, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); - _render_canvas_item_tree(p_render_target, NULL, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } } } @@ -946,12 +946,12 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); - if (bool(canvas_item->copy_back_buffer != NULL) != p_enable) { + if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) { if (p_enable) { canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer); } else { memdelete(canvas_item->copy_back_buffer); - canvas_item->copy_back_buffer = NULL; + canvas_item->copy_back_buffer = nullptr; } } diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h index c79b74f287..9da11462db 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/rendering_server_canvas.h @@ -59,7 +59,7 @@ public: Item() { children_order_dirty = true; - E = NULL; + E = nullptr; z_index = 0; modulate = Color(1, 1, 1, 1); self_modulate = Color(1, 1, 1, 1); diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp index 251cf64184..5a270520a9 100644 --- a/servers/rendering/rendering_server_globals.cpp +++ b/servers/rendering/rendering_server_globals.cpp @@ -30,11 +30,11 @@ #include "rendering_server_globals.h" -RasterizerStorage *RenderingServerGlobals::storage = NULL; -RasterizerCanvas *RenderingServerGlobals::canvas_render = NULL; -RasterizerScene *RenderingServerGlobals::scene_render = NULL; -Rasterizer *RenderingServerGlobals::rasterizer = NULL; +RasterizerStorage *RenderingServerGlobals::storage = nullptr; +RasterizerCanvas *RenderingServerGlobals::canvas_render = nullptr; +RasterizerScene *RenderingServerGlobals::scene_render = nullptr; +Rasterizer *RenderingServerGlobals::rasterizer = nullptr; -RenderingServerCanvas *RenderingServerGlobals::canvas = NULL; -RenderingServerViewport *RenderingServerGlobals::viewport = NULL; -RenderingServerScene *RenderingServerGlobals::scene = NULL; +RenderingServerCanvas *RenderingServerGlobals::canvas = nullptr; +RenderingServerViewport *RenderingServerGlobals::viewport = nullptr; +RenderingServerScene *RenderingServerGlobals::scene = nullptr; diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index 7c18bf91ce..1b9755397a 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -456,7 +456,7 @@ public: BIND0R(RID, viewport_create) - BIND2(viewport_set_use_arvr, RID, bool) + BIND2(viewport_set_use_xr, RID, bool) BIND3(viewport_set_size, RID, int, int) BIND2(viewport_set_active, RID, bool) @@ -523,7 +523,9 @@ public: #if 0 BIND2(environment_set_camera_feed_id, RID, int) #endif - BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool) + BIND6(environment_set_ssr, RID, bool, int, float, float, float) + BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) + BIND9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float) BIND2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool) @@ -539,6 +541,8 @@ public: BIND5(environment_set_fog_height, RID, bool, float, float, float) BIND2(screen_space_roughness_limiter_set_active, bool, float) + BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) + BIND2(sub_surface_scattering_set_scale, float, float) /* CAMERA EFFECTS */ @@ -550,6 +554,8 @@ public: BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) BIND3(camera_effects_set_custom_exposure, RID, bool, float) + BIND1(shadow_filter_set, ShadowFilter) + /* SCENARIO API */ #undef BINDBASE diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 04e4b8dace..d66708587a 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -194,7 +194,7 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return gi_probe->lights.insert(A); } - return NULL; + return nullptr; } void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { @@ -375,7 +375,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { #endif if (instance->scenario && light->D) { instance->scenario->directional_lights.erase(light->D); - light->D = NULL; + light->D = nullptr; } RSG::scene_render->free(light->instance); } break; @@ -416,7 +416,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { Instance *capture = (Instance *)instance->lightmap_capture; InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(capture->base_data); lightmap_capture->users.erase(instance); - instance->lightmap_capture = NULL; + instance->lightmap_capture = nullptr; instance->lightmap = RID(); } @@ -429,7 +429,7 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { if (instance->base_data) { memdelete(instance->base_data); - instance->base_data = NULL; + instance->base_data = nullptr; } instance->blend_values.clear(); @@ -533,7 +533,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) #endif if (light->D) { instance->scenario->directional_lights.erase(light->D); - light->D = NULL; + light->D = nullptr; } } break; case RS::INSTANCE_REFLECTION_PROBE: { @@ -564,7 +564,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } } - instance->scenario = NULL; + instance->scenario = nullptr; } if (p_scenario.is_valid()) { @@ -720,7 +720,7 @@ void RenderingServerScene::instance_set_use_lightmap(RID p_instance, RID p_light InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data); lightmap_capture->users.erase(instance); instance->lightmap = RID(); - instance->lightmap_capture = NULL; + instance->lightmap_capture = nullptr; } if (p_lightmap_instance.is_valid()) { @@ -744,16 +744,16 @@ void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) if (p_aabb != AABB()) { // Set custom AABB - if (instance->custom_aabb == NULL) + if (instance->custom_aabb == nullptr) instance->custom_aabb = memnew(AABB); *instance->custom_aabb = p_aabb; } else { // Clear custom AABB - if (instance->custom_aabb != NULL) { + if (instance->custom_aabb != nullptr) { memdelete(instance->custom_aabb); - instance->custom_aabb = NULL; + instance->custom_aabb = nullptr; } } @@ -1334,7 +1334,7 @@ void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instan } } -bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) { +bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); @@ -1347,16 +1347,18 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c case RS::LIGHT_DIRECTIONAL: { - float max_distance = p_cam_projection.get_z_far(); - float shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); + real_t max_distance = p_cam_projection.get_z_far(); + real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera max_distance = MIN(shadow_max, max_distance); } max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001); - float min_distance = MIN(p_cam_projection.get_z_near(), max_distance); + real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance); RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base); + real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE); + if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) { //optimize min/max Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform); @@ -1365,8 +1367,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //check distance max and min bool found_items = false; - float z_max = -1e20; - float z_min = 1e20; + real_t z_max = -1e20; + real_t z_min = 1e20; for (int i = 0; i < cull_count; i++) { @@ -1379,7 +1381,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c animated_material_found = true; } - float max, min; + real_t max, min; instance->transformed_aabb.project_range_in_plane(base, min, max); if (max > z_max) { @@ -1399,7 +1401,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - float range = max_distance - min_distance; + real_t range = max_distance - min_distance; int splits = 0; switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) { @@ -1408,7 +1410,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break; } - float distances[5]; + real_t distances[5]; distances[0] = min_distance; for (int i = 0; i < splits; i++) { @@ -1417,11 +1419,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c distances[splits] = max_distance; - float texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance); + real_t texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance); bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base); - float first_radius = 0.0; + real_t first_radius = 0.0; + + real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0; for (int i = 0; i < splits; i++) { @@ -1430,7 +1434,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c // setup a camera matrix for that range! CameraMatrix camera_matrix; - float aspect = p_cam_projection.get_aspect(); + real_t aspect = p_cam_projection.get_aspect(); if (p_cam_orthogonal) { @@ -1439,8 +1443,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } else { - float fov = p_cam_projection.get_fov(); - camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it + camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); } //obtain the frustum endpoints @@ -1458,26 +1462,27 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized(); //z_vec points agsint the camera, like in default opengl - float x_min = 0.f, x_max = 0.f; - float y_min = 0.f, y_max = 0.f; - float z_min = 0.f, z_max = 0.f; + real_t x_min = 0.f, x_max = 0.f; + real_t y_min = 0.f, y_max = 0.f; + real_t z_min = 0.f, z_max = 0.f; // FIXME: z_max_cam is defined, computed, but not used below when setting up // ortho_camera. Commented out for now to fix warnings but should be investigated. - float x_min_cam = 0.f, x_max_cam = 0.f; - float y_min_cam = 0.f, y_max_cam = 0.f; - float z_min_cam = 0.f; - //float z_max_cam = 0.f; + real_t x_min_cam = 0.f, x_max_cam = 0.f; + real_t y_min_cam = 0.f, y_max_cam = 0.f; + real_t z_min_cam = 0.f; + //real_t z_max_cam = 0.f; - float bias_scale = 1.0; + real_t bias_scale = 1.0; + real_t aspect_bias_scale = 1.0; //used for culling for (int j = 0; j < 8; j++) { - float d_x = x_vec.dot(endpoints[j]); - float d_y = y_vec.dot(endpoints[j]); - float d_z = z_vec.dot(endpoints[j]); + real_t d_x = x_vec.dot(endpoints[j]); + real_t d_y = y_vec.dot(endpoints[j]); + real_t d_z = z_vec.dot(endpoints[j]); if (j == 0 || d_x < x_min) x_min = d_x; @@ -1495,11 +1500,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c z_max = d_z; } + real_t radius = 0; + real_t soft_shadow_expand = 0; + Vector3 center; + { //camera viewport stuff - Vector3 center; - for (int j = 0; j < 8; j++) { center += endpoints[j]; @@ -1508,11 +1515,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5; - float radius = 0; - for (int j = 0; j < 8; j++) { - float d = center.distance_to(endpoints[j]); + real_t d = center.distance_to(endpoints[j]); if (d > radius) radius = d; } @@ -1525,18 +1530,35 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c bias_scale = radius / first_radius; } - x_max_cam = x_vec.dot(center) + radius; - x_min_cam = x_vec.dot(center) - radius; - y_max_cam = y_vec.dot(center) + radius; - y_min_cam = y_vec.dot(center) - radius; - //z_max_cam = z_vec.dot(center) + radius; z_min_cam = z_vec.dot(center) - radius; + { + + float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE); + + if (soft_shadow_angle > 0.0 && pancake_size > 0.0) { + + float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam; + soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range; + + x_max += soft_shadow_expand; + y_max += soft_shadow_expand; + + x_min -= soft_shadow_expand; + y_min -= soft_shadow_expand; + } + } + + x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand; + x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand; + y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand; + y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand; + if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) { //this trick here is what stabilizes the shadow (make potential jaggies to not move) //at the cost of some wasted resolution. Still the quality increase is very well worth it - float unit = radius * 2.0 / texture_size; + real_t unit = radius * 2.0 / texture_size; x_max_cam = Math::stepify(x_max_cam, unit); x_min_cam = Math::stepify(x_min_cam, unit); @@ -1566,9 +1588,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); + real_t cull_max = 0; for (int j = 0; j < cull_count; j++) { - float min, max; + real_t min, max; Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1580,8 +1603,91 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max); instance->depth = near_plane.distance_to(instance->transform.origin); instance->depth_layer = 0; - if (max > z_max) - z_max = max; + if (j == 0 || max > cull_max) { + cull_max = max; + } + } + + if (cull_max > z_max) { + z_max = cull_max; + } + + if (pancake_size > 0) { + z_max = z_vec.dot(center) + radius + pancake_size; + } + + if (aspect != 1.0) { + + // if the aspect is different, then the radius will become larger. + // if this happens, then bias needs to be adjusted too, as depth will increase + // to do this, compare the depth of one that would have resulted from a square frustum + + CameraMatrix camera_matrix_square; + if (p_cam_orthogonal) { + + Vector2 vp_he = camera_matrix.get_viewport_half_extents(); + if (p_cam_vaspect) { + camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); + } else { + camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + } + } else { + Vector2 vp_he = camera_matrix.get_viewport_half_extents(); + if (p_cam_vaspect) { + camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); + } else { + camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + } + + if (i == 0) { + //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents()); + } + } + + Vector3 endpoints_square[8]; // frustum plane endpoints + res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square); + ERR_CONTINUE(!res); + Vector3 center_square; + real_t z_max_square = 0; + + for (int j = 0; j < 8; j++) { + + center_square += endpoints_square[j]; + + real_t d_z = z_vec.dot(endpoints_square[j]); + + if (j == 0 || d_z > z_max_square) + z_max_square = d_z; + } + + if (cull_max > z_max_square) { + z_max_square = cull_max; + } + + center_square /= 8.0; + + real_t radius_square = 0; + + for (int j = 0; j < 8; j++) { + + real_t d = center_square.distance_to(endpoints_square[j]); + if (d > radius_square) + radius_square = d; + } + + radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side + + if (pancake_size > 0) { + z_max_square = z_vec.dot(center_square) + radius_square + pancake_size; + } + + real_t z_min_cam_square = z_vec.dot(center_square) - radius_square; + + aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square); + + // this is not entirely perfect, because the cull-adjusted z-max may be different + // but at least it's warranted that it results in a greater bias, so no acne should be present either way. + // pancaking also helps with this. } { @@ -1592,11 +1698,19 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam)); + Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam)); + Transform ortho_transform; ortho_transform.basis = transform.basis; ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max; - RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale); + { + Vector3 max_in_view = p_cam_transform.affine_inverse().xform(z_vec * cull_max); + Vector3 dir_in_view = p_cam_transform.xform_inv(z_vec).normalized(); + cull_max = dir_in_view.dot(max_in_view); + } + + RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale); } RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); @@ -1614,9 +1728,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - float z = i == 0 ? -1 : 1; + real_t z = i == 0 ? -1 : 1; Vector<Plane> planes; planes.resize(5); planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius)); @@ -1645,12 +1759,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } } else { //shadow cube - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); CameraMatrix cm; cm.set_perspective(90, 1, 0.01, radius); @@ -1699,12 +1813,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } //restore the regular DP matrix - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); } } break; @@ -1712,8 +1826,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c RENDER_TIMESTAMP("Culling Spot Light"); - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - float angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); CameraMatrix cm; cm.set_perspective(angle * 2.0, 1.0, 0.01, radius); @@ -1738,7 +1852,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } break; @@ -1793,12 +1907,12 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID } break; } - _prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); #endif } -void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { +void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { // render for AR/VR interface Camera *camera = camera_owner.getornull(p_camera); @@ -1810,16 +1924,14 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface // We also ignore our camera position, it will have been positioned with a slightly old tracking position. // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo! - Transform world_origin = ARVRServer::get_singleton()->get_world_origin(); + Transform world_origin = XRServer::get_singleton()->get_world_origin(); Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin); // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye - if (p_eye == ARVRInterface::EYE_LEFT) { - ///@TODO possibly move responsibility for this into our ARVRServer or ARVRInterface? - + if (p_eye == XRInterface::EYE_LEFT) { // Center our transform, we assume basis is equal. Transform mono_transform = cam_transform; - Transform right_transform = p_interface->get_transform_for_eye(ARVRInterface::EYE_RIGHT, world_origin); + Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin); mono_transform.origin += right_transform.origin; mono_transform.origin *= 0.5; @@ -1872,17 +1984,17 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface mono_transform *= apply_z_shift; // now prepare our scene with our adjusted transform projection matrix - _prepare_scene(mono_transform, combined_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); - } else if (p_eye == ARVRInterface::EYE_MONO) { + _prepare_scene(mono_transform, combined_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + } else if (p_eye == XRInterface::EYE_MONO) { // For mono render, prepare as per usual - _prepare_scene(cam_transform, camera_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + _prepare_scene(cam_transform, camera_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); } // And render our scene... _render_scene(p_render_buffers, cam_transform, camera_matrix, false, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); }; -void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { +void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -2112,7 +2224,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i)); - _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario); + _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i)); } @@ -2214,7 +2326,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const if (redraw) { //must redraw! RENDER_TIMESTAMP(">Rendering Light " + itos(i)); - light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario); + light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); RENDER_TIMESTAMP("<Rendering Light " + itos(i)); } } @@ -2259,7 +2371,7 @@ void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenar else environment = scenario->fallback_environment; RENDER_TIMESTAMP("Render Empty Scene "); - RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, NULL, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); #endif } @@ -2324,7 +2436,7 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i } RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); - _prepare_scene(xform, cm, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows); + _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows); _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step); } else { @@ -2827,7 +2939,7 @@ bool RenderingServerScene::free(RID p_rid) { return true; } -RenderingServerScene *RenderingServerScene::singleton = NULL; +RenderingServerScene *RenderingServerScene::singleton = nullptr; RenderingServerScene::RenderingServerScene() { diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index 9e09136216..0970fed6c4 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -39,7 +39,7 @@ #include "core/os/thread.h" #include "core/rid_owner.h" #include "core/self_list.h" -#include "servers/arvr/arvr_interface.h" +#include "servers/xr/xr_interface.h" class RenderingServerScene { public: @@ -196,7 +196,7 @@ public: update_item(this) { octree_id = 0; - scenario = NULL; + scenario = nullptr; update_aabb = false; update_dependencies = false; @@ -213,9 +213,9 @@ public: last_render_pass = 0; last_frame_pass = 0; version = 1; - base_data = NULL; + base_data = nullptr; - custom_aabb = NULL; + custom_aabb = nullptr; } ~Instance() { @@ -301,9 +301,9 @@ public: InstanceLightData() { shadow_dirty = true; - D = NULL; + D = nullptr; last_version = 0; - baked_light = NULL; + baked_light = nullptr; } }; @@ -418,15 +418,15 @@ public: _FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance); _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); - _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario); + _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true); + void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true); void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); - void render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); + void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); void update_dirty_instances(); void render_probes(); diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index f80b914760..87dcb772bc 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -62,24 +62,24 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi return xf; } -void RenderingServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { +void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); - Ref<ARVRInterface> arvr_interface; - if (ARVRServer::get_singleton() != NULL) { - arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + Ref<XRInterface> xr_interface; + if (XRServer::get_singleton() != nullptr) { + xr_interface = XRServer::get_singleton()->get_primary_interface(); } - if (p_viewport->use_arvr && arvr_interface.is_valid()) { - RSG::scene->render_camera(p_viewport->render_buffers, arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + if (p_viewport->use_xr && xr_interface.is_valid()) { + RSG::scene->render_camera(p_viewport->render_buffers, xr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } RENDER_TIMESTAMP("<End Rendering 3D Scene"); } -void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { +void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { /* Camera should always be BEFORE any other 3D */ @@ -128,9 +128,9 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); - RasterizerCanvas::Light *lights = NULL; - RasterizerCanvas::Light *lights_with_shadow = NULL; - RasterizerCanvas::Light *lights_with_mask = NULL; + RasterizerCanvas::Light *lights = nullptr; + RasterizerCanvas::Light *lights_with_shadow = nullptr; + RasterizerCanvas::Light *lights_with_mask = nullptr; Rect2 shadow_rect; int light_count = 0; @@ -160,7 +160,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface cl->filter_next_ptr = lights; lights = cl; - // cl->texture_cache = NULL; + // cl->texture_cache = nullptr; Transform2D scale; scale.scale(cl->rect_cache.size); scale.elements[2] = cl->rect_cache.position; @@ -169,7 +169,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface if (cl->use_shadow) { cl->shadows_next_ptr = lights_with_shadow; - if (lights_with_shadow == NULL) { + if (lights_with_shadow == nullptr) { shadow_rect = cl->xform_cache.xform(cl->rect_cache); } else { shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache)); @@ -196,7 +196,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface if (lights_with_shadow) { //update shadows if any - RasterizerCanvas::LightOccluderInstance *occluders = NULL; + RasterizerCanvas::LightOccluderInstance *occluders = nullptr; RENDER_TIMESTAMP(">Render 2D Shadows"); RENDER_TIMESTAMP("Cull Occluders"); @@ -249,7 +249,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); - RasterizerCanvas::Light *canvas_lights = NULL; + RasterizerCanvas::Light *canvas_lights = nullptr; RasterizerCanvas::Light *ptr = lights; while (ptr) { @@ -293,17 +293,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface void RenderingServerViewport::draw_viewports() { -#if 0 - // get our arvr interface in case we need it - Ref<ARVRInterface> arvr_interface; + // get our xr interface in case we need it + Ref<XRInterface> xr_interface; - if (ARVRServer::get_singleton() != NULL) { - arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + if (XRServer::get_singleton() != nullptr) { + xr_interface = XRServer::get_singleton()->get_primary_interface(); // process all our active interfaces - ARVRServer::get_singleton()->_process(); + XRServer::get_singleton()->_process(); } -#endif if (Engine::get_singleton()->is_editor_hint()) { set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color")); @@ -367,38 +365,41 @@ void RenderingServerViewport::draw_viewports() { RSG::storage->render_target_set_as_unused(vp->render_target); #if 0 - if (vp->use_arvr && arvr_interface.is_valid()) { + // TODO fix up this code after we change our commit_for_eye to accept our new render targets + + if (vp->use_xr && xr_interface.is_valid()) { // override our size, make sure it matches our required size - vp->size = arvr_interface->get_render_targetsize(); + vp->size = xr_interface->get_render_targetsize(); RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y); // render mono or left eye first - ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO; + XRInterface::Eyes leftOrMono = xr_interface->is_stereo() ? XRInterface::EYE_LEFT : XRInterface::EYE_MONO; // check for an external texture destination for our left eye/mono - RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono)); + // TODO investigate how we're going to make external textures work + RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono)); // set our render target as current RSG::rasterizer->set_current_render_target(vp->render_target); // and draw left eye/mono _draw_viewport(vp, leftOrMono); - arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); + xr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); // render right eye - if (leftOrMono == ARVRInterface::EYE_LEFT) { + if (leftOrMono == XRInterface::EYE_LEFT) { // check for an external texture destination for our right eye - RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT)); + RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(XRInterface::EYE_RIGHT)); // commit for eye may have changed the render target RSG::rasterizer->set_current_render_target(vp->render_target); - _draw_viewport(vp, ARVRInterface::EYE_RIGHT); - arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect); + _draw_viewport(vp, XRInterface::EYE_RIGHT); + xr_interface->commit_for_eye(XRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect); } // and for our frame timing, mark when we've finished committing our eyes - ARVRServer::get_singleton()->_mark_commit(); + XRServer::get_singleton()->_mark_commit(); } else { #endif { @@ -470,11 +471,11 @@ RID RenderingServerViewport::viewport_create() { return rid; } -void RenderingServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) { +void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - viewport->use_arvr = p_use_arvr; + viewport->use_xr = p_use_xr; } void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index f574c58d96..71d8408ed1 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -34,8 +34,8 @@ #include "core/rid_owner.h" #include "core/self_list.h" #include "rasterizer.h" -#include "servers/arvr/arvr_interface.h" #include "servers/rendering_server.h" +#include "servers/xr/xr_interface.h" class RenderingServerViewport { public: @@ -47,7 +47,7 @@ public: RID self; RID parent; - bool use_arvr; /* use arvr interface to override camera positioning and projection matrices and control output */ + bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */ Size2i size; RID camera; @@ -127,7 +127,7 @@ public: for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) { render_info[i] = 0; } - use_arvr = false; + use_xr = false; } }; @@ -152,13 +152,13 @@ public: Vector<Viewport *> active_viewports; private: - void _draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye); - void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO); + void _draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye); + void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO); public: RID viewport_create(); - void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr); + void viewport_set_use_xr(RID p_viewport, bool p_use_xr); void viewport_set_size(RID p_viewport, int p_width, int p_height); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index 5d6d523901..4ca13dbef9 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -126,17 +126,6 @@ void RenderingServerWrapMT::init() { void RenderingServerWrapMT::finish() { - if (thread) { - - command_queue.push(this, &RenderingServerWrapMT::thread_exit); - Thread::wait_to_finish(thread); - memdelete(thread); - - thread = NULL; - } else { - rendering_server->finish(); - } - sky_free_cached_ids(); shader_free_cached_ids(); material_free_cached_ids(); @@ -161,6 +150,17 @@ void RenderingServerWrapMT::finish() { canvas_item_free_cached_ids(); canvas_light_occluder_free_cached_ids(); canvas_occluder_polygon_free_cached_ids(); + + if (thread) { + + command_queue.push(this, &RenderingServerWrapMT::thread_exit); + Thread::wait_to_finish(thread); + memdelete(thread); + + thread = nullptr; + } else { + rendering_server->finish(); + } } void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { @@ -168,7 +168,7 @@ void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { singleton_mt->call_set_use_vsync(p_enable); } -RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = NULL; +RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr; RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) : command_queue(p_create_thread) { @@ -178,7 +178,7 @@ RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool rendering_server = p_contained; create_thread = p_create_thread; - thread = NULL; + thread = nullptr; draw_pending = 0; draw_thread_up = false; pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index bcd1344f44..9a98841b2c 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -370,7 +370,7 @@ public: FUNCRID(viewport) - FUNC2(viewport_set_use_arvr, RID, bool) + FUNC2(viewport_set_use_xr, RID, bool) FUNC3(viewport_set_size, RID, int, int) @@ -437,7 +437,9 @@ public: #if 0 FUNC2(environment_set_camera_feed_id, RID, int) #endif - FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool) + FUNC6(environment_set_ssr, RID, bool, int, float, float, float) + FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) + FUNC9(environment_set_ssao, RID, bool, float, float, float, float, float, EnvironmentSSAOBlur, float) FUNC2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool) @@ -454,6 +456,8 @@ public: FUNC5(environment_set_fog_height, RID, bool, float, float, float) FUNC2(screen_space_roughness_limiter_set_active, bool, float) + FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) + FUNC2(sub_surface_scattering_set_scale, float, float) FUNCRID(camera_effects) @@ -463,6 +467,8 @@ public: FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) FUNC3(camera_effects_set_custom_exposure, RID, bool, float) + FUNC1(shadow_filter_set, ShadowFilter) + FUNCRID(scenario) FUNC2(scenario_set_debug, RID, ScenarioDebugMode) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 300c38db22..76a81a4a1c 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -328,7 +328,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_REPEAT_ENABLE, "repeat_enable" }, { TK_REPEAT_DISABLE, "repeat_disable" }, { TK_SHADER_TYPE, "shader_type" }, - { TK_ERROR, NULL } + { TK_ERROR, nullptr } }; ShaderLanguage::Token ShaderLanguage::_get_token() { @@ -879,7 +879,7 @@ void ShaderLanguage::clear() { current_function = StringName(); completion_type = COMPLETION_NONE; - completion_block = NULL; + completion_block = nullptr; completion_function = StringName(); completion_class = SubClassTag::TAG_GLOBAL; completion_struct = StringName(); @@ -913,7 +913,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea return true; } - FunctionNode *function = NULL; + FunctionNode *function = nullptr; while (p_block) { @@ -2107,14 +2107,14 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { //array { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY, true }, - { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL, false } + { nullptr, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL, false } }; const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] = { //constructors { "modf", 1 }, - { NULL, 0 } + { nullptr, 0 } }; bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) { @@ -3150,7 +3150,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons while (true) { - Node *expr = NULL; + Node *expr = nullptr; TkPos prepos = _get_tkpos(); Token tk = _get_token(); TkPos pos = _get_tkpos(); @@ -3162,14 +3162,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = _parse_and_reduce_expression(p_block, p_builtin_types); if (!expr) - return NULL; + return nullptr; tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in expression"); - return NULL; + return nullptr; } } else if (tk.type == TK_REAL_CONSTANT) { @@ -3214,7 +3214,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //make sure void is not used in expression _set_error("Void value not allowed in Expression"); - return NULL; + return nullptr; } else if (is_token_nonvoid_datatype(tk.type)) { //basic type constructor @@ -3234,7 +3234,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_PARENTHESIS_OPEN) { _set_error("Expected '(' after type name"); - return NULL; + return nullptr; } int carg = -1; @@ -3250,11 +3250,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } if (!ok) - return NULL; + return nullptr; if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); - return NULL; + return nullptr; } expr = _reduce_expression(p_block, func); @@ -3265,7 +3265,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons StringName identifier; - StructNode *pstruct = NULL; + StructNode *pstruct = nullptr; bool struct_init = false; _get_completable_identifier(p_block, COMPLETION_IDENTIFIER, identifier); @@ -3317,7 +3317,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } else { if (!is_token_variable_datatype(tk.type)) { _set_error("Invalid data type for array"); - return NULL; + return nullptr; } type2 = get_token_datatype(tk.type); } @@ -3335,7 +3335,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { _set_error("Expected single integer constant > 0"); - return NULL; + return nullptr; } ConstantNode *cnode = (ConstantNode *)n; @@ -3343,24 +3343,24 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons array_size2 = cnode->values[0].sint; if (array_size2 <= 0) { _set_error("Expected single integer constant > 0"); - return NULL; + return nullptr; } } else { _set_error("Expected single integer constant > 0"); - return NULL; + return nullptr; } tk = _get_token(); if (tk.type != TK_BRACKET_CLOSE) { _set_error("Expected ']'"); - return NULL; + return nullptr; } else { tk = _get_token(); } } } else { _set_error("Expected '['"); - return NULL; + return nullptr; } if (type != type2 || struct_name != struct_name2 || array_size != array_size2) { @@ -3383,7 +3383,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons error_str += itos(array_size); error_str += "]'"; _set_error(error_str); - return NULL; + return nullptr; } } @@ -3396,12 +3396,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) { - return NULL; + return nullptr; } if (type != n->get_datatype() || struct_name != n->get_datatype_name()) { _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'"); - return NULL; + return nullptr; } tk = _get_token(); @@ -3419,30 +3419,30 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Expected '}' or ','"); else _set_error("Expected ')' or ','"); - return NULL; + return nullptr; } } if (an->initializer.size() != array_size) { _set_error("Array size mismatch"); - return NULL; + return nullptr; } } else { _set_error("Expected array initialization!"); - return NULL; + return nullptr; } nexpr = an; } else { nexpr = _parse_and_reduce_expression(p_block, p_builtin_types); if (!nexpr) { - return NULL; + return nullptr; } Node *node = pstruct->members[i]; if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) { String type_name = nexpr->get_datatype() == TYPE_STRUCT ? nexpr->get_datatype_name() : get_datatype_name(nexpr->get_datatype()); String type_name2 = node->get_datatype() == TYPE_STRUCT ? node->get_datatype_name() : get_datatype_name(node->get_datatype()); _set_error("Invalid assignment of '" + type_name + "' to '" + type_name2 + "'"); - return NULL; + return nullptr; } } @@ -3450,7 +3450,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_COMMA) { _set_error("Expected ','"); - return NULL; + return nullptr; } } func->arguments.push_back(nexpr); @@ -3458,7 +3458,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { _set_error("Expected ')'"); - return NULL; + return nullptr; } expr = func; @@ -3482,7 +3482,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons while (bnode) { if (bnode->variables.has(name)) { _set_error("Expected function name"); - return NULL; + return nullptr; } bnode = bnode->parent_block; } @@ -3514,11 +3514,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } if (!ok) - return NULL; + return nullptr; if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching function found for: '" + String(funcname->name) + "'"); - return NULL; + return nullptr; } completion_class = TAG_GLOBAL; // reset sub-class if (function_index >= 0) { @@ -3529,7 +3529,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (call_function) { //get current base function - FunctionNode *base_function = NULL; + FunctionNode *base_function = nullptr; { BlockNode *b = p_block; @@ -3544,7 +3544,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } - ERR_FAIL_COND_V(!base_function, NULL); //bug, wtf + ERR_FAIL_COND_V(!base_function, nullptr); //bug, wtf for (int i = 0; i < call_function->arguments.size(); i++) { int argidx = i + 1; @@ -3556,7 +3556,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons error = true; } else if (n->type == Node::TYPE_ARRAY) { ArrayNode *an = static_cast<ArrayNode *>(n); - if (an->call_expression != NULL) { + if (an->call_expression != nullptr) { error = true; } } else if (n->type == Node::TYPE_VARIABLE) { @@ -3584,7 +3584,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } if (error) { _set_error(vformat("Constant value cannot be passed for '%s' parameter!", _get_qualifier_str(call_function->arguments[i].qualifier))); - return NULL; + return nullptr; } } if (is_sampler_type(call_function->arguments[i].type)) { @@ -3599,12 +3599,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ERR_CONTINUE(u->type != call_function->arguments[i].type); //this should have been validated previously //propagate if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat)) { - return NULL; + return nullptr; } } else if (p_builtin_types.has(varname)) { //a built-in if (!_propagate_function_call_sampler_builtin_reference(name, i, varname)) { - return NULL; + return nullptr; } } else { //or this comes from an argument, but nothing else can be a sampler @@ -3653,30 +3653,30 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } if (!found) { _set_error("Unknown identifier in expression: " + String(identifier)); - return NULL; + return nullptr; } } else { if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) { _set_error("Unknown identifier in expression: " + String(identifier)); - return NULL; + return nullptr; } if (ident_type == IDENTIFIER_FUNCTION) { _set_error("Can't use function as identifier: " + String(identifier)); - return NULL; + return nullptr; } } - Node *index_expression = NULL; - Node *call_expression = NULL; + Node *index_expression = nullptr; + Node *call_expression = nullptr; if (array_size > 0) { tk = _get_token(); if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD) { _set_error("Expected '[' or '.'"); - return NULL; + return nullptr; } if (tk.type == TK_PERIOD) { @@ -3685,17 +3685,17 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons call_expression = _parse_and_reduce_expression(p_block, p_builtin_types); p_block->block_tag = SubClassTag::TAG_GLOBAL; if (!call_expression) - return NULL; + return nullptr; data_type = call_expression->get_datatype(); } else { // indexing index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); if (!index_expression) - return NULL; + return nullptr; if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); - return NULL; + return nullptr; } if (index_expression->type == Node::TYPE_CONSTANT) { @@ -3705,7 +3705,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int value = cnode->values[0].sint; if (value < 0 || value >= array_size) { _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); - return NULL; + return nullptr; } } } @@ -3714,7 +3714,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_BRACKET_CLOSE) { _set_error("Expected ']'"); - return NULL; + return nullptr; } } @@ -3750,18 +3750,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TK_OP_BIT_INVERT: e.op = OP_BIT_INVERT; break; case TK_OP_INCREMENT: e.op = OP_INCREMENT; break; case TK_OP_DECREMENT: e.op = OP_DECREMENT; break; - default: ERR_FAIL_V(NULL); + default: ERR_FAIL_V(nullptr); } expression.push_back(e); continue; } else { _set_error("Expected expression, found: " + get_token_text(tk)); - return NULL; + return nullptr; //nothing } - ERR_FAIL_COND_V(!expr, NULL); + ERR_FAIL_COND_V(!expr, nullptr); /* OK now see what's NEXT to the operator.. */ /* OK now see what's NEXT to the operator.. */ @@ -3791,7 +3791,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (identifier == StringName()) { _set_error("Expected identifier as member"); - return NULL; + return nullptr; } String ident = identifier; @@ -4042,12 +4042,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (mix_error) { _set_error("Cannot combine symbols from different sets in expression ." + ident); - return NULL; + return nullptr; } if (!ok) { _set_error("Invalid member for " + (dt == TYPE_STRUCT ? st : get_datatype_name(dt)) + " expression: ." + ident); - return NULL; + return nullptr; } MemberNode *mn = alloc_node<MemberNode>(); @@ -4066,16 +4066,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type == TK_PERIOD) { _set_error("Nested array length() is not yet implemented"); - return NULL; + return nullptr; } else if (tk.type == TK_BRACKET_OPEN) { Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); if (!index_expression) - return NULL; + return nullptr; if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); - return NULL; + return nullptr; } if (index_expression->type == Node::TYPE_CONSTANT) { @@ -4085,7 +4085,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int value = cnode->values[0].sint; if (value < 0 || value >= array_size) { _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); - return NULL; + return nullptr; } } } @@ -4094,13 +4094,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_BRACKET_CLOSE) { _set_error("Expected ']'"); - return NULL; + return nullptr; } mn->index_expression = index_expression; } else { _set_error("Expected '[' or '.'"); - return NULL; + return nullptr; } } @@ -4120,11 +4120,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *index = _parse_and_reduce_expression(p_block, p_builtin_types); if (!index) - return NULL; + return nullptr; if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) { _set_error("Only integer datatypes are allowed for indexing"); - return NULL; + return nullptr; } DataType member_type = TYPE_VOID; @@ -4139,7 +4139,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; if (index_constant >= 2) { _set_error("Index out of range (0-1)"); - return NULL; + return nullptr; } } @@ -4162,7 +4162,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; if (index_constant >= 3) { _set_error("Index out of range (0-2)"); - return NULL; + return nullptr; } } @@ -4184,7 +4184,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; if (index_constant >= 4) { _set_error("Index out of range (0-3)"); - return NULL; + return nullptr; } } @@ -4199,7 +4199,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons break; default: { _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed"); - return NULL; + return nullptr; } } @@ -4213,7 +4213,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type != TK_BRACKET_CLOSE) { _set_error("Expected ']' after indexing expression"); - return NULL; + return nullptr; } } else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) { @@ -4224,12 +4224,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (!_validate_operator(op, &op->return_cache)) { _set_error("Invalid base type for increment/decrement operator"); - return NULL; + return nullptr; } if (!_validate_assign(expr, p_builtin_types)) { _set_error("Invalid use of increment/decrement operator in constant expression."); - return NULL; + return nullptr; } expr = op; } else { @@ -4287,7 +4287,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TK_COLON: o.op = OP_SELECT_ELSE; break; default: { _set_error("Invalid token for operator: " + get_token_text(tk)); - return NULL; + return nullptr; } } @@ -4379,7 +4379,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons break; default: - ERR_FAIL_V(NULL); //unexpected operator + ERR_FAIL_V(nullptr); //unexpected operator } if (priority < min_priority) { @@ -4392,7 +4392,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } - ERR_FAIL_COND_V(next_op == -1, NULL); + ERR_FAIL_COND_V(next_op == -1, nullptr); // OK! create operator.. // OK! create operator.. @@ -4405,7 +4405,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (expr_pos == expression.size()) { //can happen.. _set_error("Unexpected end of expression..."); - return NULL; + return nullptr; } } @@ -4417,7 +4417,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) { _set_error("Can't use increment/decrement operator in constant expression."); - return NULL; + return nullptr; } op->arguments.push_back(expression[i + 1].node); @@ -4433,7 +4433,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons at += get_datatype_name(op->arguments[j]->get_datatype()); } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); - return NULL; + return nullptr; } expression.remove(i + 1); } @@ -4442,12 +4442,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); - ERR_FAIL_V(NULL); + ERR_FAIL_V(nullptr); } if (next_op + 2 >= expression.size() || !expression[next_op + 2].is_op || expression[next_op + 2].op != OP_SELECT_ELSE) { _set_error("Missing matching ':' for select operator"); - return NULL; + return nullptr; } OperatorNode *op = alloc_node<OperatorNode>(); @@ -4467,7 +4467,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons at += get_datatype_name(op->arguments[i]->get_datatype()); } _set_error("Invalid argument to ternary ?: operator: " + at); - return NULL; + return nullptr; } for (int i = 0; i < 4; i++) { @@ -4478,7 +4478,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); - ERR_FAIL_V(NULL); + ERR_FAIL_V(nullptr); } OperatorNode *op = alloc_node<OperatorNode>(); @@ -4487,7 +4487,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (expression[next_op - 1].is_op) { _set_error("Parser bug..."); - ERR_FAIL_V(NULL); + ERR_FAIL_V(nullptr); } if (_is_operator_assign(op->op)) { @@ -4496,7 +4496,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) { _set_error(assign_message); - return NULL; + return nullptr; } } @@ -4528,7 +4528,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } _set_error("Invalid arguments to operator '" + get_operator_text(op->op) + "' :" + at); - return NULL; + return nullptr; } expression.remove(next_op); @@ -4658,7 +4658,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_ ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types); if (!expr) //errored - return NULL; + return nullptr; expr = _reduce_expression(p_block, expr); @@ -4741,7 +4741,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); - Node *vardecl = NULL; + Node *vardecl = nullptr; while (true) { @@ -4752,7 +4752,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui StringName name = tk.text; ShaderLanguage::IdentifierType itype; - if (_find_identifier(p_block, true, p_builtin_types, name, (ShaderLanguage::DataType *)0, &itype)) { + if (_find_identifier(p_block, true, p_builtin_types, name, (ShaderLanguage::DataType *)nullptr, &itype)) { if (itype != IDENTIFIER_FUNCTION) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; @@ -5025,7 +5025,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui VariableDeclarationNode::Declaration decl; decl.name = name; - decl.initializer = NULL; + decl.initializer = nullptr; //variable created with assignment! must parse an expression Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); @@ -5061,7 +5061,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui VariableDeclarationNode::Declaration decl; decl.name = name; - decl.initializer = NULL; + decl.initializer = nullptr; node->declarations.push_back(decl); } @@ -5326,7 +5326,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui // while() {} bool is_do = tk.type == TK_CF_DO; - BlockNode *do_block = NULL; + BlockNode *do_block = nullptr; if (is_do) { do_block = alloc_node<BlockNode>(); @@ -5694,7 +5694,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct while (true) { StringName mode; - _get_completable_identifier(NULL, COMPLETION_RENDER_MODE, mode); + _get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode); if (mode == StringName()) { _set_error("Expected identifier for render mode"); @@ -5898,7 +5898,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct name = tk.text; - if (_find_identifier(NULL, false, Map<StringName, BuiltInInfo>(), name)) { + if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; } @@ -6074,7 +6074,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (tk.type == TK_OP_ASSIGN) { - Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>()); + Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); if (!expr) return ERR_PARSE_ERROR; if (expr->type != Node::TYPE_CONSTANT) { @@ -6191,14 +6191,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } _set_tkpos(prev_pos); - _get_completable_identifier(NULL, COMPLETION_MAIN_FUNCTION, name); + _get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name); if (name == StringName()) { _set_error("Expected function name after datatype"); return ERR_PARSE_ERROR; } - if (_find_identifier(NULL, false, Map<StringName, BuiltInInfo>(), name)) { + if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; } @@ -6222,7 +6222,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct constant.type = is_struct ? TYPE_STRUCT : type; constant.type_str = struct_name; constant.precision = precision; - constant.initializer = NULL; + constant.initializer = nullptr; if (tk.type == TK_OP_ASSIGN) { @@ -6232,7 +6232,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } //variable created with assignment! must parse an expression - Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>()); + Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); if (!expr) return ERR_PARSE_ERROR; if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) { @@ -6266,7 +6266,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } name = tk.text; - if (_find_identifier(NULL, false, Map<StringName, BuiltInInfo>(), name)) { + if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; } @@ -6405,7 +6405,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct pname = tk.text; ShaderLanguage::IdentifierType itype; - if (_find_identifier(func_node->body, false, builtin_types, pname, (ShaderLanguage::DataType *)0, &itype)) { + if (_find_identifier(func_node->body, false, builtin_types, pname, (ShaderLanguage::DataType *)nullptr, &itype)) { if (itype != IDENTIFIER_FUNCTION) { _set_error("Redefinition of '" + String(pname) + "'"); return ERR_PARSE_ERROR; @@ -6645,7 +6645,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi code = p_code; - nodes = NULL; + nodes = nullptr; shader = alloc_node<ShaderNode>(); Error err = _parse_shader(p_functions, p_render_modes, p_shader_types); @@ -6662,7 +6662,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct code = p_code; - nodes = NULL; + nodes = nullptr; shader = alloc_node<ShaderNode>(); _parse_shader(p_functions, p_render_modes, p_shader_types); @@ -7001,7 +7001,7 @@ ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() { ShaderLanguage::ShaderLanguage() { - nodes = NULL; + nodes = nullptr; completion_class = TAG_GLOBAL; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 9124bee633..beabae0dda 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -342,7 +342,7 @@ public: virtual String get_datatype_name() const { return ""; } Node(Type t) : - next(NULL), + next(nullptr), type(t) {} virtual ~Node() {} }; @@ -423,8 +423,8 @@ public: ArrayNode() : Node(TYPE_ARRAY), datatype_cache(TYPE_VOID), - index_expression(NULL), - call_expression(NULL), + index_expression(nullptr), + call_expression(nullptr), is_const(false) {} }; @@ -511,8 +511,8 @@ public: BlockNode() : Node(TYPE_BLOCK), - parent_function(NULL), - parent_block(NULL), + parent_function(nullptr), + parent_block(nullptr), block_type(BLOCK_TYPE_STANDART), block_tag(SubClassTag::TAG_GLOBAL), single_statement(false) {} @@ -550,8 +550,8 @@ public: basetype_const(false), datatype(TYPE_VOID), array_size(0), - owner(NULL), - index_expression(NULL), + owner(nullptr), + index_expression(nullptr), has_swizzling_duplicates(false) {} }; @@ -592,7 +592,7 @@ public: Node(TYPE_FUNCTION), return_type(TYPE_VOID), return_precision(PRECISION_DEFAULT), - body(NULL), + body(nullptr), can_discard(false) {} }; @@ -733,7 +733,7 @@ public: static bool is_token_nonvoid_datatype(TokenType p_type); static bool is_token_operator(TokenType p_type); - static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = NULL); + static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = nullptr); static DataType get_scalar_type(DataType p_type); static int get_cardinality(DataType p_type); static bool is_scalar_type(DataType p_type); @@ -825,10 +825,10 @@ private: IDENTIFIER_CONSTANT, }; - bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL, bool *r_is_const = NULL, int *r_array_size = NULL, StringName *r_struct_name = NULL); + bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr); bool _is_operator_assign(Operator p_op) const; - bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL); - bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); + bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = nullptr); + bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr); struct BuiltinFuncDef { enum { MAX_ARGS = 5 }; @@ -861,7 +861,7 @@ private: bool _compare_datatypes_in_nodes(Node *a, Node *b) const; bool _validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str); - bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL); + bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = nullptr); bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat); bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index b144d6d612..de69fea16f 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -44,7 +44,7 @@ const Set<String> &ShaderTypes::get_types() { return shader_types; } -ShaderTypes *ShaderTypes::singleton = NULL; +ShaderTypes *ShaderTypes::singleton = nullptr; static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) { @@ -108,7 +108,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO_LIGHT_AFFECT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3; @@ -145,7 +149,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = constt(ShaderLanguage::TYPE_VEC3); - shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["TRANSMISSION"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["BACKLIGHT"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3; @@ -168,6 +172,8 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_test_disabled"); + shader_modes[RS::SHADER_SPATIAL].modes.push_back("sss_mode_skin"); + shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_back"); shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_front"); shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_disabled"); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0bad644b95..0a1b7b98e4 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -33,8 +33,8 @@ #include "core/method_bind_ext.gen.inc" #include "core/project_settings.h" -RenderingServer *RenderingServer::singleton = NULL; -RenderingServer *(*RenderingServer::create_func)() = NULL; +RenderingServer *RenderingServer::singleton = nullptr; +RenderingServer *(*RenderingServer::create_func)() = nullptr; RenderingServer *RenderingServer::get_singleton() { @@ -43,12 +43,12 @@ RenderingServer *RenderingServer::get_singleton() { RenderingServer *RenderingServer::create() { - ERR_FAIL_COND_V(singleton, NULL); + ERR_FAIL_COND_V(singleton, nullptr); if (create_func) return create_func(); - return NULL; + return nullptr; } Array RenderingServer::_texture_debug_usage_bind() { @@ -333,7 +333,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint uint8_t *vw = r_vertex_array.ptrw(); - uint8_t *iw = NULL; + uint8_t *iw = nullptr; if (r_index_array.size()) { iw = r_index_array.ptrw(); } @@ -1766,7 +1766,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("camera_set_use_vertical_aspect", "camera", "enable"), &RenderingServer::camera_set_use_vertical_aspect); ClassDB::bind_method(D_METHOD("viewport_create"), &RenderingServer::viewport_create); - ClassDB::bind_method(D_METHOD("viewport_set_use_arvr", "viewport", "use_arvr"), &RenderingServer::viewport_set_use_arvr); + ClassDB::bind_method(D_METHOD("viewport_set_use_xr", "viewport", "use_xr"), &RenderingServer::viewport_set_use_xr); ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &RenderingServer::viewport_set_size); ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &RenderingServer::viewport_set_active); ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport); @@ -1805,7 +1805,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "level_flags", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap"), &RenderingServer::environment_set_glow); ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white", "auto_exposure", "min_luminance", "max_luminance", "auto_exp_speed", "auto_exp_grey"), &RenderingServer::environment_set_tonemap); ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &RenderingServer::environment_set_adjustment); - ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance", "roughness"), &RenderingServer::environment_set_ssr); + ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr); ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "bias", "light_affect", "ao_channel_affect", "blur", "bilateral_sharpness"), &RenderingServer::environment_set_ssao); ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "color", "sun_color", "sun_amount"), &RenderingServer::environment_set_fog); @@ -2030,7 +2030,6 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION); - BIND_ENUM_CONSTANT(LIGHT_PARAM_CONTACT_SHADOW_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET); @@ -2038,7 +2037,6 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS); - BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); @@ -2098,6 +2096,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS); BIND_ENUM_CONSTANT(SKY_MODE_QUALITY); BIND_ENUM_CONSTANT(SKY_MODE_REALTIME); @@ -2312,7 +2311,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1); GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled (Fastest),PCF5,PCF13 (Slowest)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled (Fast),PCF5 (Average),PCF13 (Slow)")); GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true); @@ -2326,7 +2325,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false); GLOBAL_DEF("rendering/quality/gi_probes/quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Ultra-Low (1 cone - fastest),Medium (4 cones), High (6 cones - slowest)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Lowest (1 Cone - Fast),Medium (4 Cones - Average),High (6 Cones - Slow)")); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true); @@ -2342,26 +2341,36 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/filters/max_anisotropy", 4); GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_shape", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fastest),Hexagon,Circle (Slowest)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_quality", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low,Medium,High (Slow)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)")); GLOBAL_DEF("rendering/quality/filters/depth_of_field_use_jitter", false); GLOBAL_DEF("rendering/quality/ssao/quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Low (Fast),Medium,High (Slow),Ultra (Very Slow)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Low (Fast),Medium (Average),High (Slow),Ultra (Slower)")); GLOBAL_DEF("rendering/quality/ssao/half_size", false); GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled,Enabled (Small Cost)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled (Fast),Enabled (Average)")); GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter_curve", 1.0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter_curve", PropertyInfo(Variant::FLOAT, "rendering/quality/filters/screen_space_roughness_limiter_curve", PROPERTY_HINT_EXP_EASING, "0.01,8,0.01")); GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slower)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)")); GLOBAL_DEF("rendering/quality/glow/upscale_mode.mobile", 0); + + GLOBAL_DEF("rendering/quality/screen_space_reflection/roughness_quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/quality/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); + + GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/subsurface_scattering_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); + GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_scale", 0.05); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); + GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", 0.01); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); } RenderingServer::~RenderingServer() { - singleton = NULL; + singleton = nullptr; } diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 702a66405a..1907660dd7 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -382,10 +382,10 @@ public: LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, + LIGHT_PARAM_SIZE, LIGHT_PARAM_ATTENUATION, LIGHT_PARAM_SPOT_ANGLE, LIGHT_PARAM_SPOT_ATTENUATION, - LIGHT_PARAM_CONTACT_SHADOW_SIZE, LIGHT_PARAM_SHADOW_MAX_DISTANCE, LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, @@ -393,7 +393,8 @@ public: LIGHT_PARAM_SHADOW_FADE_START, LIGHT_PARAM_SHADOW_NORMAL_BIAS, LIGHT_PARAM_SHADOW_BIAS, - LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, + LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + LIGHT_PARAM_TRANSMITTANCE_BIAS, LIGHT_PARAM_MAX }; @@ -580,7 +581,7 @@ public: virtual RID viewport_create() = 0; - virtual void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) = 0; + virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0; virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0; virtual void viewport_set_active(RID p_viewport, bool p_active) = 0; virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0; @@ -666,6 +667,7 @@ public: VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE, VIEWPORT_DEBUG_DRAW_SSAO, VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER, + VIEWPORT_DEBUG_DRAW_PSSM_SPLITS, }; @@ -747,7 +749,16 @@ public: virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_grey) = 0; virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0; - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0; + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0; + + enum EnvironmentSSRRoughnessQuality { + ENV_SSR_ROUGNESS_QUALITY_DISABLED, + ENV_SSR_ROUGNESS_QUALITY_LOW, + ENV_SSR_ROUGNESS_QUALITY_MEDIUM, + ENV_SSR_ROUGNESS_QUALITY_HIGH, + }; + + virtual void environment_set_ssr_roughness_quality(EnvironmentSSRRoughnessQuality p_quality) = 0; enum EnvironmentSSAOBlur { ENV_SSAO_BLUR_DISABLED, @@ -773,6 +784,16 @@ public: virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0; + enum SubSurfaceScatteringQuality { + SUB_SURFACE_SCATTERING_QUALITY_DISABLED, + SUB_SURFACE_SCATTERING_QUALITY_LOW, + SUB_SURFACE_SCATTERING_QUALITY_MEDIUM, + SUB_SURFACE_SCATTERING_QUALITY_HIGH, + }; + + virtual void sub_surface_scattering_set_quality(SubSurfaceScatteringQuality p_quality) = 0; + virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + /* CAMERA EFFECTS */ virtual RID camera_effects_create() = 0; @@ -797,6 +818,15 @@ public: virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + enum ShadowFilter { + SHADOW_FILTER_NONE, + SHADOW_FILTER_PCF5, + SHADOW_FILTER_PCF13, + SHADOW_FILTER_MAX + }; + + virtual void shadow_filter_set(ShadowFilter p_filter) = 0; + /* SCENARIO API */ virtual RID scenario_create() = 0; diff --git a/servers/arvr/SCsub b/servers/xr/SCsub index 86681f9c74..86681f9c74 100644 --- a/servers/arvr/SCsub +++ b/servers/xr/SCsub diff --git a/servers/arvr/arvr_interface.cpp b/servers/xr/xr_interface.cpp index 577b4cdd8a..c1233ae810 100644 --- a/servers/arvr/arvr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface.cpp */ +/* xr_interface.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_interface.h" +#include "xr_interface.h" -void ARVRInterface::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_name"), &ARVRInterface::get_name); - ClassDB::bind_method(D_METHOD("get_capabilities"), &ARVRInterface::get_capabilities); +void XRInterface::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_name"), &XRInterface::get_name); + ClassDB::bind_method(D_METHOD("get_capabilities"), &XRInterface::get_capabilities); - ClassDB::bind_method(D_METHOD("is_primary"), &ARVRInterface::is_primary); - ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &ARVRInterface::set_is_primary); + ClassDB::bind_method(D_METHOD("is_primary"), &XRInterface::is_primary); + ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &XRInterface::set_is_primary); - ClassDB::bind_method(D_METHOD("is_initialized"), &ARVRInterface::is_initialized); - ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &ARVRInterface::set_is_initialized); - ClassDB::bind_method(D_METHOD("initialize"), &ARVRInterface::initialize); - ClassDB::bind_method(D_METHOD("uninitialize"), &ARVRInterface::uninitialize); + ClassDB::bind_method(D_METHOD("is_initialized"), &XRInterface::is_initialized); + ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &XRInterface::set_is_initialized); + ClassDB::bind_method(D_METHOD("initialize"), &XRInterface::initialize); + ClassDB::bind_method(D_METHOD("uninitialize"), &XRInterface::uninitialize); - ClassDB::bind_method(D_METHOD("get_tracking_status"), &ARVRInterface::get_tracking_status); + ClassDB::bind_method(D_METHOD("get_tracking_status"), &XRInterface::get_tracking_status); - ClassDB::bind_method(D_METHOD("get_render_targetsize"), &ARVRInterface::get_render_targetsize); - ClassDB::bind_method(D_METHOD("is_stereo"), &ARVRInterface::is_stereo); + ClassDB::bind_method(D_METHOD("get_render_targetsize"), &XRInterface::get_render_targetsize); + ClassDB::bind_method(D_METHOD("is_stereo"), &XRInterface::is_stereo); ADD_GROUP("Interface", "interface_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interface_is_primary"), "set_is_primary", "is_primary"); @@ -54,55 +54,55 @@ void ARVRInterface::_bind_methods() { // we don't have any properties specific to VR yet.... // but we do have properties specific to AR.... - ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &ARVRInterface::get_anchor_detection_is_enabled); - ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &ARVRInterface::set_anchor_detection_is_enabled); - ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &ARVRInterface::get_camera_feed_id); + ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &XRInterface::get_anchor_detection_is_enabled); + ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &XRInterface::set_anchor_detection_is_enabled); + ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &XRInterface::get_camera_feed_id); ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); - BIND_ENUM_CONSTANT(ARVR_NONE); - BIND_ENUM_CONSTANT(ARVR_MONO); - BIND_ENUM_CONSTANT(ARVR_STEREO); - BIND_ENUM_CONSTANT(ARVR_AR); - BIND_ENUM_CONSTANT(ARVR_EXTERNAL); + BIND_ENUM_CONSTANT(XR_NONE); + BIND_ENUM_CONSTANT(XR_MONO); + BIND_ENUM_CONSTANT(XR_STEREO); + BIND_ENUM_CONSTANT(XR_AR); + BIND_ENUM_CONSTANT(XR_EXTERNAL); BIND_ENUM_CONSTANT(EYE_MONO); BIND_ENUM_CONSTANT(EYE_LEFT); BIND_ENUM_CONSTANT(EYE_RIGHT); - BIND_ENUM_CONSTANT(ARVR_NORMAL_TRACKING); - BIND_ENUM_CONSTANT(ARVR_EXCESSIVE_MOTION); - BIND_ENUM_CONSTANT(ARVR_INSUFFICIENT_FEATURES); - BIND_ENUM_CONSTANT(ARVR_UNKNOWN_TRACKING); - BIND_ENUM_CONSTANT(ARVR_NOT_TRACKING); + BIND_ENUM_CONSTANT(XR_NORMAL_TRACKING); + BIND_ENUM_CONSTANT(XR_EXCESSIVE_MOTION); + BIND_ENUM_CONSTANT(XR_INSUFFICIENT_FEATURES); + BIND_ENUM_CONSTANT(XR_UNKNOWN_TRACKING); + BIND_ENUM_CONSTANT(XR_NOT_TRACKING); }; -StringName ARVRInterface::get_name() const { +StringName XRInterface::get_name() const { return "Unknown"; }; -bool ARVRInterface::is_primary() { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, false); +bool XRInterface::is_primary() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, false); - return arvr_server->get_primary_interface() == this; + return xr_server->get_primary_interface() == this; }; -void ARVRInterface::set_is_primary(bool p_is_primary) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRInterface::set_is_primary(bool p_is_primary) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); if (p_is_primary) { ERR_FAIL_COND(!is_initialized()); - arvr_server->set_primary_interface(this); + xr_server->set_primary_interface(this); } else { - arvr_server->clear_primary_interface_if(this); + xr_server->clear_primary_interface_if(this); }; }; -void ARVRInterface::set_is_initialized(bool p_initialized) { +void XRInterface::set_is_initialized(bool p_initialized) { if (p_initialized) { if (!is_initialized()) { initialize(); @@ -114,31 +114,31 @@ void ARVRInterface::set_is_initialized(bool p_initialized) { }; }; -ARVRInterface::Tracking_status ARVRInterface::get_tracking_status() const { +XRInterface::Tracking_status XRInterface::get_tracking_status() const { return tracking_state; }; -ARVRInterface::ARVRInterface() { - tracking_state = ARVR_UNKNOWN_TRACKING; +XRInterface::XRInterface() { + tracking_state = XR_UNKNOWN_TRACKING; }; -ARVRInterface::~ARVRInterface(){}; +XRInterface::~XRInterface(){}; // optional render to external texture which enhances performance on those platforms that require us to submit our end result into special textures. -unsigned int ARVRInterface::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) { +unsigned int XRInterface::get_external_texture_for_eye(XRInterface::Eyes p_eye) { return 0; }; /** these will only be implemented on AR interfaces, so we want dummies for VR **/ -bool ARVRInterface::get_anchor_detection_is_enabled() const { +bool XRInterface::get_anchor_detection_is_enabled() const { return false; }; -void ARVRInterface::set_anchor_detection_is_enabled(bool p_enable){ +void XRInterface::set_anchor_detection_is_enabled(bool p_enable){ // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. }; -int ARVRInterface::get_camera_feed_id() { +int XRInterface::get_camera_feed_id() { // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. return 0; diff --git a/servers/arvr/arvr_interface.h b/servers/xr/xr_interface.h index 861061cbf5..99fcef7925 100644 --- a/servers/arvr/arvr_interface.h +++ b/servers/xr/xr_interface.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface.h */ +/* xr_interface.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_INTERFACE_H -#define ARVR_INTERFACE_H +#ifndef XR_INTERFACE_H +#define XR_INTERFACE_H #include "core/math/camera_matrix.h" #include "core/os/thread_safe.h" #include "scene/main/window.h" -#include "servers/arvr_server.h" +#include "servers/xr_server.h" /** @author Bastiaan Olij <mux213@gmail.com> - The ARVR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. + The XR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server. @@ -48,16 +48,16 @@ Note that we may make this into a fully instantiable class for GDNative support. */ -class ARVRInterface : public Reference { - GDCLASS(ARVRInterface, Reference); +class XRInterface : public Reference { + GDCLASS(XRInterface, Reference); public: enum Capabilities { /* purely meta data, provides some info about what this interface supports */ - ARVR_NONE = 0, /* no capabilities */ - ARVR_MONO = 1, /* can be used with mono output */ - ARVR_STEREO = 2, /* can be used with stereo output */ - ARVR_AR = 4, /* offers a camera feed for AR */ - ARVR_EXTERNAL = 8 /* renders to external device */ + XR_NONE = 0, /* no capabilities */ + XR_MONO = 1, /* can be used with mono output */ + XR_STEREO = 2, /* can be used with stereo output */ + XR_AR = 4, /* offers a camera feed for AR */ + XR_EXTERNAL = 8 /* renders to external device */ }; enum Eyes { @@ -67,11 +67,11 @@ public: }; enum Tracking_status { /* tracking status currently based on AR but we can start doing more with this for VR as well */ - ARVR_NORMAL_TRACKING, - ARVR_EXCESSIVE_MOTION, - ARVR_INSUFFICIENT_FEATURES, - ARVR_UNKNOWN_TRACKING, - ARVR_NOT_TRACKING + XR_NORMAL_TRACKING, + XR_EXCESSIVE_MOTION, + XR_INSUFFICIENT_FEATURES, + XR_UNKNOWN_TRACKING, + XR_NOT_TRACKING }; protected: @@ -107,20 +107,20 @@ public: virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */ virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */ - virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ - virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ - virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye); /* if applicable return external texture to render to */ - virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ + virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ + virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye); /* if applicable return external texture to render to */ + virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ virtual void process() = 0; virtual void notification(int p_what) = 0; - ARVRInterface(); - ~ARVRInterface(); + XRInterface(); + ~XRInterface(); }; -VARIANT_ENUM_CAST(ARVRInterface::Capabilities); -VARIANT_ENUM_CAST(ARVRInterface::Eyes); -VARIANT_ENUM_CAST(ARVRInterface::Tracking_status); +VARIANT_ENUM_CAST(XRInterface::Capabilities); +VARIANT_ENUM_CAST(XRInterface::Eyes); +VARIANT_ENUM_CAST(XRInterface::Tracking_status); #endif diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index dabeb7b86f..808b0a608f 100644 --- a/servers/arvr/arvr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_positional_tracker.cpp */ +/* xr_positional_tracker.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,192 +28,192 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_positional_tracker.h" +#include "xr_positional_tracker.h" #include "core/input/input_filter.h" -void ARVRPositionalTracker::_bind_methods() { +void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN); BIND_ENUM_CONSTANT(TRACKER_LEFT_HAND); BIND_ENUM_CONSTANT(TRACKER_RIGHT_HAND); // this class is read only from GDScript, so we only have access to getters.. - ClassDB::bind_method(D_METHOD("get_type"), &ARVRPositionalTracker::get_type); - ClassDB::bind_method(D_METHOD("get_tracker_id"), &ARVRPositionalTracker::get_tracker_id); - ClassDB::bind_method(D_METHOD("get_name"), &ARVRPositionalTracker::get_name); - ClassDB::bind_method(D_METHOD("get_joy_id"), &ARVRPositionalTracker::get_joy_id); - ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &ARVRPositionalTracker::get_tracks_orientation); - ClassDB::bind_method(D_METHOD("get_orientation"), &ARVRPositionalTracker::get_orientation); - ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position); - ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position); - ClassDB::bind_method(D_METHOD("get_hand"), &ARVRPositionalTracker::get_hand); - ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRPositionalTracker::get_mesh); + ClassDB::bind_method(D_METHOD("get_type"), &XRPositionalTracker::get_type); + ClassDB::bind_method(D_METHOD("get_tracker_id"), &XRPositionalTracker::get_tracker_id); + ClassDB::bind_method(D_METHOD("get_name"), &XRPositionalTracker::get_name); + ClassDB::bind_method(D_METHOD("get_joy_id"), &XRPositionalTracker::get_joy_id); + ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &XRPositionalTracker::get_tracks_orientation); + ClassDB::bind_method(D_METHOD("get_orientation"), &XRPositionalTracker::get_orientation); + ClassDB::bind_method(D_METHOD("get_tracks_position"), &XRPositionalTracker::get_tracks_position); + ClassDB::bind_method(D_METHOD("get_position"), &XRPositionalTracker::get_position); + ClassDB::bind_method(D_METHOD("get_hand"), &XRPositionalTracker::get_hand); + ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &XRPositionalTracker::get_transform); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRPositionalTracker::get_mesh); // these functions we don't want to expose to normal users but do need to be callable from GDNative - ClassDB::bind_method(D_METHOD("_set_type", "type"), &ARVRPositionalTracker::set_type); - ClassDB::bind_method(D_METHOD("_set_name", "name"), &ARVRPositionalTracker::set_name); - ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id); - ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation); - ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position); - ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &ARVRPositionalTracker::set_mesh); - ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRPositionalTracker::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRPositionalTracker::set_rumble); + ClassDB::bind_method(D_METHOD("_set_type", "type"), &XRPositionalTracker::set_type); + ClassDB::bind_method(D_METHOD("_set_name", "name"), &XRPositionalTracker::set_name); + ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &XRPositionalTracker::set_joy_id); + ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &XRPositionalTracker::set_orientation); + ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &XRPositionalTracker::set_rw_position); + ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &XRPositionalTracker::set_mesh); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble"); }; -void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) { +void XRPositionalTracker::set_type(XRServer::TrackerType p_type) { if (type != p_type) { type = p_type; - hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + hand = XRPositionalTracker::TRACKER_HAND_UNKNOWN; - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // get a tracker id for our type // note if this is a controller this will be 3 or higher but we may change it later. - tracker_id = arvr_server->get_free_tracker_id_for_type(p_type); + tracker_id = xr_server->get_free_tracker_id_for_type(p_type); }; }; -ARVRServer::TrackerType ARVRPositionalTracker::get_type() const { +XRServer::TrackerType XRPositionalTracker::get_type() const { return type; }; -void ARVRPositionalTracker::set_name(const String &p_name) { +void XRPositionalTracker::set_name(const String &p_name) { name = p_name; }; -StringName ARVRPositionalTracker::get_name() const { +StringName XRPositionalTracker::get_name() const { return name; }; -int ARVRPositionalTracker::get_tracker_id() const { +int XRPositionalTracker::get_tracker_id() const { return tracker_id; }; -void ARVRPositionalTracker::set_joy_id(int p_joy_id) { +void XRPositionalTracker::set_joy_id(int p_joy_id) { joy_id = p_joy_id; }; -int ARVRPositionalTracker::get_joy_id() const { +int XRPositionalTracker::get_joy_id() const { return joy_id; }; -bool ARVRPositionalTracker::get_tracks_orientation() const { +bool XRPositionalTracker::get_tracks_orientation() const { return tracks_orientation; }; -void ARVRPositionalTracker::set_orientation(const Basis &p_orientation) { +void XRPositionalTracker::set_orientation(const Basis &p_orientation) { _THREAD_SAFE_METHOD_ tracks_orientation = true; // obviously we have this orientation = p_orientation; }; -Basis ARVRPositionalTracker::get_orientation() const { +Basis XRPositionalTracker::get_orientation() const { _THREAD_SAFE_METHOD_ return orientation; }; -bool ARVRPositionalTracker::get_tracks_position() const { +bool XRPositionalTracker::get_tracks_position() const { return tracks_position; }; -void ARVRPositionalTracker::set_position(const Vector3 &p_position) { +void XRPositionalTracker::set_position(const Vector3 &p_position) { _THREAD_SAFE_METHOD_ - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); - real_t world_scale = arvr_server->get_world_scale(); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + real_t world_scale = xr_server->get_world_scale(); ERR_FAIL_COND(world_scale == 0); tracks_position = true; // obviously we have this rw_position = p_position / world_scale; }; -Vector3 ARVRPositionalTracker::get_position() const { +Vector3 XRPositionalTracker::get_position() const { _THREAD_SAFE_METHOD_ - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, rw_position); - real_t world_scale = arvr_server->get_world_scale(); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, rw_position); + real_t world_scale = xr_server->get_world_scale(); return rw_position * world_scale; }; -void ARVRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) { +void XRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) { _THREAD_SAFE_METHOD_ tracks_position = true; // obviously we have this rw_position = p_rw_position; }; -Vector3 ARVRPositionalTracker::get_rw_position() const { +Vector3 XRPositionalTracker::get_rw_position() const { _THREAD_SAFE_METHOD_ return rw_position; }; -void ARVRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) { +void XRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) { _THREAD_SAFE_METHOD_ mesh = p_mesh; }; -Ref<Mesh> ARVRPositionalTracker::get_mesh() const { +Ref<Mesh> XRPositionalTracker::get_mesh() const { _THREAD_SAFE_METHOD_ return mesh; }; -ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const { +XRPositionalTracker::TrackerHand XRPositionalTracker::get_hand() const { return hand; }; -void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRPositionalTracker::set_hand(const XRPositionalTracker::TrackerHand p_hand) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); if (hand != p_hand) { // we can only set this if we've previously set this to be a controller!! - ERR_FAIL_COND((type != ARVRServer::TRACKER_CONTROLLER) && (p_hand != ARVRPositionalTracker::TRACKER_HAND_UNKNOWN)); + ERR_FAIL_COND((type != XRServer::TRACKER_CONTROLLER) && (p_hand != XRPositionalTracker::TRACKER_HAND_UNKNOWN)); hand = p_hand; - if (hand == ARVRPositionalTracker::TRACKER_LEFT_HAND) { - if (!arvr_server->is_tracker_id_in_use_for_type(type, 1)) { + if (hand == XRPositionalTracker::TRACKER_LEFT_HAND) { + if (!xr_server->is_tracker_id_in_use_for_type(type, 1)) { tracker_id = 1; }; - } else if (hand == ARVRPositionalTracker::TRACKER_RIGHT_HAND) { - if (!arvr_server->is_tracker_id_in_use_for_type(type, 2)) { + } else if (hand == XRPositionalTracker::TRACKER_RIGHT_HAND) { + if (!xr_server->is_tracker_id_in_use_for_type(type, 2)) { tracker_id = 2; }; }; }; }; -Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { +Transform XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { Transform new_transform; new_transform.basis = get_orientation(); new_transform.origin = get_position(); if (p_adjust_by_reference_frame) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, new_transform); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, new_transform); - new_transform = arvr_server->get_reference_frame() * new_transform; + new_transform = xr_server->get_reference_frame() * new_transform; }; return new_transform; }; -real_t ARVRPositionalTracker::get_rumble() const { +real_t XRPositionalTracker::get_rumble() const { return rumble; }; -void ARVRPositionalTracker::set_rumble(real_t p_rumble) { +void XRPositionalTracker::set_rumble(real_t p_rumble) { if (p_rumble > 0.0) { rumble = p_rumble; } else { @@ -221,8 +221,8 @@ void ARVRPositionalTracker::set_rumble(real_t p_rumble) { }; }; -ARVRPositionalTracker::ARVRPositionalTracker() { - type = ARVRServer::TRACKER_UNKNOWN; +XRPositionalTracker::XRPositionalTracker() { + type = XRServer::TRACKER_UNKNOWN; name = "Unknown"; joy_id = -1; tracker_id = 0; @@ -232,6 +232,6 @@ ARVRPositionalTracker::ARVRPositionalTracker() { rumble = 0.0; }; -ARVRPositionalTracker::~ARVRPositionalTracker(){ +XRPositionalTracker::~XRPositionalTracker(){ }; diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 03c6b33ffe..d9d1f909e9 100644 --- a/servers/arvr/arvr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_positional_tracker.h */ +/* xr_positional_tracker.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_POSITIONAL_TRACKER_H -#define ARVR_POSITIONAL_TRACKER_H +#ifndef XR_POSITIONAL_TRACKER_H +#define XR_POSITIONAL_TRACKER_H #include "core/os/thread_safe.h" #include "scene/resources/mesh.h" -#include "servers/arvr_server.h" +#include "servers/xr_server.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -43,8 +43,8 @@ This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking. */ -class ARVRPositionalTracker : public Object { - GDCLASS(ARVRPositionalTracker, Object); +class XRPositionalTracker : public Object { + GDCLASS(XRPositionalTracker, Object); _THREAD_SAFE_CLASS_ public: @@ -55,7 +55,7 @@ public: }; private: - ARVRServer::TrackerType type; // type of tracker + XRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker int tracker_id; // tracker index id that is unique per type int joy_id; // if we also have a related joystick entity, the id of the joystick @@ -65,14 +65,14 @@ private: Vector3 rw_position; // our position "in the real world, so without world_scale applied" Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker TrackerHand hand; // if known, the hand this tracker is held in - real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, arvr_interface is responsible for execution + real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution protected: static void _bind_methods(); public: - void set_type(ARVRServer::TrackerType p_type); - ARVRServer::TrackerType get_type() const; + void set_type(XRServer::TrackerType p_type); + XRServer::TrackerType get_type() const; void set_name(const String &p_name); StringName get_name() const; int get_tracker_id() const; @@ -86,8 +86,8 @@ public: Vector3 get_position() const; // get position with world_scale applied void set_rw_position(const Vector3 &p_rw_position); Vector3 get_rw_position() const; - ARVRPositionalTracker::TrackerHand get_hand() const; - void set_hand(const ARVRPositionalTracker::TrackerHand p_hand); + XRPositionalTracker::TrackerHand get_hand() const; + void set_hand(const XRPositionalTracker::TrackerHand p_hand); real_t get_rumble() const; void set_rumble(real_t p_rumble); void set_mesh(const Ref<Mesh> &p_mesh); @@ -95,10 +95,10 @@ public: Transform get_transform(bool p_adjust_by_reference_frame) const; - ARVRPositionalTracker(); - ~ARVRPositionalTracker(); + XRPositionalTracker(); + ~XRPositionalTracker(); }; -VARIANT_ENUM_CAST(ARVRPositionalTracker::TrackerHand); +VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand); #endif diff --git a/servers/arvr_server.cpp b/servers/xr_server.cpp index 724414ae96..a93b99025f 100644 --- a/servers/arvr_server.cpp +++ b/servers/xr_server.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_server.cpp */ +/* xr_server.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,41 +28,41 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_server.h" -#include "arvr/arvr_interface.h" -#include "arvr/arvr_positional_tracker.h" +#include "xr_server.h" #include "core/project_settings.h" +#include "xr/xr_interface.h" +#include "xr/xr_positional_tracker.h" -ARVRServer *ARVRServer::singleton = NULL; +XRServer *XRServer::singleton = nullptr; -ARVRServer *ARVRServer::get_singleton() { +XRServer *XRServer::get_singleton() { return singleton; }; -void ARVRServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale); - ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale); - ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame); - ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd); - ClassDB::bind_method(D_METHOD("get_hmd_transform"), &ARVRServer::get_hmd_transform); +void XRServer::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_world_scale"), &XRServer::get_world_scale); + ClassDB::bind_method(D_METHOD("set_world_scale"), &XRServer::set_world_scale); + ClassDB::bind_method(D_METHOD("get_reference_frame"), &XRServer::get_reference_frame); + ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &XRServer::center_on_hmd); + ClassDB::bind_method(D_METHOD("get_hmd_transform"), &XRServer::get_hmd_transform); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); - ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count); - ClassDB::bind_method(D_METHOD("get_interface", "idx"), &ARVRServer::get_interface); - ClassDB::bind_method(D_METHOD("get_interfaces"), &ARVRServer::get_interfaces); - ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface); - ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count); - ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker); + ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count); + ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface); + ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces); + ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface); + ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count); + ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker); - ClassDB::bind_method(D_METHOD("get_primary_interface"), &ARVRServer::get_primary_interface); - ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface); + ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface); + ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface"); - ClassDB::bind_method(D_METHOD("get_last_process_usec"), &ARVRServer::get_last_process_usec); - ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &ARVRServer::get_last_commit_usec); - ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &ARVRServer::get_last_frame_usec); + ClassDB::bind_method(D_METHOD("get_last_process_usec"), &XRServer::get_last_process_usec); + ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec); + ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec); BIND_ENUM_CONSTANT(TRACKER_CONTROLLER); BIND_ENUM_CONSTANT(TRACKER_BASESTATION); @@ -82,11 +82,11 @@ void ARVRServer::_bind_methods() { ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); }; -real_t ARVRServer::get_world_scale() const { +real_t XRServer::get_world_scale() const { return world_scale; }; -void ARVRServer::set_world_scale(real_t p_world_scale) { +void XRServer::set_world_scale(real_t p_world_scale) { if (p_world_scale < 0.01) { p_world_scale = 0.01; } else if (p_world_scale > 1000.0) { @@ -96,25 +96,25 @@ void ARVRServer::set_world_scale(real_t p_world_scale) { world_scale = p_world_scale; }; -Transform ARVRServer::get_world_origin() const { +Transform XRServer::get_world_origin() const { return world_origin; }; -void ARVRServer::set_world_origin(const Transform &p_world_origin) { +void XRServer::set_world_origin(const Transform &p_world_origin) { world_origin = p_world_origin; }; -Transform ARVRServer::get_reference_frame() const { +Transform XRServer::get_reference_frame() const { return reference_frame; }; -void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { - if (primary_interface != NULL) { +void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { + if (primary_interface != nullptr) { // clear our current reference frame or we'll end up double adjusting it reference_frame = Transform(); // requesting our EYE_MONO transform should return our current HMD position - Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform()); + Transform new_reference_frame = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); // remove our tilt if (p_rotation_mode == 1) { @@ -140,15 +140,15 @@ void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) }; }; -Transform ARVRServer::get_hmd_transform() { +Transform XRServer::get_hmd_transform() { Transform hmd_transform; - if (primary_interface != NULL) { - hmd_transform = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, hmd_transform); + if (primary_interface != nullptr) { + hmd_transform = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, hmd_transform); }; return hmd_transform; }; -void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { +void XRServer::add_interface(const Ref<XRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); for (int i = 0; i < interfaces.size(); i++) { @@ -163,7 +163,7 @@ void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { emit_signal("interface_added", p_interface->get_name()); }; -void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) { +void XRServer::remove_interface(const Ref<XRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); int idx = -1; @@ -178,23 +178,23 @@ void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) { ERR_FAIL_COND(idx == -1); - print_verbose("ARVR: Removed interface" + p_interface->get_name()); + print_verbose("XR: Removed interface" + p_interface->get_name()); emit_signal("interface_removed", p_interface->get_name()); interfaces.remove(idx); }; -int ARVRServer::get_interface_count() const { +int XRServer::get_interface_count() const { return interfaces.size(); }; -Ref<ARVRInterface> ARVRServer::get_interface(int p_index) const { - ERR_FAIL_INDEX_V(p_index, interfaces.size(), NULL); +Ref<XRInterface> XRServer::get_interface(int p_index) const { + ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr); return interfaces[p_index]; }; -Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const { +Ref<XRInterface> XRServer::find_interface(const String &p_name) const { int idx = -1; for (int i = 0; i < interfaces.size(); i++) { @@ -205,12 +205,12 @@ Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const { }; }; - ERR_FAIL_COND_V(idx == -1, NULL); + ERR_FAIL_COND_V(idx == -1, nullptr); return interfaces[idx]; }; -Array ARVRServer::get_interfaces() const { +Array XRServer::get_interfaces() const { Array ret; for (int i = 0; i < interfaces.size(); i++) { @@ -238,7 +238,7 @@ Array ARVRServer::get_interfaces() const { - using this approach the shield disappears or is no longer tracked, but the gun stays firmly in your right hand because that is still controller 2, further more, if controller 1 is replaced the shield will return. */ -bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { +bool XRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { for (int i = 0; i < trackers.size(); i++) { if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { return true; @@ -249,13 +249,13 @@ bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p return false; }; -int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { +int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { // We start checking at 1, 0 means that it's not a controller.. // Note that for controller we reserve: // - 1 for the left hand controller and // - 2 for the right hand controller // so we start at 3 :) - int tracker_id = p_tracker_type == ARVRServer::TRACKER_CONTROLLER ? 3 : 1; + int tracker_id = p_tracker_type == XRServer::TRACKER_CONTROLLER ? 3 : 1; while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) { // try the next one @@ -265,14 +265,14 @@ int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { return tracker_id; }; -void ARVRServer::add_tracker(ARVRPositionalTracker *p_tracker) { +void XRServer::add_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); trackers.push_back(p_tracker); emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); }; -void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { +void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); int idx = -1; @@ -291,18 +291,18 @@ void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { trackers.remove(idx); }; -int ARVRServer::get_tracker_count() const { +int XRServer::get_tracker_count() const { return trackers.size(); }; -ARVRPositionalTracker *ARVRServer::get_tracker(int p_index) const { - ERR_FAIL_INDEX_V(p_index, trackers.size(), NULL); +XRPositionalTracker *XRServer::get_tracker(int p_index) const { + ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr); return trackers[p_index]; }; -ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { - ERR_FAIL_COND_V(p_tracker_id == 0, NULL); +XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { + ERR_FAIL_COND_V(p_tracker_id == 0, nullptr); for (int i = 0; i < trackers.size(); i++) { if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { @@ -310,39 +310,39 @@ ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_typ }; }; - return NULL; + return nullptr; }; -Ref<ARVRInterface> ARVRServer::get_primary_interface() const { +Ref<XRInterface> XRServer::get_primary_interface() const { return primary_interface; }; -void ARVRServer::set_primary_interface(const Ref<ARVRInterface> &p_primary_interface) { +void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) { primary_interface = p_primary_interface; - print_verbose("ARVR: Primary interface set to: " + primary_interface->get_name()); + print_verbose("XR: Primary interface set to: " + primary_interface->get_name()); }; -void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface) { +void XRServer::clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface) { if (primary_interface == p_primary_interface) { - print_verbose("ARVR: Clearing primary interface"); + print_verbose("XR: Clearing primary interface"); primary_interface.unref(); }; }; -uint64_t ARVRServer::get_last_process_usec() { +uint64_t XRServer::get_last_process_usec() { return last_process_usec; }; -uint64_t ARVRServer::get_last_commit_usec() { +uint64_t XRServer::get_last_commit_usec() { return last_commit_usec; }; -uint64_t ARVRServer::get_last_frame_usec() { +uint64_t XRServer::get_last_frame_usec() { return last_frame_usec; }; -void ARVRServer::_process() { +void XRServer::_process() { /* called from rendering_server_viewport.draw_viewports right before we start drawing our viewports */ /* mark for our frame timing */ @@ -358,7 +358,7 @@ void ARVRServer::_process() { }; }; -void ARVRServer::_mark_commit() { +void XRServer::_mark_commit() { /* time this */ last_commit_usec = OS::get_singleton()->get_ticks_usec(); @@ -366,12 +366,12 @@ void ARVRServer::_mark_commit() { last_frame_usec = last_commit_usec - last_process_usec; }; -ARVRServer::ARVRServer() { +XRServer::XRServer() { singleton = this; world_scale = 1.0; }; -ARVRServer::~ARVRServer() { +XRServer::~XRServer() { primary_interface.unref(); while (interfaces.size() > 0) { @@ -382,5 +382,5 @@ ARVRServer::~ARVRServer() { trackers.remove(0); } - singleton = NULL; + singleton = nullptr; }; diff --git a/servers/arvr_server.h b/servers/xr_server.h index ab2f0d721b..e04c7b3592 100644 --- a/servers/arvr_server.h +++ b/servers/xr_server.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_server.h */ +/* xr_server.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_SERVER_H -#define ARVR_SERVER_H +#ifndef XR_SERVER_H +#define XR_SERVER_H #include "core/os/os.h" #include "core/os/thread_safe.h" @@ -37,16 +37,16 @@ #include "core/rid.h" #include "core/variant.h" -class ARVRInterface; -class ARVRPositionalTracker; +class XRInterface; +class XRPositionalTracker; /** @author Bastiaan Olij <mux213@gmail.com> - The ARVR server is a singleton object that gives access to the various + The XR server is a singleton object that gives access to the various objects and SDKs that are available on the system. Because there can be multiple SDKs active this is exposed as an array - and our ARVR server object acts as a pass through + and our XR server object acts as a pass through Also each positioning tracker is accessible from here. I've added some additional info into this header file that should move @@ -54,8 +54,8 @@ class ARVRPositionalTracker; or as a separate PR once this has been merged into the master branch. **/ -class ARVRServer : public Object { - GDCLASS(ARVRServer, Object); +class XRServer : public Object { + GDCLASS(XRServer, Object); _THREAD_SAFE_CLASS_ public: @@ -76,10 +76,10 @@ public: }; private: - Vector<Ref<ARVRInterface>> interfaces; - Vector<ARVRPositionalTracker *> trackers; + Vector<Ref<XRInterface>> interfaces; + Vector<XRPositionalTracker *> trackers; - Ref<ARVRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ + Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ real_t world_scale; /* scale by which we multiply our tracker positions */ Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */ @@ -90,12 +90,12 @@ private: uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */ protected: - static ARVRServer *singleton; + static XRServer *singleton; static void _bind_methods(); public: - static ARVRServer *get_singleton(); + static XRServer *get_singleton(); /* World scale allows you to specify a scale factor that is applied to all positioning vectors in our VR world in essence scaling up, or scaling down the world. @@ -105,7 +105,7 @@ public: Most VR platforms, and our assumption, is that 1 unit in our virtual world equates to 1 meter in the real mode. This scale basically effects the unit size relationship to real world size. - I may remove access to this property in GDScript in favour of exposing it on the ARVROrigin node + I may remove access to this property in GDScript in favour of exposing it on the XROrigin3D node */ real_t get_world_scale() const; void set_world_scale(real_t p_world_scale); @@ -116,7 +116,7 @@ public: actions be it straffing, teleporting, etc. Movement of the player by moving through the physical space is always tracked in relation to this point. - Note that the ARVROrigin spatial node in your scene automatically updates this property and it should be used instead of + Note that the XROrigin3D spatial node in your scene automatically updates this property and it should be used instead of direct access to this property and it therefore is not available in GDScript Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world @@ -146,20 +146,20 @@ public: /* Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc. */ - void add_interface(const Ref<ARVRInterface> &p_interface); - void remove_interface(const Ref<ARVRInterface> &p_interface); + void add_interface(const Ref<XRInterface> &p_interface); + void remove_interface(const Ref<XRInterface> &p_interface); int get_interface_count() const; - Ref<ARVRInterface> get_interface(int p_index) const; - Ref<ARVRInterface> find_interface(const String &p_name) const; + Ref<XRInterface> get_interface(int p_index) const; + Ref<XRInterface> find_interface(const String &p_name) const; Array get_interfaces() const; /* note, more then one interface can technically be active, especially on mobile, but only one interface is used for rendering. This interface identifies itself by calling set_primary_interface when it is initialized */ - Ref<ARVRInterface> get_primary_interface() const; - void set_primary_interface(const Ref<ARVRInterface> &p_primary_interface); - void clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */ + Ref<XRInterface> get_primary_interface() const; + void set_primary_interface(const Ref<XRInterface> &p_primary_interface); + void clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */ /* Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc. @@ -167,11 +167,11 @@ public: */ bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const; int get_free_tracker_id_for_type(TrackerType p_tracker_type); - void add_tracker(ARVRPositionalTracker *p_tracker); - void remove_tracker(ARVRPositionalTracker *p_tracker); + void add_tracker(XRPositionalTracker *p_tracker); + void remove_tracker(XRPositionalTracker *p_tracker); int get_tracker_count() const; - ARVRPositionalTracker *get_tracker(int p_index) const; - ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; + XRPositionalTracker *get_tracker(int p_index) const; + XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; uint64_t get_last_process_usec(); uint64_t get_last_commit_usec(); @@ -180,13 +180,13 @@ public: void _process(); void _mark_commit(); - ARVRServer(); - ~ARVRServer(); + XRServer(); + ~XRServer(); }; -#define ARVR ARVRServer +#define XR XRServer -VARIANT_ENUM_CAST(ARVRServer::TrackerType); -VARIANT_ENUM_CAST(ARVRServer::RotationMode); +VARIANT_ENUM_CAST(XRServer::TrackerType); +VARIANT_ENUM_CAST(XRServer::RotationMode); #endif |