Improved outline shader

This commit is contained in:
Eduard Urbach 2024-01-17 21:48:35 +01:00
parent 6934f2936b
commit 7eba25c83b
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
8 changed files with 200 additions and 54 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
!*.sum
!*.md
!*.gd
!*.gdshader
!*.import
!*.svg
!*.tres

50
enemy/Slime.blend.import Normal file
View File

@ -0,0 +1,50 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://b358op5h1y83m"
path="res://.godot/imported/Slime.blend-8da460d18e3c1f7085d49df94a74fec6.scn"
[deps]
source_file="res://enemy/Slime.blend"
dest_files=["res://.godot/imported/Slime.blend-8da460d18e3c1f7085d49df94a74fec6.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
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
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1
blender/nodes/visible=0
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true

31
enemy/Slime.tscn Normal file
View File

@ -0,0 +1,31 @@
[gd_scene load_steps=4 format=3 uid="uid://cb2t7bvvf3gwh"]
[ext_resource type="PackedScene" uid="uid://b358op5h1y83m" path="res://enemy/Slime.blend" id="1_1h1hj"]
[sub_resource type="Animation" id="Animation_mdtm7"]
resource_name = "slime_idle"
length = 2.0
loop_mode = 1
tracks/0/type = "scale_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Slime")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 1, 1, 1, 0.5, 1, 0.9, 1.1, 0.9, 1, 1, 1, 1, 1, 1.5, 1, 1.1, 0.9, 1.1, 2, 1, 1, 1, 1)
[sub_resource type="AnimationLibrary" id="AnimationLibrary_1bw8m"]
_data = {
"slime_idle": SubResource("Animation_mdtm7")
}
[node name="Slime" type="Node3D"]
[node name="Model" parent="." instance=ExtResource("1_1h1hj")]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
root_node = NodePath("../Model")
libraries = {
"": SubResource("AnimationLibrary_1bw8m")
}
autoplay = "slime_idle"

View File

@ -18,7 +18,6 @@ func _physics_process(delta):
func movement():
var direction = (Global.camera.transform.basis * Vector3(move.x, 0, move.y)).normalized()
# var direction = Vector3(move.x, 0, move.y).normalized()
if direction:
velocity.x = direction.x * MOVE_SPEED

View File

@ -2,15 +2,18 @@ extends Camera3D
@export var center: Node3D
@export var follow_speed: float
@export var shake_strength: float
var noise = FastNoiseLite.new()
func _ready():
Global.camera = self
func _process(delta):
if Global.player == null:
return
center.position = lerp(center.position, Global.player.position, follow_speed * delta)
# @export var shake_strength: float
# var noise = FastNoiseLite.new()
# func shake(time):
# var trauma_sq := 1.0
# var h_offset := noise.get_noise_2d(time, 0) * trauma_sq * shake_strength

View File

@ -1,11 +1,9 @@
[gd_scene load_steps=26 format=3 uid="uid://b40y7iuskv1ar"]
[gd_scene load_steps=20 format=3 uid="uid://b40y7iuskv1ar"]
[ext_resource type="Script" path="res://world/Game.gd" id="1_xmqq4"]
[ext_resource type="Script" path="res://world/RotateY.gd" id="3_4gn6n"]
[ext_resource type="Script" path="res://ui/FPSLabel.gd" id="3_k5d80"]
[ext_resource type="Script" path="res://ui/PingLabel.gd" id="4_1a3hc"]
[ext_resource type="Script" path="res://network/Network.gd" id="4_ao4cj"]
[ext_resource type="Shader" path="res://world/shader/Outline.gdshader" id="4_gweie"]
[ext_resource type="Script" path="res://network/Ping.gd" id="4_vx388"]
[ext_resource type="PackedScene" uid="uid://2lcnu3dy54lx" path="res://player/Player.tscn" id="5_6c2x8"]
[ext_resource type="Environment" uid="uid://dixa0yso2s1u3" path="res://world/Environment.tres" id="5_bll74"]
@ -14,20 +12,12 @@
[ext_resource type="Script" path="res://network/Login.gd" id="6_augbg"]
[ext_resource type="Script" path="res://ui/PositionLabel.gd" id="8_jc5xy"]
[ext_resource type="Script" path="res://world/Camera.gd" id="9_qfhy4"]
[ext_resource type="Material" uid="uid://ddy5gkw0k16dq" path="res://world/shader/OutlineMaterial.tres" id="10_dii8l"]
[ext_resource type="PackedScene" uid="uid://hnn0n1xc2qt7" path="res://world/Tree.blend" id="15_csh38"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qm56v"]
render_priority = 0
shader = ExtResource("4_gweie")
shader_parameter/depth_threshold = 0.05
shader_parameter/reverse_depth_threshold = 0.25
shader_parameter/normal_threshold = 0.6
shader_parameter/darken_amount = 0.3
shader_parameter/lighten_amount = 1.5
shader_parameter/light_direction = Vector3(0.122788, -0.707107, -0.696364)
[ext_resource type="PackedScene" uid="uid://cb2t7bvvf3gwh" path="res://enemy/Slime.tscn" id="16_fuixr"]
[sub_resource type="QuadMesh" id="QuadMesh_7yiqd"]
material = SubResource("ShaderMaterial_qm56v")
material = ExtResource("10_dii8l")
flip_faces = true
size = Vector2(2, 2)
@ -42,23 +32,6 @@ size = Vector3(20, 0.5, 20)
[sub_resource type="BoxShape3D" id="BoxShape3D_58ws3"]
size = Vector3(20, 0.5, 20)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4w7ln"]
diffuse_mode = 3
albedo_color = Color(0.294118, 0.356863, 0.439216, 1)
[sub_resource type="BoxMesh" id="BoxMesh_hf021"]
material = SubResource("StandardMaterial3D_4w7ln")
[sub_resource type="BoxShape3D" id="BoxShape3D_3lxo8"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ahmjh"]
diffuse_mode = 3
albedo_color = Color(0.14902, 0.517647, 1, 1)
roughness = 0.08
[sub_resource type="TorusMesh" id="TorusMesh_mu45b"]
material = SubResource("StandardMaterial3D_ahmjh")
[node name="Game" type="Node"]
script = ExtResource("1_xmqq4")
@ -145,9 +118,9 @@ handle_input_locally = false
size = Vector2i(384, 216)
render_target_update_mode = 4
[node name="CameraCenter" type="Node3D" parent="SubViewportContainer/SubViewport"]
[node name="CameraPivot" type="Node3D" parent="SubViewportContainer/SubViewport"]
[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport/CameraCenter" node_paths=PackedStringArray("center")]
[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport/CameraPivot" node_paths=PackedStringArray("center")]
transform = Transform3D(0.707107, 0.408607, -0.577096, 0, 0.816138, 0.577858, 0.707107, -0.408607, 0.577096, -10, 10, 10)
projection = 1
current = true
@ -158,7 +131,7 @@ script = ExtResource("9_qfhy4")
center = NodePath("..")
follow_speed = 5.0
[node name="PostProcessing" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/CameraCenter/Camera"]
[node name="PostProcessing" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/CameraPivot/Camera"]
unique_name_in_owner = true
extra_cull_margin = 16384.0
mesh = SubResource("QuadMesh_7yiqd")
@ -166,7 +139,7 @@ mesh = SubResource("QuadMesh_7yiqd")
[node name="Sun" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport"]
transform = Transform3D(0.984808, 0.122788, -0.122788, 0, 0.707107, 0.707107, 0.173648, -0.696364, 0.696364, 0, 5, 0)
shadow_enabled = true
directional_shadow_split_1 = 0.028
directional_shadow_mode = 0
script = ExtResource("5_pf5uw")
[node name="Environment" type="WorldEnvironment" parent="SubViewportContainer/SubViewport"]
@ -185,27 +158,25 @@ skeleton = NodePath("../../../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="SubViewportContainer/SubViewport/World/Ground/StaticBody3D"]
shape = SubResource("BoxShape3D_58ws3")
[node name="Box" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -4)
mesh = SubResource("BoxMesh_hf021")
skeleton = NodePath("../..")
[node name="RigidBody3D" type="RigidBody3D" parent="SubViewportContainer/SubViewport/World/Box"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="SubViewportContainer/SubViewport/World/Box/RigidBody3D"]
shape = SubResource("BoxShape3D_3lxo8")
[node name="Torus" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World"]
transform = Transform3D(0.7, 0, 0, 0, -3.0598e-08, -0.7, 0, 0.7, -3.0598e-08, 0, 1.79933, -4)
mesh = SubResource("TorusMesh_mu45b")
skeleton = NodePath("../..")
script = ExtResource("3_4gn6n")
[node name="Tree" parent="SubViewportContainer/SubViewport/World" instance=ExtResource("15_csh38")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, -4.64839)
[node name="Tree2" parent="SubViewportContainer/SubViewport/World" instance=ExtResource("15_csh38")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, 5.35161)
[node name="Players" type="Node3D" parent="SubViewportContainer/SubViewport"]
unique_name_in_owner = true
[node name="Enemies" type="Node3D" parent="SubViewportContainer/SubViewport"]
[node name="Slime" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 0, -3.79687)
[node name="Slime2" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.00829, 0, -1.95247)
[node name="Slime3" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 0, -0.306177)
[connection signal="timeout" from="Network/Ping/Timer" to="Network/Ping" method="send_ping"]
[connection signal="timeout" from="Network/Login/Timer" to="Network/Login" method="send_login"]

View File

@ -0,0 +1,76 @@
shader_type spatial;
render_mode unshaded;
uniform sampler2D screen_texture : source_color, hint_screen_texture, filter_nearest;
uniform sampler2D depth_texture : source_color, hint_depth_texture, filter_nearest;
uniform sampler2D normal_texture : source_color, hint_normal_roughness_texture, filter_nearest;
uniform bool depth_layer = true;
uniform bool normal_layer = true;
uniform bool original_layer = true;
uniform float depth_edge_strength : hint_range(-1, 1, 0.01) = -0.5;
uniform float normal_edge_strength : hint_range(-1, 1, 0.01) = 0.5;
uniform float depth_edge_threshold : hint_range(0, 1) = 0.2;
uniform float normal_edge_threshold : hint_range(0, 1) = 0.6;
uniform vec3 normal_edge_bias = vec3(1, 1, 1);
float get_depth(vec2 screen_uv, mat4 inv_projection_matrix) {
float depth = texture(depth_texture, screen_uv).r;
vec3 ndc = vec3(screen_uv * 2.0 - 1.0, depth);
vec4 view = inv_projection_matrix * vec4(ndc, 1.0);
view.xyz /= view.w;
return -view.z;
}
vec2[4] create_uvs(vec2 screen_uv, vec2 texel_size) {
vec2 uvs[4];
uvs[0] = vec2(screen_uv.x, min(1.0 - texel_size.y, screen_uv.y + texel_size.y));
uvs[1] = vec2(screen_uv.x, max(0.0, screen_uv.y - texel_size.y));
uvs[2] = vec2(min(1.0 - texel_size.x, screen_uv.x + texel_size.x), screen_uv.y);
uvs[3] = vec2(max(0.0, screen_uv.x - texel_size.x), screen_uv.y);
return uvs;
}
float normal_detection(vec2 uv, vec3 normal) {
vec3 neighbor_normal = texture(normal_texture, uv).xyz * 2.0 - 1.0;
vec3 normal_diff = normal - neighbor_normal;
float normal_bias_diff = dot(normal_diff, normal_edge_bias);
float normal_indicator = smoothstep(0.01, -0.01, normal_bias_diff);
return dot(normal_diff, normal_diff) * normal_indicator;
}
void vertex() {
POSITION = vec4(VERTEX, 1.0);
}
void fragment() {
vec3 original = texture(screen_texture, SCREEN_UV).rgb;
vec3 normal = texture(normal_texture, SCREEN_UV).xyz * 2.0 - 1.0;
float depth = get_depth(SCREEN_UV, INV_PROJECTION_MATRIX);
vec2 texel_size = 1.0 / VIEWPORT_SIZE.xy;
vec2 neighbors[4] = create_uvs(SCREEN_UV, texel_size);
float depth_diff = 0.0;
float normal_diff = 0.0;
for (int i = 0; i < 4; i++) {
float neighbor_depth = get_depth(neighbors[i], INV_PROJECTION_MATRIX);
depth_diff += neighbor_depth - depth;
normal_diff += normal_detection(neighbors[i], normal);
}
float strength = 0.0;
if (depth_layer && depth_diff > depth_edge_threshold) {
strength = 1.0 + depth_edge_strength;
} else if (normal_layer && normal_diff > normal_edge_threshold && depth_diff > 0.0) {
strength = 1.0 + normal_edge_strength;
} else if(original_layer) {
strength = 1.0;
}
ALBEDO = original * strength;
}

View File

@ -0,0 +1,15 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://ddy5gkw0k16dq"]
[ext_resource type="Shader" path="res://world/shader/Outline.gdshader" id="1_fmkjv"]
[resource]
render_priority = 0
shader = ExtResource("1_fmkjv")
shader_parameter/depth_layer = true
shader_parameter/normal_layer = true
shader_parameter/original_layer = true
shader_parameter/depth_edge_strength = -0.5
shader_parameter/normal_edge_strength = 0.5
shader_parameter/depth_edge_threshold = 0.2
shader_parameter/normal_edge_threshold = 0.6
shader_parameter/normal_edge_bias = Vector3(1, 1, 1)