Browse Source

Merge pull request #413 from Calinou/add-viewport-3d-scaling-demo

Add a viewport 3D scaling demo
Aaron Franke 5 years ago
parent
commit
001e51d2d3

+ 11 - 0
viewport/3d_scaling/README.md

@@ -0,0 +1,11 @@
+# 3D 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 by using TextureRect to display the ViewportTexture
+delivered by the Viewport node. 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.
+
+ViewportContainer can also be used to display a viewport in a GUI, but it
+doesn't offer the ability to enable filtering.

+ 9 - 0
viewport/3d_scaling/default_env.tres

@@ -0,0 +1,9 @@
+[gd_resource type="Environment" load_steps=2 format=2]
+
+[sub_resource type="ProceduralSky" id=1]
+sky_top_color = Color( 0.207843, 0.239216, 0.254902, 1 )
+sky_horizon_color = Color( 0.466667, 0.478431, 0.490196, 1 )
+
+[resource]
+background_mode = 2
+background_sky = SubResource( 1 )

+ 42 - 0
viewport/3d_scaling/hud.gd

@@ -0,0 +1,42 @@
+extends Control
+
+# The viewport is displayed using a TextureRect node instead of a ViewportContainer.
+# This allows filtering the texture that's displayed in the root viewport.
+
+# 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 this to work.
+var scale_factor = 1.0
+
+onready var texture_rect = $TextureRect
+onready var viewport = $TextureRect/Viewport
+onready var scale_label = $VBoxContainer/Scale
+onready var filter_label = $VBoxContainer/Filter
+
+func _ready():
+	# Required to change the 3D viewport's size when the window is resized.
+	# warning-ignore:return_value_discarded
+	get_viewport().connect("size_changed", self, "_root_viewport_size_changed")
+
+
+func _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)
+
+	if event.is_action_pressed("toggle_filtering"):
+		# Toggle the Filter flag on the ViewportTexture.
+		texture_rect.texture.flags ^= ImageTexture.FLAG_FILTER
+
+		var filter_enabled = texture_rect.texture.flags & ImageTexture.FLAG_FILTER
+		filter_label.text = "Filter: %s" % ("Enabled" if filter_enabled else "Disabled")
+
+
+# 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

+ 104 - 0
viewport/3d_scaling/hud.tscn

@@ -0,0 +1,104 @@
+[gd_scene load_steps=7 format=2]
+
+[ext_resource path="res://noto_sans_ui_regular.ttf" type="DynamicFontData" id=1]
+[ext_resource path="res://spatial.tscn" type="PackedScene" id=2]
+[ext_resource path="res://hud.gd" type="Script" id=3]
+
+[sub_resource type="DynamicFont" id=1]
+size = 20
+font_data = ExtResource( 1 )
+
+[sub_resource type="Theme" id=2]
+default_font = SubResource( 1 )
+
+[sub_resource type="ViewportTexture" id=3]
+viewport_path = NodePath("TextureRect/Viewport")
+
+[node name="HUD" type="Control"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+theme = SubResource( 2 )
+script = ExtResource( 3 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="TextureRect" type="TextureRect" parent="."]
+anchor_right = 1.0
+anchor_bottom = 1.0
+texture = SubResource( 3 )
+expand = true
+flip_v = true
+__meta__ = {
+"_edit_use_anchors_": false,
+"_editor_description_": ""
+}
+
+[node name="Viewport" type="Viewport" parent="TextureRect"]
+size = Vector2( 1024, 600 )
+handle_input_locally = false
+usage = 3
+render_target_update_mode = 3
+shadow_atlas_size = 4096
+
+[node name="Spatial" parent="TextureRect/Viewport" instance=ExtResource( 2 )]
+
+[node name="ViewportContainer" type="ViewportContainer" parent="."]
+anchor_right = 1.0
+anchor_bottom = 1.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Help" type="Label" parent="."]
+anchor_top = 1.0
+anchor_bottom = 1.0
+margin_left = 16.0
+margin_top = -106.0
+margin_right = 554.0
+margin_bottom = -16.0
+custom_fonts/font = SubResource( 1 )
+custom_colors/font_color_shadow = Color( 0, 0, 0, 0.752941 )
+custom_constants/shadow_offset_x = 2
+custom_constants/shadow_offset_y = 2
+custom_constants/shadow_as_outline = 0
+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."
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+margin_left = 16.0
+margin_top = 16.0
+margin_right = 124.0
+margin_bottom = 76.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Scale" type="Label" parent="VBoxContainer"]
+margin_right = 137.0
+margin_bottom = 28.0
+custom_colors/font_color_shadow = Color( 0, 0, 0, 0.752941 )
+custom_constants/shadow_offset_x = 2
+custom_constants/shadow_offset_y = 2
+custom_constants/shadow_as_outline = 0
+text = "Scale: 100%"
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Filter" type="Label" parent="VBoxContainer"]
+margin_top = 32.0
+margin_right = 137.0
+margin_bottom = 60.0
+custom_colors/font_color_shadow = Color( 0, 0, 0, 0.752941 )
+custom_constants/shadow_offset_x = 2
+custom_constants/shadow_offset_y = 2
+custom_constants/shadow_as_outline = 0
+text = "Filter: Disabled"
+__meta__ = {
+"_edit_use_anchors_": false
+}

BIN
viewport/3d_scaling/icon.png


+ 34 - 0
viewport/3d_scaling/icon.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.png"
+dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0

BIN
viewport/3d_scaling/noto_sans_ui_regular.ttf


+ 43 - 0
viewport/3d_scaling/project.godot

@@ -0,0 +1,43 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+;   [section] ; section goes between []
+;   param=value ; assign values to parameters
+
+config_version=4
+
+_global_script_classes=[  ]
+_global_script_class_icons={
+
+}
+
+[application]
+
+config/name="3D Viewport Scaling"
+run/main_scene="res://hud.tscn"
+config/icon="res://icon.png"
+
+[display]
+
+window/stretch/mode="2d"
+window/stretch/aspect="expand"
+
+[input]
+
+cycle_viewport_resolution={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
+ ]
+}
+toggle_filtering={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"unicode":0,"echo":false,"script":null)
+ ]
+}
+
+[rendering]
+
+quality/intended_usage/framebuffer_allocation=3
+environment/default_environment="res://default_env.tres"

+ 23 - 0
viewport/3d_scaling/spatial.tscn

@@ -0,0 +1,23 @@
+[gd_scene load_steps=2 format=2]
+
+[sub_resource type="CubeMesh" id=1]
+
+[node name="Spatial" type="Spatial"]
+
+[node name="MeshInstance" type="MeshInstance" parent="."]
+mesh = SubResource( 1 )
+material/0 = null
+
+[node name="MeshInstance2" type="MeshInstance" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, -1 )
+mesh = SubResource( 1 )
+material/0 = null
+
+[node name="Camera" type="Camera" parent="."]
+transform = Transform( 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="OmniLight" type="OmniLight" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 2, 1 )
+shadow_enabled = true
+shadow_bias = 0.08