From f97a2da5c2c6a93aabf20fb09ec6f717b2c21ba4 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Thu, 6 Mar 2025 14:57:57 -0700 Subject: [PATCH] Better particle beam effects --- .../props/wall_switch/wall_switch2.blend | Bin 576592 -> 576592 bytes .../props/wall_switch/wall_switch2.blend1 | Bin 574776 -> 576592 bytes assets/materials/laser_spray.tres | 45 ++++++++ src/effects/laser_dust.tscn | 43 ++++++++ src/equipment/laser_cast/laser_cast.gd | 23 ++++ src/equipment/laser_cast/laser_cast.tscn | 19 ++++ src/equipment/point_spray/point_spray.gd | 23 ++-- src/equipment/point_spray/point_spray.tscn | 69 +++++++++--- src/equipment/spray.gd | 16 ++- src/equipment/spring_cast.gd | 13 +++ src/equipment/wide_spray/wide_spray.gd | 23 ++-- src/equipment/wide_spray/wide_spray.tscn | 98 ++++++++++++------ src/player/camera_controller.gd | 2 +- src/player/player.tscn | 6 +- src/shaders/gunk.gdshader | 2 +- src/shaders/hologram.gdshader | 47 +++++++++ src/shaders/plasma.gdshader | 59 +++++++++++ src/world/gunk_body/gunk_body.tscn | 1 + vault/assets/color_palette.md | 3 + 19 files changed, 422 insertions(+), 70 deletions(-) create mode 100644 assets/materials/laser_spray.tres create mode 100644 src/effects/laser_dust.tscn create mode 100644 src/equipment/laser_cast/laser_cast.gd create mode 100644 src/equipment/laser_cast/laser_cast.tscn create mode 100644 src/equipment/spring_cast.gd create mode 100644 src/shaders/hologram.gdshader create mode 100644 src/shaders/plasma.gdshader diff --git a/asset_dev/props/wall_switch/wall_switch2.blend b/asset_dev/props/wall_switch/wall_switch2.blend index b88fc25c48ab00fe466774b760e808db0f81a2d4..601c98afbfd4af38baa38b26fb1cb769fbfc0929 100644 GIT binary patch delta 9566 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 I|M5Tm2Lj!OtN;K2 delta 13902 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 E0d+ZOSO5S3 delta 12694 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 T%<9dLL{l3U*!)P$^VR void: + if is_colliding() and parent_tool.firing: + var child_pos := get_collision_point() + get_collision_normal() * NORMAL_OFFSET + + laser_dust.global_position = child_pos + laser_dust.emitting = true + + glow_light.global_position = child_pos + glow_light.visible = true # TODO: tween maybe? + else: + laser_dust.emitting = false + glow_light.visible = false diff --git a/src/equipment/laser_cast/laser_cast.tscn b/src/equipment/laser_cast/laser_cast.tscn new file mode 100644 index 0000000..d407a27 --- /dev/null +++ b/src/equipment/laser_cast/laser_cast.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=3 format=3 uid="uid://b8vradbaw61ga"] + +[ext_resource type="Script" path="res://src/equipment/laser_cast/laser_cast.gd" id="1_xntcr"] +[ext_resource type="PackedScene" uid="uid://oc6t5ubyybsa" path="res://src/effects/laser_dust.tscn" id="2_m5xmf"] + +[node name="LaserCast" type="RayCast3D"] +target_position = Vector3(0, 0, -2) +script = ExtResource("1_xntcr") + +[node name="LaserDust" parent="." instance=ExtResource("2_m5xmf")] +unique_name_in_owner = true + +[node name="GlowLight" type="OmniLight3D" parent="."] +unique_name_in_owner = true +layers = 2 +light_color = Color(0, 1, 0.301961, 1) +light_energy = 0.3 +light_cull_mask = 4294967293 +shadow_enabled = true diff --git a/src/equipment/point_spray/point_spray.gd b/src/equipment/point_spray/point_spray.gd index 65bf547..02d14fa 100644 --- a/src/equipment/point_spray/point_spray.gd +++ b/src/equipment/point_spray/point_spray.gd @@ -3,22 +3,29 @@ class_name PointSpray extends Spray @export var spray_scale := 3.0 -@onready var raycast: RayCast3D = %RayCast3D +@onready var laser: LaserCast = %LaserCast @onready var spray_effect: MeshInstance3D = %SprayEffect +@onready var beam_particles_1: GPUParticles3D = $BeamParticles1 +@onready var beam_particles_2: GPUParticles3D = $BeamParticles2 -func fire() -> void: - if raycast.is_colliding(): - var collider := raycast.get_collider() + +func _fire() -> void: + if laser.is_colliding(): + var collider := laser.get_collider() if collider is GunkBody: - var point := raycast.get_collision_point() - var point_scale := sqrt(point.distance_to(global_position)) * spray_scale + var point := laser.get_collision_point() + var point_scale := point.distance_to(global_position) * spray_scale (collider as GunkBody).paint_continuous( - point, raycast.get_collision_normal(), point_scale + point, laser.get_collision_normal(), point_scale ) spray_effect.visible = true + beam_particles_1.emitting = true + beam_particles_2.emitting = true -func idle() -> void: +func _idle() -> void: spray_effect.visible = false + beam_particles_1.emitting = false + beam_particles_2.emitting = false diff --git a/src/equipment/point_spray/point_spray.tscn b/src/equipment/point_spray/point_spray.tscn index 3e099b3..84f1fc8 100644 --- a/src/equipment/point_spray/point_spray.tscn +++ b/src/equipment/point_spray/point_spray.tscn @@ -1,35 +1,76 @@ -[gd_scene load_steps=5 format=3 uid="uid://cc102xko0u6yj"] +[gd_scene load_steps=10 format=3 uid="uid://cc102xko0u6yj"] [ext_resource type="Script" path="res://src/equipment/point_spray/point_spray.gd" id="1_2yl2v"] +[ext_resource type="Material" uid="uid://c00gndxoepuqh" path="res://assets/materials/laser_spray.tres" id="2_0pfy3"] [ext_resource type="Texture2D" uid="uid://bn0gcsy37ahto" path="res://assets/ui/hud/reticle_large.png" id="2_qcl8j"] +[ext_resource type="PackedScene" uid="uid://b8vradbaw61ga" path="res://src/equipment/laser_cast/laser_cast.tscn" id="3_qmoff"] -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ng43h"] -transparency = 1 -shading_mode = 0 +[sub_resource type="CylinderMesh" id="CylinderMesh_j5thb"] +material = ExtResource("2_0pfy3") +top_radius = 0.0 +bottom_radius = 0.2 +height = 2.2 +radial_segments = 16 + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_nc5qr"] +direction = Vector3(0, 0, -1) +spread = 4.0 +initial_velocity_min = 2.0 +initial_velocity_max = 2.0 +gravity = Vector3(0, 0, 0) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6k0bn"] vertex_color_use_as_albedo = true -albedo_color = Color(0, 1, 0.301961, 0.254902) +albedo_color = Color(0, 1, 0.301961, 0.392157) +emission_enabled = true +emission = Color(0, 1, 0.301961, 1) +emission_energy_multiplier = 10.0 +texture_filter = 2 +billboard_mode = 3 +billboard_keep_scale = true +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false -[sub_resource type="PrismMesh" id="PrismMesh_ow0jh"] -material = SubResource("StandardMaterial3D_ng43h") -size = Vector3(0.2, 2, 0.2) +[sub_resource type="QuadMesh" id="QuadMesh_fgb4j"] +material = SubResource("StandardMaterial3D_6k0bn") +size = Vector2(0.01, 0.01) + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_vwgy4"] +direction = Vector3(0, 0, -1) +spread = 4.0 +initial_velocity_min = 1.0 +initial_velocity_max = 1.0 +gravity = Vector3(0, 0, 0) [node name="PointSpray" type="Node3D"] script = ExtResource("1_2yl2v") -[node name="RayCast3D" type="RayCast3D" parent="."] +[node name="LaserCast" parent="." node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_qmoff")] unique_name_in_owner = true -target_position = Vector3(0, 0, -2) +visible = false +parent_tool = NodePath("..") [node name="SprayEffect" type="MeshInstance3D" parent="."] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) -visible = false +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, -1) layers = 2 -mesh = SubResource("PrismMesh_ow0jh") -skeleton = NodePath("../../../..") +mesh = SubResource("CylinderMesh_j5thb") + +[node name="BeamParticles1" type="GPUParticles3D" parent="."] +lifetime = 0.9 +process_material = SubResource("ParticleProcessMaterial_nc5qr") +draw_pass_1 = SubResource("QuadMesh_fgb4j") + +[node name="BeamParticles2" type="GPUParticles3D" parent="."] +amount = 16 +lifetime = 1.8 +process_material = SubResource("ParticleProcessMaterial_vwgy4") +draw_pass_1 = SubResource("QuadMesh_fgb4j") [node name="Decal" type="Decal" parent="."] transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("2_qcl8j") +texture_emission = ExtResource("2_qcl8j") cull_mask = 1048573 diff --git a/src/equipment/spray.gd b/src/equipment/spray.gd index 4eca758..601248f 100644 --- a/src/equipment/spray.gd +++ b/src/equipment/spray.gd @@ -1,12 +1,24 @@ class_name Spray extends Node3D ## Abstract base class for spraygun types +var firing := false + + +func _fire() -> void: + pass + + +func _idle() -> void: + pass + ## Called each frame that this spray is being fired. func fire() -> void: - pass + firing = true + _fire() ## Called each frame that this spray is not being fired. func idle() -> void: - pass + firing = false + _idle() diff --git a/src/equipment/spring_cast.gd b/src/equipment/spring_cast.gd new file mode 100644 index 0000000..7ea154b --- /dev/null +++ b/src/equipment/spring_cast.gd @@ -0,0 +1,13 @@ +class_name SpringCast extends RayCast3D +## Raycast which places its children at the collision point (if any) + +@export var normal_offset := 0.0 + + +func _process(_delta: float) -> void: + if is_colliding(): + for child: Node3D in get_children(): + child.global_position = get_collision_point() + get_collision_normal() * normal_offset + visible = true + else: + visible = false diff --git a/src/equipment/wide_spray/wide_spray.gd b/src/equipment/wide_spray/wide_spray.gd index 758e9b1..f823dc1 100644 --- a/src/equipment/wide_spray/wide_spray.gd +++ b/src/equipment/wide_spray/wide_spray.gd @@ -6,20 +6,23 @@ const SPRAYCAST_GROUP := "SprayCast" @export var spray_scale := 2.0 @onready var spray_casts: Node3D = %SprayCasts -@onready var spray_effect: MeshInstance3D = %SprayEffect +@onready var spray_effect: Node3D = %SprayEffect + +@onready var beam_particles_1: GPUParticles3D = $BeamParticles1 +@onready var beam_particles_2: GPUParticles3D = $BeamParticles2 -func fire() -> void: +func _fire() -> void: var prev_target: GunkBody = null var prev_point: Vector3 var prev_normal: Vector3 - for raycast: RayCast3D in spray_casts.get_children(): - if raycast.is_colliding(): - var target := raycast.get_collider() as GunkBody + for laser: LaserCast in spray_casts.get_children(): + if laser.is_colliding(): + var target := laser.get_collider() as GunkBody if target: - var point := raycast.get_collision_point() - var normal := raycast.get_collision_normal() + var point := laser.get_collision_point() + var normal := laser.get_collision_normal() # Always paint at least a dot, to cap the ends of the line target.paint_dot(point, normal, spray_scale) @@ -33,7 +36,11 @@ func fire() -> void: prev_normal = normal spray_effect.visible = true + beam_particles_1.emitting = true + beam_particles_2.emitting = true -func idle() -> void: +func _idle() -> void: spray_effect.visible = false + beam_particles_1.emitting = false + beam_particles_2.emitting = false diff --git a/src/equipment/wide_spray/wide_spray.tscn b/src/equipment/wide_spray/wide_spray.tscn index ce3f73f..9b5aef7 100644 --- a/src/equipment/wide_spray/wide_spray.tscn +++ b/src/equipment/wide_spray/wide_spray.tscn @@ -1,23 +1,50 @@ -[gd_scene load_steps=9 format=3 uid="uid://d2hnxr5l6w2x4"] +[gd_scene load_steps=12 format=3 uid="uid://d2hnxr5l6w2x4"] [ext_resource type="Script" path="res://src/equipment/wide_spray/wide_spray.gd" id="1_ggkto"] -[ext_resource type="Texture2D" uid="uid://dwavqltjrmupx" path="res://assets/ui/hud/wide_reticle_large.png" id="2_d01sr"] +[ext_resource type="Material" uid="uid://c00gndxoepuqh" path="res://assets/materials/laser_spray.tres" id="2_26efp"] [ext_resource type="Texture2D" uid="uid://cx28sj02y31kj" path="res://assets/ui/hud/reticle_crosshair.png" id="3_78jy6"] +[ext_resource type="PackedScene" uid="uid://b8vradbaw61ga" path="res://src/equipment/laser_cast/laser_cast.tscn" id="3_xahet"] [ext_resource type="Texture2D" uid="uid://carrggw6kp14w" path="res://assets/ui/hud/reticle_left.png" id="4_rotxf"] [ext_resource type="Texture2D" uid="uid://wp03nuwt8hp5" path="res://assets/ui/hud/reticle_right.png" id="5_xo3vu"] -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cdyoo"] -transparency = 1 -shading_mode = 0 +[sub_resource type="CylinderMesh" id="CylinderMesh_48buk"] +material = ExtResource("2_26efp") +top_radius = 0.0 +bottom_radius = 0.7 +radial_segments = 6 + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_pr4yq"] +direction = Vector3(0, 0, -1) +spread = 15.0 +flatness = 0.82 +initial_velocity_min = 2.0 +initial_velocity_max = 2.0 +gravity = Vector3(0, 0, 0) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6k0bn"] vertex_color_use_as_albedo = true -albedo_color = Color(0, 1, 0.301961, 0.254902) +albedo_color = Color(0, 1, 0.301961, 0.392157) +emission_enabled = true +emission = Color(0, 1, 0.301961, 1) +emission_energy_multiplier = 10.0 +texture_filter = 2 +billboard_mode = 3 +billboard_keep_scale = true +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false -[sub_resource type="PrismMesh" id="PrismMesh_vh2mt"] -material = SubResource("StandardMaterial3D_cdyoo") -size = Vector3(1, 2, 0.2) +[sub_resource type="QuadMesh" id="QuadMesh_trcry"] +material = SubResource("StandardMaterial3D_6k0bn") +size = Vector2(0.01, 0.01) -[sub_resource type="QuadMesh" id="QuadMesh_lvw1u"] -size = Vector2(2, 2) +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_lyk2j"] +direction = Vector3(0, 0, -1) +spread = 15.0 +flatness = 0.82 +initial_velocity_min = 1.0 +initial_velocity_max = 1.0 +gravity = Vector3(0, 0, 0) [node name="WideSpray" type="Node3D"] script = ExtResource("1_ggkto") @@ -25,41 +52,38 @@ script = ExtResource("1_ggkto") [node name="SprayCasts" type="Node3D" parent="."] unique_name_in_owner = true -[node name="RayCast3D" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.5, 0, -2) +parent_tool = NodePath("../..") -[node name="RayCast3D2" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast2" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.333, 0, -2) +parent_tool = NodePath("../..") -[node name="RayCast3D3" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast3" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.167, 0, -2) +parent_tool = NodePath("../..") -[node name="RayCast3D4" type="RayCast3D" parent="SprayCasts"] -target_position = Vector3(0, 0, -2) +[node name="LaserCast4" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +parent_tool = NodePath("../..") -[node name="RayCast3D5" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast5" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.167, 0, -2) +parent_tool = NodePath("../..") -[node name="RayCast3D6" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast6" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.333, 0, -2) +parent_tool = NodePath("../..") -[node name="RayCast3D7" type="RayCast3D" parent="SprayCasts"] +[node name="LaserCast7" parent="SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.5, 0, -2) +parent_tool = NodePath("../..") [node name="SprayEffect" type="MeshInstance3D" parent="."] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) -visible = false +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -0.15, 0, 1, -6.55671e-09, 0, 0, -1) layers = 2 -mesh = SubResource("PrismMesh_vh2mt") -skeleton = NodePath("../../../..") - -[node name="Decal" type="Decal" parent="."] -transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) -visible = false -size = Vector3(1, 10, 0.2) -texture_albedo = ExtResource("2_d01sr") -cull_mask = 1048573 +mesh = SubResource("CylinderMesh_48buk") [node name="ReticleDecals" type="Node3D" parent="."] @@ -87,7 +111,13 @@ size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("5_xo3vu") cull_mask = 1048573 -[node name="DebugMesh" type="MeshInstance3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.67743) -visible = false -mesh = SubResource("QuadMesh_lvw1u") +[node name="BeamParticles1" type="GPUParticles3D" parent="."] +lifetime = 0.9 +process_material = SubResource("ParticleProcessMaterial_pr4yq") +draw_pass_1 = SubResource("QuadMesh_trcry") + +[node name="BeamParticles2" type="GPUParticles3D" parent="."] +amount = 16 +lifetime = 1.8 +process_material = SubResource("ParticleProcessMaterial_lyk2j") +draw_pass_1 = SubResource("QuadMesh_trcry") diff --git a/src/player/camera_controller.gd b/src/player/camera_controller.gd index 948e146..7a438e9 100644 --- a/src/player/camera_controller.gd +++ b/src/player/camera_controller.gd @@ -2,7 +2,7 @@ class_name CameraController extends Node3D const PITCH_LIMIT := deg_to_rad(85.0) const FOCUS_SENSITIVITY := 0.2 -const FOCUS_ACCELERATION := 3 +const FOCUS_ACCELERATION := 8 @onready var player: Player = owner diff --git a/src/player/player.tscn b/src/player/player.tscn index 842c117..2558c0f 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -28,9 +28,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, -0.1, -0.1) unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15) -[node name="WideSpray" parent="CameraPivot/SprayMount/SprayMuzzle" instance=ExtResource("3_ibq07")] - [node name="PointSpray" parent="CameraPivot/SprayMount/SprayMuzzle" instance=ExtResource("3_6wgkm")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) + +[node name="WideSpray" parent="CameraPivot/SprayMount/SprayMuzzle" instance=ExtResource("3_ibq07")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) visible = false [node name="SprayRumbler" type="Node3D" parent="CameraPivot/SprayMount"] diff --git a/src/shaders/gunk.gdshader b/src/shaders/gunk.gdshader index 2379d40..980aa3f 100644 --- a/src/shaders/gunk.gdshader +++ b/src/shaders/gunk.gdshader @@ -1,5 +1,5 @@ shader_type spatial; -render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx, sss_mode_skin; +render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_burley, specular_schlick_ggx, sss_mode_skin; uniform vec3 color_1: source_color = vec3(0.0, 0.03, 0.1); uniform vec3 color_2: source_color = vec3(0.0, 0.1, 0.3); diff --git a/src/shaders/hologram.gdshader b/src/shaders/hologram.gdshader new file mode 100644 index 0000000..e66a446 --- /dev/null +++ b/src/shaders/hologram.gdshader @@ -0,0 +1,47 @@ +// Hologram shader +// Adapted from https://godotshaders.com/shader/scifi-hologram/ + +shader_type spatial; +render_mode unshaded; + +uniform sampler2D texture_image; + +uniform mediump vec4 line_color : source_color = vec4(0.0, 1.0, 0.0, 1.0); +uniform mediump float line_width : hint_range(0, 1) = 0.005; +uniform mediump float line_blur : hint_range(0, 1) = 0.2; +uniform mediump float line_speed : hint_range(-1, 1) = 0.02; +uniform bool straight_lines = true; + +uniform mediump float interrupt_width : hint_range(0, 1) = 0.5; +uniform mediump float interrupt_blur : hint_range(0, 1) = 0.25; +uniform mediump float interrupt_speed : hint_range(-1, 1) = 0.2; + +uniform mediump vec4 glow_color : source_color = vec4(0.5, 0.75, 1.0, 1.0); +uniform lowp float glow_itensity : hint_range(0, 20) = 4.5; +uniform lowp float glow_amount : hint_range(0, 20) = 4.5; +uniform lowp float flickering : hint_range(0, 1) = 0.55; + +vec3 fresnel_glow(float amount, float intensity, vec3 color, vec3 normal, vec3 view) { + return pow((1.0 - dot(normalize(normal), normalize(view))), amount) * color * intensity; +} + +void fragment () { + vec2 canvas; + if (straight_lines) { + canvas = SCREEN_UV; + } else { + canvas = vec2(VIEW.x, VIEW.y); + } + vec2 lines = vec2(clamp(sin((TIME * line_speed + canvas.y) / line_width), line_blur, 1.0 - line_blur), canvas.x); + vec2 interupts = vec2(clamp(sin((TIME * interrupt_speed + canvas.y) / interrupt_width * 3.0), interrupt_blur, 1.0 - interrupt_blur), canvas.x); + + float flicker = clamp(fract(cos(TIME) * 43758.5453123), flickering, 1.0); + vec4 imgtex = flicker * line_color * texture(texture_image, lines * interupts); + vec3 imgtex_color = vec3(imgtex.r, imgtex.g, imgtex.b); + vec3 fresnel_color = vec3(glow_color.r, glow_color.g, glow_color.b); + vec3 fresnel = fresnel_glow(glow_amount, glow_itensity, fresnel_color, NORMAL, VIEW); + ALBEDO = imgtex_color + fresnel; + + EMISSION = glow_amount * vec3(glow_color.r, glow_color.g, glow_color.b); + ALPHA = lines.x * interupts.x; +} \ No newline at end of file diff --git a/src/shaders/plasma.gdshader b/src/shaders/plasma.gdshader new file mode 100644 index 0000000..5a974cc --- /dev/null +++ b/src/shaders/plasma.gdshader @@ -0,0 +1,59 @@ +// Plasma Pulse shader +// Adapted from https://godotshaders.com/shader/scifi-hologram/ + +shader_type spatial; +render_mode unshaded, cull_back; + +uniform mediump vec3 albedo: source_color = vec3(0.9, 0.0, 0.7); + +uniform bool transpose_axis = false; + +group_uniforms wave; +uniform mediump sampler2D wave_gradient; +uniform mediump float wave_width: hint_range(0, 10) = 1; +uniform mediump float wave_speed = 0.4; + +group_uniforms glow; +uniform mediump vec4 glow_color: source_color = vec4(0.5, 0.75, 1.0, 1.0); +uniform lowp float glow_intensity: hint_range(0, 20) = 0.618; +uniform lowp float glow_amount: hint_range(0, 20) = 4.5; + +group_uniforms pulse; +uniform mediump sampler2D pulse_gradient; +uniform mediump float pulse_speed: hint_range(0, 10) = 0.3; + +group_uniforms edge_wave; +uniform mediump sampler2D edge_gradient; +uniform mediump vec2 edge_size = vec2(0.1, 0.05); +uniform mediump vec2 edge_bias = vec2(0.0, 0.5); +uniform mediump float edge_speed = 0.3; + +vec3 fresnel_glow(float amount, float intensity, vec3 color, vec3 normal, vec3 view) { + return pow((1.0 - dot(normalize(normal), normalize(view))), amount) * color * intensity; +} + +void fragment () { + float canvas = -UV.x; + float t_canvas = UV.y; + if(transpose_axis) { + canvas = -UV.y; + t_canvas = UV.x; + } + float wave_value = texture(wave_gradient, vec2((canvas + TIME * wave_speed) / wave_width, 0)).r; + + vec3 fresnel_color = vec3(glow_color.r, glow_color.g, glow_color.b); + vec3 fresnel = fresnel_glow(glow_amount, glow_intensity, fresnel_color, NORMAL, VIEW); + + float pulse_value = texture(pulse_gradient, vec2(TIME * pulse_speed, 0)).r; + + float edge_sample = texture(edge_gradient, vec2(canvas, TIME * edge_speed)).r; + vec2 edge = edge_sample * edge_size + edge_bias; + float edge_factor = 1.0; + if(t_canvas < edge.x || t_canvas > 1.0 - edge.y) { + edge_factor = 0.0; + } + + ALBEDO = albedo + fresnel; + EMISSION = glow_amount * vec3(glow_color.r, glow_color.g, glow_color.b); + ALPHA = wave_value * pulse_value * edge_factor; +} \ No newline at end of file diff --git a/src/world/gunk_body/gunk_body.tscn b/src/world/gunk_body/gunk_body.tscn index 4c0be0f..ea07f44 100644 --- a/src/world/gunk_body/gunk_body.tscn +++ b/src/world/gunk_body/gunk_body.tscn @@ -25,6 +25,7 @@ grow_vertical = 2 script = ExtResource("2_kkcjw") [node name="DebugDraw" type="Control" parent="."] +visible = false layout_mode = 3 anchors_preset = 0 offset_right = 40.0 diff --git a/vault/assets/color_palette.md b/vault/assets/color_palette.md index 6529ea7..06666a6 100644 --- a/vault/assets/color_palette.md +++ b/vault/assets/color_palette.md @@ -1,3 +1,6 @@ +## Player +- \#00ff4d Laser Green SAMPLE + ## Grunk - \#001a4d Grunk Blue SAMPLE - \#00081a Grunk Dark Blue SAMPLE