Skip to content

Commit 5c4dd4c

Browse files
committed
Allow any Vector2 value as a 3D rendering scale option
This allows for finer control over 3D rendering resolution, including support for anamorphic scaling (different scale factor for the horizontal and vertical axis). Anamorphic scaling can be used to make the visual impact of lowering the rendering scale less noticeable, usually by reducing the widest/talleast axis' rendering scale first. Supersampling can also be performed by setting a 3D rendering resolution above 1.0, which is useful for offline rendering or for very high-end GPUs.
1 parent 4d08a73 commit 5c4dd4c

10 files changed

+36
-103
lines changed

doc/classes/ProjectSettings.xml

+4-3
Original file line numberDiff line numberDiff line change
@@ -1473,11 +1473,12 @@
14731473
</member>
14741474
<member name="rendering/2d/snap/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false">
14751475
</member>
1476-
<member name="rendering/3d/viewport/scale" type="int" setter="" getter="" default="0">
1477-
Scale the 3D render buffer based on the viewport size. The smaller the faster 3D rendering is performed but at the cost of quality.
1476+
<member name="rendering/3d/viewport/scale" type="Vector2" setter="" getter="" default="Vector2(1, 1)">
1477+
Scales the 3D render buffer on each axis 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). The value on each axis is clamped between [code]0.1[/code] and [code]2.0[/code]. See also [member rendering/anti_aliasing/quality/msaa] for multi-sample antialiasing, which is significantly cheaper but only smoothens the edges of polygons.
1478+
[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.
14781479
</member>
14791480
<member name="rendering/anti_aliasing/quality/msaa" type="int" setter="" getter="" default="0">
1480-
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.
1481+
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.
14811482
</member>
14821483
<member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0">
14831484
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.

doc/classes/RenderingServer.xml

+1-11
Original file line numberDiff line numberDiff line change
@@ -3085,7 +3085,7 @@
30853085
<method name="viewport_set_scale_3d">
30863086
<return type="void" />
30873087
<argument index="0" name="viewport" type="RID" />
3088-
<argument index="1" name="scale" type="int" enum="RenderingServer.ViewportScale3D" />
3088+
<argument index="1" name="scale" type="Vector2" />
30893089
<description>
30903090
Sets the scale at which we render 3D contents.
30913091
</description>
@@ -3904,16 +3904,6 @@
39043904
</constant>
39053905
<constant name="VIEWPORT_DEBUG_DRAW_OCCLUDERS" value="23" enum="ViewportDebugDraw">
39063906
</constant>
3907-
<constant name="VIEWPORT_SCALE_3D_DISABLED" value="0" enum="ViewportScale3D">
3908-
</constant>
3909-
<constant name="VIEWPORT_SCALE_3D_75_PERCENT" value="1" enum="ViewportScale3D">
3910-
</constant>
3911-
<constant name="VIEWPORT_SCALE_3D_50_PERCENT" value="2" enum="ViewportScale3D">
3912-
</constant>
3913-
<constant name="VIEWPORT_SCALE_3D_33_PERCENT" value="3" enum="ViewportScale3D">
3914-
</constant>
3915-
<constant name="VIEWPORT_SCALE_3D_25_PERCENT" value="4" enum="ViewportScale3D">
3916-
</constant>
39173907
<constant name="SKY_MODE_AUTOMATIC" value="0" enum="SkyMode">
39183908
</constant>
39193909
<constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode">

doc/classes/Viewport.xml

+5-13
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,18 @@
203203
<member name="lod_threshold" type="float" setter="set_lod_threshold" getter="get_lod_threshold" default="1.0">
204204
</member>
205205
<member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA" default="0">
206-
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.
206+
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.
207207
</member>
208208
<member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false">
209209
If [code]true[/code], the viewport will use the [World3D] defined in [member world_3d].
210210
</member>
211211
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
212212
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
213213
</member>
214-
<member name="scale_3d" type="int" setter="set_scale_3d" getter="get_scale_3d" enum="Viewport.Scale3D" default="0">
215-
The scale at which 3D content is rendered.
214+
<member name="scale_3d" type="Vector2" setter="set_scale_3d" getter="get_scale_3d" default="Vector2(1, 1)">
215+
Scales the 3D render buffer on each axis based on the viewport size and displays the result with linear filtering. Only values greater than [code]0.0[/code] are valid. 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). The value on each axis is clamped between [code]0.1[/code] and [code]2.0[/code]. See also [member msaa] for multi-sample antialiasing, which is significantly cheaper but only smoothens the edges of polygons.
216+
To control this property on the root viewport, set the [member ProjectSettings.rendering/3d/viewport/scale] project setting.
217+
[b]Note:[/b] [member scale_3d] should not be changed every frame as it will reallocate the buffer textures every time it is changed. This is a slow operation which can introduce stuttering if done too often.
216218
</member>
217219
<member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0">
218220
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.
@@ -274,16 +276,6 @@
274276
</signal>
275277
</signals>
276278
<constants>
277-
<constant name="SCALE_3D_DISABLED" value="0" enum="Scale3D">
278-
</constant>
279-
<constant name="SCALE_3D_75_PERCENT" value="1" enum="Scale3D">
280-
</constant>
281-
<constant name="SCALE_3D_50_PERCENT" value="2" enum="Scale3D">
282-
</constant>
283-
<constant name="SCALE_3D_33_PERCENT" value="3" enum="Scale3D">
284-
</constant>
285-
<constant name="SCALE_3D_25_PERCENT" value="4" enum="Scale3D">
286-
</constant>
287279
<constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED" value="0" enum="ShadowAtlasQuadrantSubdiv">
288280
This quadrant will not be used.
289281
</constant>

scene/main/viewport.cpp

+8-13
Original file line numberDiff line numberDiff line change
@@ -3456,13 +3456,15 @@ bool Viewport::is_using_xr() {
34563456
return use_xr;
34573457
}
34583458

3459-
void Viewport::set_scale_3d(const Scale3D p_scale_3d) {
3460-
scale_3d = p_scale_3d;
3459+
void Viewport::set_scale_3d(Vector2 p_scale_3d) {
3460+
// Clamp to reasonable values that are actually useful.
3461+
// For supersampling, values above 2.0 serve no purpose since the viewport isn't displayed with mipmaps.
3462+
scale_3d = Vector2(CLAMP(p_scale_3d.x, 0.1, 2.0), CLAMP(p_scale_3d.y, 0.1, 2.0));
34613463

3462-
RS::get_singleton()->viewport_set_scale_3d(viewport, RS::ViewportScale3D(scale_3d));
3464+
RS::get_singleton()->viewport_set_scale_3d(viewport, scale_3d);
34633465
}
34643466

3465-
Viewport::Scale3D Viewport::get_scale_3d() const {
3467+
Vector2 Viewport::get_scale_3d() const {
34663468
return scale_3d;
34673469
}
34683470

@@ -3595,7 +3597,7 @@ void Viewport::_bind_methods() {
35953597

35963598
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
35973599
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr");
3598-
ADD_PROPERTY(PropertyInfo(Variant::INT, "scale_3d", PROPERTY_HINT_ENUM, String::utf8("Disabled,75%,50%,33%,25%")), "set_scale_3d", "get_scale_3d");
3600+
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale_3d"), "set_scale_3d", "get_scale_3d");
35993601
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d");
36003602
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
36013603
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
@@ -3639,12 +3641,6 @@ void Viewport::_bind_methods() {
36393641
ADD_SIGNAL(MethodInfo("size_changed"));
36403642
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
36413643

3642-
BIND_ENUM_CONSTANT(SCALE_3D_DISABLED);
3643-
BIND_ENUM_CONSTANT(SCALE_3D_75_PERCENT);
3644-
BIND_ENUM_CONSTANT(SCALE_3D_50_PERCENT);
3645-
BIND_ENUM_CONSTANT(SCALE_3D_33_PERCENT);
3646-
BIND_ENUM_CONSTANT(SCALE_3D_25_PERCENT);
3647-
36483644
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
36493645
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1);
36503646
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4);
@@ -3760,8 +3756,7 @@ Viewport::Viewport() {
37603756
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
37613757

37623758
#ifndef _3D_DISABLED
3763-
int scale = GLOBAL_GET("rendering/3d/viewport/scale");
3764-
set_scale_3d((Scale3D)scale);
3759+
set_scale_3d(GLOBAL_GET("rendering/3d/viewport/scale"));
37653760
#endif // _3D_DISABLED
37663761

37673762
set_sdf_oversize(sdf_oversize); //set to server

scene/main/viewport.h

+3-12
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,6 @@ class Viewport : public Node {
8888
GDCLASS(Viewport, Node);
8989

9090
public:
91-
enum Scale3D {
92-
SCALE_3D_DISABLED,
93-
SCALE_3D_75_PERCENT,
94-
SCALE_3D_50_PERCENT,
95-
SCALE_3D_33_PERCENT,
96-
SCALE_3D_25_PERCENT
97-
};
98-
9991
enum ShadowAtlasQuadrantSubdiv {
10092
SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED,
10193
SHADOW_ATLAS_QUADRANT_SUBDIV_1,
@@ -585,7 +577,7 @@ class Viewport : public Node {
585577

586578
#ifndef _3D_DISABLED
587579
bool use_xr = false;
588-
Scale3D scale_3d = SCALE_3D_DISABLED;
580+
Vector2 scale_3d = Vector2(1.0, 1.0);
589581
friend class Listener3D;
590582
Listener3D *listener_3d = nullptr;
591583
Set<Listener3D *> listener_3d_set;
@@ -657,8 +649,8 @@ class Viewport : public Node {
657649
void set_use_xr(bool p_use_xr);
658650
bool is_using_xr();
659651

660-
void set_scale_3d(const Scale3D p_scale_3d);
661-
Scale3D get_scale_3d() const;
652+
void set_scale_3d(Vector2 p_scale_3d);
653+
Vector2 get_scale_3d() const;
662654
#endif // _3D_DISABLED
663655

664656
Viewport();
@@ -717,7 +709,6 @@ VARIANT_ENUM_CAST(SubViewport::UpdateMode);
717709
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
718710
VARIANT_ENUM_CAST(Viewport::MSAA);
719711
VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA);
720-
VARIANT_ENUM_CAST(Viewport::Scale3D);
721712
VARIANT_ENUM_CAST(Viewport::DebugDraw);
722713
VARIANT_ENUM_CAST(Viewport::SDFScale);
723714
VARIANT_ENUM_CAST(Viewport::SDFOversize);

servers/rendering/renderer_viewport.cpp

+10-26
Original file line numberDiff line numberDiff line change
@@ -77,33 +77,17 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
7777
RSG::scene->free(p_viewport->render_buffers);
7878
p_viewport->render_buffers = RID();
7979
} else {
80-
RS::ViewportScale3D scale_3d = p_viewport->scale_3d;
81-
if (Engine::get_singleton()->is_editor_hint()) { // ignore this inside of the editor
82-
scale_3d = RS::VIEWPORT_SCALE_3D_DISABLED;
80+
Vector2 scale_3d = p_viewport->scale_3d;
81+
if (Engine::get_singleton()->is_editor_hint()) {
82+
// Ignore the 3D viewport render scaling inside of the editor.
83+
// The Half Resolution 3D editor viewport option should be used instead.
84+
scale_3d = Vector2(1.0, 1.0);
8385
}
8486

85-
int width = p_viewport->size.width;
86-
int height = p_viewport->size.height;
87-
switch (scale_3d) {
88-
case RS::VIEWPORT_SCALE_3D_75_PERCENT: {
89-
width = (width * 3) / 4;
90-
height = (height * 3) / 4;
91-
}; break;
92-
case RS::VIEWPORT_SCALE_3D_50_PERCENT: {
93-
width = width >> 1;
94-
height = height >> 1;
95-
}; break;
96-
case RS::VIEWPORT_SCALE_3D_33_PERCENT: {
97-
width = width / 3;
98-
height = height / 3;
99-
}; break;
100-
case RS::VIEWPORT_SCALE_3D_25_PERCENT: {
101-
width = width >> 2;
102-
height = height >> 2;
103-
}; break;
104-
default:
105-
break;
106-
}
87+
// Clamp 3D rendering resolution to reasonable values supported on most hardware.
88+
// This prevents freezing the engine or outright crashing on lower-end GPUs.
89+
const int width = CLAMP(p_viewport->size.width * scale_3d.x, 1, 16384);
90+
const int height = CLAMP(p_viewport->size.height * scale_3d.y, 1, 16384);
10791
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());
10892
}
10993
}
@@ -690,7 +674,7 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
690674
_configure_3d_render_buffers(viewport);
691675
}
692676

693-
void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) {
677+
void RendererViewport::viewport_set_scale_3d(RID p_viewport, Vector2 p_scale_3d) {
694678
Viewport *viewport = viewport_owner.getornull(p_viewport);
695679
ERR_FAIL_COND(!viewport);
696680

servers/rendering/renderer_viewport.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class RendererViewport {
4949

5050
bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */
5151

52-
RS::ViewportScale3D scale_3d = RenderingServer::VIEWPORT_SCALE_3D_DISABLED;
52+
Vector2 scale_3d = Vector2(1.0, 1.0);
5353

5454
Size2i size;
5555
RID camera;
@@ -207,7 +207,7 @@ class RendererViewport {
207207
void viewport_initialize(RID p_rid);
208208

209209
void viewport_set_use_xr(RID p_viewport, bool p_use_xr);
210-
void viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d);
210+
void viewport_set_scale_3d(RID p_viewport, Vector2 p_scale_3d);
211211

212212
void viewport_set_size(RID p_viewport, int p_width, int p_height);
213213

servers/rendering/rendering_server_default.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ class RenderingServerDefault : public RenderingServer {
526526
FUNCRIDSPLIT(viewport)
527527

528528
FUNC2(viewport_set_use_xr, RID, bool)
529-
FUNC2(viewport_set_scale_3d, RID, ViewportScale3D)
529+
FUNC2(viewport_set_scale_3d, RID, Vector2)
530530
FUNC3(viewport_set_size, RID, int, int)
531531

532532
FUNC2(viewport_set_active, RID, bool)

servers/rendering_server.cpp

+1-11
Original file line numberDiff line numberDiff line change
@@ -2256,12 +2256,6 @@ void RenderingServer::_bind_methods() {
22562256
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES);
22572257
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OCCLUDERS);
22582258

2259-
BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_DISABLED);
2260-
BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_75_PERCENT);
2261-
BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_50_PERCENT);
2262-
BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_33_PERCENT);
2263-
BIND_ENUM_CONSTANT(VIEWPORT_SCALE_3D_25_PERCENT);
2264-
22652259
/* SKY API */
22662260

22672261
ClassDB::bind_method(D_METHOD("sky_create"), &RenderingServer::sky_create);
@@ -2802,11 +2796,7 @@ RenderingServer::RenderingServer() {
28022796
"rendering/vulkan/rendering/back_end",
28032797
PROPERTY_HINT_ENUM, "Forward Clustered (Supports Desktop Only),Forward Mobile (Supports Desktop and Mobile)"));
28042798

2805-
GLOBAL_DEF("rendering/3d/viewport/scale", 0);
2806-
ProjectSettings::get_singleton()->set_custom_property_info("rendering/3d/viewport/scale",
2807-
PropertyInfo(Variant::INT,
2808-
"rendering/3d/viewport/scale",
2809-
PROPERTY_HINT_ENUM, "Disabled,75%,50%,33%,25%"));
2799+
GLOBAL_DEF("rendering/3d/viewport/scale", Vector2(1.0, 1.0));
28102800

28112801
GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true);
28122802
GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true);

servers/rendering_server.h

+1-11
Original file line numberDiff line numberDiff line change
@@ -752,19 +752,10 @@ class RenderingServer : public Object {
752752
CANVAS_ITEM_TEXTURE_REPEAT_MAX,
753753
};
754754

755-
enum ViewportScale3D {
756-
VIEWPORT_SCALE_3D_DISABLED,
757-
VIEWPORT_SCALE_3D_75_PERCENT,
758-
VIEWPORT_SCALE_3D_50_PERCENT,
759-
VIEWPORT_SCALE_3D_33_PERCENT,
760-
VIEWPORT_SCALE_3D_25_PERCENT,
761-
VIEWPORT_SCALE_3D_MAX,
762-
};
763-
764755
virtual RID viewport_create() = 0;
765756

766757
virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0;
767-
virtual void viewport_set_scale_3d(RID p_viewport, ViewportScale3D p_scale_3d) = 0;
758+
virtual void viewport_set_scale_3d(RID p_viewport, Vector2 p_scale_3d) = 0;
768759
virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0;
769760
virtual void viewport_set_active(RID p_viewport, bool p_active) = 0;
770761
virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0;
@@ -1553,7 +1544,6 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw);
15531544
VARIANT_ENUM_CAST(RenderingServer::ViewportOcclusionCullingBuildQuality);
15541545
VARIANT_ENUM_CAST(RenderingServer::ViewportSDFOversize);
15551546
VARIANT_ENUM_CAST(RenderingServer::ViewportSDFScale);
1556-
VARIANT_ENUM_CAST(RenderingServer::ViewportScale3D);
15571547
VARIANT_ENUM_CAST(RenderingServer::SkyMode);
15581548
VARIANT_ENUM_CAST(RenderingServer::EnvironmentBG);
15591549
VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);

0 commit comments

Comments
 (0)