Used procedural mesh in semaphore level

This commit is contained in:
Vojtěch Struhár 2025-02-24 22:49:03 +01:00
parent f39c7e70c7
commit a50449c71b
5 changed files with 75 additions and 10 deletions

View File

@ -30,10 +30,32 @@ venkovního úhlu. Protože reálně jsem od něj mega daleko, takže portálov
- Free-standing portál neni uplně dobrý příklad, protože by to světlo mělo házet _výseč_ ven. To ničím fajné, to jsme zpátky u raytracingu. Leda by to člověk oblbnul nějakým shadow meshem nebo něco.. hm. Velmi specifické. Ale u těch dveří jako v semaforovém levelu by to fungovalo asi v pohodě, protože kolem futer je stěna. - Free-standing portál neni uplně dobrý příklad, protože by to světlo mělo házet _výseč_ ven. To ničím fajné, to jsme zpátky u raytracingu. Leda by to člověk oblbnul nějakým shadow meshem nebo něco.. hm. Velmi specifické. Ale u těch dveří jako v semaforovém levelu by to fungovalo asi v pohodě, protože kolem futer je stěna.
- Spotlight..? - Spotlight..?
### Gizmos
- Kreslím kubickou bezierku, která spojuje portál s exit portálem, ale nevypadá to nic moc. Je to blbě vidět a hloubka se dost ztrácí.
- Možná by bylo lepší ten exit portal _highlightnout_ podobně jak je zrovna vybraný node - double line gizmo
- TODO: Handly na procedurální mesh. Inspirace v godotím CollisionShape
### Procedural mesh ### Procedural mesh
Momentálně procedural mesh generuju helper nodem. Tohle je ideální kandidát na _gizmo handles_ podobně jak collision shape
- Normály jsou pass. Mám jenom 8 vertexů, takže to bude dycky vypadat blbě. Ale portály jsou stejně vždycky unshaded. - Normály jsou pass. Mám jenom 8 vertexů, takže to bude dycky vypadat blbě. Ale portály jsou stejně vždycky unshaded.
- Zmínit v DP! Docela dobrý sell, obhajoba rozhodnutí. - **Zmínit v DP!** Docela dobrý sell, obhajoba rozhodnutí.
- Když se na portál podívám přímo zepředu (ortogonálně), tak ten indent není vubec vidět. Nejsem si jistý jestli to je k něčemu.. ten portálový mesh který jsem vzal z _simple portal sytem_ ani žádné UV coodinates nemá. - *UV coords:* Když se na portál podívám přímo zepředu (ortogonálně), tak ten indent není vubec vidět. Nejsem si jistý jestli to je k něčemu.. ten portálový mesh který jsem vzal z _simple portal sytem_ ani žádné UV coodinates nemá. Procedural mesh funguje hezky ✅
- Možná by se to hodilo kdyby měl portál "inactive" texturu... ale to se dá obejít placatým meshem narvaným před něj.. a neřešíš prohlubeň. Asi undefined behavior tady :D nechám na vývojářích
- Na to kolik jsem s tím teď zabil času, tak tohle je asi nanic. Prohlubeň je extrémně důležitá featura.
![portal-uv-coordinates](assets/portal-uv-coordinates.png) ![portal-uv-coordinates](assets/portal-uv-coordinates.png)
- **Stíny** - shadow mesh tam můžu a nemusím plácnout (stejný jako hlavní). Další věc je že stíny by asi měly být na OFF a nebo DOUBLE_SIDED. Asi to nechám na uživateli.. to s meshem nesouvisí nutně.
### Texture portal mask
Mám v plánu udělat texture masku pro tvarování protálů. S házením stínů to bude průser. V tomhle je přístup s _tvarem meshe_ lepší. Měl bych nakódit generování vícero tvarů...?
:exclamation: Tohle asi nebude fungovat kvůli té prohlubni
- Kdybys měl oblouk nahoře, tak nemůžeš jenom tak clipnout obdélníkový portál. Kdyby byl plochý, tak jo. Ale takhle.
:question: Tohle asi řeší tenký box s **culling- off** jak měl Sebastian ve svém Unity videu. Akorát to žere trochu renderingu.. ale v porovnání s X kamerama navíc je to asi fuk.

View File

@ -1,12 +1,12 @@
[gd_scene load_steps=12 format=3 uid="uid://27pb62xwsqd8"] [gd_scene load_steps=14 format=4 uid="uid://27pb62xwsqd8"]
[ext_resource type="PackedScene" uid="uid://b5x7fmpwck335" path="res://hud.tscn" id="1_mmt1i"] [ext_resource type="PackedScene" uid="uid://b5x7fmpwck335" path="res://hud.tscn" id="1_mmt1i"]
[ext_resource type="MeshLibrary" uid="uid://bedqgubx1g1uf" path="res://prototypes.tres" id="2_vdsn8"] [ext_resource type="MeshLibrary" uid="uid://bedqgubx1g1uf" path="res://prototypes.tres" id="2_vdsn8"]
[ext_resource type="ArrayMesh" uid="uid://bqilnvlfws6xh" path="res://portal-mesh.tres" id="3_c4jka"]
[ext_resource type="Script" uid="uid://d2bvvjsibau8c" path="res://addons/simple-portal-system/scripts/portal.gd" id="4_top28"] [ext_resource type="Script" uid="uid://d2bvvjsibau8c" path="res://addons/simple-portal-system/scripts/portal.gd" id="4_top28"]
[ext_resource type="Script" uid="uid://bkv7t4hw21byg" path="res://addons/simple-portal-system/scripts/simple_portal_teleport.gd" id="5_evjit"] [ext_resource type="Script" uid="uid://bkv7t4hw21byg" path="res://addons/simple-portal-system/scripts/simple_portal_teleport.gd" id="5_evjit"]
[ext_resource type="PackedScene" uid="uid://cgdlowfuuorvi" path="res://player.tscn" id="6_hlt8e"] [ext_resource type="PackedScene" uid="uid://cgdlowfuuorvi" path="res://player.tscn" id="6_hlt8e"]
[ext_resource type="Script" uid="uid://cili3lyodjqel" path="res://portal_environment_adapter.gd" id="7_2gewm"] [ext_resource type="Script" uid="uid://cili3lyodjqel" path="res://portal_environment_adapter.gd" id="7_2gewm"]
[ext_resource type="PackedScene" uid="uid://d1dtxvwk86ple" path="res://procedural_mesh_maker.tscn" id="8_vdsn8"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_b0o0q"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_b0o0q"]
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
@ -22,9 +22,37 @@ tonemap_mode = 3
tonemap_exposure = 1.5 tonemap_exposure = 1.5
glow_enabled = true glow_enabled = true
[sub_resource type="ArrayMesh" id="ArrayMesh_vdsn8"]
_surfaces = [{
"aabb": AABB(-1, -1, -0.1, 2, 2, 0.1),
"attribute_data": PackedByteArray("AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAgD/NzEw9zcxMPTMzcz/NzEw9zcxMPTMzcz8zM3M/MzNzPw=="),
"format": 34359742487,
"index_count": 30,
"index_data": PackedByteArray("AAABAAQABAABAAUAAQADAAUABQADAAcAAwACAAcABwACAAYAAgAAAAYABgAAAAQABAAFAAYABgAFAAcA"),
"name": "Portal Material",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 8,
"vertex_data": PackedByteArray("AACAvwAAgD8AAAAAAACAPwAAgD8AAAAAAACAvwAAgL8AAAAAAACAPwAAgL8AAAAAZmZmv2ZmZj/NzMy9ZmZmP2ZmZj/NzMy9ZmZmv2ZmZr/NzMy9ZmZmP2ZmZr/NzMy9/3//f/9/AID/f/9//38AgP9//3//fwCA/3//f/9/AID/f/9//38AgP9//3//fwCA/3//f/9/AID/f/9//38AgA==")
}]
[sub_resource type="BoxShape3D" id="BoxShape3D_cgnft"] [sub_resource type="BoxShape3D" id="BoxShape3D_cgnft"]
size = Vector3(2, 2, 0.5) size = Vector3(2, 2, 0.5)
[sub_resource type="ArrayMesh" id="ArrayMesh_mmt1i"]
_surfaces = [{
"aabb": AABB(-1, -1, -0.1, 2, 2, 0.1),
"attribute_data": PackedByteArray("AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAgD/NzEw9zcxMPTMzcz/NzEw9zcxMPTMzcz8zM3M/MzNzPw=="),
"format": 34359742487,
"index_count": 30,
"index_data": PackedByteArray("AAABAAQABAABAAUAAQADAAUABQADAAcAAwACAAcABwACAAYAAgAAAAYABgAAAAQABAAFAAYABgAFAAcA"),
"name": "Portal Material",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 8,
"vertex_data": PackedByteArray("AACAvwAAgD8AAAAAAACAPwAAgD8AAAAAAACAvwAAgL8AAAAAAACAPwAAgL8AAAAAZmZmv2ZmZj/NzMy9ZmZmP2ZmZj/NzMy9ZmZmv2ZmZr/NzMy9ZmZmP2ZmZr/NzMy9/3//f/9/AID/f/9//38AgP9//3//fwCA/3//f/9/AID/f/9//38AgP9//3//fwCA/3//f/9/AID/f/9//38AgA==")
}]
[node name="level_3rooms" type="Node3D"] [node name="level_3rooms" type="Node3D"]
[node name="HUD" parent="." instance=ExtResource("1_mmt1i")] [node name="HUD" parent="." instance=ExtResource("1_mmt1i")]
@ -44,7 +72,7 @@ metadata/_editor_floor_ = Vector3(0, 3, 0)
[node name="Portal_red" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")] [node name="Portal_red" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.5, 2, -4) transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.5, 2, -4)
mesh = ExtResource("3_c4jka") mesh = SubResource("ArrayMesh_vdsn8")
skeleton = NodePath("") skeleton = NodePath("")
script = ExtResource("4_top28") script = ExtResource("4_top28")
vertical_viewport_resolution = 1080 vertical_viewport_resolution = 1080
@ -63,7 +91,7 @@ shape = SubResource("BoxShape3D_cgnft")
[node name="Portal_orange" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")] [node name="Portal_orange" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 2, -0.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 2, -0.5)
mesh = ExtResource("3_c4jka") mesh = SubResource("ArrayMesh_mmt1i")
skeleton = NodePath("") skeleton = NodePath("")
script = ExtResource("4_top28") script = ExtResource("4_top28")
vertical_viewport_resolution = 1080 vertical_viewport_resolution = 1080
@ -104,3 +132,7 @@ omni_range = 4.0
[node name="PortalEnvironmentAdapter" type="Node" parent="." node_paths=PackedStringArray("base")] [node name="PortalEnvironmentAdapter" type="Node" parent="." node_paths=PackedStringArray("base")]
script = ExtResource("7_2gewm") script = ExtResource("7_2gewm")
base = NodePath("../WorldEnvironment") base = NodePath("../WorldEnvironment")
[node name="ProceduralMeshMaker" parent="." node_paths=PackedStringArray("portal") instance=ExtResource("8_vdsn8")]
width = 2.0
portal = NodePath("../Portal_orange")

View File

@ -64,7 +64,9 @@ script = ExtResource("1_ksg6r")
height = 2.6 height = 2.6
width = 2.0 width = 2.0
indent = 0.133 indent = 0.133
shadow_mesh = true
portal = NodePath("../MeshInstance3D") portal = NodePath("../MeshInstance3D")
portal_material = ExtResource("1_dn1le")
[node name="OmniLight3D" type="OmniLight3D" parent="."] [node name="OmniLight3D" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.52963, 0, 1.51112) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.52963, 0, 1.51112)

View File

@ -6,9 +6,11 @@ extends Node
## Player camera's NEAR clip distance ## Player camera's NEAR clip distance
@export_range(0, 0.2, 0.001) var indent: float = 0.1 @export_range(0, 0.2, 0.001) var indent: float = 0.1
@export var portal: Portal @export var shadow_mesh: bool = true
@export var portal: Portal
@export var portal_material: BaseMaterial3D
const UV_CHECKER_MATERIAL = preload("res://textures/uv-checker-material.tres")
func _add_inspector_buttons() -> Array: func _add_inspector_buttons() -> Array:
var buttons = [] var buttons = []
@ -117,9 +119,15 @@ func generate_portal_mesh() -> void:
surface_array[Mesh.ARRAY_NORMAL] = normals surface_array[Mesh.ARRAY_NORMAL] = normals
surface_array[Mesh.ARRAY_INDEX] = indices surface_array[Mesh.ARRAY_INDEX] = indices
# TODO: Shadow mesh maybe? Should a portal even cast a shadow?
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array) mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)
mesh.surface_set_material(0, UV_CHECKER_MATERIAL) if portal_material:
mesh.surface_set_material(0, portal_material)
mesh.surface_set_name(0, "Portal Material") mesh.surface_set_name(0, "Portal Material")
portal.mesh = mesh portal.mesh = mesh
# TODO: Shadow mesh maybe? Should a portal even cast a shadow?
if shadow_mesh:
mesh.shadow_mesh = mesh
print("[PMM] Mesh assigned") print("[PMM] Mesh assigned")

View File

@ -4,3 +4,4 @@
[node name="ProceduralMeshMaker" type="Node"] [node name="ProceduralMeshMaker" type="Node"]
script = ExtResource("1_1a4ua") script = ExtResource("1_1a4ua")
shadow_mesh = null