From 0589d4d25327fa0b0711ada8065670c1b32c8db7 Mon Sep 17 00:00:00 2001 From: teatov Date: Fri, 4 Jul 2025 04:54:04 +1000 Subject: [PATCH] add projectile model and material --- assets/models/projectiles/projectile.glb | 3 + .../models/projectiles/projectile.glb.import | 43 +++++++++++ assets/textures/effects/stripes.png | 3 + assets/textures/effects/stripes.png.import | 36 ++++++++++ assets/textures/light_decal.png | 3 + assets/textures/light_decal.png.import | 36 ++++++++++ .../projectiles/projectile_glow_mat.tres | 13 ++++ .../materials/projectiles/projectile_mat.tres | 17 +++++ scenes/projectiles/projectile.tscn | 33 ++++++--- scenes/test.tscn | 10 +-- scripts/projectiles/projectile.gd | 19 +++++ shaders/projectile.gdshader | 72 +++++++++++++++++++ shaders/projectile.gdshader.uid | 1 + 13 files changed, 275 insertions(+), 14 deletions(-) create mode 100644 assets/models/projectiles/projectile.glb create mode 100644 assets/models/projectiles/projectile.glb.import create mode 100644 assets/textures/effects/stripes.png create mode 100644 assets/textures/effects/stripes.png.import create mode 100644 assets/textures/light_decal.png create mode 100644 assets/textures/light_decal.png.import create mode 100644 resources/materials/projectiles/projectile_glow_mat.tres create mode 100644 resources/materials/projectiles/projectile_mat.tres create mode 100644 shaders/projectile.gdshader create mode 100644 shaders/projectile.gdshader.uid diff --git a/assets/models/projectiles/projectile.glb b/assets/models/projectiles/projectile.glb new file mode 100644 index 0000000..e560f11 --- /dev/null +++ b/assets/models/projectiles/projectile.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62ef82f362ed44a184745c29123ed7180925caac083ee5a8c592b75051e563fc +size 26900 diff --git a/assets/models/projectiles/projectile.glb.import b/assets/models/projectiles/projectile.glb.import new file mode 100644 index 0000000..d10dd7e --- /dev/null +++ b/assets/models/projectiles/projectile.glb.import @@ -0,0 +1,43 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bl3flu6un3op1" +path="res://.godot/imported/projectile.glb-af3cf412720af56f90ee1f2373fcb033.scn" + +[deps] + +source_file="res://assets/models/projectiles/projectile.glb" +dest_files=["res://.godot/imported/projectile.glb-af3cf412720af56f90ee1f2373fcb033.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="Model" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={ +"materials": { +"@MATERIAL:0": { +"use_external/path": "uid://8ehagthiwlw" +} +} +} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/assets/textures/effects/stripes.png b/assets/textures/effects/stripes.png new file mode 100644 index 0000000..634ca42 --- /dev/null +++ b/assets/textures/effects/stripes.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ecce8eef11088f0f5aa86a4ec714d1edce2a76fb8377093891c13fb3748a280 +size 34266 diff --git a/assets/textures/effects/stripes.png.import b/assets/textures/effects/stripes.png.import new file mode 100644 index 0000000..dd49a79 --- /dev/null +++ b/assets/textures/effects/stripes.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djqrrvlpfyiax" +path.s3tc="res://.godot/imported/stripes.png-8a038ce05c63176cd1d7081153e209d2.s3tc.ctex" +path.etc2="res://.godot/imported/stripes.png-8a038ce05c63176cd1d7081153e209d2.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} + +[deps] + +source_file="res://assets/textures/effects/stripes.png" +dest_files=["res://.godot/imported/stripes.png-8a038ce05c63176cd1d7081153e209d2.s3tc.ctex", "res://.godot/imported/stripes.png-8a038ce05c63176cd1d7081153e209d2.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +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=0 diff --git a/assets/textures/light_decal.png b/assets/textures/light_decal.png new file mode 100644 index 0000000..728dc42 --- /dev/null +++ b/assets/textures/light_decal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e900f59c20db950f7a3a46efd9e6615c823248bae81adb0e0f3fc93cacef9bf +size 16364 diff --git a/assets/textures/light_decal.png.import b/assets/textures/light_decal.png.import new file mode 100644 index 0000000..0c8785f --- /dev/null +++ b/assets/textures/light_decal.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c85b8i5dign4u" +path.s3tc="res://.godot/imported/light_decal.png-200e46dc4d0c6b58698ba55123a52301.s3tc.ctex" +path.etc2="res://.godot/imported/light_decal.png-200e46dc4d0c6b58698ba55123a52301.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} + +[deps] + +source_file="res://assets/textures/light_decal.png" +dest_files=["res://.godot/imported/light_decal.png-200e46dc4d0c6b58698ba55123a52301.s3tc.ctex", "res://.godot/imported/light_decal.png-200e46dc4d0c6b58698ba55123a52301.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +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=0 diff --git a/resources/materials/projectiles/projectile_glow_mat.tres b/resources/materials/projectiles/projectile_glow_mat.tres new file mode 100644 index 0000000..58623bc --- /dev/null +++ b/resources/materials/projectiles/projectile_glow_mat.tres @@ -0,0 +1,13 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://d3f5sarakjtlg"] + +[ext_resource type="Texture2D" uid="uid://c85b8i5dign4u" path="res://assets/textures/light_decal.png" id="1_3d8vv"] + +[resource] +transparency = 1 +blend_mode = 1 +albedo_color = Color(0.964706, 0.788235, 0.215686, 0.164706) +albedo_texture = ExtResource("1_3d8vv") +billboard_mode = 1 +billboard_keep_scale = true +proximity_fade_enabled = true +proximity_fade_distance = 0.1 diff --git a/resources/materials/projectiles/projectile_mat.tres b/resources/materials/projectiles/projectile_mat.tres new file mode 100644 index 0000000..7a1c9c5 --- /dev/null +++ b/resources/materials/projectiles/projectile_mat.tres @@ -0,0 +1,17 @@ +[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://dnyl326cg2rvh"] + +[ext_resource type="Shader" uid="uid://cqndfxuhkpcxq" path="res://shaders/projectile.gdshader" id="1_lb22p"] +[ext_resource type="Texture2D" uid="uid://djqrrvlpfyiax" path="res://assets/textures/effects/stripes.png" id="2_k4n51"] + +[resource] +render_priority = 0 +shader = ExtResource("1_lb22p") +shader_parameter/inside_color = Color(1, 1, 1, 1) +shader_parameter/middle_color = Color(0.964706, 0.788235, 0.215686, 1) +shader_parameter/rim_texture = ExtResource("2_k4n51") +shader_parameter/tiling = Vector2(1, 1) +shader_parameter/offset = Vector2(0, 0) +shader_parameter/offset_speed = Vector2(0.1, 0.1) +shader_parameter/speed = 1.0 +shader_parameter/scale = 1.0 +shader_parameter/distortion = 5.0 diff --git a/scenes/projectiles/projectile.tscn b/scenes/projectiles/projectile.tscn index b5bbde4..fffa2ce 100644 --- a/scenes/projectiles/projectile.tscn +++ b/scenes/projectiles/projectile.tscn @@ -1,29 +1,42 @@ -[gd_scene load_steps=6 format=3 uid="uid://cejn8wfgw14xs"] +[gd_scene load_steps=9 format=3 uid="uid://cejn8wfgw14xs"] [ext_resource type="Script" uid="uid://bbd22tc1scoom" path="res://scripts/projectiles/projectile.gd" id="1_kv6x5"] [ext_resource type="Material" uid="uid://cux40v5s5sok3" path="res://resources/materials/debug/debug_projectile.tres" id="2_b024o"] [ext_resource type="PackedScene" uid="uid://c8gqrealje3o" path="res://scenes/effects/shadow_decal.tscn" id="3_2dqcj"] +[ext_resource type="PackedScene" uid="uid://bl3flu6un3op1" path="res://assets/models/projectiles/projectile.glb" id="3_oc4rm"] +[ext_resource type="Material" uid="uid://dnyl326cg2rvh" path="res://resources/materials/projectiles/projectile_mat.tres" id="4_u2n0m"] +[ext_resource type="Material" uid="uid://d3f5sarakjtlg" path="res://resources/materials/projectiles/projectile_glow_mat.tres" id="5_fdcqu"] + +[sub_resource type="QuadMesh" id="QuadMesh_u2n0m"] +size = Vector2(2.5, 2.5) [sub_resource type="SphereShape3D" id="SphereShape3D_vc8th"] radius = 0.25 -[sub_resource type="SphereMesh" id="SphereMesh_ctqwx"] -radius = 0.25 -height = 0.5 - [node name="Projectile" type="Area3D"] collision_layer = 32 collision_mask = 49 script = ExtResource("1_kv6x5") _collision_debug_material = ExtResource("2_b024o") +[node name="Model" parent="." instance=ExtResource("3_oc4rm")] + +[node name="ProjectileMesh" parent="Model" index="0"] +transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0, 0) +layers = 64 +cast_shadow = 0 +surface_material_override/0 = ExtResource("4_u2n0m") + +[node name="ProjectileGlow" type="MeshInstance3D" parent="Model/ProjectileMesh" index="0"] +transform = Transform3D(4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0) +mesh = SubResource("QuadMesh_u2n0m") +skeleton = NodePath("../..") +surface_material_override/0 = ExtResource("5_fdcqu") + [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("SphereShape3D_vc8th") debug_color = Color(0, 0.6, 0.7, 0.42) -[node name="MeshInstance3D" type="MeshInstance3D" parent="."] -layers = 64 -cast_shadow = 0 -mesh = SubResource("SphereMesh_ctqwx") - [node name="ShadowDecal" parent="." instance=ExtResource("3_2dqcj")] + +[editable path="Model"] diff --git a/scenes/test.tscn b/scenes/test.tscn index 612825f..af5ed13 100644 --- a/scenes/test.tscn +++ b/scenes/test.tscn @@ -1,14 +1,12 @@ -[gd_scene load_steps=23 format=3 uid="uid://c0buetf2h266d"] +[gd_scene load_steps=24 format=3 uid="uid://c0buetf2h266d"] [ext_resource type="Material" uid="uid://btpy4dp5lb8il" path="res://resources/materials/test_triplanar.tres" id="1_ixaua"] [ext_resource type="PackedScene" uid="uid://b73y71y3efmv" path="res://scenes/player.tscn" id="2_f4ehn"] [ext_resource type="PackedScene" uid="uid://bq8pflbvlf8q7" path="res://scenes/main_camera.tscn" id="3_74lek"] [ext_resource type="PackedScene" uid="uid://cksoaevb5sloo" path="res://scenes/enemies/projectile_spawner.tscn" id="4_84n74"] +[ext_resource type="PackedScene" uid="uid://cejn8wfgw14xs" path="res://scenes/projectiles/projectile.tscn" id="5_j5jx5"] [sub_resource type="Environment" id="Environment_wctar"] -tonemap_mode = 4 -tonemap_exposure = 1.5 -tonemap_white = 5.74 [sub_resource type="Animation" id="Animation_at5dv"] resource_name = "!ass" @@ -127,3 +125,7 @@ libraries = { &"": SubResource("AnimationLibrary_lpvoh"), &"maa": SubResource("AnimationLibrary_daiq8") } + +[node name="Projectile" parent="." instance=ExtResource("5_j5jx5")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.2686, 1.08522, -3.37655) +script = null diff --git a/scripts/projectiles/projectile.gd b/scripts/projectiles/projectile.gd index 91dca39..e3c12c6 100644 --- a/scripts/projectiles/projectile.gd +++ b/scripts/projectiles/projectile.gd @@ -2,23 +2,34 @@ class_name Projectile extends Area3D const HEIGHT: float = 1 +const MAX_STRETCH: float = 0.75 + +@export var _speed_stretch_factor: float = 100 @export var _collision_debug_material: Material var _start_position: Vector3 var _velocity: Vector3 var _lifetime: float +var _size: float = 0.25 var _life_timer: float var _debug_collision_shapes := DebugCollisionShapes.new() +@onready var _model_base: Node3D = $Model +@onready var _model_mesh: MeshInstance3D = $Model/ProjectileMesh + func _ready() -> void: _life_timer = _lifetime _debug_collision_shapes.init(get_children(), self, _collision_debug_material) global_position = _start_position body_entered.connect(_on_body_entered) + _model_mesh.rotation = Vector3( + randf_range(0, TAU), randf_range(0, TAU), randf_range(0, TAU) + ) + _model_mesh.scale = Vector3.ONE * _size func _physics_process(delta: float) -> void: @@ -27,6 +38,14 @@ func _physics_process(delta: float) -> void: _life_timer -= delta global_position += _velocity * delta + look_at(global_position + _velocity, Vector3.UP, true) + + var speed_squash := clampf( + _velocity.length() / _speed_stretch_factor, 0, MAX_STRETCH + ) + _model_base.scale = Vector3( + 1 - speed_squash, 1 - speed_squash, 1 + speed_squash + ) func init(velocity: Vector3, start_position: Vector3, lifetime: float = 10) -> void: diff --git a/shaders/projectile.gdshader b/shaders/projectile.gdshader new file mode 100644 index 0000000..7f9fb27 --- /dev/null +++ b/shaders/projectile.gdshader @@ -0,0 +1,72 @@ +// using noise displacement code from +// https://godotshaders.com/shader/3d-bubble-spatial-shield-shader/ and local +// screen space UV from https://godotshaders.com/shader/local-screen-space-uv/ + +shader_type spatial; +render_mode cull_back, unshaded; + +group_uniforms Colors; + +uniform vec4 inside_color : source_color; +uniform vec4 middle_color : source_color; +uniform sampler2D rim_texture : source_color; +uniform vec2 tiling = vec2(1.0); +uniform vec2 offset = vec2(0.0); +uniform vec2 offset_speed = vec2(0.1); + +group_uniforms VertexDisplacement; + +uniform float speed = 1.0; +uniform float scale = 1.0; +uniform float distortion = 5.0; + +varying vec4 NODE_POSITION_CLIP; + +float noise(vec3 p) { + return fract(sin(dot(p, vec3(12.9898, 78.233, 45.5432))) * 43758.5453); +} + +float fbm(vec3 p) { + float value = 0.0; + float amplitude = 0.5; + float frequency = 1.0; + for (int i = 0; i < 5; i++) { + value += amplitude * noise(p * frequency); + amplitude *= 0.5; + frequency *= 2.0; + } + return value; +} + +void vertex() { + float displacement = + (fbm(VERTEX * scale + vec3(0.0, 0.0, TIME * speed * 0.000001)) - 0.5) * + distortion; + VERTEX += NORMAL * displacement * 0.1; + + NODE_POSITION_CLIP = (PROJECTION_MATRIX * vec4(NODE_POSITION_VIEW, 1.0)); +} + +void fragment() { + if (COLOR.r >= 0.5) { + ALBEDO = inside_color.rgb; + } else if (COLOR.g >= 0.5) { + ALBEDO = middle_color.rgb; + } else if (COLOR.b >= 0.5) { + vec2 local_uv = + (SCREEN_UV * 2.0 - 1.0) * NODE_POSITION_CLIP.w - NODE_POSITION_CLIP.xy; + + local_uv.x *= VIEWPORT_SIZE.x / VIEWPORT_SIZE.y; + local_uv *= -1.0 / PROJECTION_MATRIX[1][1]; + + vec3 color = texture(rim_texture, + local_uv * tiling + 0.5 + offset + TIME * offset_speed) + .rgb; + + if (color.r < 0.5) { + discard; + } + + ALBEDO = middle_color.rgb; + } +} diff --git a/shaders/projectile.gdshader.uid b/shaders/projectile.gdshader.uid new file mode 100644 index 0000000..c8fb5f2 --- /dev/null +++ b/shaders/projectile.gdshader.uid @@ -0,0 +1 @@ +uid://cqndfxuhkpcxq