diff --git a/gmtk_2024/Throne_Hall_Background.png b/gmtk_2024/Throne_Hall_Background.png new file mode 100644 index 0000000..b31d7d8 Binary files /dev/null and b/gmtk_2024/Throne_Hall_Background.png differ diff --git a/gmtk_2024/Throne_Hall_Background.png.import b/gmtk_2024/Throne_Hall_Background.png.import new file mode 100644 index 0000000..7d7b390 --- /dev/null +++ b/gmtk_2024/Throne_Hall_Background.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kfqpb7ld704r" +path="res://.godot/imported/Throne_Hall_Background.png-40c61316a331b1da8d03a470d9696b64.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Throne_Hall_Background.png" +dest_files=["res://.godot/imported/Throne_Hall_Background.png-40c61316a331b1da8d03a470d9696b64.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/gmtk_2024/canvas_layer.tscn b/gmtk_2024/canvas_layer.tscn new file mode 100644 index 0000000..1ad89a5 --- /dev/null +++ b/gmtk_2024/canvas_layer.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=4 format=3 uid="uid://cxbalfjqtp06t"] + +[ext_resource type="Texture2D" uid="uid://kfqpb7ld704r" path="res://Throne_Hall_Background.png" id="1_87jyn"] +[ext_resource type="Shader" path="res://shaders/crt.gdshader" id="2_wxq0n"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_c8ly2"] +shader = ExtResource("2_wxq0n") +shader_parameter/crt_curve = 0.02 +shader_parameter/crt_scan_line_color = 0.347 +shader_parameter/aperture_grille_rate = 0.4 +shader_parameter/rf_switch_esque_blur = 1.0 +shader_parameter/white_noise_rate = 0.0 + +[node name="CanvasLayer" type="CanvasLayer"] + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_87jyn") +centered = false +region_enabled = true +region_rect = Rect2(0, 0, 1152, 648) + +[node name="ColorRect" type="ColorRect" parent="."] +material = SubResource("ShaderMaterial_c8ly2") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/gmtk_2024/shaders/crt.gdshader b/gmtk_2024/shaders/crt.gdshader new file mode 100644 index 0000000..4dc8b9a --- /dev/null +++ b/gmtk_2024/shaders/crt.gdshader @@ -0,0 +1,87 @@ +/* + CRT shader for Godot Engine by Yui Kinomoto @arlez80 +*/ +shader_type canvas_item; + +// 画面 +uniform sampler2D screen_texture : hint_screen_texture; + +// ブラウン管のガラスの曲がり具合(フラットなやつは0.0でいいかな) +uniform float crt_curve : hint_range( 0.0, 1.0 ) = 0.02; +// 走査線の濃さ +uniform float crt_scan_line_color : hint_range( 0.0, 1.0 ) = 0.347; +// 光量 +uniform float aperture_grille_rate : hint_range( 0.0, 1.0 ) = 0.4; +// RFスイッチ的ブラー +uniform float rf_switch_esque_blur : hint_range( 0.0, 1.0 ) = 1.0; +// 白色ノイズ +uniform float white_noise_rate : hint_range( 0.0, 1.0 ) = 0.0; + +float random( vec2 pos ) +{ + return fract(sin(dot(pos, vec2(12.9898,78.233))) * 43758.5453); +} + +void fragment( ) +{ + // ガラスの曲がり具合 + vec2 crt_curve_shift = ( vec2( 1.0, 1.0 ) - sin( UV.yx * PI ) ) * crt_curve; + vec2 crt_curve_scale = vec2( 1.0, 1.0 ) + crt_curve_shift * 2.0; + vec2 texture_fixed_uv = UV * crt_curve_scale - crt_curve_shift; + vec2 fixed_uv = SCREEN_UV * crt_curve_scale - crt_curve_shift; + // 範囲外を消す + float enable_color = float( 0.0 <= texture_fixed_uv.x && texture_fixed_uv.x <= 1.0 && 0.0 <= texture_fixed_uv.y && texture_fixed_uv.y <= 1.0 ); + + // ガラスの曲がり具合から元色を取得 + RFスイッチ的ブラー + COLOR.rgb = ( + ( + texture( screen_texture, fixed_uv ).rgb + * ( 1.0 - rf_switch_esque_blur * 0.5 ) + ) + + ( + ( + texture( screen_texture, fixed_uv + vec2( -SCREEN_PIXEL_SIZE.x * 3.1, 0.0 ) ).rgb + + texture( screen_texture, fixed_uv + vec2( SCREEN_PIXEL_SIZE.x * 3.1, 0.0 ) ).rgb + ) + * ( rf_switch_esque_blur * 0.25 ) // (RFノイズ)0.5 * (テクスチャから読んだ2箇所を半分にしたい)0.5 + ) + ) * enable_color; + COLOR.a = 1.0; + + // ------------------------------------------------ + // 以下はアパーチャグリル上の1ピクセルごとの処理 + vec2 aperture_grille_pixel = vec2( floor( ( fixed_uv.x / SCREEN_PIXEL_SIZE.x ) / 3.0 ) * 3.0, fixed_uv.y ); + + // 白色ノイズ + float white_noise = random( aperture_grille_pixel + vec2( sin( TIME * 0.543254 ), cos( TIME * 0.254323563 ) ) ); + COLOR.rgb = mix( + COLOR.rgb + , vec3( white_noise, white_noise, white_noise ) + , white_noise_rate * enable_color + ); + + // アパーチャグリル再現 + float aperture_grille_point = mod( ( ( SCREEN_UV.x * crt_curve_scale.x ) - crt_curve_shift.x ) / SCREEN_PIXEL_SIZE.x, 3.0 ); + float aperture_grille_r_rate = clamp( 1.0 - aperture_grille_point, 0.0, 1.0 ) + clamp( aperture_grille_point - 2.0, 0.0, 1.0 ); + float aperture_grille_g_rate = clamp( 1.0 - abs( 1.0 - aperture_grille_point ), 0.0, 1.0 ); + float aperture_grille_b_rate = 1.0 - aperture_grille_r_rate - aperture_grille_g_rate; + COLOR = clamp( + COLOR * vec4( + normalize( vec3( + clamp( aperture_grille_r_rate, aperture_grille_rate, 1.0 ) + , clamp( aperture_grille_g_rate, aperture_grille_rate, 1.0 ) + , clamp( aperture_grille_b_rate, aperture_grille_rate, 1.0 ) + ) ) + , 1.0 + ) + , vec4( 0.0, 0.0, 0.0, 0.0 ) + , vec4( 1.0, 1.0, 1.0, 1.0 ) + ); + + // 走査線 + COLOR = mix( + COLOR + , vec4( 0.0, 0.0, 0.0, 1.0 ) + , float( 0 == int( fixed_uv.y / SCREEN_PIXEL_SIZE.y ) % 2 ) * crt_scan_line_color + ); +}