diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 640189a26eb..ac8d50c419b 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -445,6 +445,21 @@ Ref Camera::get_environment() const { return environment; } +void Camera::set_effects(const Ref &p_effects) { + + effects = p_effects; + if (effects.is_valid()) + VS::get_singleton()->camera_set_camera_effects(camera, effects->get_rid()); + else + VS::get_singleton()->camera_set_camera_effects(camera, RID()); + _update_camera_mode(); +} + +Ref Camera::get_effects() const { + + return effects; +} + void Camera::set_keep_aspect_mode(KeepAspect p_aspect) { keep_aspect = p_aspect; VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH); @@ -512,6 +527,8 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cull_mask"), &Camera::get_cull_mask); ClassDB::bind_method(D_METHOD("set_environment", "env"), &Camera::set_environment); ClassDB::bind_method(D_METHOD("get_environment"), &Camera::get_environment); + ClassDB::bind_method(D_METHOD("set_effects", "env"), &Camera::set_effects); + ClassDB::bind_method(D_METHOD("get_effects"), &Camera::get_effects); ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode); ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); @@ -527,6 +544,7 @@ void Camera::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_effects", "get_effects"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index e215783a584..6ac3ece798d 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -82,6 +82,7 @@ private: uint32_t layers; Ref environment; + Ref effects; virtual bool _can_gizmo_scale() const; @@ -157,6 +158,9 @@ public: void set_environment(const Ref &p_environment); Ref get_environment() const; + void set_effects(const Ref &p_effects); + Ref get_effects() const; + void set_keep_aspect_mode(KeepAspect p_aspect); KeepAspect get_keep_aspect_mode() const; diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index c8d7382e819..a4c990c81d6 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -43,12 +43,25 @@ void WorldEnvironment::_notification(int p_what) { add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } + if (camera_effects.is_valid()) { + if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding."); + } + get_viewport()->find_world()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } + } else if (p_what == Spatial::NOTIFICATION_EXIT_WORLD || p_what == Spatial::NOTIFICATION_EXIT_TREE) { if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { get_viewport()->find_world()->set_environment(Ref()); remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } + + if (camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { + get_viewport()->find_world()->set_camera_effects(Ref()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } } } @@ -77,6 +90,31 @@ Ref WorldEnvironment::get_environment() const { return environment; } +void WorldEnvironment::set_camera_effects(const Ref &p_camera_effects) { + + if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { + get_viewport()->find_world()->set_camera_effects(Ref()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + //clean up + } + + camera_effects = p_camera_effects; + if (is_inside_tree() && camera_effects.is_valid()) { + if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding."); + } + get_viewport()->find_world()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } + + update_configuration_warning(); +} + +Ref WorldEnvironment::get_camera_effects() const { + + return camera_effects; +} + String WorldEnvironment::get_configuration_warning() const { if (!environment.is_valid()) { @@ -106,6 +144,10 @@ void WorldEnvironment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_environment", "env"), &WorldEnvironment::set_environment); ClassDB::bind_method(D_METHOD("get_environment"), &WorldEnvironment::get_environment); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); + + ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &WorldEnvironment::set_camera_effects); + ClassDB::bind_method(D_METHOD("get_camera_effects"), &WorldEnvironment::get_camera_effects); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); } WorldEnvironment::WorldEnvironment() { diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 6e89fe85175..0c590bfc07e 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -38,6 +38,7 @@ class WorldEnvironment : public Node { GDCLASS(WorldEnvironment, Node); Ref environment; + Ref camera_effects; protected: void _notification(int p_what); @@ -47,6 +48,9 @@ public: void set_environment(const Ref &p_environment); Ref get_environment() const; + void set_camera_effects(const Ref &p_camera_effects); + Ref get_camera_effects() const; + String get_configuration_warning() const; WorldEnvironment(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 957e41ce9b2..779c63111a0 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -650,6 +650,7 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_virtual_class(); ClassDB::register_virtual_class(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 1cf291b8675..aeca10ab562 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -343,8 +343,6 @@ void Environment::_validate_property(PropertyInfo &property) const { "auto_exposure_", "ss_reflections_", "ssao_", - "dof_blur_far_", - "dof_blur_near_", "glow_", "adjustment_", NULL @@ -704,115 +702,6 @@ bool Environment::is_glow_bicubic_upscale_enabled() const { return glow_bicubic_upscale; } -void Environment::set_dof_blur_far_enabled(bool p_enable) { - - dof_blur_far_enabled = p_enable; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); - _change_notify(); -} - -bool Environment::is_dof_blur_far_enabled() const { - - return dof_blur_far_enabled; -} - -void Environment::set_dof_blur_far_distance(float p_distance) { - - dof_blur_far_distance = p_distance; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_distance() const { - - return dof_blur_far_distance; -} - -void Environment::set_dof_blur_far_transition(float p_distance) { - - dof_blur_far_transition = p_distance; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_transition() const { - - return dof_blur_far_transition; -} - -void Environment::set_dof_blur_far_amount(float p_amount) { - - dof_blur_far_amount = p_amount; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_amount() const { - - return dof_blur_far_amount; -} - -void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) { - - dof_blur_far_quality = p_quality; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} - -Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const { - - return dof_blur_far_quality; -} - -void Environment::set_dof_blur_near_enabled(bool p_enable) { - - dof_blur_near_enabled = p_enable; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); - _change_notify(); -} - -bool Environment::is_dof_blur_near_enabled() const { - - return dof_blur_near_enabled; -} - -void Environment::set_dof_blur_near_distance(float p_distance) { - - dof_blur_near_distance = p_distance; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_distance() const { - - return dof_blur_near_distance; -} - -void Environment::set_dof_blur_near_transition(float p_distance) { - - dof_blur_near_transition = p_distance; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_transition() const { - - return dof_blur_near_transition; -} - -void Environment::set_dof_blur_near_amount(float p_amount) { - - dof_blur_near_amount = p_amount; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_amount() const { - - return dof_blur_near_amount; -} - -void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) { - - dof_blur_near_quality = p_quality; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const { - - return dof_blur_near_quality; -} - void Environment::set_fog_enabled(bool p_enabled) { fog_enabled = p_enabled; @@ -1187,50 +1076,6 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness"); - ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &Environment::set_dof_blur_far_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &Environment::is_dof_blur_far_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &Environment::set_dof_blur_far_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &Environment::get_dof_blur_far_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &Environment::set_dof_blur_far_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &Environment::get_dof_blur_far_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_amount", "intensity"), &Environment::set_dof_blur_far_amount); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_amount"), &Environment::get_dof_blur_far_amount); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_quality", "intensity"), &Environment::set_dof_blur_far_quality); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_quality"), &Environment::get_dof_blur_far_quality); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &Environment::set_dof_blur_near_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &Environment::is_dof_blur_near_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &Environment::set_dof_blur_near_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &Environment::get_dof_blur_near_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &Environment::set_dof_blur_near_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &Environment::get_dof_blur_near_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_amount", "intensity"), &Environment::set_dof_blur_near_amount); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_amount"), &Environment::get_dof_blur_near_amount); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_quality", "level"), &Environment::set_dof_blur_near_quality); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_quality"), &Environment::get_dof_blur_near_quality); - - ADD_GROUP("DOF Far Blur", "dof_blur_far_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_far_amount", "get_dof_blur_far_amount"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_far_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_far_quality", "get_dof_blur_far_quality"); - - ADD_GROUP("DOF Near Blur", "dof_blur_near_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_near_amount", "get_dof_blur_near_amount"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_near_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_near_quality", "get_dof_blur_near_quality"); - ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled); ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled); @@ -1334,10 +1179,6 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(TONE_MAPPER_ACES); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH); - BIND_ENUM_CONSTANT(SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(SSAO_BLUR_2x2); @@ -1353,9 +1194,7 @@ Environment::Environment() : tone_mapper(TONE_MAPPER_LINEAR), ssao_blur(SSAO_BLUR_3x3), ssao_quality(SSAO_QUALITY_MEDIUM), - glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE), - dof_blur_far_quality(DOF_BLUR_QUALITY_LOW), - dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) { + glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE) { environment = VS::get_singleton()->environment_create(); @@ -1419,18 +1258,6 @@ Environment::Environment() : glow_hdr_bleed_scale = 2.0; glow_bicubic_upscale = false; - dof_blur_far_enabled = false; - dof_blur_far_distance = 10; - dof_blur_far_transition = 5; - dof_blur_far_amount = 0.1; - dof_blur_far_quality = DOF_BLUR_QUALITY_MEDIUM; - - dof_blur_near_enabled = false; - dof_blur_near_distance = 2; - dof_blur_near_transition = 1; - dof_blur_near_amount = 0.1; - dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM; - fog_enabled = false; fog_color = Color(0.5, 0.5, 0.5); fog_sun_color = Color(0.8, 0.8, 0.0); @@ -1458,3 +1285,188 @@ Environment::~Environment() { VS::get_singleton()->free(environment); } + +////////////////////// + +void CameraEffects::set_dof_blur_far_enabled(bool p_enable) { + + dof_blur_far_enabled = p_enable; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} + +bool CameraEffects::is_dof_blur_far_enabled() const { + + return dof_blur_far_enabled; +} + +void CameraEffects::set_dof_blur_far_distance(float p_distance) { + + dof_blur_far_distance = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} +float CameraEffects::get_dof_blur_far_distance() const { + + return dof_blur_far_distance; +} + +void CameraEffects::set_dof_blur_far_transition(float p_distance) { + + dof_blur_far_transition = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} +float CameraEffects::get_dof_blur_far_transition() const { + + return dof_blur_far_transition; +} + +void CameraEffects::set_dof_blur_near_enabled(bool p_enable) { + + dof_blur_near_enabled = p_enable; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); + _change_notify(); +} + +bool CameraEffects::is_dof_blur_near_enabled() const { + + return dof_blur_near_enabled; +} + +void CameraEffects::set_dof_blur_near_distance(float p_distance) { + + dof_blur_near_distance = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} + +float CameraEffects::get_dof_blur_near_distance() const { + + return dof_blur_near_distance; +} + +void CameraEffects::set_dof_blur_near_transition(float p_distance) { + + dof_blur_near_transition = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} + +float CameraEffects::get_dof_blur_near_transition() const { + + return dof_blur_near_transition; +} + +void CameraEffects::set_dof_blur_amount(float p_amount) { + + dof_blur_amount = p_amount; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} +float CameraEffects::get_dof_blur_amount() const { + + return dof_blur_amount; +} + +void CameraEffects::set_dof_blur_quality(DOFBlurQuality p_quality) { + + dof_blur_quality = p_quality; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount, VS::DOFBlurQuality(dof_blur_quality)); +} + +CameraEffects::DOFBlurQuality CameraEffects::get_dof_blur_quality() const { + + return dof_blur_quality; +} + +void CameraEffects::set_override_exposure_enabled(bool p_enabled) { + override_exposure_enabled = p_enabled; + VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); +} + +bool CameraEffects::is_override_exposure_enabled() const { + return override_exposure_enabled; +} + +void CameraEffects::set_override_exposure(float p_exposure) { + override_exposure = p_exposure; + VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); +} + +float CameraEffects::get_override_exposure() const { + return override_exposure; +} + +RID CameraEffects::get_rid() const { + return camera_effects; +} + +void CameraEffects::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled); + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &CameraEffects::set_dof_blur_far_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance); + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &CameraEffects::set_dof_blur_far_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &CameraEffects::set_dof_blur_near_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &CameraEffects::set_dof_blur_near_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "intensity"), &CameraEffects::set_dof_blur_amount); + ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount); + + ClassDB::bind_method(D_METHOD("set_dof_blur_quality", "level"), &CameraEffects::set_dof_blur_quality); + ClassDB::bind_method(D_METHOD("get_dof_blur_quality"), &CameraEffects::get_dof_blur_quality); + + ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enable"), &CameraEffects::set_override_exposure); + ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled); + + ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure); + ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure); + + ADD_GROUP("DOF Blur", "dof_blur_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_quality", "get_dof_blur_quality"); + ADD_GROUP("Override Exposure", "override_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enable"), "set_override_exposure_enabled", "is_override_exposure_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure"); + + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH); +} + +CameraEffects::CameraEffects() { + + camera_effects = VS::get_singleton()->camera_effects_create(); + + dof_blur_far_enabled = false; + dof_blur_far_distance = 10; + dof_blur_far_transition = 5; + + dof_blur_near_enabled = false; + dof_blur_near_distance = 2; + dof_blur_near_transition = 1; + + dof_blur_amount = 0.1; + + set_dof_blur_quality(DOF_BLUR_QUALITY_MEDIUM); //update server + + override_exposure_enabled = false; + set_override_exposure(1.0); +} + +CameraEffects::~CameraEffects() { + + VS::get_singleton()->free(camera_effects); +} diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 7926d5d2840..530fa727b12 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -80,12 +80,6 @@ public: GLOW_BLEND_MODE_MIX, }; - enum DOFBlurQuality { - DOF_BLUR_QUALITY_LOW, - DOF_BLUR_QUALITY_MEDIUM, - DOF_BLUR_QUALITY_HIGH, - }; - enum SSAOBlur { SSAO_BLUR_DISABLED, SSAO_BLUR_1x1, @@ -163,18 +157,6 @@ private: float glow_hdr_luminance_cap; bool glow_bicubic_upscale; - bool dof_blur_far_enabled; - float dof_blur_far_distance; - float dof_blur_far_transition; - float dof_blur_far_amount; - DOFBlurQuality dof_blur_far_quality; - - bool dof_blur_near_enabled; - float dof_blur_near_distance; - float dof_blur_near_transition; - float dof_blur_near_amount; - DOFBlurQuality dof_blur_near_quality; - bool fog_enabled; Color fog_color; Color fog_sun_color; @@ -356,36 +338,6 @@ public: void set_glow_bicubic_upscale(bool p_enable); bool is_glow_bicubic_upscale_enabled() const; - void set_dof_blur_far_enabled(bool p_enable); - bool is_dof_blur_far_enabled() const; - - void set_dof_blur_far_distance(float p_distance); - float get_dof_blur_far_distance() const; - - void set_dof_blur_far_transition(float p_distance); - float get_dof_blur_far_transition() const; - - void set_dof_blur_far_amount(float p_amount); - float get_dof_blur_far_amount() const; - - void set_dof_blur_far_quality(DOFBlurQuality p_quality); - DOFBlurQuality get_dof_blur_far_quality() const; - - void set_dof_blur_near_enabled(bool p_enable); - bool is_dof_blur_near_enabled() const; - - void set_dof_blur_near_distance(float p_distance); - float get_dof_blur_near_distance() const; - - void set_dof_blur_near_transition(float p_distance); - float get_dof_blur_near_transition() const; - - void set_dof_blur_near_amount(float p_amount); - float get_dof_blur_near_amount() const; - - void set_dof_blur_near_quality(DOFBlurQuality p_quality); - DOFBlurQuality get_dof_blur_near_quality() const; - void set_fog_enabled(bool p_enabled); bool is_fog_enabled() const; @@ -439,8 +391,77 @@ VARIANT_ENUM_CAST(Environment::AmbientSource) VARIANT_ENUM_CAST(Environment::ReflectionSource) VARIANT_ENUM_CAST(Environment::ToneMapper) VARIANT_ENUM_CAST(Environment::GlowBlendMode) -VARIANT_ENUM_CAST(Environment::DOFBlurQuality) VARIANT_ENUM_CAST(Environment::SSAOQuality) VARIANT_ENUM_CAST(Environment::SSAOBlur) +class CameraEffects : public Resource { + + GDCLASS(CameraEffects, Resource); + +public: + enum DOFBlurQuality { + DOF_BLUR_QUALITY_LOW, + DOF_BLUR_QUALITY_MEDIUM, + DOF_BLUR_QUALITY_HIGH, + }; + +private: + RID camera_effects; + + bool dof_blur_far_enabled; + float dof_blur_far_distance; + float dof_blur_far_transition; + + bool dof_blur_near_enabled; + float dof_blur_near_distance; + float dof_blur_near_transition; + + float dof_blur_amount; + DOFBlurQuality dof_blur_quality; + + bool override_exposure_enabled; + float override_exposure; + +protected: + static void _bind_methods(); + +public: + void set_dof_blur_far_enabled(bool p_enable); + bool is_dof_blur_far_enabled() const; + + void set_dof_blur_far_distance(float p_distance); + float get_dof_blur_far_distance() const; + + void set_dof_blur_far_transition(float p_distance); + float get_dof_blur_far_transition() const; + + void set_dof_blur_near_enabled(bool p_enable); + bool is_dof_blur_near_enabled() const; + + void set_dof_blur_near_distance(float p_distance); + float get_dof_blur_near_distance() const; + + void set_dof_blur_near_transition(float p_distance); + float get_dof_blur_near_transition() const; + + void set_dof_blur_amount(float p_amount); + float get_dof_blur_amount() const; + + void set_dof_blur_quality(DOFBlurQuality p_quality); + DOFBlurQuality get_dof_blur_quality() const; + + void set_override_exposure_enabled(bool p_enabled); + bool is_override_exposure_enabled() const; + + void set_override_exposure(float p_exposure); + float get_override_exposure() const; + + virtual RID get_rid() const; + + CameraEffects(); + ~CameraEffects(); +}; + +VARIANT_ENUM_CAST(CameraEffects::DOFBlurQuality) + #endif // ENVIRONMENT_H diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index e1e39740164..78c08080b58 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -306,6 +306,20 @@ Ref World::get_fallback_environment() const { return fallback_environment; } +void World::set_camera_effects(const Ref &p_camera_effects) { + + camera_effects = p_camera_effects; + if (camera_effects.is_valid()) + VS::get_singleton()->scenario_set_camera_effects(scenario, camera_effects->get_rid()); + else + VS::get_singleton()->scenario_set_camera_effects(scenario, RID()); +} + +Ref World::get_camera_effects() const { + + return camera_effects; +} + PhysicsDirectSpaceState *World::get_direct_space_state() { return PhysicsServer::get_singleton()->space_get_direct_state(space); @@ -326,9 +340,12 @@ void World::_bind_methods() { ClassDB::bind_method(D_METHOD("get_environment"), &World::get_environment); ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World::set_fallback_environment); ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World::get_fallback_environment); + ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &World::set_camera_effects); + ClassDB::bind_method(D_METHOD("get_camera_effects"), &World::get_camera_effects); ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World::get_direct_space_state); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state"); diff --git a/scene/resources/world.h b/scene/resources/world.h index b6248b28c8b..6fd79abaaff 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -50,6 +50,7 @@ private: SpatialIndexer *indexer; Ref environment; Ref fallback_environment; + Ref camera_effects; protected: static void _bind_methods(); @@ -77,6 +78,9 @@ public: void set_fallback_environment(const Ref &p_environment); Ref get_fallback_environment() const; + void set_camera_effects(const Ref &p_camera_effects); + Ref get_camera_effects() const; + void get_camera_list(List *r_cameras); PhysicsDirectSpaceState *get_direct_space_state(); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index e7746eec90a..04643354cac 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -75,8 +75,6 @@ public: virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; #endif - virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0; - virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0; virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) = 0; virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0; @@ -95,6 +93,11 @@ public: virtual VS::EnvironmentBG environment_get_background(RID p_env) const = 0; virtual int environment_get_canvas_max_layer(RID p_env) const = 0; + virtual RID camera_effects_create() = 0; + + 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, VS::DOFBlurQuality p_quality) = 0; + virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + struct InstanceBase; struct InstanceDependency { @@ -240,7 +243,7 @@ public: virtual bool gi_probe_needs_update(RID p_probe) const = 0; virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; - virtual void render_scene(RID p_render_buffers, 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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; + virtual void render_scene(RID p_render_buffers, 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) = 0; virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 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; diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp index 72329d8a131..f1ab55e7bf7 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp @@ -406,6 +406,70 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i RD::get_singleton()->compute_list_end(); } +void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_bokeh_texture, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, VS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { + + bokeh.push_constant.blur_far_active = p_dof_far; + bokeh.push_constant.blur_far_begin = p_dof_far_begin; + bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; + + bokeh.push_constant.blur_near_active = p_dof_near; + bokeh.push_constant.blur_near_begin = p_dof_near_begin; + bokeh.push_constant.blur_near_end = MAX(0, p_dof_near_begin - p_dof_near_size); + + bokeh.push_constant.size[0] = p_base_texture_size.x; + bokeh.push_constant.size[1] = p_base_texture_size.y; + + bokeh.push_constant.z_near = p_cam_znear; + bokeh.push_constant.z_far = p_cam_zfar; + bokeh.push_constant.orthogonal = p_cam_orthogonal; + bokeh.push_constant.blur_size = p_bokeh_size; + bokeh.push_constant.blur_scale = 0.5; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[BOKEH_GEN_BLUR_SIZE]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_texture), 1); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + int32_t x_groups = (p_base_texture_size.x - 1) / 8 + 1; + int32_t y_groups = (p_base_texture_size.y - 1) / 8 + 1; + + 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, bokeh.pipelines[BOKEH_GEN_BOKEH]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_bokeh_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_texture), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 2); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; + y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; + + 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, bokeh.pipelines[BOKEH_COMPOSITE]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_bokeh_texture), 1); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + x_groups = (p_base_texture_size.x - 1) / 8 + 1; + y_groups = (p_base_texture_size.y - 1) / 8 + 1; + + 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_end(); +} + RasterizerEffectsRD::RasterizerEffectsRD() { { @@ -511,6 +575,22 @@ RasterizerEffectsRD::RasterizerEffectsRD() { } } + { + // Initialize bokeh + Vector bokeh_modes; + bokeh_modes.push_back("\n#define MODE_GEN_BLUR_SIZE\n"); + bokeh_modes.push_back("\n#define MODE_GEN_BOKEH\n"); + bokeh_modes.push_back("\n#define MODE_COMPOSITE_BOKEH\n"); + + bokeh.shader.initialize(bokeh_modes); + + bokeh.shader_version = bokeh.shader.version_create(); + + for (int i = 0; i < BOKEH_MAX; i++) { + bokeh.pipelines[i] = RD::get_singleton()->compute_pipeline_create(bokeh.shader.version_get_shader(bokeh.shader_version, i)); + } + } + RD::SamplerState sampler; sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h index 1fee77e41c9..f050e298a98 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h @@ -34,11 +34,13 @@ #include "core/math/camera_matrix.h" #include "render_pipeline_vertex_format_cache_rd.h" #include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h" +#include "servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/copy.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/tonemap.glsl.gen.h" + #include "servers/visual_server.h" class RasterizerEffectsRD { @@ -221,6 +223,40 @@ class RasterizerEffectsRD { RenderPipelineVertexFormatCacheRD pipelines[COPY_MODE_MAX]; } copy; + struct BokehPushConstant { + uint32_t size[2]; + float z_far; + float z_near; + + uint32_t orthogonal; + float blur_size; + float blur_scale; + uint32_t pad; + + uint32_t blur_near_active; + float blur_near_begin; + float blur_near_end; + uint32_t blur_far_active; + float blur_far_begin; + float blur_far_end; + uint32_t pad2[2]; + }; + + enum BokehMode { + BOKEH_GEN_BLUR_SIZE, + BOKEH_GEN_BOKEH, + BOKEH_COMPOSITE, + BOKEH_MAX + }; + + struct Bokeh { + + BokehPushConstant push_constant; + BokehDofShaderRD shader; + RID shader_version; + RID pipelines[BOKEH_MAX]; + } bokeh; + RID default_sampler; RID default_mipmap_sampler; RID index_buffer; @@ -248,6 +284,7 @@ public: void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size); void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); + void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_bokeh_texture, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, VS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); struct TonemapSettings { diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp index 248a3efede1..3959986f3ac 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp @@ -535,30 +535,16 @@ void RasterizerSceneForwardRD::RenderBufferDataForward::clear() { RD::get_singleton()->free(color_fb); color_fb = RID(); } - - if (depth.is_valid()) { - RD::get_singleton()->free(depth); - depth = RID(); - } } -void RasterizerSceneForwardRD::RenderBufferDataForward::configure(RID p_color_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa) { +void RasterizerSceneForwardRD::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa) { clear(); width = p_width; height = p_height; color = p_color_buffer; - - { - RD::TextureFormat tf; - tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; - tf.width = p_width; - tf.height = p_height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - - depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } + depth = p_depth_buffer; { Vector fb; @@ -1625,7 +1611,7 @@ void RasterizerSceneForwardRD::_setup_lights(RID *p_light_cull_result, int p_lig } } -void RasterizerSceneForwardRD::_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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { +void RasterizerSceneForwardRD::_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) { RenderBufferDataForward *render_buffer = NULL; if (p_render_buffer.is_valid()) { @@ -1855,15 +1841,6 @@ void RasterizerSceneForwardRD::_render_scene(RID p_render_buffer, const Transfor } } #endif - if (p_reflection_probe.is_valid()) { - //was rendering a probe, so do no more - return; - } - - RENDER_TIMESTAMP("Tonemap"); - - render_buffers_post_process_and_tonemap(p_render_buffer, p_environment); - render_buffers_debug_draw(p_render_buffer, p_shadow_atlas); #if 0 _post_process(env, p_cam_projection); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h index 8517e4201c6..dd86c8ae272 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h @@ -195,7 +195,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD { int width, height; void clear(); - virtual void configure(RID p_color_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa); + virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa); ~RenderBufferDataForward(); }; @@ -538,7 +538,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD { void _draw_sky(RD::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, float p_alpha); 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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); + 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_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); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index a97c68a6193..e5b199261f2 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -1117,6 +1117,36 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { ////////////////////////////////////////////////// +RID RasterizerSceneRD::camera_effects_create() { + + return camera_effects_owner.make_rid(CameraEffects()); +} + +void RasterizerSceneRD::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, VS::DOFBlurQuality p_quality) { + CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + ERR_FAIL_COND(!camfx); + + camfx->dof_blur_far_enabled = p_far_enable; + camfx->dof_blur_far_distance = p_far_distance; + camfx->dof_blur_far_transition = p_far_transition; + + camfx->dof_blur_near_enabled = p_near_enable; + camfx->dof_blur_near_distance = p_near_distance; + camfx->dof_blur_near_transition = p_near_transition; + + camfx->dof_blur_quality = p_quality; + camfx->dof_blur_amount = p_amount; +} + +void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { + + CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + ERR_FAIL_COND(!camfx); + + camfx->override_exposure_enabled = p_enable; + camfx->override_exposure = p_exposure; +} + RID RasterizerSceneRD::light_instance_create(RID p_light) { RID li = light_instance_owner.make_rid(LightInstance()); @@ -2172,7 +2202,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { tf.width = rb->width; tf.height = rb->height; tf.type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; rb->blur[0].texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -2254,6 +2284,12 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { if (rb->texture.is_valid()) { RD::get_singleton()->free(rb->texture); + rb->texture = RID(); + } + + if (rb->depth_texture.is_valid()) { + RD::get_singleton()->free(rb->depth_texture); + rb->depth_texture = RID(); } for (int i = 0; i < 2; i++) { @@ -2279,16 +2315,27 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { } } -void RasterizerSceneRD::render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment) { +void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); Environent *env = environment_owner.getornull(p_environment); //glow (if enabled) + CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); bool can_use_effects = rb->width >= 8 && rb->height >= 8; + if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) { + + if (rb->blur[0].texture.is_null()) { + _allocate_blur_textures(rb); + } + + float bokeh_size = camfx->dof_blur_amount * 20.0; + storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[1].mipmaps[0].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, camfx->dof_blur_quality, p_projection.get_z_near(), p_projection.get_z_far(), p_projection.is_orthogonal()); + } + if (can_use_effects && env && env->auto_exposure) { if (rb->luminance.current.is_null()) { @@ -2388,7 +2435,7 @@ void RasterizerSceneRD::render_buffers_post_process_and_tonemap(RID p_render_buf storage->render_target_disable_clear_request(rb->render_target); } -void RasterizerSceneRD::render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) { +void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas) { RasterizerEffectsRD *effects = storage->get_effects(); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); @@ -2443,12 +2490,22 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->width; tf.height = rb->height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; rb->texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } - rb->data->configure(rb->texture, p_width, p_height, p_msaa); + { + RD::TextureFormat tf; + tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; + tf.width = p_width; + tf.height = p_height; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + } + + rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa); } int RasterizerSceneRD::get_roughness_layers() const { @@ -2465,7 +2522,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data( return rb->data; } -void RasterizerSceneRD::render_scene(RID p_render_buffers, 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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +void RasterizerSceneRD::render_scene(RID p_render_buffers, 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) { Color clear_color; if (p_render_buffers.is_valid()) { @@ -2476,7 +2533,14 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca clear_color = storage->get_default_clear_color(); } - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_environment, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); + + if (p_render_buffers.is_valid()) { + RENDER_TIMESTAMP("Tonemap"); + + _render_buffers_post_process_and_tonemap(p_render_buffers, p_environment, p_camera_effects, p_cam_projection); + _render_buffers_debug_draw(p_render_buffers, p_shadow_atlas); + } } void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { @@ -2670,6 +2734,9 @@ bool RasterizerSceneRD::free(RID p_rid) { } else if (environment_owner.owns(p_rid)) { //not much to delete, just free it environment_owner.free(p_rid); + } else if (camera_effects_owner.owns(p_rid)) { + //not much to delete, just free it + camera_effects_owner.free(p_rid); } else if (reflection_atlas_owner.owns(p_rid)) { reflection_atlas_set_size(p_rid, 0, 0); reflection_atlas_owner.free(p_rid); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h index ae4bcde4b4b..cfd11e9a38a 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h @@ -49,12 +49,12 @@ public: protected: struct RenderBufferData { - virtual void configure(RID p_color_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa) = 0; + virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa) = 0; virtual ~RenderBufferData() {} }; 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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 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_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; @@ -487,6 +487,28 @@ private: mutable RID_Owner environment_owner; + /* CAMERA EFFECTS */ + + struct CameraEffects { + + bool dof_blur_far_enabled = false; + float dof_blur_far_distance = 10; + float dof_blur_far_transition = 5; + + bool dof_blur_near_enabled = false; + float dof_blur_near_distance = 2; + float dof_blur_near_transition = 1; + + float dof_blur_amount = 0.1; + + VS::DOFBlurQuality dof_blur_quality = VS::DOF_BLUR_QUALITY_MEDIUM; + + bool override_exposure_enabled = false; + float override_exposure = 1; + }; + + mutable RID_Owner camera_effects_owner; + /* RENDER BUFFERS */ struct RenderBuffers { @@ -499,6 +521,7 @@ private: uint64_t auto_exposure_version = 1; RID texture; //main texture for rendering to, must be filled after done rendering + RID depth_texture; //main depth texture //built-in textures used for ping pong image processing and blurring struct Blur { @@ -529,6 +552,9 @@ private: void _allocate_blur_textures(RenderBuffers *rb); void _allocate_luminance_textures(RenderBuffers *rb); + void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas); + void _render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection); + uint64_t scene_pass = 0; uint64_t shadow_atlas_realloc_tolerance_msec = 500; @@ -607,8 +633,6 @@ public: bool is_environment(RID p_env) const; - void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {} - void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {} void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale); void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {} @@ -623,6 +647,11 @@ public: void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {} void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {} + virtual RID camera_effects_create(); + + 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, VS::DOFBlurQuality p_quality); + virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure); + 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); @@ -846,10 +875,8 @@ public: void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); - void render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas); - void render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment); - void render_scene(RID p_render_buffers, 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_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + void render_scene(RID p_render_buffers, 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_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); diff --git a/servers/visual/rasterizer_rd/shaders/SCsub b/servers/visual/rasterizer_rd/shaders/SCsub index 7d5e88b0abe..194d7d6c0ea 100644 --- a/servers/visual/rasterizer_rd/shaders/SCsub +++ b/servers/visual/rasterizer_rd/shaders/SCsub @@ -15,5 +15,4 @@ if 'RD_GLSL' in env['BUILDERS']: env.RD_GLSL('giprobe_debug.glsl'); env.RD_GLSL('giprobe_sdf.glsl'); env.RD_GLSL('luminance_reduce.glsl'); - - + env.RD_GLSL('bokeh_dof.glsl'); diff --git a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl new file mode 100644 index 00000000000..7042b72d2a2 --- /dev/null +++ b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl @@ -0,0 +1,141 @@ +/* clang-format off */ +[compute] +/* clang-format on */ +#version 450 + +VERSION_DEFINES + +#define BLOCK_SIZE 8 + +layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; + + +#ifdef MODE_GEN_BLUR_SIZE +layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; +layout(set = 1, binding = 0) uniform sampler2D source_depth; +#endif + +#ifdef MODE_GEN_BOKEH +layout(set = 2, binding = 0) uniform sampler2D color_texture; +layout(set = 1, binding = 0) uniform sampler2D source_depth; +layout(rgba16f, set = 0, binding = 0) uniform restrict writeonly image2D bokeh_image; +#endif + +#ifdef MODE_COMPOSITE_BOKEH +layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; +layout(set = 1, binding = 0) uniform sampler2D source_bokeh; +#endif + + + + +layout(push_constant, binding = 1, std430) uniform Params { + ivec2 size; + float z_far; + float z_near; + + bool orthogonal; + float blur_size; + float blur_scale; + uint pad; + + bool blur_near_active; + float blur_near_begin; + float blur_near_end; + bool blur_far_active; + float blur_far_begin; + float blur_far_end; + uint pad2[2]; + +} params; + +#ifndef MODE_COMPOSITE_BOKEH + +float get_depth_at_pos(vec2 uv) { + float depth = textureLod(source_depth,uv,0.0).x; + if (params.orthogonal) { + depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; + } else { + depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + } + return depth; +} + +float get_blur_size(float depth) { + + if (params.blur_near_active && depth < params.blur_near_begin) { + return smoothstep(params.blur_near_end,params.blur_near_begin,depth) * params.blur_size; + } + + if (params.blur_far_active && depth > params.blur_far_begin) { + return smoothstep(params.blur_far_begin,params.blur_far_end,depth) * params.blur_size; + } + + return 0.0; +} + +#endif + +const float GOLDEN_ANGLE = 2.39996323; + +void main() { + + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + + if (any(greaterThan(pos,params.size))) { //too large, do nothing + return; + } + + vec2 uv = vec2(pos) / vec2(params.size); + +#ifdef MODE_GEN_BLUR_SIZE + //precompute size in alpha channel + float depth = get_depth_at_pos(uv); + float size = get_blur_size(depth); + + vec4 color = imageLoad(color_image,pos); + color.a = size; + imageStore(color_image,pos,color); +#endif + +#ifdef MODE_GEN_BOKEH + + float depth = get_depth_at_pos(uv); + float size = get_blur_size(depth); + vec4 color = texture(color_texture,uv); + float accum = 1.0; + float radius = params.blur_scale; + vec2 pixel_size = 1.0/vec2(params.size); + + for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) { + + vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; + vec4 sample_color = texture(color_texture, suv); + float sample_depth = get_depth_at_pos(suv); + if (sample_depth > depth) { + sample_color.a = clamp(sample_color.a, 0.0, size*2.0); + } + + float m = smoothstep(radius-0.5, radius+0.5, sample_color.a); + color += mix(color/accum, sample_color, m); + accum += 1.0; + radius += params.blur_size/radius; + } + + color /= accum; + + imageStore(bokeh_image,pos,color); +#endif + +#ifdef MODE_COMPOSITE_BOKEH + + vec4 color = imageLoad(color_image,pos); + vec4 bokeh = texture(source_bokeh,uv); + if (max(color.a,bokeh.a) > 0.5) { //there is some blur in this pixel, so use bokeh + color = bokeh; + } + color.a=0; //reset alpha + imageStore(color_image,pos,color); +#endif + +} diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index cc80a96efc8..f0811f5b548 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -445,6 +445,7 @@ public: BIND2(camera_set_transform, RID, const Transform &) BIND2(camera_set_cull_mask, RID, uint32_t) BIND2(camera_set_environment, RID, RID) + BIND2(camera_set_camera_effects, RID, RID) BIND2(camera_set_use_vertical_aspect, RID, bool) #undef BINDBASE @@ -526,8 +527,6 @@ public: BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool) BIND13(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float) - BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality) - BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality) BIND12(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float, bool) BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) @@ -538,6 +537,13 @@ public: BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) + /* CAMERA EFFECTS */ + + BIND0R(RID, camera_effects_create) + + BIND9(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float, DOFBlurQuality) + BIND3(camera_effects_set_custom_exposure, RID, bool, float) + /* SCENARIO API */ #undef BINDBASE @@ -547,6 +553,7 @@ public: BIND2(scenario_set_debug, RID, ScenarioDebugMode) BIND2(scenario_set_environment, RID, RID) + BIND2(scenario_set_camera_effects, RID, RID) BIND2(scenario_set_fallback_environment, RID, RID) /* INSTANCING API */ diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 61e6755ee27..0df8853f127 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -96,6 +96,13 @@ void VisualServerScene::camera_set_environment(RID p_camera, RID p_env) { camera->env = p_env; } +void VisualServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) { + + Camera *camera = camera_owner.getornull(p_camera); + ERR_FAIL_COND(!camera); + camera->effects = p_fx; +} + void VisualServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { Camera *camera = camera_owner.getornull(p_camera); @@ -295,6 +302,13 @@ void VisualServerScene::scenario_set_environment(RID p_scenario, RID p_environme scenario->environment = p_environment; } +void VisualServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { + + Scenario *scenario = scenario_owner.getornull(p_scenario); + ERR_FAIL_COND(!scenario); + scenario->camera_effects = p_camera_effects; +} + void VisualServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { Scenario *scenario = scenario_owner.getornull(p_scenario); @@ -1779,8 +1793,8 @@ void VisualServerScene::render_camera(RID p_render_buffers, RID p_camera, RID p_ } break; } - _prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); - _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, camera->env, p_scenario, p_shadow_atlas, RID(), -1); + _prepare_scene(camera->transform, camera_matrix, ortho, 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 } @@ -1858,17 +1872,17 @@ void VisualServerScene::render_camera(RID p_render_buffers, Ref & 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->visible_layers, p_scenario, p_shadow_atlas, RID()); + _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) { // For mono render, prepare as per usual - _prepare_scene(cam_transform, camera_matrix, false, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + _prepare_scene(cam_transform, camera_matrix, 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, p_scenario, p_shadow_atlas, RID(), -1); + _render_scene(p_render_buffers, cam_transform, camera_matrix, false, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); }; -void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { +void VisualServerScene::_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) { // 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 @@ -2207,7 +2221,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca } } -void VisualServerScene::_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_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +void VisualServerScene::_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) { Scenario *scenario = scenario_owner.getornull(p_scenario); @@ -2221,10 +2235,16 @@ void VisualServerScene::_render_scene(RID p_render_buffers, const Transform p_ca else environment = scenario->fallback_environment; + RID camera_effects; + if (p_force_camera_effects.is_valid()) { + camera_effects = p_force_camera_effects; + } else { + camera_effects = scenario->camera_effects; + } /* PROCESS GEOMETRY AND DRAW SCENE */ RENDER_TIMESTAMP("Render Scene "); - VSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, environment, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); + VSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } void VisualServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { @@ -2239,7 +2259,7 @@ void VisualServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, else environment = scenario->fallback_environment; RENDER_TIMESTAMP("Render Empty Scene "); - VSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + VSG::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); #endif } @@ -2304,8 +2324,8 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int } RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); - _prepare_scene(xform, cm, false, RID(), VSG::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(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step); + _prepare_scene(xform, cm, false, RID(), RID(), VSG::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 { //do roughness postprocess step until it believes it's done diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 3034d06d6b7..a811e8b27a8 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -74,6 +74,7 @@ public: uint32_t visible_layers; bool vaspect; RID env; + RID effects; Transform transform; @@ -99,6 +100,7 @@ public: virtual void camera_set_transform(RID p_camera, const Transform &p_transform); virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers); virtual void camera_set_environment(RID p_camera, RID p_env); + virtual void camera_set_camera_effects(RID p_camera, RID p_fx); virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable); /* SCENARIO API */ @@ -115,6 +117,7 @@ public: List directional_lights; RID environment; RID fallback_environment; + RID camera_effects; RID reflection_probe_shadow_atlas; RID reflection_atlas; @@ -132,6 +135,7 @@ public: virtual void scenario_set_debug(RID p_scenario, VS::ScenarioDebugMode p_debug_mode); virtual void scenario_set_environment(RID p_scenario, RID p_environment); + virtual void scenario_set_camera_effects(RID p_scenario, RID p_fx); virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment); virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count); @@ -418,8 +422,8 @@ public: _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); 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, 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_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + 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 _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); diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index 4bce8eb942f..9a5e5e896ad 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -153,6 +153,7 @@ void VisualServerWrapMT::finish() { camera_free_cached_ids(); viewport_free_cached_ids(); environment_free_cached_ids(); + camera_effects_free_cached_ids(); scenario_free_cached_ids(); instance_free_cached_ids(); canvas_free_cached_ids(); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 201d60cb409..0d40a4e1eae 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -363,6 +363,7 @@ public: FUNC2(camera_set_transform, RID, const Transform &) FUNC2(camera_set_cull_mask, RID, uint32_t) FUNC2(camera_set_environment, RID, RID) + FUNC2(camera_set_camera_effects, RID, RID) FUNC2(camera_set_use_vertical_aspect, RID, bool) /* VIEWPORT TARGET API */ @@ -440,8 +441,6 @@ public: FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool) FUNC13(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, const Color &, EnvironmentSSAOQuality, EnvironmentSSAOBlur, float) - FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality) - FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality) FUNC12(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float, bool) FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) @@ -452,10 +451,16 @@ public: FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float) + FUNCRID(camera_effects) + + FUNC9(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float, DOFBlurQuality) + FUNC3(camera_effects_set_custom_exposure, RID, bool, float) + FUNCRID(scenario) FUNC2(scenario_set_debug, RID, ScenarioDebugMode) FUNC2(scenario_set_environment, RID, RID) + FUNC2(scenario_set_camera_effects, RID, RID) FUNC2(scenario_set_fallback_environment, RID, RID) /* INSTANCING API */ @@ -624,8 +629,12 @@ public: FUNC1(set_debug_generate_wireframes, bool) - virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); } - virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); } + virtual bool has_feature(Features p_feature) const { + return visual_server->has_feature(p_feature); + } + virtual bool has_os_feature(const String &p_feature) const { + return visual_server->has_os_feature(p_feature); + } FUNC1(call_set_use_vsync, bool) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 5092b1e6931..9a9775508f2 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1821,8 +1821,6 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_set_bg_energy", "env", "energy"), &VisualServer::environment_set_bg_energy); ClassDB::bind_method(D_METHOD("environment_set_canvas_max_layer", "env", "max_layer"), &VisualServer::environment_set_canvas_max_layer); ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "energy", "sky_contibution"), &VisualServer::environment_set_ambient_light, DEFVAL(1.0), DEFVAL(0.0)); - ClassDB::bind_method(D_METHOD("environment_set_dof_blur_near", "env", "enable", "distance", "transition", "far_amount", "quality"), &VisualServer::environment_set_dof_blur_near); - ClassDB::bind_method(D_METHOD("environment_set_dof_blur_far", "env", "enable", "distance", "transition", "far_amount", "quality"), &VisualServer::environment_set_dof_blur_far); ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "level_flags", "intensity", "strength", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap", "bicubic_upscale"), &VisualServer::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"), &VisualServer::environment_set_tonemap); ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &VisualServer::environment_set_adjustment); @@ -2177,9 +2175,9 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_DISABLED); BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_SKY); - BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_LOW); - BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_HIGH); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN); diff --git a/servers/visual_server.h b/servers/visual_server.h index da6e98854e5..c61e9840078 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -565,6 +565,7 @@ public: virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0; virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0; virtual void camera_set_environment(RID p_camera, RID p_env) = 0; + virtual void camera_set_camera_effects(RID p_camera, RID p_camera_effects) = 0; virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0; /* @@ -723,19 +724,6 @@ public: virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; #endif - //set default SSAO options - //set default SSR options - //set default SSSSS options - - enum EnvironmentDOFBlurQuality { - ENV_DOF_BLUR_QUALITY_LOW, - ENV_DOF_BLUR_QUALITY_MEDIUM, - ENV_DOF_BLUR_QUALITY_HIGH, - }; - - virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, EnvironmentDOFBlurQuality p_quality) = 0; - virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, EnvironmentDOFBlurQuality p_quality) = 0; - enum EnvironmentGlowBlendMode { GLOW_BLEND_MODE_ADDITIVE, GLOW_BLEND_MODE_SCREEN, @@ -776,6 +764,19 @@ public: virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + /* CAMERA EFFECTS */ + + virtual RID camera_effects_create() = 0; + + enum DOFBlurQuality { + DOF_BLUR_QUALITY_LOW, + DOF_BLUR_QUALITY_MEDIUM, + DOF_BLUR_QUALITY_HIGH, + }; + + 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, DOFBlurQuality p_quality) = 0; + virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + /* SCENARIO API */ virtual RID scenario_create() = 0; @@ -791,6 +792,7 @@ public: virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0; virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0; + virtual void scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) = 0; /* INSTANCING API */ @@ -1119,11 +1121,11 @@ VARIANT_ENUM_CAST(VisualServer::ParticlesDrawOrder); VARIANT_ENUM_CAST(VisualServer::EnvironmentBG); VARIANT_ENUM_CAST(VisualServer::EnvironmentAmbientSource); VARIANT_ENUM_CAST(VisualServer::EnvironmentReflectionSource); -VARIANT_ENUM_CAST(VisualServer::EnvironmentDOFBlurQuality); VARIANT_ENUM_CAST(VisualServer::EnvironmentGlowBlendMode); VARIANT_ENUM_CAST(VisualServer::EnvironmentToneMapper); VARIANT_ENUM_CAST(VisualServer::EnvironmentSSAOQuality); VARIANT_ENUM_CAST(VisualServer::EnvironmentSSAOBlur); +VARIANT_ENUM_CAST(VisualServer::DOFBlurQuality); VARIANT_ENUM_CAST(VisualServer::InstanceFlags); VARIANT_ENUM_CAST(VisualServer::ShadowCastingSetting); VARIANT_ENUM_CAST(VisualServer::CanvasItemTextureFilter);