diff options
author | Juan Linietsky <reduzio@gmail.com> | 2020-01-15 21:23:21 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 12:15:26 +0100 |
commit | f8b5c5f0631ac629c00795b5f3f8775c32a0368b (patch) | |
tree | f58d19c2a3480497ff37fe657dfcc76c45d556da | |
parent | c05da81268ca754493e59f359ba08a60ec7092bf (diff) | |
download | redot-engine-f8b5c5f0631ac629c00795b5f3f8775c32a0368b.tar.gz |
DOF fully implemented, can be edited on the fly.
-rw-r--r-- | editor/editor_node.cpp | 8 | ||||
-rw-r--r-- | scene/resources/environment.cpp | 37 | ||||
-rw-r--r-- | scene/resources/environment.h | 13 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 5 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp | 145 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_effects_rd.h | 16 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp | 21 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/rasterizer_scene_rd.h | 11 | ||||
-rw-r--r-- | servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl | 155 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 5 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 5 | ||||
-rw-r--r-- | servers/visual_server.cpp | 10 | ||||
-rw-r--r-- | servers/visual_server.h | 13 |
13 files changed, 343 insertions, 101 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e7cda66d3c..2fb417ad49 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -343,7 +343,7 @@ void EditorNode::_notification(int p_what) { scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"))); - { + { //TODO should only happen on settings changed int current_filter = GLOBAL_GET("rendering/canvas_textures/default_texture_filter"); if (current_filter != scene_root->get_default_canvas_item_texture_filter()) { Viewport::DefaultCanvasItemTextureFilter tf = (Viewport::DefaultCanvasItemTextureFilter)current_filter; @@ -354,6 +354,12 @@ void EditorNode::_notification(int p_what) { Viewport::DefaultCanvasItemTextureRepeat tr = (Viewport::DefaultCanvasItemTextureRepeat)current_repeat; scene_root->set_default_canvas_item_texture_repeat(tr); } + + VS::DOFBokehShape dof_shape = VS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape"))); + VS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape); + VS::DOFBlurQuality dof_quality = VS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))); + bool dof_jitter = GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter"); + VS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); } ResourceImporterTexture::get_singleton()->update_imports(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index aeca10ab56..30ba8762dd 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1291,7 +1291,7 @@ Environment::~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)); + 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); } bool CameraEffects::is_dof_blur_far_enabled() const { @@ -1302,7 +1302,7 @@ bool CameraEffects::is_dof_blur_far_enabled() const { 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)); + 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); } float CameraEffects::get_dof_blur_far_distance() const { @@ -1312,7 +1312,7 @@ float CameraEffects::get_dof_blur_far_distance() const { 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)); + 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); } float CameraEffects::get_dof_blur_far_transition() const { @@ -1322,7 +1322,7 @@ float CameraEffects::get_dof_blur_far_transition() const { 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)); + 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); _change_notify(); } @@ -1334,7 +1334,7 @@ bool CameraEffects::is_dof_blur_near_enabled() const { 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)); + 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); } float CameraEffects::get_dof_blur_near_distance() const { @@ -1345,7 +1345,7 @@ float CameraEffects::get_dof_blur_near_distance() const { 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)); + 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); } float CameraEffects::get_dof_blur_near_transition() const { @@ -1356,24 +1356,13 @@ float CameraEffects::get_dof_blur_near_transition() const { 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)); + 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); } 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); @@ -1419,9 +1408,6 @@ void CameraEffects::_bind_methods() { 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); @@ -1436,14 +1422,9 @@ void CameraEffects::_bind_methods() { 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() { @@ -1458,9 +1439,7 @@ CameraEffects::CameraEffects() { 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 + set_dof_blur_amount(0.1); override_exposure_enabled = false; set_override_exposure(1.0); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 530fa727b1..2e799d8a86 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -398,13 +398,6 @@ 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; @@ -417,7 +410,6 @@ private: float dof_blur_near_transition; float dof_blur_amount; - DOFBlurQuality dof_blur_quality; bool override_exposure_enabled; float override_exposure; @@ -447,9 +439,6 @@ public: 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; @@ -462,6 +451,4 @@ public: ~CameraEffects(); }; -VARIANT_ENUM_CAST(CameraEffects::DOFBlurQuality) - #endif // ENVIRONMENT_H diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 04643354ca..0bfd323ec0 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -95,7 +95,10 @@ public: 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_dof_blur_quality(VS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; + virtual void camera_effects_set_dof_blur_bokeh_shape(VS::DOFBokehShape p_shape) = 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) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; struct InstanceBase; diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp index ff3f6f294b..111ad06f5b 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "rasterizer_effects_rd.h" +#include "core/os/os.h" static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) { p_array[0] = p_basis.elements[0][0]; @@ -406,7 +407,7 @@ 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) { +void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, 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, VisualServer::DOFBokehShape p_bokeh_shape, VS::DOFBlurQuality p_quality, bool p_use_jitter, 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; @@ -415,15 +416,25 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con 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.use_jitter = p_use_jitter; + bokeh.push_constant.jitter_seed = Math::randf() * 1000.0; 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.second_pass = false; + bokeh.push_constant.half_size = false; + bokeh.push_constant.blur_scale = 0.5; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + /* FIRST PASS */ + // The alpha channel of the source color texture is filled with the expected circle size + // If used for DOF far, the size is positive, if used for near, its negative. + 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); @@ -439,36 +450,122 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con 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]); + if (p_bokeh_shape == VS::DOF_BOKEH_BOX || p_bokeh_shape == VS::DOF_BOKEH_HEXAGON) { - 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); + //second pass + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[p_bokeh_shape == VS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL]); - x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; - y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; - bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; - bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; + static const int quality_samples[4] = { 6, 12, 12, 24 }; - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + bokeh.push_constant.steps = quality_samples[p_quality]; - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); + if (p_quality == VS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == VS::DOF_BLUR_QUALITY_LOW) { + //box and hexagon are more or less the same, and they can work in either half (very low and low quality) or full (medium and high quality_ sizes) - 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_halfsize_texture1), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); - 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); + x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; + y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; + bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + bokeh.push_constant.blur_size *= 0.5; - x_groups = (p_base_texture_size.x - 1) / 8 + 1; - y_groups = (p_base_texture_size.y - 1) / 8 + 1; - bokeh.push_constant.size[0] = p_base_texture_size.x; - bokeh.push_constant.size[1] = p_base_texture_size.y; + } else { + //medium and high quality use full size + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_secondary_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); + } - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - 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_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + //third pass + bokeh.push_constant.second_pass = true; + + if (p_quality == VS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == VS::DOF_BLUR_QUALITY_LOW) { + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture2), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1); + } else { + 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_secondary_texture), 1); + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + if (p_quality == VS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == VS::DOF_BLUR_QUALITY_LOW) { + //forth pass, upscale for low quality + + 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_halfsize_texture2), 1); + + x_groups = (p_base_texture_size.x - 1) / 8 + 1; + y_groups = (p_base_texture_size.y - 1) / 8 + 1; + bokeh.push_constant.size[0] = p_base_texture_size.x; + bokeh.push_constant.size[1] = p_base_texture_size.y; + bokeh.push_constant.half_size = false; + bokeh.push_constant.second_pass = false; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + } + } else { + //circle + + //second pass + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[BOKEH_GEN_BOKEH_CIRCULAR]); + + static const float quality_scale[4] = { 8.0, 4.0, 1.0, 0.5 }; + + bokeh.push_constant.steps = 0; + bokeh.push_constant.blur_scale = quality_scale[p_quality]; + + //circle always runs in half size, otherwise too expensive + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); + + x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; + y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; + bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + //circle is just one pass, then upscale + + // upscale + + 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_halfsize_texture1), 1); + + x_groups = (p_base_texture_size.x - 1) / 8 + 1; + y_groups = (p_base_texture_size.y - 1) / 8 + 1; + bokeh.push_constant.size[0] = p_base_texture_size.x; + bokeh.push_constant.size[1] = p_base_texture_size.y; + bokeh.push_constant.half_size = false; + bokeh.push_constant.second_pass = false; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + } RD::get_singleton()->compute_list_end(); } @@ -582,7 +679,9 @@ RasterizerEffectsRD::RasterizerEffectsRD() { // Initialize bokeh Vector<String> 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_BOKEH_BOX\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_HEXAGONAL\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_CIRCULAR\n"); bokeh_modes.push_back("\n#define MODE_COMPOSITE_BOKEH\n"); bokeh.shader.initialize(bokeh_modes); diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h index f050e298a9..77779f2c84 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h @@ -231,20 +231,28 @@ class RasterizerEffectsRD { uint32_t orthogonal; float blur_size; float blur_scale; - uint32_t pad; + uint32_t steps; 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]; + uint32_t second_pass; + uint32_t half_size; + + uint32_t use_jitter; + float jitter_seed; + uint32_t pad[2]; }; enum BokehMode { BOKEH_GEN_BLUR_SIZE, - BOKEH_GEN_BOKEH, + BOKEH_GEN_BOKEH_BOX, + BOKEH_GEN_BOKEH_HEXAGONAL, + BOKEH_GEN_BOKEH_CIRCULAR, BOKEH_COMPOSITE, BOKEH_MAX }; @@ -284,7 +292,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<RID> 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); + void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, 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::DOFBokehShape p_bokeh_shape, VS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); struct TonemapSettings { diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index e5b199261f..c9f3f696eb 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -1122,7 +1122,18 @@ 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) { +void RasterizerSceneRD::camera_effects_set_dof_blur_quality(VS::DOFBlurQuality p_quality, bool p_use_jitter) { + + dof_blur_quality = p_quality; + dof_blur_use_jitter = p_use_jitter; +} + +void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(VS::DOFBokehShape p_shape) { + + dof_blur_bokeh_shape = p_shape; +} + +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) { CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); ERR_FAIL_COND(!camfx); @@ -1134,7 +1145,6 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p 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; } @@ -2332,8 +2342,8 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu _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()); + float bokeh_size = camfx->dof_blur_amount * 64.0; + storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].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, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_projection.get_z_near(), p_projection.get_z_far(), p_projection.is_orthogonal()); } if (can_use_effects && env && env->auto_exposure) { @@ -2908,6 +2918,9 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { giprobe_debug_shader_version_pipelines[i].setup(giprobe_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); } } + + camera_effects_set_dof_blur_bokeh_shape(VS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape")))); + camera_effects_set_dof_blur_quality(VS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter")); } RasterizerSceneRD::~RasterizerSceneRD() { diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h index cfd11e9a38..c6d13e4d34 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h @@ -501,12 +501,14 @@ private: 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; }; + VS::DOFBlurQuality dof_blur_quality = VS::DOF_BLUR_QUALITY_MEDIUM; + VS::DOFBokehShape dof_blur_bokeh_shape = VS::DOF_BOKEH_HEXAGON; + bool dof_blur_use_jitter = false; + mutable RID_Owner<CameraEffects> camera_effects_owner; /* RENDER BUFFERS */ @@ -649,7 +651,10 @@ public: 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_dof_blur_quality(VS::DOFBlurQuality p_quality, bool p_use_jitter); + virtual void camera_effects_set_dof_blur_bokeh_shape(VS::DOFBokehShape p_shape); + + 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); virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure); RID light_instance_create(RID p_light); diff --git a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl index 83e77a19fc..e4508d3c8c 100644 --- a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl +++ b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl @@ -15,9 +15,8 @@ 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; +#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) || defined(MODE_BOKEH_CIRCULAR) +layout(set = 1, binding = 0) uniform sampler2D color_texture; layout(rgba16f, set = 0, binding = 0) uniform restrict writeonly image2D bokeh_image; #endif @@ -26,7 +25,7 @@ layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; layout(set = 1, binding = 0) uniform sampler2D source_bokeh; #endif - +// based on https://www.shadertoy.com/view/Xd3GDl layout(push_constant, binding = 1, std430) uniform Params { @@ -37,19 +36,27 @@ layout(push_constant, binding = 1, std430) uniform Params { bool orthogonal; float blur_size; float blur_scale; - uint pad; + int blur_steps; 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]; + bool second_pass; + bool half_size; + bool use_jitter; + float jitter_seed; + uint pad[2]; } params; -#ifndef MODE_COMPOSITE_BOKEH +//used to work around downsampling filter +#define DEPTH_GAP 0.0 + +#ifdef MODE_GEN_BLUR_SIZE float get_depth_at_pos(vec2 uv) { float depth = textureLod(source_depth,uv,0.0).x; @@ -61,14 +68,15 @@ float get_depth_at_pos(vec2 uv) { return depth; } + float get_blur_size(float depth) { if (params.blur_near_active && depth < params.blur_near_begin) { - return (1.0 - smoothstep(params.blur_near_end,params.blur_near_begin,depth) ) * params.blur_size; + return - (1.0 - smoothstep(params.blur_near_end,params.blur_near_begin,depth) ) * params.blur_size - DEPTH_GAP; //near blur is negative } 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 smoothstep(params.blur_far_begin,params.blur_far_end,depth) * params.blur_size + DEPTH_GAP; } return 0.0; @@ -78,6 +86,63 @@ float get_blur_size(float depth) { const float GOLDEN_ANGLE = 2.39996323; + +//note: uniform pdf rand [0;1[ +float hash12n(vec2 p) { + p = fract(p * vec2(5.3987, 5.4421)); + p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); + return fract(p.x * p.y * 95.4307); +} + +#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) + +vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { + + dir *= pixel_size; + vec4 color = texture(color_texture,uv); + + vec4 accum = color; + float total = 1.0; + + float blur_scale = params.blur_size/float(params.blur_steps); + + if (params.use_jitter) { + uv += dir * (hash12n(uv+params.jitter_seed) - 0.5); + } + + for(int i=-params.blur_steps;i<=params.blur_steps;i++) { + + if (i==0) { + continue; + } + float radius = float(i) * blur_scale; + vec2 suv = uv + dir * radius; + radius = abs(radius); + + vec4 sample_color = texture(color_texture, suv); + float limit; + + if (sample_color.a < color.a) { + limit = abs(sample_color.a); + } else { + limit = abs(color.a); + } + + limit -= DEPTH_GAP; + + float m = smoothstep(radius-0.5, radius+0.5, limit); + + accum += mix(color, sample_color, m ); + + total += 1.0; + + } + + return accum / total; +} + +#endif + void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); @@ -100,14 +165,61 @@ void main() { imageStore(color_image,pos,color); #endif -#ifdef MODE_GEN_BOKEH +#ifdef MODE_BOKEH_BOX - pixel_size*=0.5; //resolution is doubled + //pixel_size*=0.5; //resolution is doubled + if (params.second_pass || !params.half_size) { + uv+=pixel_size * 0.5; //half pixel to read centers + } else { + uv+=pixel_size * 0.25; //half pixel to read centers from full res + } + + vec2 dir = (params.second_pass ? vec2(0.0,1.0) : vec2(1.0,0.0)); + + vec4 color = weighted_filter_dir(dir,uv,pixel_size); + + imageStore(bokeh_image,pos,color); + +#endif + +#ifdef MODE_BOKEH_HEXAGONAL + + + //pixel_size*=0.5; //resolution is doubled + if (params.second_pass || !params.half_size) { + uv+=pixel_size * 0.5; //half pixel to read centers + } else { + uv+=pixel_size * 0.25; //half pixel to read centers from full res + } + + vec2 dir = (params.second_pass ? normalize(vec2( 1.0, 0.577350269189626 )) : vec2(0.0,1.0)); + + vec4 color = weighted_filter_dir(dir,uv,pixel_size); + + if (params.second_pass) { + dir = normalize(vec2( -1.0, 0.577350269189626 )); + + vec4 color2 = weighted_filter_dir(dir,uv,pixel_size); + + color.rgb = min(color.rgb,color2.rgb); + color.a = (color.a + color2.a) * 0.5; + } + + imageStore(bokeh_image,pos,color); + + + +#endif + + +#ifdef MODE_BOKEH_CIRCULAR + + if (params.half_size) { + pixel_size*=0.5; //resolution is doubled + } uv+=pixel_size * 0.5; //half pixel to read centers - 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; @@ -116,12 +228,12 @@ void main() { 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 sample_size = abs(sample_color.a); + if (sample_color.a > color.a) { + sample_size = clamp(sample_size, 0.0, abs(color.a)*2.0); } - float m = smoothstep(radius-0.5, radius+0.5, sample_color.a); + float m = smoothstep(radius-0.5, radius+0.5, sample_size); color += mix(color/accum, sample_color, m); accum += 1.0; radius += params.blur_scale/radius; @@ -138,7 +250,14 @@ void main() { vec4 color = imageLoad(color_image,pos); vec4 bokeh = texture(source_bokeh,uv); - color.rgb = mix(color.rgb,bokeh.rgb,min(1.0,max(color.a,bokeh.a))); //blend between hires and lowres + float mix_amount; + if (bokeh.a < color.a) { + mix_amount = min(1.0,max(0.0,max(abs(color.a),abs(bokeh.a))-DEPTH_GAP)); + } else { + mix_amount = min(1.0,max(0.0,abs(color.a)-DEPTH_GAP)); + } + + color.rgb = mix(color.rgb,bokeh.rgb,mix_amount); //blend between hires and lowres color.a=0; //reset alpha imageStore(color_image,pos,color); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index f0811f5b54..51ce440320 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -541,7 +541,10 @@ public: BIND0R(RID, camera_effects_create) - BIND9(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float, DOFBlurQuality) + BIND2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) + BIND1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) + + BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) BIND3(camera_effects_set_custom_exposure, RID, bool, float) /* SCENARIO API */ diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 0d40a4e1ea..ddb0f8e76c 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -453,7 +453,10 @@ public: FUNCRID(camera_effects) - FUNC9(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float, DOFBlurQuality) + FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) + FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) + + FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) FUNC3(camera_effects_set_custom_exposure, RID, bool, float) FUNCRID(scenario) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 9a9775508f..60ea292d8f 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2287,7 +2287,7 @@ VisualServer::VisualServer() { 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,PCF5,PCF13")); + 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)")); GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 6); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true); @@ -2302,7 +2302,7 @@ VisualServer::VisualServer() { 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),Medium (4 cones), High (6 cones)")); + 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)")); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true); @@ -2316,6 +2316,12 @@ VisualServer::VisualServer() { GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); 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)")); + 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)")); + GLOBAL_DEF("rendering/quality/filters/depth_of_field_use_jitter", false); } VisualServer::~VisualServer() { diff --git a/servers/visual_server.h b/servers/visual_server.h index c61e984007..dde8025eb2 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -769,12 +769,23 @@ public: virtual RID camera_effects_create() = 0; enum DOFBlurQuality { + DOF_BLUR_QUALITY_VERY_LOW, 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_dof_blur_quality(DOFBlurQuality p_quality, bool p_use_jitter) = 0; + + enum DOFBokehShape { + DOF_BOKEH_BOX, + DOF_BOKEH_HEXAGON, + DOF_BOKEH_CIRCLE + }; + + virtual void camera_effects_set_dof_blur_bokeh_shape(DOFBokehShape p_shape) = 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) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; /* SCENARIO API */ |