Add resolution-independent pixelation
This commit is contained in:
parent
46175ee405
commit
6f51f91324
10 changed files with 220 additions and 33 deletions
26
main/main.gd
26
main/main.gd
|
|
@ -30,6 +30,9 @@ const UIPixelationPresenterType = preload(
|
|||
const PixelationResetOverlayType = preload(
|
||||
"res://ui/pixelation_reset_overlay.gd"
|
||||
)
|
||||
const WorldPixelationPostprocessType = preload(
|
||||
"res://main/world_pixelation_postprocess.gd"
|
||||
)
|
||||
|
||||
const TITLE_MUSIC_SILENCE_DB: float = -80.0
|
||||
|
||||
|
|
@ -53,6 +56,9 @@ const TITLE_MUSIC_SILENCE_DB: float = -80.0
|
|||
@onready var _pixelation_reset: PixelationResetOverlayType = (
|
||||
%PixelationResetOverlay
|
||||
)
|
||||
@onready var _world_pixelation: WorldPixelationPostprocessType = (
|
||||
%WorldPixelationPostprocess
|
||||
)
|
||||
|
||||
var _gameplay_started: bool = false
|
||||
var _shop_interaction: FishingShopInteractionType
|
||||
|
|
@ -241,14 +247,7 @@ func _process(_delta: float) -> void:
|
|||
func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
|
||||
if settings == null:
|
||||
return
|
||||
var root_viewport: Viewport = get_viewport()
|
||||
root_viewport.scaling_3d_mode = Viewport.SCALING_3D_MODE_NEAREST
|
||||
root_viewport.scaling_3d_scale = PlayerSettingsType.get_world_render_scale(
|
||||
settings.world_pixel_size
|
||||
)
|
||||
root_viewport.msaa_3d = Viewport.MSAA_DISABLED
|
||||
root_viewport.screen_space_aa = Viewport.SCREEN_SPACE_AA_DISABLED
|
||||
root_viewport.use_taa = false
|
||||
_apply_world_pixelation(settings.world_pixel_size)
|
||||
_ui_pixelation.set_pixel_size(settings.ui_pixel_size)
|
||||
_game_ui.get_title_screen().set_world_pixelation(
|
||||
settings.world_pixel_size
|
||||
|
|
@ -264,6 +263,16 @@ func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
|
|||
)
|
||||
|
||||
|
||||
func _apply_world_pixelation(pixel_size: int) -> void:
|
||||
var root_viewport: Viewport = get_viewport()
|
||||
root_viewport.scaling_3d_mode = Viewport.SCALING_3D_MODE_NEAREST
|
||||
root_viewport.scaling_3d_scale = 1.0
|
||||
root_viewport.msaa_3d = Viewport.MSAA_DISABLED
|
||||
root_viewport.screen_space_aa = Viewport.SCREEN_SPACE_AA_DISABLED
|
||||
root_viewport.use_taa = false
|
||||
_world_pixelation.set_pixel_size(pixel_size)
|
||||
|
||||
|
||||
func _on_effective_ui_pixel_size_changed(
|
||||
_requested_pixel_size: int,
|
||||
effective_pixel_size: int,
|
||||
|
|
@ -281,6 +290,7 @@ func _reset_pixelation() -> void:
|
|||
|
||||
func _set_gameplay_active(active: bool) -> void:
|
||||
_gameplay_started = active
|
||||
_world_pixelation.set_gameplay_active(active)
|
||||
_ui_pixelation.set_gameplay_active(active)
|
||||
if not active:
|
||||
_player.item_effects.reset_all()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=16 format=3]
|
||||
[gd_scene load_steps=17 format=3]
|
||||
|
||||
[ext_resource type="PackedScene" path="res://world/test_world.tscn" id="1_world"]
|
||||
[ext_resource type="PackedScene" path="res://player/player.tscn" id="2_player"]
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
[ext_resource type="AudioStream" path="res://audio/music/title/as_in_four_wolves.ogg" id="13_title_music"]
|
||||
[ext_resource type="Script" path="res://ui/ui_pixelation_presenter.gd" id="14_pixelation"]
|
||||
[ext_resource type="PackedScene" path="res://ui/pixelation_reset_overlay.tscn" id="15_reset"]
|
||||
[ext_resource type="PackedScene" path="res://main/world_pixelation_postprocess.tscn" id="16_world_pixelation"]
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("3_main")
|
||||
|
|
@ -53,6 +54,9 @@ stream = ExtResource("13_title_music")
|
|||
volume_db = -80.0
|
||||
bus = &"Music"
|
||||
|
||||
[node name="WorldPixelationPostprocess" parent="." instance=ExtResource("16_world_pixelation")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="UIPresentation" type="SubViewportContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
texture_filter = 1
|
||||
|
|
|
|||
51
main/world_pixelation_postprocess.gd
Normal file
51
main/world_pixelation_postprocess.gd
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
class_name WorldPixelationPostprocess
|
||||
extends CanvasLayer
|
||||
|
||||
@onready var _screen_grid: ColorRect = %ScreenGrid
|
||||
|
||||
var _pixel_size: int = PlayerSettings.DEFAULT_WORLD_PIXEL_SIZE
|
||||
var _gameplay_active: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
get_viewport().size_changed.connect(_refresh_grid)
|
||||
_refresh_grid()
|
||||
|
||||
|
||||
func set_pixel_size(pixel_size: int) -> void:
|
||||
_pixel_size = clampi(
|
||||
pixel_size,
|
||||
PlayerSettings.MIN_WORLD_PIXEL_SIZE,
|
||||
PlayerSettings.MAX_WORLD_PIXEL_SIZE
|
||||
)
|
||||
_refresh_grid()
|
||||
|
||||
|
||||
func set_gameplay_active(active: bool) -> void:
|
||||
_gameplay_active = active
|
||||
_refresh_grid()
|
||||
|
||||
|
||||
func get_grid_size() -> Vector2i:
|
||||
return PlayerSettings.get_world_grid_size(
|
||||
_pixel_size,
|
||||
get_window().size
|
||||
)
|
||||
|
||||
|
||||
func _refresh_grid() -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
var effect_enabled: bool = (
|
||||
_gameplay_active
|
||||
and _pixel_size != PlayerSettings.MIN_WORLD_PIXEL_SIZE
|
||||
)
|
||||
_screen_grid.visible = effect_enabled
|
||||
if not effect_enabled:
|
||||
return
|
||||
var shader_material := _screen_grid.material as ShaderMaterial
|
||||
if shader_material != null:
|
||||
shader_material.set_shader_parameter(
|
||||
"logical_grid_size",
|
||||
Vector2(get_grid_size())
|
||||
)
|
||||
1
main/world_pixelation_postprocess.gd.uid
Normal file
1
main/world_pixelation_postprocess.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c3n47x8egoc8x
|
||||
15
main/world_pixelation_postprocess.gdshader
Normal file
15
main/world_pixelation_postprocess.gdshader
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
shader_type canvas_item;
|
||||
render_mode unshaded;
|
||||
|
||||
uniform sampler2D screen_texture
|
||||
: hint_screen_texture, filter_nearest, repeat_disable;
|
||||
uniform vec2 logical_grid_size = vec2(640.0, 360.0);
|
||||
|
||||
|
||||
void fragment() {
|
||||
vec2 safe_grid = max(logical_grid_size, vec2(1.0));
|
||||
vec2 snapped_uv = (
|
||||
floor(SCREEN_UV * safe_grid) + vec2(0.5)
|
||||
) / safe_grid;
|
||||
COLOR = texture(screen_texture, snapped_uv);
|
||||
}
|
||||
1
main/world_pixelation_postprocess.gdshader.uid
Normal file
1
main/world_pixelation_postprocess.gdshader.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://sq224d8sn1b4
|
||||
21
main/world_pixelation_postprocess.tscn
Normal file
21
main/world_pixelation_postprocess.tscn
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://main/world_pixelation_postprocess.gd" id="1_script"]
|
||||
[ext_resource type="Shader" path="res://main/world_pixelation_postprocess.gdshader" id="2_shader"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_world_pixelation"]
|
||||
shader = ExtResource("2_shader")
|
||||
|
||||
[node name="WorldPixelationPostprocess" type="CanvasLayer"]
|
||||
layer = -1
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="ScreenGrid" type="ColorRect" parent="."]
|
||||
unique_name_in_owner = true
|
||||
material = SubResource("ShaderMaterial_world_pixelation")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
Loading…
Add table
Add a link
Reference in a new issue