From 4d036d8b8732f6cf86beb0439433d0303835adda Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Sun, 21 Jul 2024 14:38:56 -0600 Subject: [PATCH] Threshold shader --- src/main.tscn | 19 ++++---- src/maps/arena_map/arena_map.tscn | 53 ++++++++++++++++++++- src/player/player.tscn | 40 +++++----------- src/shaders/blur.gdshader | 7 +++ src/{player => shaders}/cel_shader.gdshader | 0 src/{ => shaders}/hard_edge.gdshader | 0 src/shaders/outline.gdshader | 25 ++++++++++ src/shaders/threshold.gdshader | 23 +++++++++ 8 files changed, 127 insertions(+), 40 deletions(-) create mode 100644 src/shaders/blur.gdshader rename src/{player => shaders}/cel_shader.gdshader (100%) rename src/{ => shaders}/hard_edge.gdshader (100%) create mode 100644 src/shaders/outline.gdshader create mode 100644 src/shaders/threshold.gdshader diff --git a/src/main.tscn b/src/main.tscn index f18bc76..b255704 100644 --- a/src/main.tscn +++ b/src/main.tscn @@ -1,21 +1,20 @@ -[gd_scene load_steps=5 format=3 uid="uid://d75odchj18u1"] +[gd_scene load_steps=4 format=3 uid="uid://d75odchj18u1"] +[ext_resource type="Shader" path="res://src/shaders/threshold.gdshader" id="1_bg1gg"] [ext_resource type="PackedScene" uid="uid://drbiyuustse8b" path="res://src/maps/arena_map/arena_map.tscn" id="1_bvhtq"] -[ext_resource type="Shader" path="res://src/hard_edge.gdshader" id="1_y05i6"] -[ext_resource type="Texture2D" uid="uid://deu1gf4gxbvvh" path="res://assets/palette_moonlight.png" id="2_uwrk1"] -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ab1b3"] -shader = ExtResource("1_y05i6") -shader_parameter/bit_depth = 32 +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ubp15"] +shader = ExtResource("1_bg1gg") +shader_parameter/color_low = Color(0, 0, 0, 1) +shader_parameter/color_hi = Color(1, 1, 1, 1) +shader_parameter/threshold = 0.697 shader_parameter/contrast = 1.0 -shader_parameter/offset = null -shader_parameter/color_tex = ExtResource("2_uwrk1") +shader_parameter/offset = 0.0 [node name="Main" type="Node3D"] [node name="ViewportContainer" type="SubViewportContainer" parent="."] -material = SubResource("ShaderMaterial_ab1b3") -custom_minimum_size = Vector2(1900, 768) +material = SubResource("ShaderMaterial_ubp15") offset_right = 1900.0 offset_bottom = 768.0 stretch = true diff --git a/src/maps/arena_map/arena_map.tscn b/src/maps/arena_map/arena_map.tscn index 34a510b..29d61d3 100644 --- a/src/maps/arena_map/arena_map.tscn +++ b/src/maps/arena_map/arena_map.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://drbiyuustse8b"] +[gd_scene load_steps=14 format=3 uid="uid://drbiyuustse8b"] [ext_resource type="PackedScene" uid="uid://bqp5mwyat3asv" path="res://src/player/player.tscn" id="1_tgee4"] [ext_resource type="Material" uid="uid://7a1uvst7oef2" path="res://assets/textures/metal_plate_1k/metal_plate.tres" id="2_ewgwm"] @@ -32,6 +32,44 @@ material = ExtResource("2_ewgwm") [sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_oxcjq"] points = PackedVector3Array(-0.5, -1, 0, -0.497651, -1, -0.0490407, -0.497651, -1, 0.0489429, -0.5, 1, 0, -0.490407, -1, -0.097592, -0.497651, 1, -0.0490407, -0.490407, -1, 0.0974941, -0.497651, 1, 0.0489429, -0.478563, -1, -0.145164, -0.490407, 1, -0.097592, -0.478563, -1, 0.145067, -0.490407, 1, 0.0974941, -0.46202, -1, -0.191366, -0.478563, 1, -0.145164, -0.46202, -1, 0.191269, -0.478563, 1, 0.145067, -0.440975, -1, -0.235709, -0.46202, 1, -0.191366, -0.440975, -1, 0.235611, -0.46202, 1, 0.191269, -0.415818, -1, -0.2778, -0.440975, 1, -0.235709, -0.415818, -1, 0.277702, -0.440975, 1, 0.235611, -0.386551, -1, -0.317247, -0.415818, 1, -0.2778, -0.386551, -1, 0.31715, -0.415818, 1, 0.277702, -0.353563, -1, -0.353563, -0.386551, 1, -0.317247, -0.353563, -1, 0.353465, -0.386551, 1, 0.31715, -0.317247, -1, -0.386551, -0.353563, 1, -0.353563, -0.317247, -1, 0.386453, -0.353563, 1, 0.353465, -0.2778, -1, -0.415818, -0.317247, 1, -0.386551, -0.2778, -1, 0.41572, -0.317247, 1, 0.386453, -0.235709, -1, -0.440975, -0.2778, 1, -0.415818, -0.235709, -1, 0.440877, -0.2778, 1, 0.41572, -0.191366, -1, -0.46202, -0.235709, 1, -0.440975, -0.191366, -1, 0.461922, -0.235709, 1, 0.440877, -0.145164, -1, -0.478563, -0.191366, 1, -0.46202, -0.145164, -1, 0.478465, -0.191366, 1, 0.461922, -0.097592, -1, -0.490407, -0.145164, 1, -0.478563, -0.097592, -1, 0.490309, -0.145164, 1, 0.478465, -0.0490407, -1, -0.497651, -0.097592, 1, -0.490407, -0.0490407, -1, 0.497553, -0.097592, 1, 0.490309, 0, -1, -0.5, -0.0490407, 1, -0.497651, 0, -1, 0.5, -0.0490407, 1, 0.497553, 0.0489429, -1, -0.497651, 0, 1, -0.5, 0.0489429, -1, 0.497553, 0, 1, 0.5, 0.0974941, -1, -0.490407, 0.0489429, 1, -0.497651, 0.0974941, -1, 0.490309, 0.0489429, 1, 0.497553, 0.145067, -1, -0.478563, 0.0974941, 1, -0.490407, 0.145067, -1, 0.478465, 0.0974941, 1, 0.490309, 0.191269, -1, -0.46202, 0.145067, 1, -0.478563, 0.191269, -1, 0.461922, 0.145067, 1, 0.478465, 0.235611, -1, -0.440975, 0.191269, 1, -0.46202, 0.235611, -1, 0.440877, 0.191269, 1, 0.461922, 0.277702, -1, -0.415818, 0.235611, 1, -0.440975, 0.277702, -1, 0.41572, 0.235611, 1, 0.440877, 0.31715, -1, -0.386551, 0.277702, 1, -0.415818, 0.31715, -1, 0.386453, 0.277702, 1, 0.41572, 0.353465, -1, -0.353563, 0.31715, 1, -0.386551, 0.353465, -1, 0.353465, 0.31715, 1, 0.386453, 0.386453, -1, -0.317247, 0.353465, 1, -0.353563, 0.386453, -1, 0.31715, 0.353465, 1, 0.353465, 0.41572, -1, -0.2778, 0.386453, 1, -0.317247, 0.41572, -1, 0.277702, 0.386453, 1, 0.31715, 0.440877, -1, -0.235709, 0.41572, 1, -0.2778, 0.440877, -1, 0.235611, 0.41572, 1, 0.277702, 0.461922, -1, -0.191366, 0.440877, 1, -0.235709, 0.461922, -1, 0.191269, 0.440877, 1, 0.235611, 0.478465, -1, -0.145164, 0.461922, 1, -0.191366, 0.478465, -1, 0.145067, 0.461922, 1, 0.191269, 0.490309, -1, -0.097592, 0.478465, 1, -0.145164, 0.490309, -1, 0.0974941, 0.478465, 1, 0.145067, 0.497553, -1, -0.0490407, 0.490309, 1, -0.097592, 0.497553, -1, 0.0489429, 0.490309, 1, 0.0974941, 0.5, -1, 0, 0.497553, 1, -0.0490407, 0.497553, 1, 0.0489429, 0.5, 1, 0) +[sub_resource type="Animation" id="Animation_0hul6"] +resource_name = "light_cycle" +length = 4.0 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Environment/LightAxis:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 6.28319, 0)] +} + +[sub_resource type="Animation" id="Animation_48do4"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Environment/LightAxis:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_h554d"] +_data = { +"RESET": SubResource("Animation_48do4"), +"light_cycle": SubResource("Animation_0hul6") +} + [node name="ArenaMap" type="Node3D"] [node name="Player" parent="." instance=ExtResource("1_tgee4")] @@ -45,6 +83,13 @@ environment = SubResource("Environment_0cwcw") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 5, 0) +[node name="LightAxis" type="Node3D" parent="Environment"] + +[node name="OmniLight3D" type="OmniLight3D" parent="Environment/LightAxis"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20, 1, 0) +light_energy = 16.0 +omni_range = 14.586 + [node name="WorldGeometry" type="Node3D" parent="."] [node name="Floor" type="MeshInstance3D" parent="WorldGeometry"] @@ -98,3 +143,9 @@ skeleton = NodePath("../..") [node name="CollisionShape3D" type="CollisionShape3D" parent="WorldGeometry/Pillar4/StaticBody3D"] shape = SubResource("ConvexPolygonShape3D_oxcjq") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_h554d") +} +autoplay = "light_cycle" diff --git a/src/player/player.tscn b/src/player/player.tscn index cc8bbd1..6365459 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -1,40 +1,22 @@ -[gd_scene load_steps=12 format=3 uid="uid://bqp5mwyat3asv"] +[gd_scene load_steps=9 format=3 uid="uid://bqp5mwyat3asv"] [ext_resource type="Script" path="res://src/player/player.gd" id="1_h16ke"] [ext_resource type="Texture2D" uid="uid://b0yefajw1cqo" path="res://assets/textures/character_placeholder.png" id="1_iys0p"] -[ext_resource type="Shader" path="res://src/player/cel_shader.gdshader" id="2_lc05i"] +[ext_resource type="Shader" path="res://src/shaders/outline.gdshader" id="3_ebm66"] [ext_resource type="Script" path="res://src/player/third_person_camera.gd" id="3_gichr"] -[sub_resource type="Gradient" id="Gradient_n24ft"] -offsets = PackedFloat32Array(0.443836, 0.852055) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_k01mp"] -gradient = SubResource("Gradient_n24ft") - -[sub_resource type="Gradient" id="Gradient_s23j5"] -interpolation_mode = 1 -offsets = PackedFloat32Array(0.49, 0.5) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_5ivp0"] -gradient = SubResource("Gradient_s23j5") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_4kmto"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_tgc5x"] render_priority = 0 -shader = ExtResource("2_lc05i") -shader_parameter/albedo = Color(1, 1, 1, 1) -shader_parameter/roughness = 1.0 -shader_parameter/metallic_texture_channel = null -shader_parameter/metallic = 0.0 -shader_parameter/uv1_scale = Vector3(1, 1, 1) -shader_parameter/uv1_offset = Vector3(0, 0, 0) -shader_parameter/uv2_scale = Vector3(1, 1, 1) -shader_parameter/uv2_offset = Vector3(0, 0, 0) -shader_parameter/texture_albedo = ExtResource("1_iys0p") -shader_parameter/shadow_gradient = SubResource("GradientTexture1D_5ivp0") -shader_parameter/fresnel_ramp = SubResource("GradientTexture1D_k01mp") +shader = ExtResource("3_ebm66") +shader_parameter/color = Color(1, 1, 1, 1) +shader_parameter/width = 4.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vf1qj"] +next_pass = SubResource("ShaderMaterial_tgc5x") +albedo_texture = ExtResource("1_iys0p") [sub_resource type="CapsuleMesh" id="CapsuleMesh_8sedy"] -material = SubResource("ShaderMaterial_4kmto") +material = SubResource("StandardMaterial3D_vf1qj") [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_otw5j"] diff --git a/src/shaders/blur.gdshader b/src/shaders/blur.gdshader new file mode 100644 index 0000000..00f7f49 --- /dev/null +++ b/src/shaders/blur.gdshader @@ -0,0 +1,7 @@ +shader_type canvas_item; + +uniform float lod: hint_range(0.0, 5.0) = 0.0; + +void fragment() { + COLOR = texture(TEXTURE, SCREEN_UV, lod); +} \ No newline at end of file diff --git a/src/player/cel_shader.gdshader b/src/shaders/cel_shader.gdshader similarity index 100% rename from src/player/cel_shader.gdshader rename to src/shaders/cel_shader.gdshader diff --git a/src/hard_edge.gdshader b/src/shaders/hard_edge.gdshader similarity index 100% rename from src/hard_edge.gdshader rename to src/shaders/hard_edge.gdshader diff --git a/src/shaders/outline.gdshader b/src/shaders/outline.gdshader new file mode 100644 index 0000000..1b5d05e --- /dev/null +++ b/src/shaders/outline.gdshader @@ -0,0 +1,25 @@ +/* Outline shader + * Adapted from https://godotshaders.com/shader/pixel-perfect-outline-shader/ + */ +shader_type spatial; +render_mode cull_front, unshaded; + +uniform vec4 color: source_color; +uniform float width = 1.0; + +void vertex() { + vec4 clip_position = PROJECTION_MATRIX * (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)); + vec3 clip_normal = mat3(PROJECTION_MATRIX) * (mat3(MODELVIEW_MATRIX) * NORMAL); + + vec2 offset = normalize(clip_normal.xy) / VIEWPORT_SIZE * clip_position.w * width * 2.0; + + clip_position.xy += offset; + POSITION = clip_position; +} + +void fragment() { + ALBEDO = color.rgb; + if (color.a < 1.0) { + ALPHA = color.a; + } +} diff --git a/src/shaders/threshold.gdshader b/src/shaders/threshold.gdshader new file mode 100644 index 0000000..1fe4238 --- /dev/null +++ b/src/shaders/threshold.gdshader @@ -0,0 +1,23 @@ +/* Binary threshold shader */ + +shader_type canvas_item; + +uniform vec4 color_low: source_color = vec4(0.0, 0.0, 0.0, 1.0); +uniform vec4 color_hi: source_color = vec4(1.0, 1.0, 1.0, 1.0); + +uniform float threshold: hint_range(0.0, 1.0) = 0.5; +uniform float contrast: hint_range(0.0, 1.0) = 1.0; +uniform float offset: hint_range(-1.0, 1.0) = 0.0; + + +void fragment() { + vec3 screen_col = texture(TEXTURE, UV).rgb; + + // calculate pixel luminosity + float luminosity = (screen_col.r * 0.299) + (screen_col.g * 0.587) + (screen_col.b * 0.114); + + // adjust contrast & offset + luminosity = clamp((luminosity - 0.5 + offset) * contrast + 0.5, 0.0, 1.0); + + COLOR.rgba = luminosity > threshold ? color_hi : color_low; +}