diff --git a/core/shaders/screen_effects.gdshader b/core/shaders/screen_effects.gdshader index 27f389e..2b5548f 100644 --- a/core/shaders/screen_effects.gdshader +++ b/core/shaders/screen_effects.gdshader @@ -1,41 +1,54 @@ shader_type canvas_item; render_mode unshaded; +// uniforms + uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap; -// simple edge detection +// constants + +const vec3 BLACK = vec3(0); +const float glow_strength = 0.5; +const float glow_size_lod = 3.0; +const int outline_radius = 1; + +// simple edge detection based on black + bool is_edge(int radius, vec2 screen_uv, vec2 screen_pixel_size) { - bool ed_found_black = false; + bool ed_found_bg = false; bool ed_found_color = false; // check neighbor pixels for (int x = -radius; x < radius+1; x++) { for (int y = -radius; y < radius+1; y++) { vec4 p = texture(screen_texture, screen_uv + (vec2(float(x), float(y)) * screen_pixel_size)); - if (p.rgb == vec3(0.0)) { - ed_found_black = true; + if (p.rgb == BLACK) { + ed_found_bg = true; } else { ed_found_color = true; } } } - return ed_found_black && ed_found_color; + return ed_found_bg && ed_found_color; } +// + void fragment() { // get screen texture vec4 screen = texture(screen_texture, SCREEN_UV); // apply edge detection - int radius = max(int(0.003 * (1.0/SCREEN_PIXEL_SIZE.y)), 1); // with a relative radius - if (is_edge(radius, SCREEN_UV, SCREEN_PIXEL_SIZE)) { - COLOR = screen; - } else { - COLOR = vec4(0, 0, 0, 1); + if (is_edge(outline_radius, SCREEN_UV, SCREEN_PIXEL_SIZE)) { + if (screen.rgb != BLACK) { // would be incompatible with target backgrounds != black + COLOR = screen; + } } // apply glow // blur a relative radius -> x * log(1.0/SCREEN_PIXEL_SIZE.y) // using log, because the LOD value seems to affect the blur radius exponentially - vec4 glow = textureLod(screen_texture, SCREEN_UV, 0.5 * log(1.0/SCREEN_PIXEL_SIZE.y)); - if (screen.rgb == vec3(0.0)) { - COLOR = mix(COLOR, glow, 0.4) + (glow * 0.3); + vec4 glow = textureLod(screen_texture, SCREEN_UV, glow_size_lod); + if (screen.rgb == BLACK) { + COLOR += glow * glow_strength; } + // set alpha to 1 + COLOR.a = 1.0; } diff --git a/core/shaders/screen_effects_2.gdshader b/core/shaders/screen_effects_2.gdshader new file mode 100644 index 0000000..4f54c6b --- /dev/null +++ b/core/shaders/screen_effects_2.gdshader @@ -0,0 +1,29 @@ +shader_type canvas_item; +render_mode unshaded; + +// uniforms + +uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap; +uniform sampler2D vignette_mask; + +// constants + +const float rgb_distortion_v_mult = 0.9; +const float rgb_distortion_v_exp = 2.0; +const float rgb_distortion_v_min = 0.04; +const float rgb_distortion_v_max = 0.12; + +// + +void fragment() { + float v = texture(vignette_mask, SCREEN_UV).r; + // rgb & blur distortion + float v_ = clamp( + pow(v * rgb_distortion_v_mult, rgb_distortion_v_exp), + rgb_distortion_v_min, + rgb_distortion_v_max + ); + COLOR.r = textureLod(screen_texture, SCREEN_UV - (v_ * 0.01), v).r; + COLOR.g = textureLod(screen_texture, SCREEN_UV + (v_ * 0.01), v).g; + COLOR.b = textureLod(screen_texture, SCREEN_UV, v).b; +} diff --git a/core/shaders/vignette_mask.tres b/core/shaders/vignette_mask.tres new file mode 100644 index 0000000..a53bcf5 --- /dev/null +++ b/core/shaders/vignette_mask.tres @@ -0,0 +1,10 @@ +[gd_resource type="GradientTexture2D" load_steps=2 format=3 uid="uid://bwlgypt4xjocj"] + +[sub_resource type="Gradient" id="Gradient_h26vj"] + +[resource] +gradient = SubResource("Gradient_h26vj") +width = 640 +height = 640 +fill = 1 +fill_from = Vector2(0.5, 0.5) diff --git a/levels/waking_up.tscn b/levels/waking_up.tscn index f9eb58f..4061b25 100644 --- a/levels/waking_up.tscn +++ b/levels/waking_up.tscn @@ -12,10 +12,10 @@ position = Vector2(400, 224) [node name="DynamicPolygon" parent="StaticBody2D" instance=ExtResource("2_83sm2")] polygon = PackedVector2Array(296, 288, 296, 368, 536, 368, 536, 336, 776, 336, 776, 400, 104, 400, 104, 360, 184, 360, 184, 304, 248, 304, 248, 288) -color = Color(0.110313, 0.574619, 0.546744, 1) +color = Color(0.235294, 0.607843, 0.643137, 1) update = false [node name="DynamicPolygon2" parent="StaticBody2D" instance=ExtResource("2_83sm2")] polygon = PackedVector2Array(520, 96, 520, 280, 552, 280, 552, 32, 632, 32, 632, -8, 520, -8) -color = Color(0.109804, 0.576471, 0.545098, 1) +color = Color(0.236278, 0.606088, 0.644729, 1) update = false diff --git a/main.tscn b/main.tscn index 199fce6..8d1b36c 100644 --- a/main.tscn +++ b/main.tscn @@ -1,21 +1,43 @@ -[gd_scene load_steps=4 format=3 uid="uid://c13h0uf5fgx60"] +[gd_scene load_steps=7 format=3 uid="uid://c13h0uf5fgx60"] [ext_resource type="PackedScene" uid="uid://ptqto8ctsp4u" path="res://levels/waking_up.tscn" id="1_3swad"] [ext_resource type="Shader" path="res://core/shaders/screen_effects.gdshader" id="2_ha2mu"] +[ext_resource type="Shader" path="res://core/shaders/screen_effects_2.gdshader" id="3_lm730"] +[ext_resource type="Texture2D" uid="uid://bwlgypt4xjocj" path="res://core/shaders/vignette_mask.tres" id="4_wc582"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_myg35"] shader = ExtResource("2_ha2mu") +[sub_resource type="ShaderMaterial" id="ShaderMaterial_gsqgo"] +shader = ExtResource("3_lm730") +shader_parameter/vignette_mask = ExtResource("4_wc582") + [node name="Main" type="Node2D"] [node name="WakingUp" parent="." instance=ExtResource("1_3swad")] -[node name="CanvasLayer" type="CanvasLayer" parent="."] +[node name="ScreenShader" type="Node2D" parent="."] -[node name="ColorRect" type="ColorRect" parent="CanvasLayer"] +[node name="CanvasLayer" type="CanvasLayer" parent="ScreenShader"] +editor_description = "Outline & glow" + +[node name="ColorRect" type="ColorRect" parent="ScreenShader/CanvasLayer"] material = SubResource("ShaderMaterial_myg35") anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +color = Color(0, 0, 0, 1) +metadata/_edit_use_anchors_ = true + +[node name="CanvasLayer2" type="CanvasLayer" parent="ScreenShader"] +editor_description = "Distortion effects" + +[node name="ColorRect" type="ColorRect" parent="ScreenShader/CanvasLayer2"] +material = SubResource("ShaderMaterial_gsqgo") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/player/player.tscn b/player/player.tscn index 05c70b4..f93e270 100644 --- a/player/player.tscn +++ b/player/player.tscn @@ -27,4 +27,4 @@ position = Vector2(4, 0) target_position = Vector2(0, -8.1) [node name="Polygon2D" type="Polygon2D" parent="."] -polygon = PackedVector2Array(-7, -7, -7, 7, 7, 7, 7, -7) +polygon = PackedVector2Array(-9, -9, -9, 9, 9, 9, 9, -9) diff --git a/project.godot b/project.godot index 9219ca7..a95a271 100644 --- a/project.godot +++ b/project.godot @@ -13,6 +13,7 @@ config_version=5 config/name="rectangular" run/main_scene="res://main.tscn" config/features=PackedStringArray("4.3", "Forward Plus") +boot_splash/bg_color=Color(0, 0, 0, 1) config/icon="res://icon.svg" [debug] @@ -23,7 +24,7 @@ settings/stdout/print_fps=true window/size/viewport_width=800 window/size/viewport_height=450 -window/stretch/mode="canvas_items" +window/stretch/mode="viewport" window/stretch/aspect="expand" [input]