diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index b3872121bfa..5403bd48d56 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1479,11 +1479,12 @@
-
- Scale the 3D render buffer based on the viewport size. The smaller the faster 3D rendering is performed but at the cost of quality.
+
+ Scales the 3D render buffer based on the viewport size and displays the result with linear filtering. Values lower than [code]1.0[/code] can be used to speed up 3D rendering at the cost of quality (undersampling). Values greater than [code]1.0[/code] can be used to improve 3D rendering quality at a high performance cost (supersampling). See also [member rendering/anti_aliasing/quality/msaa] for multi-sample antialiasing, which is significantly cheaper but only smoothens the edges of polygons.
+ [b]Note:[/b] This property is only read when the project starts. To change the 3D rendering resolution scale at runtime, set [member Viewport.scale_3d] instead.
- 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.
+ 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. See also [member rendering/3d/viewport/scale] for supersampling, which provides higher quality but is much more expensive.
Sets the screen-space antialiasing mode for the default screen [Viewport]. 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.
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 65b7e53ecdd..6f19114c16a 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -3102,7 +3102,7 @@
-
+
Sets the scale at which we render 3D contents.
@@ -3918,16 +3918,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index cdb9e7632be..e79cf0d2334 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -204,7 +204,7 @@
- The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 4 is best unless targeting very high-end systems.
+ The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 2 or 4 is best unless targeting very high-end systems. See also [member scale_3d] for supersampling, which provides higher quality but is much more expensive.
If [code]true[/code], the viewport will use the [World3D] defined in [member world_3d].
@@ -212,8 +212,9 @@
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
-
- The scale at which 3D content is rendered.
+
+ Scales the 3D render buffer based on the viewport size and displays the result with linear filtering. Values lower than [code]1.0[/code] can be used to speed up 3D rendering at the cost of quality (undersampling). Values greater than [code]1.0[/code] can be used to improve 3D rendering quality at a high performance cost (supersampling). See also [member msaa] for multi-sample antialiasing, which is significantly cheaper but only smoothens the edges of polygons.
+ To control this property on the root viewport, set the [member ProjectSettings.rendering/3d/viewport/scale] project setting.
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.
@@ -275,16 +276,6 @@
-
-
-
-
-
-
-
-
-
-
This quadrant will not be used.
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index e88bb3b952b..3ab6e12e01c 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -3443,13 +3443,16 @@ bool Viewport::is_using_xr() {
return use_xr;
}
-void Viewport::set_scale_3d(const Scale3D p_scale_3d) {
- scale_3d = p_scale_3d;
+void Viewport::set_scale_3d(float p_scale_3d) {
+ // Clamp to reasonable values that are actually useful.
+ // Values above 2.0 don't serve a practical purpose since the viewport
+ // isn't displayed with mipmaps.
+ scale_3d = CLAMP(p_scale_3d, 0.1, 2.0);
- RS::get_singleton()->viewport_set_scale_3d(viewport, RS::ViewportScale3D(scale_3d));
+ RS::get_singleton()->viewport_set_scale_3d(viewport, scale_3d);
}
-Viewport::Scale3D Viewport::get_scale_3d() const {
+float Viewport::get_scale_3d() const {
return scale_3d;
}
@@ -3582,7 +3585,7 @@ void Viewport::_bind_methods() {
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::FLOAT, "scale_3d", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "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");
@@ -3626,12 +3629,6 @@ 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);
@@ -3744,8 +3741,7 @@ Viewport::Viewport() {
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);
+ set_scale_3d(GLOBAL_GET("rendering/3d/viewport/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 3732f9cfd18..1f19ff04c9b 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -89,14 +89,6 @@ 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,
@@ -592,7 +584,7 @@ public:
#ifndef _3D_DISABLED
bool use_xr = false;
- Scale3D scale_3d = SCALE_3D_DISABLED;
+ float scale_3d = 1.0;
friend class AudioListener3D;
AudioListener3D *audio_listener_3d = nullptr;
Set audio_listener_3d_set;
@@ -664,8 +656,8 @@ 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;
+ void set_scale_3d(float p_scale_3d);
+ float get_scale_3d() const;
#endif // _3D_DISABLED
Viewport();
@@ -724,7 +716,6 @@ 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_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 74f18b1da53..b67b1cd8061 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -77,33 +77,17 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
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;
+ float scale_3d = p_viewport->scale_3d;
+ if (Engine::get_singleton()->is_editor_hint()) {
+ // Ignore the 3D viewport render scaling inside of the editor.
+ // The Half Resolution 3D editor viewport option should be used instead.
+ scale_3d = 1.0;
}
- 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;
- }
+ // Clamp 3D rendering resolution to reasonable values supported on most hardware.
+ // This prevents freezing the engine or outright crashing on lower-end GPUs.
+ const int width = CLAMP(p_viewport->size.width * scale_3d, 1, 16384);
+ const int height = CLAMP(p_viewport->size.height * scale_3d, 1, 16384);
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());
}
}
@@ -690,15 +674,18 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
_configure_3d_render_buffers(viewport);
}
-void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) {
+void RendererViewport::viewport_set_scale_3d(RID p_viewport, float p_scale_3d) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
- if (viewport->scale_3d == p_scale_3d) {
+ // Clamp to reasonable values that are actually useful.
+ // Values above 2.0 don't serve a practical purpose since the viewport
+ // isn't displayed with mipmaps.
+ if (viewport->scale_3d == CLAMP(p_scale_3d, 0.1, 2.0)) {
return;
}
- viewport->scale_3d = p_scale_3d;
+ viewport->scale_3d = CLAMP(p_scale_3d, 0.1, 2.0);
_configure_3d_render_buffers(viewport);
}
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 41d818cf990..f6e6cc8e842 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -49,7 +49,7 @@ 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;
+ float scale_3d = 1.0;
Size2i size;
RID camera;
@@ -207,7 +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_scale_3d(RID p_viewport, float p_scale_3d);
void viewport_set_size(RID p_viewport, int p_width, int p_height);
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 49ade3c6a15..911d4c463ba 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -526,7 +526,7 @@ public:
FUNCRIDSPLIT(viewport)
FUNC2(viewport_set_use_xr, RID, bool)
- FUNC2(viewport_set_scale_3d, RID, ViewportScale3D)
+ FUNC2(viewport_set_scale_3d, RID, float)
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 93919a5ec62..7e66ddbb0f5 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2269,12 +2269,6 @@ 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);
@@ -2817,11 +2811,11 @@ 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);
+ GLOBAL_DEF("rendering/3d/viewport/scale", 1.0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/3d/viewport/scale",
- PropertyInfo(Variant::INT,
+ PropertyInfo(Variant::FLOAT,
"rendering/3d/viewport/scale",
- PROPERTY_HINT_ENUM, "Disabled,75%,50%,33%,25%"));
+ PROPERTY_HINT_RANGE, "0.25,2.0,0.01"));
GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true);
GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 2dffa6bc75e..b50da66d031 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -752,19 +752,10 @@ 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_scale_3d(RID p_viewport, float 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;
@@ -1553,7 +1544,6 @@ 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);