Update viewport scaling demo to 4.x

The 3d_scaling demo was updated to use the built-in 3D scaling mechanisms
in the Forward+ and Mobile renderer (Compatibility in 4.3).

Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
This commit is contained in:
Ryan Roden-Corrent
2023-03-18 07:42:58 -04:00
committed by Hugo Locurcio
parent 4d01a2678f
commit 722bd11689
9 changed files with 146 additions and 79 deletions

View File

@@ -1,19 +1,15 @@
# 3D Viewport Scaling
# 3D Resolution Scaling
This demo shows how to scale the 3D viewport rendering without affecting 2D
elements such as the HUD. It also demonstrates how to toggle filtering on a
viewport. This technique can be useful in 2D games as well. For instance, it can
be used to have a "pixel art" viewport for the main game area and a
non-pixel-art viewport for HUD elements.
This demo shows how to downscale the 3D resolution without affecting 2D
elements, to improve performance without making the UI blurry.
See [Resolution scaling](https://docs.godotengine.org/en/stable/tutorials/3d/resolution_scaling.html)
in the documentation for details.
Language: GDScript
Renderer: GLES 2
Renderer: Forward+
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/586
## Screenshot
## Screenshots
![Screenshot](screenshots/high.png)
![Screenshot](screenshots/low.png)
![3D Resolution Scaling](screenshots/3d_scaling.webp)

View File

@@ -1,10 +1,80 @@
[gd_scene load_steps=2 format=3 uid="uid://bbnebk7xoaoto"]
[gd_scene load_steps=14 format=3 uid="uid://bbnebk7xoaoto"]
[sub_resource type="Gradient" id="Gradient_20ov5"]
offsets = PackedFloat32Array(0, 0.269231, 0.538462, 1)
colors = PackedColorArray(0, 0, 0, 1, 0.211332, 0.268774, 0.382711, 1, 0.248048, 0.560964, 0.645926, 1, 1, 1, 1, 1)
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ja65t"]
fractal_type = 2
fractal_gain = 0.333
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_gdmpo"]
height = 256
seamless = true
color_ramp = SubResource("Gradient_20ov5")
noise = SubResource("FastNoiseLite_ja65t")
[sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_me6gu"]
panorama = SubResource("NoiseTexture2D_gdmpo")
[sub_resource type="Sky" id="Sky_5j6vf"]
sky_material = SubResource("PanoramaSkyMaterial_me6gu")
[sub_resource type="Environment" id="Environment_0v44j"]
background_mode = 2
sky = SubResource("Sky_5j6vf")
tonemap_mode = 2
tonemap_white = 6.0
[sub_resource type="Gradient" id="Gradient_1dao0"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_y7cc2"]
frequency = 0.001
fractal_type = 2
fractal_lacunarity = 3.0
fractal_gain = 1.4
fractal_weighted_strength = 0.25
domain_warp_enabled = true
domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_42rpi"]
seamless = true
color_ramp = SubResource("Gradient_1dao0")
noise = SubResource("FastNoiseLite_y7cc2")
[sub_resource type="FastNoiseLite" id="FastNoiseLite_rxfm5"]
frequency = 0.001
fractal_type = 2
fractal_octaves = 2
fractal_lacunarity = 3.0
fractal_gain = 1.4
fractal_weighted_strength = 0.25
domain_warp_enabled = true
domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_gwux6"]
seamless = true
as_normal_map = true
bump_strength = 10.0
color_ramp = SubResource("Gradient_1dao0")
noise = SubResource("FastNoiseLite_rxfm5")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_sany7"]
albedo_texture = SubResource("NoiseTexture2D_42rpi")
normal_enabled = true
normal_texture = SubResource("NoiseTexture2D_gwux6")
uv1_scale = Vector3(6, 4, 1)
texture_filter = 5
[sub_resource type="BoxMesh" id="1"]
material = SubResource("StandardMaterial3D_sany7")
size = Vector3(2, 2, 2)
[node name="Cubes" type="Node3D"]
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_0v44j")
[node name="MeshInstance1" type="MeshInstance3D" parent="."]
mesh = SubResource("1")
@@ -12,11 +82,36 @@ mesh = SubResource("1")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, -1)
mesh = SubResource("1")
[node name="MeshInstance3" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 0)
mesh = SubResource("1")
[node name="MeshInstance4" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 1, -1)
mesh = SubResource("1")
[node name="MeshInstance5" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, 0)
mesh = SubResource("1")
[node name="MeshInstance6" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 1, -1)
mesh = SubResource("1")
[node name="MeshInstance7" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0)
mesh = SubResource("1")
[node name="MeshInstance8" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 1, -1)
mesh = SubResource("1")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(0.877582, 0.229849, -0.420736, 0, 0.877582, 0.479426, 0.479426, -0.420736, 0.770151, -1.68294, 2.25571, 3.0806)
fov = 74.0
[node name="OmniLight3D" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 2, 1)
light_energy = 3.0
shadow_enabled = true
shadow_bias = 0.08
shadow_bias = 0.02

View File

@@ -1,10 +0,0 @@
[gd_resource type="Environment" load_steps=3 format=3 uid="uid://gvgtl0xxtewa"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_fikmw"]
[sub_resource type="Sky" id="1"]
sky_material = SubResource("ProceduralSkyMaterial_fikmw")
[resource]
background_mode = 2
sky = SubResource("1")

View File

@@ -1,42 +1,34 @@
extends Control
# The 3D viewport's scale factor. For instance, 1.0 is full resolution,
# 0.5 is half resolution and 2.0 is double resolution. Higher values look
# sharper but are slower to render. Values above 1 can be used for supersampling
# (SSAA), but filtering must be enabled for supersampling to work.
var scale_factor = 1.0
@onready var viewport_container = $SubViewportContainer
@onready var viewport = $SubViewportContainer/SubViewport
# The 3D viewport's shrink factor. For instance, 1 is full resolution,
# 2 is half resolution and 4 is quarter resolution. Lower values look
# sharper but are slower to render.
var scale_factor = 1
var filter_mode = Viewport.SCALING_3D_MODE_BILINEAR
@onready var viewport = get_tree().root
@onready var scale_label = $VBoxContainer/Scale
@onready var filter_label = $VBoxContainer/Filter
func _ready():
viewport_container.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
# Required to change the 3D viewport's size when the window is resized.
viewport.size_changed.connect(self._root_viewport_size_changed)
func _ready():
viewport.scaling_3d_mode = Viewport.SCALING_3D_MODE_BILINEAR
func _unhandled_input(event):
if event.is_action_pressed("cycle_viewport_resolution"):
scale_factor = wrapf(scale_factor + 0.25, 0.25, 2.25)
viewport.size = get_viewport().size * scale_factor
scale_label.text = "Scale: %s%%" % str(scale_factor * 100)
scale_factor = wrapi(scale_factor + 1, 1, 5)
viewport.scaling_3d_scale = 1.0 / scale_factor
scale_label.text = "Scale: %3.0f%%" % (100.0 / scale_factor)
if event.is_action_pressed("toggle_filtering"):
# Toggle the Filter flag on the ViewportTexture.
if viewport_container.texture_filter == CanvasItem.TEXTURE_FILTER_LINEAR:
viewport_container.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
filter_label.text = "Filter: Disabled"
else:
viewport_container.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
filter_label.text = "Filter: Enabled"
# Called when the root's viewport size changes (i.e. when the window is resized).
# This is done to handle multiple resolutions without losing quality.
func _root_viewport_size_changed():
# The viewport is resized depending on the window height.
# To compensate for the larger resolution, the viewport sprite is scaled down.
viewport.size = get_viewport().size * scale_factor
filter_mode = wrapi(filter_mode + 1, Viewport.SCALING_3D_MODE_BILINEAR, Viewport.SCALING_3D_MODE_MAX) as Viewport.Scaling3DMode
viewport.scaling_3d_mode = filter_mode
filter_label.text = (
ClassDB.class_get_enum_constants("Viewport", "Scaling3DMode")[filter_mode]
.capitalize()
.replace("3d", "3D")
.replace("Mode", "Mode:")
.replace("Fsr", "FSR")
)

View File

@@ -10,48 +10,42 @@ layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = SubResource("2")
script = ExtResource("3")
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
texture_filter = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
stretch = true
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
handle_input_locally = false
size = Vector2i(1152, 648)
render_target_update_mode = 4
[node name="Cubes" parent="SubViewportContainer/SubViewport" instance=ExtResource("2")]
[node name="Cubes" parent="." instance=ExtResource("2")]
[node name="Help" type="Label" parent="."]
anchors_preset = 2
layout_mode = 0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 16.0
offset_top = -106.0
offset_right = 554.0
offset_bottom = -16.0
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 4
text = "This text will always render at the native resolution.
Press Space to adjust the 3D viewport's resolution scaling.
Press Enter to toggle filtering."
Press Enter to cycle filtering modes."
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 0
offset_left = 16.0
offset_top = 16.0
offset_right = 124.0
offset_bottom = 76.0
[node name="Scale" type="Label" parent="VBoxContainer"]
offset_right = 111.0
offset_bottom = 26.0
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 4
text = "Scale: 100%"
[node name="Filter" type="Label" parent="VBoxContainer"]
offset_top = 30.0
offset_right = 111.0
offset_bottom = 56.0
text = "Filter: Enabled"
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 4
text = "Scaling 3D Mode: Bilinear"

View File

@@ -18,7 +18,7 @@ be used to have a \"pixel art\" viewport for the main game area and a
non-pixel-art viewport for HUD elements."
config/tags=PackedStringArray("3d", "demo", "official", "rendering")
run/main_scene="res://hud.tscn"
config/features=PackedStringArray("4.2")
config/features=PackedStringArray("4.3")
config/icon="res://icon.webp"
[display]
@@ -30,15 +30,15 @@ window/stretch/aspect="expand"
cycle_viewport_resolution={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
toggle_filtering={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[rendering]
environment/defaults/default_environment="res://default_env.tres"
textures/default_filters/anisotropic_filtering_level=4

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB