Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/RenderSceneBuffersConfiguration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<member name="render_target" type="RID" setter="set_render_target" getter="get_render_target" default="RID()">
The render target associated with these buffer.
</member>
<member name="scaling_3d_custom_upscaler" type="RID" setter="set_scaling_3d_custom_upscaler" getter="get_scaling_3d_custom_upscaler" default="RID()">
The custom viewport upscaler to use if [member scaling_3d_mode] is [constant RenderingServer.VIEWPORT_SCALING_3D_MODE_CUSTOM].
</member>
<member name="scaling_3d_mode" type="int" setter="set_scaling_3d_mode" getter="get_scaling_3d_mode" enum="RenderingServer.ViewportScaling3DMode" default="255">
The requested scaling mode with which we upscale/downscale if [member internal_size] and [member target_size] are not equal.
</member>
Expand Down
19 changes: 19 additions & 0 deletions doc/classes/RenderSceneBuffersRD.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@
Returns the render target associated with this buffers object.
</description>
</method>
<method name="get_scaling_3d_custom_upscaler" qualifiers="const">
<return type="RID" />
<description>
The custom viewport upscaler being used if [method get_scaling_3d_mode] returns [code]VIEWPORT_SCALING_3D_MODE_CUSTOM[/code].
</description>
</method>
<method name="get_scaling_3d_mode" qualifiers="const">
<return type="int" enum="RenderingServer.ViewportScaling3DMode" />
<description>
Expand Down Expand Up @@ -188,6 +194,19 @@
Returns a specific view of a slice (layer or mipmap) for a cached texture.
</description>
</method>
<method name="get_upscaled_layer">
<return type="RID" />
<param index="0" name="layer" type="int" />
<description>
Returns the specified layer from the upscaled texture used if 3D scaling is set to [code]FSR2[/code], [code]MetalFX (Temporal)[/code], or [code]custom[/code].
</description>
</method>
<method name="get_upscaled_texture" qualifiers="const">
<return type="RID" />
<description>
Returns the upscaled texture used if 3D scaling is set to [code]FSR2[/code], [code]MetalFX (Temporal)[/code], or [code]custom[/code].
</description>
</method>
<method name="get_use_debanding" qualifiers="const">
<return type="bool" />
<description>
Expand Down
51 changes: 50 additions & 1 deletion doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4356,6 +4356,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 screen_texture. 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.
</description>
</method>
<method name="viewport_set_scaling_3d_custom_upscaler">
<return type="void" />
<param index="0" name="viewport" type="RID" />
<param index="1" name="upscaler" type="RID" />
<description>
The custom viewport upscaler to use if [method viewport_set_scaling_3d_mode] was set to [constant VIEWPORT_SCALING_3D_MODE_CUSTOM].
</description>
</method>
<method name="viewport_set_scaling_3d_mode">
<return type="void" />
<param index="0" name="viewport" type="RID" />
Expand Down Expand Up @@ -4515,6 +4523,44 @@
If set to [constant RenderingServer.VIEWPORT_VRS_UPDATE_ONCE], the input texture is copied once and the mode is changed to [constant RenderingServer.VIEWPORT_VRS_UPDATE_DISABLED].
</description>
</method>
<method name="viewport_upscaler_create">
<return type="RID" />
<description>
Creates a new viewport upscaler object.
</description>
</method>
<method name="viewport_upscaler_set_jitter_phase_count">
<return type="void" />
<param index="0" name="viewport_upscaler" type="RID" />
<param index="1" name="jitter_phase_count" type="int" />
<description>
Sets the jitter phase count that will be used for a viewport using this upscaler.
</description>
</method>
<method name="viewport_upscaler_set_mipmap_bias">
<return type="void" />
<param index="0" name="viewport_upscaler" type="RID" />
<param index="1" name="mipmap_bias" type="float" />
<description>
Sets the mipmap bias that will be subtracted from the computer mipmap bias for a viewport using this upscaler.
</description>
</method>
<method name="viewport_upscaler_set_render_callback">
<return type="void" />
<param index="0" name="viewport_upscaler" type="RID" />
<param index="1" name="callback" type="Callable" />
<description>
Sets the callback that is called when this upscaler is used to upscale. The method called should implement the actual upscale logic.
</description>
</method>
<method name="viewport_upscaler_set_requires_motion_vectors">
<return type="void" />
<param index="0" name="viewport_upscaler" type="RID" />
<param index="1" name="requires_motion_vectors" type="bool" />
<description>
If set to [code]true[/code], this upscaler requires motion vectors to be produced.
</description>
</method>
<method name="visibility_notifier_create">
<return type="RID" />
<description>
Expand Down Expand Up @@ -5361,7 +5407,10 @@
Use nearest-neighbor filtering for the viewport's 3D buffer. This looks crisper than [constant VIEWPORT_SCALING_3D_MODE_BILINEAR] and has no additional rendering cost. The amount of scaling can be set using [member Viewport.scaling_3d_scale]. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] disables scaling.
[b]Note:[/b] When using the [b]Nearest[/b] scaling mode, to avoid uneven pixel scaling, it's highly recommended to use a value equal to an integer divisor with a dividend of [code]1[/code]. For example, it's best to use a scale of [code]0.5[/code] (1/2), [code]0.3333[/code] (1/3), [code]0.25[/code] (1/4), [code]0.2[/code] (1/5), and so on.
</constant>
<constant name="VIEWPORT_SCALING_3D_MODE_MAX" value="6" enum="ViewportScaling3DMode">
<constant name="VIEWPORT_SCALING_3D_MODE_CUSTOM" value="6" enum="ViewportScaling3DMode">
Use a custom viewport upscaler for the viewport's 3D buffer. The amount of scaling can be set using [member Viewport.scaling_3d_scale].
</constant>
<constant name="VIEWPORT_SCALING_3D_MODE_MAX" value="7" enum="ViewportScaling3DMode">
Represents the size of the [enum ViewportScaling3DMode] enum.
</constant>
<constant name="VIEWPORT_UPDATE_DISABLED" value="0" enum="ViewportUpdateMode">
Expand Down
8 changes: 7 additions & 1 deletion doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@
The shadow atlas' resolution (used for omni and spot lights). The value is rounded up to the nearest power of 2.
[b]Note:[/b] If this is set to [code]0[/code], no positional shadows will be visible at all. This can improve performance significantly on low-end systems by reducing both the CPU and GPU load (as fewer draw calls are needed to draw the scene without shadows).
</member>
<member name="scaling_3d_custom_upscaler" type="ViewportUpscaler" setter="set_scaling_3d_custom_upscaler" getter="get_scaling_3d_custom_upscaler">
The custom viewport upscaler to use if [member scaling_3d_mode] is set to [constant SCALING_3D_MODE_CUSTOM].
</member>
<member name="scaling_3d_mode" type="int" setter="set_scaling_3d_mode" getter="get_scaling_3d_mode" enum="Viewport.Scaling3DMode" default="0">
Sets scaling 3D mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. FSR should be used where possible.
To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/mode] project setting.
Expand Down Expand Up @@ -578,7 +581,10 @@
Use nearest-neighbor filtering for the viewport's 3D buffer. This looks crisper than [constant SCALING_3D_MODE_BILINEAR] and has no additional rendering cost. The amount of scaling can be set using [member scaling_3d_scale]. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] disables scaling.
[b]Note:[/b] When using the [b]Nearest[/b] scaling mode, to avoid uneven pixel scaling, it's highly recommended to use a value equal to an integer divisor with a dividend of [code]1[/code]. For example, it's best to use a scale of [code]0.5[/code] (1/2), [code]0.3333[/code] (1/3), [code]0.25[/code] (1/4), [code]0.2[/code] (1/5), and so on.
</constant>
<constant name="SCALING_3D_MODE_MAX" value="6" enum="Scaling3DMode">
<constant name="SCALING_3D_MODE_CUSTOM" value="6" enum="Scaling3DMode">
Use a custom viewport upscaler for the viewport's 3D buffer. The amount of scaling can be set using [member scaling_3d_scale].
</constant>
<constant name="SCALING_3D_MODE_MAX" value="7" enum="Scaling3DMode">
Represents the size of the [enum Scaling3DMode] enum.
</constant>
<constant name="MSAA_DISABLED" value="0" enum="MSAA">
Expand Down
31 changes: 31 additions & 0 deletions doc/classes/ViewportUpscaler.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ViewportUpscaler" inherits="Resource" api_type="core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Base class for implementing viewport upscalers.
</brief_description>
<description>
This resource type allows you to implement a viewport upscaler that can be used if the 3D scaling mode of a viewport is set to [constant Viewport.SCALING_3D_MODE_CUSTOM].
</description>
<tutorials>
</tutorials>
<methods>
<method name="_render_callback" qualifiers="virtual">
<return type="void" />
<param index="0" name="render_data" type="RenderData" />
<description>
This method is called by the rendering thread, implement your upscale logic here. Use [method RenderSceneBuffersRD.get_color_layer] to access the rendering result and [method RenderSceneBuffersRD.get_upscaled_layer] to access the destination buffer.
</description>
</method>
</methods>
<members>
<member name="jitter_phase_count" type="int" setter="set_jitter_phase_count" getter="get_jitter_phase_count">
The jitter phase count that will be used for a viewport using this upscaler.
</member>
<member name="mipmap_bias" type="float" setter="set_mipmap_bias" getter="get_mipmap_bias">
The mipmap bias that will be subtracted from the computer mipmap bias for a viewport using this upscaler.
</member>
<member name="requires_motion_vectors" type="bool" setter="set_requires_motion_vectors" getter="get_requires_motion_vectors">
If [code]true[/code] this upscaler requires motion vectors.
</member>
</members>
</class>
35 changes: 34 additions & 1 deletion scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5055,8 +5055,14 @@ void Viewport::set_scaling_3d_mode(Scaling3DMode p_scaling_3d_mode) {
return;
}

if (p_scaling_3d_mode != SCALING_3D_MODE_CUSTOM && scaling_3d_custom_upscaler.is_valid()) {
set_scaling_3d_custom_upscaler(Ref<ViewportUpscaler>());
}

scaling_3d_mode = p_scaling_3d_mode;
RS::get_singleton()->viewport_set_scaling_3d_mode(viewport, (RSE::ViewportScaling3DMode)(int)p_scaling_3d_mode);

notify_property_list_changed();
}

Viewport::Scaling3DMode Viewport::get_scaling_3d_mode() const {
Expand All @@ -5079,6 +5085,23 @@ float Viewport::get_scaling_3d_scale() const {
return scaling_3d_scale;
}

void Viewport::set_scaling_3d_custom_upscaler(const Ref<ViewportUpscaler> &p_upscaler) {
ERR_MAIN_THREAD_GUARD;
ERR_FAIL_COND_MSG(scaling_3d_mode != SCALING_3D_MODE_CUSTOM && p_upscaler.is_valid(), "Can't set a custom upscaler if the scaling mode isn't set to custom.");

scaling_3d_custom_upscaler = p_upscaler;
if (p_upscaler.is_valid()) {
RS::get_singleton()->viewport_set_scaling_3d_custom_upscaler(viewport, p_upscaler->get_rid());
} else {
RS::get_singleton()->viewport_set_scaling_3d_custom_upscaler(viewport, RID());
}
}

Ref<ViewportUpscaler> Viewport::get_scaling_3d_custom_upscaler() const {
ERR_READ_THREAD_GUARD_V(Ref<ViewportUpscaler>());
return scaling_3d_custom_upscaler;
}

void Viewport::set_fsr_sharpness(float p_fsr_sharpness) {
ERR_MAIN_THREAD_GUARD;
if (fsr_sharpness == p_fsr_sharpness) {
Expand Down Expand Up @@ -5328,6 +5351,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_scaling_3d_scale", "scale"), &Viewport::set_scaling_3d_scale);
ClassDB::bind_method(D_METHOD("get_scaling_3d_scale"), &Viewport::get_scaling_3d_scale);

ClassDB::bind_method(D_METHOD("set_scaling_3d_custom_upscaler", "upscaler"), &Viewport::set_scaling_3d_custom_upscaler);
ClassDB::bind_method(D_METHOD("get_scaling_3d_custom_upscaler"), &Viewport::get_scaling_3d_custom_upscaler);

ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &Viewport::set_fsr_sharpness);
ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &Viewport::get_fsr_sharpness);

Expand Down Expand Up @@ -5371,8 +5397,9 @@ void Viewport::_bind_methods() {

#ifndef _3D_DISABLED
ADD_GROUP("Scaling 3D", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Nearest (Fastest):5,Bilinear (Fastest):0,FSR 1.0 (Fast):1,FSR 2.2 (Slow):2,MetalFX (Spatial - Fast):3,MetalFX (Temporal - Slow):4"), "set_scaling_3d_mode", "get_scaling_3d_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Nearest (Fastest):5,Bilinear (Fastest):0,FSR 1.0 (Fast):1,FSR 2.2 (Slow):2,MetalFX (Spatial - Fast):3,MetalFX (Temporal - Slow):4,Custom:6"), "set_scaling_3d_mode", "get_scaling_3d_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scaling_3d_scale", PROPERTY_HINT_RANGE, "0.1,2.0,0.0001"), "set_scaling_3d_scale", "get_scaling_3d_scale");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scaling_3d_custom_upscaler", PROPERTY_HINT_RESOURCE_TYPE, "ViewportUpscaler"), "set_scaling_3d_custom_upscaler", "get_scaling_3d_custom_upscaler");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.001"), "set_texture_mipmap_bias", "get_texture_mipmap_bias");
ADD_PROPERTY(PropertyInfo(Variant::INT, "anisotropic_filtering_level", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Faster),4× (Fast),8× (Average),16x (Slow)")), "set_anisotropic_filtering_level", "get_anisotropic_filtering_level");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_fsr_sharpness", "get_fsr_sharpness");
Expand Down Expand Up @@ -5435,6 +5462,7 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(SCALING_3D_MODE_METALFX_SPATIAL);
BIND_ENUM_CONSTANT(SCALING_3D_MODE_METALFX_TEMPORAL);
BIND_ENUM_CONSTANT(SCALING_3D_MODE_NEAREST);
BIND_ENUM_CONSTANT(SCALING_3D_MODE_CUSTOM);
BIND_ENUM_CONSTANT(SCALING_3D_MODE_MAX);

BIND_ENUM_CONSTANT(MSAA_DISABLED);
Expand Down Expand Up @@ -5534,6 +5562,11 @@ void Viewport::_validate_property(PropertyInfo &p_property) const {
if (!Engine::get_singleton()->is_editor_hint()) {
return;
}

if (scaling_3d_mode != SCALING_3D_MODE_CUSTOM && (p_property.name == "scaling_3d_custom_upscaler")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}

if (vrs_mode != VRS_TEXTURE && (p_property.name == "vrs_texture")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
} else if (vrs_mode == VRS_DISABLED && (p_property.name == "vrs_update_mode")) {
Expand Down
6 changes: 6 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "scene/main/node.h"
#include "scene/resources/texture.h"
#include "scene/resources/viewport_upscaler.h"
#include "servers/display/display_server_enums.h"
#include "servers/rendering/rendering_server_enums.h"

Expand Down Expand Up @@ -104,6 +105,7 @@ class Viewport : public Node {
SCALING_3D_MODE_METALFX_SPATIAL,
SCALING_3D_MODE_METALFX_TEMPORAL,
SCALING_3D_MODE_NEAREST,
SCALING_3D_MODE_CUSTOM,
SCALING_3D_MODE_MAX
};

Expand Down Expand Up @@ -322,6 +324,7 @@ class Viewport : public Node {

Scaling3DMode scaling_3d_mode = SCALING_3D_MODE_BILINEAR;
float scaling_3d_scale = 1.0;
Ref<ViewportUpscaler> scaling_3d_custom_upscaler;
float fsr_sharpness = 0.2f;
float texture_mipmap_bias = 0.0f;
AnisotropicFiltering anisotropic_filtering_level = ANISOTROPY_4X;
Expand Down Expand Up @@ -607,6 +610,9 @@ class Viewport : public Node {
void set_scaling_3d_scale(float p_scaling_3d_scale);
float get_scaling_3d_scale() const;

void set_scaling_3d_custom_upscaler(const Ref<ViewportUpscaler> &p_upscaler);
Ref<ViewportUpscaler> get_scaling_3d_custom_upscaler() const;

void set_fsr_sharpness(float p_fsr_sharpness);
float get_fsr_sharpness() const;

Expand Down
2 changes: 2 additions & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
#include "scene/resources/texture_rd.h"
#include "scene/resources/theme.h"
#include "scene/resources/video_stream.h"
#include "scene/resources/viewport_upscaler.h"
#include "scene/theme/theme_db.h"
#include "servers/display/display_server.h"
#include "servers/rendering/rendering_server.h"
Expand Down Expand Up @@ -452,6 +453,7 @@ void register_scene_types() {
GDREGISTER_CLASS(ViewportTexture);

GDREGISTER_VIRTUAL_CLASS(CompositorEffect);
GDREGISTER_VIRTUAL_CLASS(ViewportUpscaler);

GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer);
GDREGISTER_CLASS(MultiplayerPeerExtension);
Expand Down
Loading