diff options
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 8 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 7 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 15 | ||||
-rw-r--r-- | scene/main/viewport.h | 4 | ||||
-rw-r--r-- | servers/rendering/rasterizer.h | 2 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp | 1 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_effects_rd.h | 3 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp | 4 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.h | 3 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/tonemap.glsl | 19 | ||||
-rw-r--r-- | servers/rendering/rendering_server_raster.h | 1 | ||||
-rw-r--r-- | servers/rendering/rendering_server_viewport.cpp | 21 | ||||
-rw-r--r-- | servers/rendering/rendering_server_viewport.h | 3 | ||||
-rw-r--r-- | servers/rendering/rendering_server_wrap_mt.h | 1 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 2 | ||||
-rw-r--r-- | servers/rendering_server.h | 2 |
16 files changed, 82 insertions, 14 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index aecbf817c4..a4eab6ab4a 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2464,12 +2464,14 @@ void Node3DEditorViewport::_notification(int p_what) { subviewport_container->set_stretch_shrink(shrink ? 2 : 1); } - //update msaa if changed + // Update MSAA, screen-space AA and debanding if changed - int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); + const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); viewport->set_msaa(Viewport::MSAA(msaa_mode)); - int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); + const int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + const bool use_debanding = GLOBAL_GET("rendering/quality/screen_filters/use_debanding"); + viewport->set_use_debanding(use_debanding); bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); if (show_info != info_label->is_visible()) { diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index adefb53862..ea0fe6fcc2 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1383,14 +1383,17 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene = nullptr; - int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); + const int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)")); root->set_msaa(Viewport::MSAA(msaa_mode)); - int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); + const int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)")); root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + const bool use_debanding = GLOBAL_DEF("rendering/quality/screen_filters/use_debanding", false); + root->set_use_debanding(use_debanding); + { //load default fallback environment //get possible extensions List<String> exts; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 3c7475a150..414e488244 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3138,6 +3138,17 @@ Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const { return screen_space_aa; } +void Viewport::set_use_debanding(bool p_use_debanding) { + if (use_debanding == p_use_debanding) + return; + use_debanding = p_use_debanding; + RS::get_singleton()->viewport_set_use_debanding(viewport, p_use_debanding); +} + +bool Viewport::is_using_debanding() const { + return use_debanding; +} + void Viewport::set_debug_draw(DebugDraw p_debug_draw) { debug_draw = p_debug_draw; RS::get_singleton()->viewport_set_debug_draw(viewport, RS::ViewportDebugDraw(p_debug_draw)); @@ -3324,6 +3335,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa); ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa); + ClassDB::bind_method(D_METHOD("set_use_debanding", "enable"), &Viewport::set_use_debanding); + ClassDB::bind_method(D_METHOD("is_using_debanding"), &Viewport::is_using_debanding); + ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); @@ -3397,6 +3411,7 @@ void Viewport::_bind_methods() { ADD_GROUP("Rendering", ""); 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::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Canvas Items", "canvas_item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 878ac47bca..f7457f8ab2 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -279,6 +279,7 @@ private: MSAA msaa; ScreenSpaceAA screen_space_aa; + bool use_debanding; Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; @@ -521,6 +522,9 @@ public: void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa); ScreenSpaceAA get_screen_space_aa() const; + void set_use_debanding(bool p_use_debanding); + bool is_using_debanding() const; + Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index e64c517a0b..cecd313fbd 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -306,7 +306,7 @@ public: virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; virtual bool screen_space_roughness_limiter_is_active() const = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index 0a3a863ee7..409cfdfecf 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -700,6 +700,7 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, tonemap.push_constant.use_color_correction = p_settings.use_color_correction; tonemap.push_constant.use_fxaa = p_settings.use_fxaa; + tonemap.push_constant.use_debanding = p_settings.use_debanding; tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x; tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index 8607a6ee67..679263fbf6 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -188,7 +188,7 @@ class RasterizerEffectsRD { float pixel_size[2]; uint32_t use_fxaa; - uint32_t pad; + uint32_t use_debanding; }; /* tonemap actually writes to a framebuffer, which is @@ -651,6 +651,7 @@ public: RID color_correction_texture; bool use_fxaa = false; + bool use_debanding = false; Vector2i texture_size; }; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 9e6225a97a..af2abe0021 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -5314,6 +5314,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.use_fxaa = true; } + tonemap.use_debanding = rb->use_debanding; tonemap.texture_size = Vector2i(rb->width, rb->height); if (env) { @@ -5693,13 +5694,14 @@ float RasterizerSceneRD::render_buffers_get_volumetric_fog_detail_spread(RID p_r return rb->volumetric_fog->spread; } -void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) { +void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; rb->height = p_height; rb->render_target = p_render_target; rb->msaa = p_msaa; rb->screen_space_aa = p_screen_space_aa; + rb->use_debanding = p_use_debanding; _free_render_buffer_data(rb); { diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 8a14598250..2ad712a9d3 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -815,6 +815,7 @@ private: int width = 0, height = 0; RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + bool use_debanding = false; RID render_target; @@ -1845,7 +1846,7 @@ public: } */ RID render_buffers_create(); - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa); + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding); RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl index 74449496f6..a464048ebd 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl @@ -48,7 +48,7 @@ layout(push_constant, binding = 1, std430) uniform Params { vec2 pixel_size; bool use_fxaa; - uint pad; + bool use_debanding; } params; @@ -301,6 +301,19 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { } } +#define QUARTER_COLOR 1.0 / 1024.0 + +// From http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf +// and https://www.shadertoy.com/view/MslGR8 (5th one starting from the bottom) +// NOTE: `frag_coord` is in pixels (i.e. not normalized UV). +vec3 screen_space_dither(vec2 frag_coord) { + // Iestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR. + vec3 dither = vec3(dot(vec2(171.0, 231.0), frag_coord)); + dither.rgb = fract(dither.rgb / vec3(103.0, 71.0, 97.0)); + + return dither.rgb / 255.0; +} + void main() { vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb; @@ -324,6 +337,10 @@ void main() { if (params.use_fxaa) { color = do_fxaa(color, exposure, uv_interp); } + if (params.use_debanding) { + // Debanding should be done before tonemapping. + color += screen_space_dither(gl_FragCoord.xy); + } color = apply_tonemapping(color, params.white); color = linear_to_srgb(color); // regular linear -> SRGB conversion diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index fb3baeca95..97477f1d3e 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -535,6 +535,7 @@ public: BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) BIND2(viewport_set_msaa, RID, ViewportMSAA) BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) + BIND2(viewport_set_use_debanding, RID, bool) BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index 48be6ca13b..bd9aa32147 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -115,7 +115,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) { //wants to draw 3D but there is no render buffer, create p_viewport->render_buffers = RSG::scene_render->render_buffers_create(); - RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa); + RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding); } RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor); @@ -491,7 +491,7 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int RSG::scene_render->free(viewport->render_buffers); viewport->render_buffers = RID(); } else { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa); + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding); } } } @@ -704,7 +704,7 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA } viewport->msaa = p_msaa; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa); + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding); } } @@ -717,7 +717,20 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V } viewport->screen_space_aa = p_mode; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode); + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding); + } +} + +void RenderingServerViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) { + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND(!viewport); + + if (viewport->use_debanding == p_use_debanding) { + return; + } + viewport->use_debanding = p_use_debanding; + if (viewport->render_buffers.is_valid()) { + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding); } } diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index 0b90646e4f..ed251f5da0 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -59,6 +59,7 @@ public: RS::ViewportMSAA msaa; RS::ViewportScreenSpaceAA screen_space_aa; + bool use_debanding; DisplayServer::WindowID viewport_to_screen; Rect2 viewport_to_screen_rect; @@ -130,6 +131,7 @@ public: debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; msaa = RS::VIEWPORT_MSAA_DISABLED; screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + use_debanding = false; for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) { render_info[i] = 0; @@ -206,6 +208,7 @@ public: void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa); void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode); + void viewport_set_use_debanding(RID p_viewport, bool p_use_debanding); virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info); virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw); diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 305a3aaee7..c2337f8c9e 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -438,6 +438,7 @@ public: FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) FUNC2(viewport_set_msaa, RID, ViewportMSAA) FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) + FUNC2(viewport_set_use_debanding, RID, bool) //this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) { diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d747f31318..4251ee3c11 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1734,6 +1734,8 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size); ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision); ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa); + ClassDB::bind_method(D_METHOD("viewport_set_use_debanding" "viewport", "enable"), &RenderingServer::viewport_set_use_debanding); + ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "info"), &RenderingServer::viewport_get_render_info); ClassDB::bind_method(D_METHOD("viewport_set_debug_draw", "viewport", "draw"), &RenderingServer::viewport_set_debug_draw); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 11c73c63d0..e50170bdf7 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -727,6 +727,8 @@ public: virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0; + virtual void viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) = 0; + enum ViewportRenderInfo { VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME, VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME, |