mirror of
https://github.com/godotengine/godot.git
synced 2025-02-16 15:50:45 +00:00
DOF fully implemented, can be edited on the fly.
This commit is contained in:
parent
c05da81268
commit
f8b5c5f063
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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() {
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user