diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 88086d0552ad..540157d6e1f2 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -1198,6 +1198,9 @@ ProjectSettings::ProjectSettings() {
custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects");
+ GLOBAL_DEF("rendering/quality/filters/sharpen_intensity", 0.0);
+ custom_prop_info["rendering/quality/filters/sharpen_intensity"] = PropertyInfo(Variant::REAL, "rendering/quality/filters/sharpen_intensity", PROPERTY_HINT_RANGE, "0,1");
+
GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1");
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 755a5a88c9d6..3e7d1be277f7 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1294,13 +1294,16 @@
Sets the number of MSAA samples to use. MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware.
[b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
+
+ If set to a value greater than [code]0.0[/code], contrast-adaptive sharpening will be applied to the 3D viewport. This has a low performance cost and can be used to recover some of the sharpness lost from using FXAA. Values around [code]0.5[/code] generally give the best results. See also [member rendering/quality/filters/use_fxaa].
+
If [code]true[/code], uses a fast post-processing filter to make banding significantly less visible. In some cases, debanding may introduce a slightly noticeable dithering pattern. It's recommended to enable debanding only when actually needed since the dithering pattern will make lossless-compressed screenshots larger.
[b]Note:[/b] Only available on the GLES3 backend. [member rendering/quality/depth/hdr] must also be [code]true[/code] for debanding to be effective.
[b]Note:[/b] There are known issues with debanding breaking rendering on mobile platforms. Due to this, it is recommended to leave this option disabled when targeting mobile platforms.
- Enables FXAA in the root Viewport. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K.
+ Enables FXAA in the root Viewport. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K. Some of the lost sharpness can be recovered by enabling contrast-adaptive sharpening (see [member rendering/quality/filters/sharpen_intensity]).
If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 6d8206e5972c..84b058f909cb 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -210,7 +210,7 @@
If [code]true[/code], the viewport will disable 3D rendering. For actual disabling use [code]usage[/code].
- Enables fast approximate antialiasing. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K.
+ Enables fast approximate antialiasing. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K. Some of the lost sharpness can be recovered by enabling contrast-adaptive sharpening (see [member sharpen_intensity]).
The global canvas transform of the viewport. The canvas transform is relative to this.
@@ -268,6 +268,9 @@
The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-created viewports default to a value of 0, this value must be set above 0 manually.
+
+ If set to a value greater than [code]0.0[/code], contrast-adaptive sharpening will be applied to the 3D viewport. This has a low performance cost and can be used to recover some of the sharpness lost from using FXAA. Values around [code]0.5[/code] generally give the best results. See also [member fxaa].
+
The width and height of viewport.
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index 767cb8e2ea5f..fa257ea16873 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -3046,6 +3046,17 @@
Sets the size of the shadow atlas's images (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
+
+
+
+
+
+
+
+
+ Sets the sharpening [code]intensity[/code] for the [code]viewport[/code]. If set to a value greater than [code]0.0[/code], contrast-adaptive sharpening will be applied to the 3D viewport. This has a low performance cost and can be used to recover some of the sharpness lost from using FXAA. Values around [code]0.5[/code] generally give the best results. See also [method viewport_set_use_fxaa].
+
+
@@ -3101,7 +3112,7 @@
- Enables fast approximate antialiasing for this viewport. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K.
+ Enables fast approximate antialiasing for this viewport. FXAA is a popular screen-space antialiasing method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K. Some of the lost sharpness can be recovered by enabling contrast-adaptive sharpening (see [method viewport_set_sharpen_intensity]).
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 242473201bce..78fffd492d7e 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -706,6 +706,7 @@ class RasterizerStorageDummy : public RasterizerStorage {
void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) {}
void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) {}
void render_target_set_use_debanding(RID p_render_target, bool p_debanding) {}
+ void render_target_set_sharpen_intensity(RID p_render_target, float p_intensity) {}
/* CANVAS SHADOW */
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 42aea361800c..0122a153196d 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -5427,12 +5427,23 @@ void RasterizerStorageGLES2::render_target_set_use_debanding(RID p_render_target
ERR_FAIL_COND(!rt);
if (p_debanding) {
- WARN_PRINT_ONCE("Debanding is not supported in the GLES2 backend. Switch to the GLES3 backend and make sure HDR is enabled.");
+ WARN_PRINT_ONCE("Debanding is not supported in the GLES2 backend. To use debanding, switch to the GLES3 backend and make sure HDR is enabled.");
}
rt->use_debanding = p_debanding;
}
+void RasterizerStorageGLES2::render_target_set_sharpen_intensity(RID p_render_target, float p_intensity) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ if (p_intensity >= 0.001) {
+ WARN_PRINT_ONCE("Sharpening is not supported in the GLES2 backend. To use sharpening, switch to the GLES3 backend.");
+ }
+
+ rt->sharpen_intensity = p_intensity;
+}
+
/* CANVAS SHADOW */
RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index 06f8314227a3..7233e20d3e58 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -1232,6 +1232,7 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
bool use_fxaa;
bool use_debanding;
+ float sharpen_intensity;
RID texture;
@@ -1254,6 +1255,7 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
msaa(VS::VIEWPORT_MSAA_DISABLED),
use_fxaa(false),
use_debanding(false),
+ sharpen_intensity(0.0),
used_dof_blur_near(false),
mip_maps_allocated(false) {
for (int i = 0; i < RENDER_TARGET_FLAG_MAX; ++i) {
@@ -1281,6 +1283,7 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa);
virtual void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa);
virtual void render_target_set_use_debanding(RID p_render_target, bool p_debanding);
+ virtual void render_target_set_sharpen_intensity(RID p_render_target, float p_intensity);
/* CANVAS SHADOW */
diff --git a/drivers/gles2/shaders/tonemap.glsl b/drivers/gles2/shaders/tonemap.glsl
index 5cd27b42c6f6..83d78f4bd55c 100644
--- a/drivers/gles2/shaders/tonemap.glsl
+++ b/drivers/gles2/shaders/tonemap.glsl
@@ -98,6 +98,10 @@ uniform vec3 bcs;
uniform vec2 pixel_size;
#endif
+#ifdef USE_SHARPENING
+uniform float sharpen_intensity;
+#endif
+
#ifdef USE_COLOR_CORRECTION
uniform sampler2D color_correction; //texunit:1
#endif
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index e1475ab5c7e5..f4a7cdbdd277 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -3512,7 +3512,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
- if ((!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] || storage->frame.current_rt->width < 4 || storage->frame.current_rt->height < 4) && !storage->frame.current_rt->use_fxaa && !storage->frame.current_rt->use_debanding) { //no post process on small render targets
+ if ((!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] || storage->frame.current_rt->width < 4 || storage->frame.current_rt->height < 4) && !storage->frame.current_rt->use_fxaa && !storage->frame.current_rt->use_debanding && storage->frame.current_rt->sharpen_intensity < 0.001) { //no post process on small render targets
//no environment or transparent render, simply return and convert to SRGB
if (storage->frame.current_rt->external.fbo != 0) {
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->external.fbo);
@@ -3871,6 +3871,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FXAA, storage->frame.current_rt->use_fxaa);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_DEBANDING, storage->frame.current_rt->use_debanding);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_SHARPENING, storage->frame.current_rt->sharpen_intensity >= 0.001);
if (env && max_glow_level >= 0) {
for (int i = 0; i < (max_glow_level + 1); i++) {
@@ -3950,11 +3951,16 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_uniform(TonemapShaderGLES3::PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
}
+ if (storage->frame.current_rt->sharpen_intensity >= 0.001) {
+ state.tonemap_shader.set_uniform(TonemapShaderGLES3::SHARPEN_INTENSITY, storage->frame.current_rt->sharpen_intensity);
+ }
+
_copy_screen(true, true);
//turn off everything used
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FXAA, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_DEBANDING, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_SHARPENING, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, false);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 802af73017ea..f5a610601d3e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -7488,6 +7488,13 @@ void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target
rt->use_debanding = p_debanding;
}
+void RasterizerStorageGLES3::render_target_set_sharpen_intensity(RID p_render_target, float p_intensity) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->sharpen_intensity = p_intensity;
+}
+
/* CANVAS SHADOW */
RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index c0bf66396ce0..e86e4627366c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -1383,6 +1383,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
VS::ViewportMSAA msaa;
bool use_fxaa;
bool use_debanding;
+ float sharpen_intensity;
RID texture;
@@ -1395,7 +1396,8 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
used_in_frame(false),
msaa(VS::VIEWPORT_MSAA_DISABLED),
use_fxaa(false),
- use_debanding(false) {
+ use_debanding(false),
+ sharpen_intensity(0.0) {
exposure.fbo = 0;
buffers.fbo = 0;
external.fbo = 0;
@@ -1426,6 +1428,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa);
virtual void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa);
virtual void render_target_set_use_debanding(RID p_render_target, bool p_debanding);
+ virtual void render_target_set_sharpen_intensity(RID p_render_target, float p_intensity);
/* CANVAS SHADOW */
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 20a44267c722..e7403d35c115 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -52,6 +52,10 @@ uniform vec3 bcs;
uniform vec2 pixel_size;
#endif
+#ifdef USE_SHARPENING
+uniform float sharpen_intensity;
+#endif
+
#ifdef USE_COLOR_CORRECTION
uniform sampler2D color_correction; //texunit:3
#endif
@@ -319,6 +323,54 @@ vec3 screen_space_dither(vec2 frag_coord) {
return (dither.rgb - 0.5) / 255.0;
}
+// Adapted from https://github.com/DadSchoorse/vkBasalt/blob/b929505ba71dea21d6c32a5a59f2d241592b30c4/src/shader/cas.frag.glsl
+// (MIT license).
+vec3 apply_cas(vec3 color, vec2 uv_interp, float sharpen_intensity) {
+ // Fetch a 3x3 neighborhood around the pixel 'e',
+ // a b c
+ // d(e)f
+ // g h i
+ vec3 a = textureLodOffset(source, uv_interp, 0.0, ivec2(-1, -1)).rgb;
+ vec3 b = textureLodOffset(source, uv_interp, 0.0, ivec2(0, -1)).rgb;
+ vec3 c = textureLodOffset(source, uv_interp, 0.0, ivec2(1, -1)).rgb;
+ vec3 d = textureLodOffset(source, uv_interp, 0.0, ivec2(-1, 0)).rgb;
+ vec3 e = color.rgb;
+ vec3 f = textureLodOffset(source, uv_interp, 0.0, ivec2(1, 0)).rgb;
+ vec3 g = textureLodOffset(source, uv_interp, 0.0, ivec2(-1, 1)).rgb;
+ vec3 h = textureLodOffset(source, uv_interp, 0.0, ivec2(0, 1)).rgb;
+ vec3 i = textureLodOffset(source, uv_interp, 0.0, ivec2(1, 1)).rgb;
+
+ // Soft min and max.
+ // a b c b
+ // d e f * 0.5 + d e f * 0.5
+ // g h i h
+ // These are 2.0x bigger (factored out the extra multiply).
+ vec3 min_rgb = min(min(min(d, e), min(f, b)), h);
+ vec3 min_rgb2 = min(min(min(min_rgb, a), min(g, c)), i);
+ min_rgb += min_rgb2;
+
+ vec3 max_rgb = max(max(max(d, e), max(f, b)), h);
+ vec3 max_rgb2 = max(max(max(max_rgb, a), max(g, c)), i);
+ max_rgb += max_rgb2;
+
+ // Smooth minimum distance to signal limit divided by smooth max.
+ vec3 rcp_max_rgb = vec3(1.0) / max_rgb;
+ vec3 amp_rgb = clamp((min(min_rgb, 2.0 - max_rgb) * rcp_max_rgb), 0.0, 1.0);
+
+ // Shaping amount of sharpening.
+ amp_rgb = inversesqrt(amp_rgb);
+ float peak = 8.0 - 3.0 * sharpen_intensity;
+ vec3 w_rgb = -vec3(1) / (amp_rgb * peak);
+ vec3 rcp_weight_rgb = vec3(1.0) / (1.0 + 4.0 * w_rgb);
+
+ // 0 w 0
+ // Filter shape: w 1 w
+ // 0 w 0
+ vec3 window = b + d + f + h;
+
+ return max(vec3(0.0), (window * w_rgb + e) * rcp_weight_rgb);
+}
+
void main() {
vec3 color = textureLod(source, uv_interp, 0.0f).rgb;
@@ -336,6 +388,12 @@ void main() {
color = apply_fxaa(color, full_exposure, uv_interp, pixel_size);
#endif
+#ifdef USE_SHARPENING
+ // CAS gives best results when applied after tonemapping, but `source` isn't tonemapped.
+ // As a workaround, apply CAS before tonemapping so that the image still has a correct appearance when tonemapped.
+ color = apply_cas(color, uv_interp, sharpen_intensity);
+#endif
+
#ifdef USE_DEBANDING
// For best results, debanding should be done before tonemapping.
// Otherwise, we're adding noise to an already-quantized image.
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 80e1a45b1506..9d8ca47a3232 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -2468,6 +2468,9 @@ void SpatialEditorViewport::_notification(int p_what) {
bool use_debanding = ProjectSettings::get_singleton()->get("rendering/quality/filters/use_debanding");
viewport->set_use_debanding(use_debanding);
+ float sharpen_intensity = ProjectSettings::get_singleton()->get("rendering/quality/filters/sharpen_intensity");
+ viewport->set_sharpen_intensity(sharpen_intensity);
+
bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
viewport->set_hdr(hdr);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index ae6db582142a..3b219e9f0381 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -2066,6 +2066,9 @@ SceneTree::SceneTree() {
const bool use_debanding = GLOBAL_DEF("rendering/quality/filters/use_debanding", false);
root->set_use_debanding(use_debanding);
+ const float sharpen_intensity = GLOBAL_GET("rendering/quality/filters/sharpen_intensity");
+ root->set_sharpen_intensity(sharpen_intensity);
+
GLOBAL_DEF_RST("rendering/quality/depth/hdr", true);
GLOBAL_DEF("rendering/quality/depth/hdr.mobile", false);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index ab1cf71a941e..01a2ba963475 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2988,6 +2988,18 @@ bool Viewport::get_use_debanding() const {
return use_debanding;
}
+void Viewport::set_sharpen_intensity(float p_intensity) {
+ if (p_intensity == sharpen_intensity) {
+ return;
+ }
+ sharpen_intensity = p_intensity;
+ VS::get_singleton()->viewport_set_sharpen_intensity(viewport, sharpen_intensity);
+}
+
+float Viewport::get_sharpen_intensity() const {
+ return sharpen_intensity;
+}
+
void Viewport::set_hdr(bool p_hdr) {
if (hdr == p_hdr) {
return;
@@ -3120,6 +3132,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_debanding", "enable"), &Viewport::set_use_debanding);
ClassDB::bind_method(D_METHOD("get_use_debanding"), &Viewport::get_use_debanding);
+ ClassDB::bind_method(D_METHOD("set_sharpen_intensity", "intensity"), &Viewport::set_sharpen_intensity);
+ ClassDB::bind_method(D_METHOD("get_sharpen_intensity"), &Viewport::get_sharpen_intensity);
+
ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr);
ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr);
@@ -3212,6 +3227,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fxaa"), "set_use_fxaa", "get_use_fxaa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debanding"), "set_use_debanding", "get_use_debanding");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sharpen_intensity"), "set_sharpen_intensity", "get_sharpen_intensity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");
@@ -3371,6 +3387,7 @@ Viewport::Viewport() {
msaa = MSAA_DISABLED;
use_fxaa = false;
use_debanding = false;
+ sharpen_intensity = 0.0;
hdr = true;
usage = USAGE_3D;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index d32927368178..360f75860452 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -281,6 +281,7 @@ class Viewport : public Node {
MSAA msaa;
bool use_fxaa;
bool use_debanding;
+ float sharpen_intensity;
bool hdr;
Ref default_texture;
@@ -502,6 +503,9 @@ class Viewport : public Node {
void set_use_debanding(bool p_debanding);
bool get_use_debanding() const;
+ void set_sharpen_intensity(float p_intensity);
+ float get_sharpen_intensity() const;
+
void set_hdr(bool p_hdr);
bool get_hdr() const;
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 678073f2600a..fc9b0021300c 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -577,6 +577,7 @@ class RasterizerStorage {
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) = 0;
virtual void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) = 0;
virtual void render_target_set_use_debanding(RID p_render_target, bool p_debanding) = 0;
+ virtual void render_target_set_sharpen_intensity(RID p_render_target, float p_intensity) = 0;
/* CANVAS SHADOW */
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 49d906b782ae..a35e64ffaf72 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -488,6 +488,7 @@ class VisualServerRaster : public VisualServer {
BIND2(viewport_set_msaa, RID, ViewportMSAA)
BIND2(viewport_set_use_fxaa, RID, bool)
BIND2(viewport_set_use_debanding, RID, bool)
+ BIND2(viewport_set_sharpen_intensity, RID, float)
BIND2(viewport_set_hdr, RID, bool)
BIND2(viewport_set_usage, RID, ViewportUsage)
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index d28646bbb720..c1c20504e003 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -630,6 +630,13 @@ void VisualServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_deb
VSG::storage->render_target_set_use_debanding(viewport->render_target, p_debanding);
}
+void VisualServerViewport::viewport_set_sharpen_intensity(RID p_viewport, float p_intensity) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VSG::storage->render_target_set_sharpen_intensity(viewport->render_target, p_intensity);
+}
+
void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 0995aba12f02..201d1c70e634 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -188,6 +188,7 @@ class VisualServerViewport {
void viewport_set_msaa(RID p_viewport, VS::ViewportMSAA p_msaa);
void viewport_set_use_fxaa(RID p_viewport, bool p_fxaa);
void viewport_set_use_debanding(RID p_viewport, bool p_debanding);
+ void viewport_set_sharpen_intensity(RID p_viewport, float p_intensity);
void viewport_set_hdr(RID p_viewport, bool p_enabled);
void viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 40e63cb01bdf..a4cd6cd444dd 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -416,6 +416,7 @@ class VisualServerWrapMT : public VisualServer {
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
FUNC2(viewport_set_use_fxaa, RID, bool)
FUNC2(viewport_set_use_debanding, RID, bool)
+ FUNC2(viewport_set_sharpen_intensity, RID, float)
FUNC2(viewport_set_hdr, RID, bool)
FUNC2(viewport_set_usage, RID, ViewportUsage)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 8b19d82d2074..a677b38e39ea 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1995,6 +1995,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &VisualServer::viewport_set_msaa);
ClassDB::bind_method(D_METHOD("viewport_set_use_fxaa", "viewport", "fxaa"), &VisualServer::viewport_set_use_fxaa);
ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "debanding"), &VisualServer::viewport_set_use_debanding);
+ ClassDB::bind_method(D_METHOD("viewport_set_sharpen_intensity", "viewport", "intensity"), &VisualServer::viewport_set_sharpen_intensity);
ClassDB::bind_method(D_METHOD("viewport_set_hdr", "viewport", "enabled"), &VisualServer::viewport_set_hdr);
ClassDB::bind_method(D_METHOD("viewport_set_usage", "viewport", "usage"), &VisualServer::viewport_set_usage);
ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "info"), &VisualServer::viewport_get_render_info);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 0518da5f2a01..6d2c3f9826eb 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -691,6 +691,7 @@ class VisualServer : public Object {
virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;
virtual void viewport_set_use_fxaa(RID p_viewport, bool p_fxaa) = 0;
virtual void viewport_set_use_debanding(RID p_viewport, bool p_debanding) = 0;
+ virtual void viewport_set_sharpen_intensity(RID p_viewport, float p_intensity) = 0;
enum ViewportUsage {
VIEWPORT_USAGE_2D,