Skip to content

Commit

Permalink
Merge pull request #51870 from BastiaanOlij/half_resolution_3d
Browse files Browse the repository at this point in the history
Optionally render 3D content at scaled resolution
  • Loading branch information
reduz authored Aug 26, 2021
2 parents eb940ca + 64626cc commit 227ab24
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 34 deletions.
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,9 @@
</member>
<member name="rendering/2d/snap/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/3d/viewport/scale" type="int" setter="" getter="" default="0">
Scale the 3D render buffer based on the viewport size. The smaller the faster 3D rendering is performed but at the cost of quality.
</member>
<member name="rendering/anti_aliasing/quality/msaa" type="int" setter="" getter="" default="0">
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.
</member>
Expand Down
18 changes: 18 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</description>
</method>
<method name="viewport_set_scale_3d">
<return type="void" />
<argument index="0" name="viewport" type="RID" />
<argument index="1" name="scale" type="int" enum="RenderingServer.ViewportScale3D" />
<description>
Sets the scale at which we render 3D contents.
</description>
</method>
<method name="viewport_set_scenario">
<return type="void" />
<argument index="0" name="viewport" type="RID" />
Expand Down Expand Up @@ -3896,6 +3904,16 @@
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_OCCLUDERS" value="23" enum="ViewportDebugDraw">
</constant>
<constant name="VIEWPORT_SCALE_3D_DISABLED" value="0" enum="ViewportScale3D">
</constant>
<constant name="VIEWPORT_SCALE_3D_75_PERCENT" value="1" enum="ViewportScale3D">
</constant>
<constant name="VIEWPORT_SCALE_3D_50_PERCENT" value="2" enum="ViewportScale3D">
</constant>
<constant name="VIEWPORT_SCALE_3D_33_PERCENT" value="3" enum="ViewportScale3D">
</constant>
<constant name="VIEWPORT_SCALE_3D_25_PERCENT" value="4" enum="ViewportScale3D">
</constant>
<constant name="SKY_MODE_AUTOMATIC" value="0" enum="SkyMode">
</constant>
<constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode">
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
</member>
<member name="scale_3d" type="int" setter="set_scale_3d" getter="get_scale_3d" enum="Viewport.Scale3D" default="0">
The scale at which 3D content is rendered.
</member>
<member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0">
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.
</member>
Expand Down Expand Up @@ -271,6 +274,16 @@
</signal>
</signals>
<constants>
<constant name="SCALE_3D_DISABLED" value="0" enum="Scale3D">
</constant>
<constant name="SCALE_3D_75_PERCENT" value="1" enum="Scale3D">
</constant>
<constant name="SCALE_3D_50_PERCENT" value="2" enum="Scale3D">
</constant>
<constant name="SCALE_3D_33_PERCENT" value="3" enum="Scale3D">
</constant>
<constant name="SCALE_3D_25_PERCENT" value="4" enum="Scale3D">
</constant>
<constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED" value="0" enum="ShadowAtlasQuadrantSubdiv">
This quadrant will not be used.
</constant>
Expand Down
8 changes: 8 additions & 0 deletions drivers/vulkan/rendering_device_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_

Expand Down
1 change: 1 addition & 0 deletions drivers/vulkan/rendering_device_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
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);
Expand Down
26 changes: 26 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
}

Expand Down
13 changes: 13 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -577,6 +585,7 @@ class Viewport : public Node {

#ifndef _3D_DISABLED
bool use_xr = false;
Scale3D scale_3d = SCALE_3D_DISABLED;
friend class Listener3D;
Listener3D *listener_3d = nullptr;
Set<Listener3D *> listener_3d_set;
Expand Down Expand Up @@ -647,6 +656,9 @@ class Viewport : public Node {

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();
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand All @@ -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))) {
Expand Down
10 changes: 6 additions & 4 deletions servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand All @@ -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);
}
}

Expand Down
Loading

0 comments on commit 227ab24

Please sign in to comment.