diff --git a/attribution.txt b/attribution.txt index 7e65028..a46e1d3 100644 --- a/attribution.txt +++ b/attribution.txt @@ -6,3 +6,6 @@ Shaders: Watercolor: https://c-chen99.github.io/watercolorShader/final.html CMKY: https://www.shadertoy.com/view/MltBW4 Fresnel: https://godotshaders.com/snippet/fresnel/ + +Code: +occlussion shader: https://www.reddit.com/r/godot/comments/rww6e9/comment/hrfa51g/?utm_source=share&utm_medium=web2x&context=3 \ No newline at end of file diff --git a/blends/.gitignore b/blends/.gitignore new file mode 100644 index 0000000..989f160 --- /dev/null +++ b/blends/.gitignore @@ -0,0 +1,6 @@ +*.blend1 +*.blend2 +*.blend3 +*.blend4 +*.blend5 + diff --git a/blends/small_room.blend b/blends/small_room.blend index b830aaf..4f65553 100644 --- a/blends/small_room.blend +++ b/blends/small_room.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7ca326bee07aee490ffc0c13074af5848a16afe08f0d933354b25181fef8eb2 -size 959896 +oid sha256:c6e3a6002d6f2611ab0741f65e74627d3f9aa36cd5f41ff9b1738ca35851c66d +size 1003500 diff --git a/blends/small_room.blend1 b/blends/small_room.blend1 index 36d92e6..ba19630 100644 Binary files a/blends/small_room.blend1 and b/blends/small_room.blend1 differ diff --git a/godot/control_scheme/control_target_overlay.gdshader b/godot/control_scheme/control_target_overlay.gdshader new file mode 100644 index 0000000..be794fe --- /dev/null +++ b/godot/control_scheme/control_target_overlay.gdshader @@ -0,0 +1,19 @@ +shader_type spatial; + +#include "res://shaders/noise.gdshaderinc" + +render_mode depth_prepass_alpha, depth_test_disabled; + +void vertex() { + VERTEX *= 0.999; +} + +void fragment() { + float scale = 50.0; + float speed = 1000.0; + float f = random2(round(UV * scale)/scale + round(TIME*speed)/speed); + if (f > 0.1) { + discard; + } + ALBEDO = vec3(0.0); +} diff --git a/godot/control_scheme/control_target_overlay.material b/godot/control_scheme/control_target_overlay.material index fcdc96e..cfaaf59 100644 --- a/godot/control_scheme/control_target_overlay.material +++ b/godot/control_scheme/control_target_overlay.material @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83a5adc4b833fc7a42cad6a04f5b3d502ca33fc2c0545d350f546aa998cb8117 -size 175 +oid sha256:9dc4b0e289692491a6dfe242e569fc0891cdd83a85220fc7e81b5cdabec140e9 +size 286 diff --git a/godot/control_scheme/controller.gd b/godot/control_scheme/controller.gd index bcf102e..0f6d6b1 100644 --- a/godot/control_scheme/controller.gd +++ b/godot/control_scheme/controller.gd @@ -1,9 +1,13 @@ extends Node3D @export var camera: Camera3D -@export var target: Node3D +@export var initial_target: Node3D +var target: Targetable = null @export var sensitivity := 0.01 +func _ready(): + set_target(initial_target) + func _input(event): if event is InputEventMouseMotion: rotate_view(event.relative*sensitivity) @@ -18,46 +22,12 @@ func rotate_view(amount: Vector2): %rotate_helper.rotate_z(amount.y) %rotate_helper.rotation_degrees.z = clampf(%rotate_helper.rotation_degrees.z, -77, 77) -func set_target(node: Node3D, should_unset=true): - if target != null and should_unset: - pass - -var old_material_props = null - -func change_material(mesh: MeshInstance3D): - if old_material_props != null: - push_error("UH OOH!!! 628") - old_material_props = [] - for i in range(mesh.get_surface_override_material_count()): - var mat := mesh.get_active_material(i) - if mat is BaseMaterial3D: - old_material_props.append(mat.depth_draw_mode) - mat.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_DISABLED - push_next_pass(mat, preload("control_target_overlay.material")) - else: - old_material_props.append(null) - push_error("Don't know how to handle shader material for", mesh) - -func unchange_material(mesh: MeshInstance3D): - if old_material_props == null: - push_error("UH OOH!!! 629") - for i in range(mesh.get_surface_override_material_count()): - var mat := mesh.get_active_material(i) - if mat is BaseMaterial3D: - mat.depth_draw_mode = old_material_props[i] - pop_next_pass(mat) - else: - push_error("Don't know how to handle shader material for", mesh) - -func push_next_pass(m: Material, with: Material): - if m.next_pass != null: - push_next_pass(m.next_pass, with) - else: - m.next_pass = with - -func pop_next_pass(m: Material): - if m == null: - return true - if pop_next_pass(m.next_pass): - m.next_pass = null - return false +func set_target(node: Node3D): + var ntarget = Targetable.is_targetable(node) + if ntarget == null: + push_error("Node is node targetable", node) + return + if target != null: + target.unmake_target() + ntarget.make_target() + target = ntarget diff --git a/godot/control_scheme/is_targetable.gd b/godot/control_scheme/is_targetable.gd new file mode 100644 index 0000000..846a38e --- /dev/null +++ b/godot/control_scheme/is_targetable.gd @@ -0,0 +1,69 @@ +extends Node3D +class_name Targetable + +@export var attached_to: Node3D = owner + +static func is_targetable(node: Node3D) -> Targetable: + return node.get_node_or_null("is_targetable") + +func make_target(): + walk_meshes_post_order(self.get_parent(), change_all_materials) + +func unmake_target(): + walk_meshes_post_order(self.get_parent(), unchange_all_materials) + +func walk_meshes_post_order(parent: Node3D, f: Callable): + for child in parent.get_children(): + walk_meshes_post_order(child, f) + if parent is MeshInstance3D: + f.call(parent) + +func change_all_materials(mesh: MeshInstance3D): + for i in range(mesh.get_surface_override_material_count()): + var original_mat: BaseMaterial3D = mesh.get_active_material(i) + var layer0 = original_mat.duplicate() + var layer1 = preload("control_target_overlay.material").duplicate() + # Non-occlused + var layer2 = original_mat.duplicate() + layer0.next_pass = layer1 + layer1.next_pass = layer2 + + layer0.render_priority = 0 + layer1.render_priority = 1 + layer2.render_priority = 2 + + + + layer0.no_depth_test = true + layer0.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS + layer0.grow = true + layer0.grow_amount = -0.001 + layer0.albedo_color = layer0.albedo_color.darkened(0.5) + + layer2.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS + layer2.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_ALWAYS + + mesh.set_surface_override_material(i, layer0) + #mesh.set_surface_override_material(i, mat) + #mat.next_pass = preload("control_target_overlay.material") + + +func unchange_all_materials(mesh: MeshInstance3D): + for i in range(mesh.get_surface_override_material_count()): + var mat := mesh.get_active_material(i) + unchange_material(mat) + while mat.next_pass != null: + unchange_material(mat.next_pass) + mat = mat.next_pass + mat.next_pass = null + +func change_material(mat: BaseMaterial3D) -> BaseMaterial3D: + mat = mat.duplicate() + mat.render_priority = 100 + mat.no_depth_test = true + return mat + +func unchange_material(mat: BaseMaterial3D) -> BaseMaterial3D: + mat.render_priority = 0 + mat.no_depth_test = false + return mat diff --git a/godot/control_scheme/is_targetable.tscn b/godot/control_scheme/is_targetable.tscn new file mode 100644 index 0000000..ab49342 --- /dev/null +++ b/godot/control_scheme/is_targetable.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://w6cldokq87k0"] + +[ext_resource type="Script" path="res://control_scheme/is_targetable.gd" id="1_108lw"] + +[node name="is_targetable" type="Node3D"] +script = ExtResource("1_108lw") diff --git a/godot/shaders/noise.gdshaderinc b/godot/shaders/noise.gdshaderinc new file mode 100644 index 0000000..0304814 --- /dev/null +++ b/godot/shaders/noise.gdshaderinc @@ -0,0 +1,31 @@ + +/* https://www.shadertoy.com/view/XsX3zB + * + * The MIT License + * Copyright © 2013 Nikita Miropolskiy + * + * ( license has been changed from CCA-NC-SA 3.0 to MIT + * + * but thanks for attributing your source code when deriving from this sample + * with a following link: https://www.shadertoy.com/view/XsX3zB ) + * + */ + +/* discontinuous pseudorandom uniformly distributed in [-0.5, +0.5]^3 */ +vec3 random3(vec3 c) { + float j = 4096.0*sin(dot(c,vec3(17.0, 59.4, 15.0))); + vec3 r; + r.z = fract(512.0*j); + j *= .125; + r.x = fract(512.0*j); + j *= .125; + r.y = fract(512.0*j); + return r-0.5; +} + +// https://godotshaders.com/snippet/random-value/ +float random2(vec2 uv) { + return fract(sin(dot(uv.xy, + vec2(12.9898,78.233))) * 43758.5453123); +} + diff --git a/godot/small_room.glb b/godot/small_room.glb index ba1e75e..aae427b 100644 --- a/godot/small_room.glb +++ b/godot/small_room.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa4ad5b52dd06febea07af3f68b655f620cd3356345bd41e8de28925bda52962 -size 13732 +oid sha256:06bb29dbd079ac6490365519f6672713690f9bc5ec6ce36fc48ed9d6bb22d8cb +size 17928 diff --git a/godot/tests/control_scheme/test_basic_controls.tscn b/godot/tests/control_scheme/test_basic_controls.tscn index 0d5bc9e..903d29d 100644 --- a/godot/tests/control_scheme/test_basic_controls.tscn +++ b/godot/tests/control_scheme/test_basic_controls.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=4 format=3 uid="uid://70bb2yncbl"] +[gd_scene load_steps=5 format=3 uid="uid://70bb2yncbl"] [ext_resource type="PackedScene" uid="uid://bua7f25rpewkp" path="res://small_room.glb" id="1_2ticn"] [ext_resource type="PackedScene" uid="uid://drmb4sitb74fx" path="res://control_scheme/controller.tscn" id="2_dcvuq"] +[ext_resource type="PackedScene" uid="uid://w6cldokq87k0" path="res://control_scheme/is_targetable.tscn" id="2_y2131"] [sub_resource type="Environment" id="Environment_f0m14"] ambient_light_source = 2 @@ -10,14 +11,16 @@ ambient_light_energy = 0.5 [node name="small_room" instance=ExtResource("1_2ticn")] +[node name="is_targetable" parent="grape" index="0" instance=ExtResource("2_y2131")] + [node name="WorldEnvironment" type="WorldEnvironment" parent="." index="3"] environment = SubResource("Environment_f0m14") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment" index="0"] transform = Transform3D(1, 0, 0, 0, 0.933762, 0.357895, 0, -0.357895, 0.933762, 0, 1.43864, 1.81738) -[node name="controller" parent="." index="4" node_paths=PackedStringArray("camera", "target") instance=ExtResource("2_dcvuq")] +[node name="controller" parent="." index="4" node_paths=PackedStringArray("camera", "initial_target") instance=ExtResource("2_dcvuq")] camera = NodePath("Camera3D") -target = NodePath("../grape") +initial_target = NodePath("../grape") [node name="Camera3D" type="Camera3D" parent="controller" index="1"]