From 64626cc435448037c3d0045f57771ff9912d146c Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Thu, 19 Aug 2021 11:52:06 +1000 Subject: [PATCH] Optionally scale 3D render content --- doc/classes/ProjectSettings.xml | 3 + doc/classes/RenderingServer.xml | 18 ++++ doc/classes/Viewport.xml | 13 +++ drivers/vulkan/rendering_device_vulkan.cpp | 8 ++ drivers/vulkan/rendering_device_vulkan.h | 1 + scene/main/viewport.cpp | 26 ++++++ scene/main/viewport.h | 13 +++ .../forward_mobile/render_forward_mobile.cpp | 12 +-- .../renderer_rd/renderer_scene_render_rd.cpp | 10 ++- servers/rendering/renderer_viewport.cpp | 82 +++++++++++++------ servers/rendering/renderer_viewport.h | 6 +- servers/rendering/rendering_device.h | 1 + servers/rendering/rendering_server_default.h | 1 + servers/rendering_server.cpp | 13 +++ servers/rendering_server.h | 11 +++ 15 files changed, 184 insertions(+), 34 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 0d1fa0e70f7..58c9d9e44bc 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1473,6 +1473,9 @@ + + Scale the 3D render buffer based on the viewport size. The smaller the faster 3D rendering is performed but at the cost of quality. + Sets the number of MSAA samples to use (as a power of two). 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. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index df8bfb7e344..638c6574924 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -3082,6 +3082,14 @@ If [code]true[/code], render the contents of the viewport directly to screen. This allows a low-level optimization where you can skip drawing a viewport to the root viewport. While this optimization can result in a significant increase in speed (especially on older devices), it comes at a cost of usability. When this is enabled, you cannot read from the viewport or from the [code]SCREEN_TEXTURE[/code]. You also lose the benefit of certain window settings, such as the various stretch modes. Another consequence to be aware of is that in 2D the rendering happens in window coordinates, so if you have a viewport that is double the size of the window, and you set this, then only the portion that fits within the window will be drawn, no automatic scaling is possible, even if your game scene is significantly larger than the window size. + + + + + + Sets the scale at which we render 3D contents. + + @@ -3896,6 +3904,16 @@ + + + + + + + + + + diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 2478b71b6ae..46f38e91f7e 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -211,6 +211,9 @@ If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process. + + The scale at which 3D content is rendered. + Sets the screen-space antialiasing method used. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. @@ -271,6 +274,16 @@ + + + + + + + + + + This quadrant will not be used. diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 2de8b9025cd..6ad24f255f6 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -2740,6 +2740,14 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { return texture_owner.owns(p_texture); } +Size2i RenderingDeviceVulkan::texture_size(RID p_texture) { + _THREAD_SAFE_METHOD_ + + Texture *tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!tex, Size2i()); + return Size2i(tex->width, tex->height); +} + Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 5ee2ca07f21..dc1b78c1d56 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1044,6 +1044,7 @@ public: virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const; virtual bool texture_is_shared(RID p_texture); virtual bool texture_is_valid(RID p_texture); + virtual Size2i texture_size(RID p_texture); virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL); virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index ea2323c651a..801c7cf86e9 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3451,6 +3451,17 @@ void Viewport::set_use_xr(bool p_use_xr) { bool Viewport::is_using_xr() { return use_xr; } + +void Viewport::set_scale_3d(const Scale3D p_scale_3d) { + scale_3d = p_scale_3d; + + RS::get_singleton()->viewport_set_scale_3d(viewport, RS::ViewportScale3D(scale_3d)); +} + +Viewport::Scale3D Viewport::get_scale_3d() const { + return scale_3d; +} + #endif // _3D_DISABLED void Viewport::_bind_methods() { @@ -3575,8 +3586,12 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr); ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr); + ClassDB::bind_method(D_METHOD("set_scale_3d", "scale"), &Viewport::set_scale_3d); + ClassDB::bind_method(D_METHOD("get_scale_3d"), &Viewport::get_scale_3d); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "scale_3d", PROPERTY_HINT_ENUM, String::utf8("Disabled,75%,50%,33%,25%")), "set_scale_3d", "get_scale_3d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); @@ -3620,6 +3635,12 @@ void Viewport::_bind_methods() { ADD_SIGNAL(MethodInfo("size_changed")); ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); + BIND_ENUM_CONSTANT(SCALE_3D_DISABLED); + BIND_ENUM_CONSTANT(SCALE_3D_75_PERCENT); + BIND_ENUM_CONSTANT(SCALE_3D_50_PERCENT); + BIND_ENUM_CONSTANT(SCALE_3D_33_PERCENT); + BIND_ENUM_CONSTANT(SCALE_3D_25_PERCENT); + BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4); @@ -3734,6 +3755,11 @@ Viewport::Viewport() { gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers +#ifndef _3D_DISABLED + int scale = GLOBAL_GET("rendering/3d/viewport/scale"); + set_scale_3d((Scale3D)scale); +#endif // _3D_DISABLED + set_sdf_oversize(sdf_oversize); //set to server } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index b24de77e6b3..d9b21ce6a82 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -88,6 +88,14 @@ class Viewport : public Node { GDCLASS(Viewport, Node); public: + enum Scale3D { + SCALE_3D_DISABLED, + SCALE_3D_75_PERCENT, + SCALE_3D_50_PERCENT, + SCALE_3D_33_PERCENT, + SCALE_3D_25_PERCENT + }; + enum ShadowAtlasQuadrantSubdiv { SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED, SHADOW_ATLAS_QUADRANT_SUBDIV_1, @@ -577,6 +585,7 @@ public: #ifndef _3D_DISABLED bool use_xr = false; + Scale3D scale_3d = SCALE_3D_DISABLED; friend class Listener3D; Listener3D *listener_3d = nullptr; Set listener_3d_set; @@ -647,6 +656,9 @@ public: void set_use_xr(bool p_use_xr); bool is_using_xr(); + + void set_scale_3d(const Scale3D p_scale_3d); + Scale3D get_scale_3d() const; #endif // _3D_DISABLED Viewport(); @@ -705,6 +717,7 @@ VARIANT_ENUM_CAST(SubViewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA); +VARIANT_ENUM_CAST(Viewport::Scale3D); VARIANT_ENUM_CAST(Viewport::DebugDraw); VARIANT_ENUM_CAST(Viewport::SDFScale); VARIANT_ENUM_CAST(Viewport::SDFOversize); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 926d599c84e..1b4052b622b 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -86,12 +86,13 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() { void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) { clear(); - bool is_half_resolution = false; // Set this once we support this feature. - msaa = p_msaa; + Size2i target_size = RD::get_singleton()->texture_size(p_target_buffer); + width = p_width; height = p_height; + bool is_scaled = (target_size.width != p_width) || (target_size.height != p_height); view_count = p_view_count; color = p_color_buffer; @@ -124,7 +125,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b passes.push_back(pass); color_fbs[FB_CONFIG_THREE_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, view_count); - if (!is_half_resolution) { + if (!is_scaled) { // - add blit to 2D pass fb.push_back(p_target_buffer); // 2 - target buffer @@ -211,7 +212,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b color_fbs[FB_CONFIG_ONE_PASS] = RD::get_singleton()->framebuffer_create_multipass(fb, one_pass_with_resolve, RenderingDevice::INVALID_ID, view_count); } - if (!is_half_resolution) { + if (!is_scaled) { // - add blit to 2D pass fb.push_back(p_target_buffer); // 3 - target buffer RD::FramebufferPass blit_pass; @@ -497,7 +498,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color bool using_subpass_transparent = true; bool using_subpass_post_process = true; - bool is_half_resolution = false; // Set this once we support this feature. bool using_ssr = false; // I don't think we support this in our mobile renderer so probably should phase it out bool using_sss = false; // I don't think we support this in our mobile renderer so probably should phase it out @@ -518,7 +518,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color screen_size.x = render_buffer->width; screen_size.y = render_buffer->height; - if (is_half_resolution) { + if (render_buffer->color_fbs[FB_CONFIG_FOUR_SUBPASSES].is_null()) { // can't do blit subpass using_subpass_post_process = false; } else if (env && (env->glow_enabled || env->auto_exposure || camera_effects_uses_dof(p_render_data->camera_effects))) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index acda68abb78..fa66ed85a90 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2591,6 +2591,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + + // Should we add an overrule per viewport? rb->width = p_width; rb->height = p_height; rb->render_target = p_render_target; @@ -2637,8 +2639,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p tf.format = RD::DATA_FORMAT_R32_SFLOAT; } - tf.width = p_width; - tf.height = p_height; + tf.width = rb->width; + tf.height = rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; tf.array_layers = rb->view_count; // create a layer for every view @@ -2660,10 +2662,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p } RID target_texture = storage->render_target_get_rd_texture(rb->render_target); - rb->data->configure(rb->texture, rb->depth_texture, target_texture, p_width, p_height, p_msaa, p_view_count); + rb->data->configure(rb->texture, rb->depth_texture, target_texture, rb->width, rb->height, p_msaa, p_view_count); if (is_clustered_enabled()) { - rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture); + rb->cluster_builder->setup(Size2i(rb->width, rb->height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture); } } diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 15ce1dbe63c..89d9f24217f 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -71,6 +71,44 @@ static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, return xf; } +void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { + if (p_viewport->render_buffers.is_valid()) { + if (p_viewport->size.width == 0 || p_viewport->size.height == 0) { + RSG::scene->free(p_viewport->render_buffers); + p_viewport->render_buffers = RID(); + } else { + RS::ViewportScale3D scale_3d = p_viewport->scale_3d; + if (Engine::get_singleton()->is_editor_hint()) { // ignore this inside of the editor + scale_3d = RS::VIEWPORT_SCALE_3D_DISABLED; + } + + int width = p_viewport->size.width; + int height = p_viewport->size.height; + switch (scale_3d) { + case RS::VIEWPORT_SCALE_3D_75_PERCENT: { + width = (width * 3) / 4; + height = (height * 3) / 4; + }; break; + case RS::VIEWPORT_SCALE_3D_50_PERCENT: { + width = width >> 1; + height = height >> 1; + }; break; + case RS::VIEWPORT_SCALE_3D_33_PERCENT: { + width = width / 3; + height = height / 3; + }; break; + case RS::VIEWPORT_SCALE_3D_25_PERCENT: { + width = width >> 2; + height = height >> 2; + }; break; + default: + break; + } + RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, width, height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_viewport->get_view_count()); + } + } +} + void RendererViewport::_draw_3d(Viewport *p_viewport) { RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); @@ -100,7 +138,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) { RENDER_TIMESTAMP("measure_render_time) { String rt_id = "vp_begin_" + itos(p_viewport->self.get_id()); RSG::storage->capture_timestamp(rt_id); @@ -142,7 +180,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_coun 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_buffers_create(); - RSG::scene->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, p_view_count); + + _configure_3d_render_buffers(p_viewport); } RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor); @@ -556,7 +595,7 @@ void RendererViewport::draw_viewports() { RSG::scene->set_debug_draw_mode(vp->debug_draw); // and draw viewport - _draw_viewport(vp, view_count); + _draw_viewport(vp); // measure @@ -580,7 +619,7 @@ void RendererViewport::draw_viewports() { RSG::scene->set_debug_draw_mode(vp->debug_draw); // render standard mono camera - _draw_viewport(vp, 1); + _draw_viewport(vp); if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) { //copy to screen if set as such @@ -648,9 +687,19 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { } viewport->use_xr = p_use_xr; - if (viewport->render_buffers.is_valid()) { - RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count()); + _configure_3d_render_buffers(viewport); +} + +void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) { + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND(!viewport); + + if (viewport->scale_3d == p_scale_3d) { + return; } + + viewport->scale_3d = p_scale_3d; + _configure_3d_render_buffers(viewport); } uint32_t RendererViewport::Viewport::get_view_count() { @@ -677,14 +726,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig viewport->size = Size2(p_width, p_height); uint32_t view_count = viewport->get_view_count(); RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count); - if (viewport->render_buffers.is_valid()) { - if (p_width == 0 || p_height == 0) { - RSG::scene->free(viewport->render_buffers); - viewport->render_buffers = RID(); - } else { - RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, view_count); - } - } + _configure_3d_render_buffers(viewport); viewport->occlusion_buffer_dirty = true; } @@ -915,9 +957,7 @@ void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa return; } viewport->msaa = p_msaa; - if (viewport->render_buffers.is_valid()) { - RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count()); - } + _configure_3d_render_buffers(viewport); } void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) { @@ -928,9 +968,7 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport return; } viewport->screen_space_aa = p_mode; - if (viewport->render_buffers.is_valid()) { - RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding, viewport->get_view_count()); - } + _configure_3d_render_buffers(viewport); } void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) { @@ -941,9 +979,7 @@ void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_deb return; } viewport->use_debanding = p_use_debanding; - if (viewport->render_buffers.is_valid()) { - RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding, viewport->get_view_count()); - } + _configure_3d_render_buffers(viewport); } void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) { diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index ac7a35f97de..f6095e18d7d 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -49,6 +49,8 @@ public: bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */ + RS::ViewportScale3D scale_3d = RenderingServer::VIEWPORT_SCALE_3D_DISABLED; + Size2i size; RID camera; RID scenario; @@ -192,8 +194,9 @@ public: int total_draw_calls_used = 0; private: + void _configure_3d_render_buffers(Viewport *p_viewport); void _draw_3d(Viewport *p_viewport); - void _draw_viewport(Viewport *p_viewport, uint32_t p_view_count = 1); + void _draw_viewport(Viewport *p_viewport); int occlusion_rays_per_thread = 512; @@ -204,6 +207,7 @@ public: void viewport_initialize(RID p_rid); void viewport_set_use_xr(RID p_viewport, bool p_use_xr); + void viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d); void viewport_set_size(RID p_viewport, int p_width, int p_height); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index e2d207dab26..2cf1f165dd4 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -495,6 +495,7 @@ public: virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0; virtual bool texture_is_shared(RID p_texture) = 0; virtual bool texture_is_valid(RID p_texture) = 0; + virtual Size2i texture_size(RID p_texture) = 0; virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index c1336ee42da..3386b99f536 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -526,6 +526,7 @@ public: FUNCRIDSPLIT(viewport) FUNC2(viewport_set_use_xr, RID, bool) + FUNC2(viewport_set_scale_3d, RID, ViewportScale3D) FUNC3(viewport_set_size, RID, int, int) FUNC2(viewport_set_active, RID, bool) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 222ea9e6229..78604dfe8c7 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2138,6 +2138,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_create"), &RenderingServer::viewport_create); ClassDB::bind_method(D_METHOD("viewport_set_use_xr", "viewport", "use_xr"), &RenderingServer::viewport_set_use_xr); + ClassDB::bind_method(D_METHOD("viewport_set_scale_3d", "viewport", "scale"), &RenderingServer::viewport_set_scale_3d); ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &RenderingServer::viewport_set_size); ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &RenderingServer::viewport_set_active); ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport); @@ -2255,6 +2256,12 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OCCLUDERS); + BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_DISABLED); + BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_75_PERCENT); + BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_50_PERCENT); + BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_33_PERCENT); + BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_25_PERCENT); + /* SKY API */ ClassDB::bind_method(D_METHOD("sky_create"), &RenderingServer::sky_create); @@ -2795,6 +2802,12 @@ RenderingServer::RenderingServer() { "rendering/vulkan/rendering/back_end", PROPERTY_HINT_ENUM, "Forward Clustered (Supports Desktop Only),Forward Mobile (Supports Desktop and Mobile)")); + GLOBAL_DEF("rendering/3d/viewport/scale", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/3d/viewport/scale", + PropertyInfo(Variant::INT, + "rendering/3d/viewport/scale", + PROPERTY_HINT_ENUM, "Disabled,75%,50%,33%,25%")); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true); GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true); GLOBAL_DEF("rendering/shader_compiler/shader_cache/use_zstd_compression", true); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 545270dcd95..6f80b52faa0 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -752,9 +752,19 @@ public: CANVAS_ITEM_TEXTURE_REPEAT_MAX, }; + enum ViewportScale3D { + VIEWPORT_SCALE_3D_DISABLED, + VIEWPORT_SCALE_3D_75_PERCENT, + VIEWPORT_SCALE_3D_50_PERCENT, + VIEWPORT_SCALE_3D_33_PERCENT, + VIEWPORT_SCALE_3D_25_PERCENT, + VIEWPORT_SCALE_3D_MAX, + }; + virtual RID viewport_create() = 0; virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0; + virtual void viewport_set_scale_3d(RID p_viewport, ViewportScale3D p_scale_3d) = 0; virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0; virtual void viewport_set_active(RID p_viewport, bool p_active) = 0; virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0; @@ -1542,6 +1552,7 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw); VARIANT_ENUM_CAST(RenderingServer::ViewportOcclusionCullingBuildQuality); VARIANT_ENUM_CAST(RenderingServer::ViewportSDFOversize); VARIANT_ENUM_CAST(RenderingServer::ViewportSDFScale); +VARIANT_ENUM_CAST(RenderingServer::ViewportScale3D); VARIANT_ENUM_CAST(RenderingServer::SkyMode); VARIANT_ENUM_CAST(RenderingServer::EnvironmentBG); VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);