From afb3f241c43c8e0816b7df01fc67d8cefd4dc423 Mon Sep 17 00:00:00 2001 From: betalars Date: Sat, 10 Feb 2024 13:34:34 +0100 Subject: [PATCH] adding fairy lights --- design/fairy_lights.blend | 3 + src/addons/LineRenderer/line_plugin.gd | 11 ++ src/addons/LineRenderer/line_render_icon.svg | 127 +++++++++++++ .../LineRenderer/line_render_icon.svg.import | 37 ++++ src/addons/LineRenderer/line_renderer.gd | 171 ++++++++++++++++++ src/addons/LineRenderer/plugin.cfg | 7 + .../youth_room/fairylights.tscn | 82 +++++++++ .../youth_room/import/fairy_light.glb | 3 + .../youth_room/import/fairy_light.glb.import | 57 ++++++ .../import/textures/wires_albedo.png | 3 + .../import/textures/wires_albedo.png.import | 35 ++++ .../import/textures/wires_normal.png | 3 + .../import/textures/wires_normal.png.import | 35 ++++ .../youth_room/shaders/fairy_light_diode.res | Bin 0 -> 14022 bytes .../youth_room/shaders/fairylight.material | Bin 0 -> 1926 bytes .../shaders/fairylight_halo.material | Bin 0 -> 1957 bytes src/project.godot | 2 +- 17 files changed, 575 insertions(+), 1 deletion(-) create mode 100644 design/fairy_lights.blend create mode 100644 src/addons/LineRenderer/line_plugin.gd create mode 100644 src/addons/LineRenderer/line_render_icon.svg create mode 100644 src/addons/LineRenderer/line_render_icon.svg.import create mode 100644 src/addons/LineRenderer/line_renderer.gd create mode 100644 src/addons/LineRenderer/plugin.cfg create mode 100644 src/base-environments/youth_room/fairylights.tscn create mode 100644 src/base-environments/youth_room/import/fairy_light.glb create mode 100644 src/base-environments/youth_room/import/fairy_light.glb.import create mode 100644 src/base-environments/youth_room/import/textures/wires_albedo.png create mode 100644 src/base-environments/youth_room/import/textures/wires_albedo.png.import create mode 100644 src/base-environments/youth_room/import/textures/wires_normal.png create mode 100644 src/base-environments/youth_room/import/textures/wires_normal.png.import create mode 100644 src/base-environments/youth_room/shaders/fairy_light_diode.res create mode 100644 src/base-environments/youth_room/shaders/fairylight.material create mode 100644 src/base-environments/youth_room/shaders/fairylight_halo.material diff --git a/design/fairy_lights.blend b/design/fairy_lights.blend new file mode 100644 index 0000000..5752dd3 --- /dev/null +++ b/design/fairy_lights.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c881fcd0d24a9082f1907821b21c4d73e485a48a83f88c6aeed452fe0f7b4478 +size 1154684 diff --git a/src/addons/LineRenderer/line_plugin.gd b/src/addons/LineRenderer/line_plugin.gd new file mode 100644 index 0000000..5dbab1b --- /dev/null +++ b/src/addons/LineRenderer/line_plugin.gd @@ -0,0 +1,11 @@ +@tool +extends EditorPlugin + +func _enter_tree(): + # Initialization of the plugin goes here. + add_custom_type("LineRenderer3D", "MeshInstance3D", preload("line_renderer.gd"), preload("line_render_icon.svg")) + + +func _exit_tree(): + # Clean-up of the plugin goes here. + remove_custom_type("Line Renderer 3D") diff --git a/src/addons/LineRenderer/line_render_icon.svg b/src/addons/LineRenderer/line_render_icon.svg new file mode 100644 index 0000000..aa4d895 --- /dev/null +++ b/src/addons/LineRenderer/line_render_icon.svg @@ -0,0 +1,127 @@ + + + + diff --git a/src/addons/LineRenderer/line_render_icon.svg.import b/src/addons/LineRenderer/line_render_icon.svg.import new file mode 100644 index 0000000..ffd167a --- /dev/null +++ b/src/addons/LineRenderer/line_render_icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://drumkfhf8d2tn" +path="res://.godot/imported/line_render_icon.svg-9fabbd2cfeb579cc989ccd151dbe0a0b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/LineRenderer/line_render_icon.svg" +dest_files=["res://.godot/imported/line_render_icon.svg-9fabbd2cfeb579cc989ccd151dbe0a0b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +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=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/src/addons/LineRenderer/line_renderer.gd b/src/addons/LineRenderer/line_renderer.gd new file mode 100644 index 0000000..a5ce4f7 --- /dev/null +++ b/src/addons/LineRenderer/line_renderer.gd @@ -0,0 +1,171 @@ +@tool +extends MeshInstance3D +class_name LineRenderer3D + +@export var points: Array[Vector3] = [Vector3(0,0,0),Vector3(0,5,0)]: + set(new_points): points = new_points +@export var start_thickness:float = 0.1: + set(new_start_thickness): start_thickness = new_start_thickness +@export var end_thickness:float = 0.1: + set(new_end_thickness): end_thickness = new_end_thickness +@export var corner_resolution:int = 5: + set(new_corner_resolution): corner_resolution = new_corner_resolution +@export var cap_resolution:int = 5: + set(new_cap_resolution): cap_resolution = new_cap_resolution +@export var draw_caps:bool = true: + set(new_draw_caps): draw_caps = new_draw_caps +@export var draw_crners:bool = true: + set(new_draw_crners): draw_crners = new_draw_crners +@export var use_global_coords:bool = true: + set(new_use_global_coords): use_global_coords = new_use_global_coords +@export var tile_texture:bool = true: + set(new_tile_texture): tile_texture = new_tile_texture + +var camera : Camera3D +var cameraOrigin : Vector3 + +func _enter_tree(): + mesh = ImmediateMesh.new() + +func _ready(): + pass + +func _process(_delta): + if points.size() < 2: + return + + camera = get_viewport().get_camera_3d() + if camera == null: + return + cameraOrigin = to_local(camera.get_global_transform().origin) + + var progressStep:float = 1.0 / points.size(); + var progress:float = 0; + var thickness:float = lerp(start_thickness, end_thickness, progress); + var nextThickness:float = lerp(start_thickness, end_thickness, progress + progressStep); + + var surface:SurfaceTool = SurfaceTool.new() + surface.begin(Mesh.PRIMITIVE_TRIANGLES) + + for i in range(points.size() - 1): + var A:Vector3 = points[i] + var B:Vector3 = points[i+1] + + if use_global_coords: + A = to_local(A) + B = to_local(B) + + var AB:Vector3 = B - A; + var orthogonalABStart:Vector3 = (cameraOrigin - ((A + B) / 2)).cross(AB).normalized() * thickness; + var orthogonalABEnd:Vector3 = (cameraOrigin - ((A + B) / 2)).cross(AB).normalized() * nextThickness; + + var AtoABStart:Vector3 = A + orthogonalABStart + var AfromABStart:Vector3 = A - orthogonalABStart + var BtoABEnd:Vector3 = B + orthogonalABEnd + var BfromABEnd:Vector3 = B - orthogonalABEnd + + if i == 0: + if draw_caps: + cap(surface, A, B, thickness, cap_resolution) + + if tile_texture: + var ABLen = AB.length() + var ABFloor = floor(ABLen) + var ABFrac = ABLen - ABFloor + + surface.set_uv(Vector2(ABFloor, 0)) + surface.add_vertex(AtoABStart) + surface.set_uv(Vector2(-ABFrac, 0)) + surface.add_vertex(BtoABEnd) + surface.set_uv(Vector2(ABFloor, 1)) + surface.add_vertex(AfromABStart) + surface.set_uv(Vector2(-ABFrac, 0)) + surface.add_vertex(BtoABEnd) + surface.set_uv(Vector2(-ABFrac, 1)) + surface.add_vertex(BfromABEnd) + surface.set_uv(Vector2(ABFloor, 1)) + surface.add_vertex(AfromABStart) + else: + surface.set_uv(Vector2(1, 0)) + surface.add_vertex(AtoABStart) + surface.set_uv(Vector2(0, 0)) + surface.add_vertex(BtoABEnd) + surface.set_uv(Vector2(1, 1)) + surface.add_vertex(AfromABStart) + surface.set_uv(Vector2(0, 0)) + surface.add_vertex(BtoABEnd) + surface.set_uv(Vector2(0, 1)) + surface.add_vertex(BfromABEnd) + surface.set_uv(Vector2(1, 1)) + surface.add_vertex(AfromABStart) + + if i == points.size() - 2: + if draw_caps: + cap(surface, B, A, nextThickness, cap_resolution) + else: + if draw_crners: + var C = points[i+2] + if use_global_coords: + C = to_local(C) + + var BC = C - B; + var orthogonalBCStart = (cameraOrigin - ((B + C) / 2)).cross(BC).normalized() * nextThickness; + + var angleDot = AB.dot(orthogonalBCStart) + + if angleDot > 0 and not angleDot == 1: + corner(surface, B, BtoABEnd, B + orthogonalBCStart, corner_resolution) + elif angleDot < 0 and not angleDot == -1: + corner(surface, B, B - orthogonalBCStart, BfromABEnd, corner_resolution) + + progress += progressStep; + thickness = lerp(start_thickness, end_thickness, progress); + nextThickness = lerp(start_thickness, end_thickness, progress + progressStep); + + surface.generate_normals() + surface.generate_tangents() + mesh = surface.commit() + +func cap(surface: SurfaceTool, center:Vector3, pivot:Vector3, thickness:float, cap_resolution:int): + var orthogonal:Vector3 = (cameraOrigin - center).cross(center - pivot).normalized() * thickness; + var axis:Vector3 = (center - cameraOrigin).normalized(); + + var vertex_array:Array = [] + for i in range(cap_resolution + 1): + vertex_array.append(Vector3(0,0,0)) + vertex_array[0] = center + orthogonal; + vertex_array[cap_resolution] = center - orthogonal; + + for i in range(1, cap_resolution): + vertex_array[i] = center + (orthogonal.rotated(axis, lerp(0.0, PI, float(i) / cap_resolution))); + + for i in range(1, cap_resolution + 1): + surface.set_uv(Vector2(0, (i - 1) / cap_resolution)) + surface.add_vertex(vertex_array[i - 1]); + surface.set_uv(Vector2(0, (i - 1) / cap_resolution)) + surface.add_vertex(vertex_array[i]); + surface.set_uv(Vector2(0.5, 0.5)) + surface.add_vertex(center); + +func corner(surface: SurfaceTool, center:Vector3, start:Vector3, end:Vector3, cap_resolution:int): + var vertex_array:Array = [] + for i in range(cap_resolution + 1): + vertex_array.append(Vector3(0,0,0)) + vertex_array[0] = start; + vertex_array[cap_resolution] = end; + + var axis:Vector3 = start.cross(end).normalized() + var offset:Vector3 = start - center + var angle:float = offset.angle_to(end - center) + + for i in range(1, cap_resolution): + vertex_array[i] = center + offset.rotated(axis, lerp(0.0, angle, float(i) / cap_resolution)); + + for i in range(1, cap_resolution + 1): + surface.set_uv(Vector2(0, (i - 1) / cap_resolution)) + surface.add_vertex(vertex_array[i - 1]); + surface.set_uv(Vector2(0, (i - 1) / cap_resolution)) + surface.add_vertex(vertex_array[i]); + surface.set_uv(Vector2(0.5, 0.5)) + surface.add_vertex(center); + diff --git a/src/addons/LineRenderer/plugin.cfg b/src/addons/LineRenderer/plugin.cfg new file mode 100644 index 0000000..14efb9b --- /dev/null +++ b/src/addons/LineRenderer/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="LineRenderer" +description="A simple line renderer for Godot 4.0, useful for rendering cylindrical volume such as lasers, trails, etc. Based on the Godot 3.0 version by @dbp8890 at https://github.com/dbp8890/line-renderer ported by @LemiSt24, which is based on the helpful C# implementation by @paulohyy at https://github.com/paulohyy/linerenderer and added some additional features such as UV tiling." +author="betalars" +version="1.0" +script="line_plugin.gd" diff --git a/src/base-environments/youth_room/fairylights.tscn b/src/base-environments/youth_room/fairylights.tscn new file mode 100644 index 0000000..d504639 --- /dev/null +++ b/src/base-environments/youth_room/fairylights.tscn @@ -0,0 +1,82 @@ +[gd_scene load_steps=9 format=3 uid="uid://cg70r0102t8nl"] + +[ext_resource type="Texture2D" uid="uid://i75aktvgsdwg" path="res://base-environments/youth_room/import/textures/wires_normal.png" id="1_p3lcj"] +[ext_resource type="Texture2D" uid="uid://chisldkpt6bf5" path="res://base-environments/youth_room/import/textures/wires_albedo.png" id="1_xsr58"] +[ext_resource type="Script" path="res://addons/LineRenderer/line_renderer.gd" id="2_javfj"] +[ext_resource type="ArrayMesh" uid="uid://f5fr2e5gq313" path="res://base-environments/youth_room/shaders/fairy_light_diode.res" id="4_qh8yy"] + +[sub_resource type="GDScript" id="GDScript_2caij"] +script/source = "@tool +extends Node3D + +@export var light_array: Array[Vector3]: + set(points): + light_array = points + if is_inside_tree(): + rebuild() + +@onready var wires:LineRenderer3D = $wires +@onready var diodes:MultiMeshInstance3D = $diodes +@export var seed:int = 42 +var rng = RandomNumberGenerator.new() +@export var size:float = 0.1: + set(new_size): + size = new_size + rebuild() + if is_inside_tree(): + wires.end_thickness = size*0.1 + wires.start_thickness = size*0.1 + +# Called when the node enters the scene tree for the first time. +func _ready(): + rebuild() + +func rebuild(): + rng.seed = seed + rng.state = 0 + for child in wires.get_children(): child.free() + wires.points = light_array + diodes.multimesh.instance_count = light_array.size() + var meshBuffer:PackedFloat32Array + for point in light_array: + rng + var base:Basis = Basis(Vector3(rng.randf_range(-1, 1), rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized(), rng.randf_range(0, PI*2)) + base = base.scaled(Vector3(size, size, size)) + meshBuffer.append_array([base.x.x, base.x.y, base.x.z, point.x, base.y.x, base.y.y, base.y.z, point.y, base.z.x, base.z.y, base.z.z, point.z]) + diodes.multimesh.buffer = meshBuffer +" + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5ca5e"] +transparency = 2 +alpha_scissor_threshold = 0.5 +alpha_antialiasing_mode = 0 +cull_mode = 2 +albedo_color = Color(0.368627, 0.368627, 0.368627, 1) +albedo_texture = ExtResource("1_xsr58") +normal_enabled = true +normal_texture = ExtResource("1_p3lcj") + +[sub_resource type="ImmediateMesh" id="ImmediateMesh_u31or"] + +[sub_resource type="MultiMesh" id="MultiMesh_ic3h7"] +transform_format = 1 +instance_count = 30 +mesh = ExtResource("4_qh8yy") +buffer = PackedFloat32Array(0.0998169, 0.00482103, -0.00365424, -0.545, -0.00428558, 0.0989875, 0.0135316, 0.915, 0.0042696, -0.0133502, 0.0990128, 1.035, 0.0700075, -0.0358849, 0.0617351, -0.47, 0.0525334, 0.0844406, -0.0104897, 0.855, -0.0483653, 0.0397751, 0.0779663, 0.905, 0.0042587, 0.0920312, -0.0388859, -0.44, -0.00571533, 0.0390819, 0.0918692, 0.871, 0.0997457, -0.00168997, 0.00692427, 0.78, 0.0219999, -0.0870806, -0.0439656, -0.385, 0.0800974, 0.041851, -0.0428124, 0.91, 0.0556813, -0.0257966, 0.0789565, 0.69, 0.0923335, 0.0288341, -0.0253597, -0.38, -0.0359662, 0.088075, -0.0308096, 0.995, 0.0134518, 0.0375685, 0.0916933, 0.595, 0.0410372, 0.0236122, 0.0880819, -0.39, -0.0818364, -0.0330796, 0.0469951, 0.925, 0.0402337, -0.0913685, 0.00574842, 0.465, 0.0963897, 0.0249758, -0.00923199, -0.364, -0.025153, 0.0967818, -0.000788714, 0.86, 0.0087379, 0.00308236, 0.0995698, 0.211, 0.0905162, -0.0353528, 0.0236008, -0.295, 0.00980512, 0.0713907, 0.0693341, 0.82, -0.0413604, -0.0604445, 0.0680866, 0.06, 0.0999699, -0.000440024, 0.00241425, -0.255, 0.00037743, 0.0999657, 0.0025912, 0.805, -0.00242483, -0.00258131, 0.0999373, -0.15, 0.0666952, -0.0744692, 0.00246829, -0.175, 0.0669796, 0.0613729, 0.0417982, 0.83, -0.0326417, -0.0262242, 0.090812, -0.355, 0.00827521, 0.0528018, -0.0845191, -0.135, 0.0951837, -0.0293119, -0.00899272, 0.955, -0.0295225, -0.0797043, -0.0526844, -0.515, 0.0983988, -0.0102168, 0.0146044, -0.025, 0.00642553, 0.0967642, 0.0244007, 0.78, -0.0166249, -0.0230716, 0.0958714, -0.615, -0.0341773, -0.0716575, -0.0608039, 0.115, 0.0144934, 0.059907, -0.078747, 0.63, 0.0928539, -0.0357262, -0.010089, -0.695, -0.0232891, -0.0711249, 0.066324, 0.245, 0.0795472, -0.0531651, -0.0290812, 0.555, 0.0559451, 0.0459861, 0.0689595, -0.745, -0.0599926, -0.0254553, -0.075848, 0.37, -0.0708402, 0.0609612, 0.0355725, 0.595, 0.0371828, 0.0750717, -0.0546048, -0.805, 0.0107775, 0.0912119, 0.0395505, 0.455, 0.0273445, -0.0409675, 0.0870284, 0.745, 0.0955831, 0.00143545, -0.0293567, -0.84, 0.0745873, 0.00700857, -0.0662391, 0.505, -0.0366242, 0.0873785, -0.0319947, 0.89, 0.0556363, 0.0481236, 0.0677401, -0.87, -0.0524777, -0.0408163, -0.0747002, 0.445, -0.0771795, -0.0142038, 0.0619805, 1.175, -0.0359084, 0.0901791, -0.024048, -0.87, 0.0652616, -0.0746751, 0.0128275, 0.26, -0.071962, -0.0663868, -0.0203536, 1.28, 0.0237149, 0.00405218, -0.0970628, -0.815, 0.0477617, -0.0860534, 0.0177096, 0.125, -0.0450234, -0.00666441, 0.089042, 1.35, -0.0754435, -0.0505014, -0.0419272, -0.8, 0.0526553, -0.07791, -0.0340215, -0.037, -0.0570784, -0.00274075, -0.0820643, 1.479, 0.0630038, 0.0626301, -0.0459129, -0.834, 0.0726285, 0.053708, 0.0429017, -0.2, -0.0349996, 0.0826095, -0.0441667, 1.601, -0.0591619, 0.0170622, 0.0787956, -0.851, 0.0581542, 0.0297762, -0.0757065, -0.359, -0.0464154, 0.0885717, -0.000817926, 1.769, 0.0668109, 0.0356151, 0.0653289, -0.85, 0.0875991, -0.0425381, 0.0227357, -0.5, 0.0336438, 0.0876653, 0.0343932, 1.949, -0.0345616, -0.022479, 0.0911054, -0.85, 0.0946831, -0.0299322, -0.0117972, -0.594, 0.0199689, 0.0259233, 0.0944946, 2.126, -0.0252261, -0.0918261, 0.0305222, -0.85, 0.0626413, -0.0766232, 0.0143161, -0.634, 0.0779479, 0.0616799, -0.0109416, 2.238, -0.000446323, 0.0180131, 0.0983633, -0.85, 0.0510754, -0.0397606, 0.076226, -0.634, -0.0155809, 0.0829139, 0.0536891, 2.035, -0.084549, -0.0392986, 0.0361536, -0.85, -0.055891, -0.072196, -0.0407913, -0.614, -0.0700671, 0.0148083, 0.0697948, 1.875, -0.0443486, 0.0675903, -0.0588622, -0.85, -0.0545317, 0.0517385, -0.0659501, -0.65, 0.0389976, 0.0853039, 0.0346761, 1.655, 0.0741989, -0.00680947, -0.0666945, -0.85, 0.0858331, 0.0430527, -0.0279131, -0.65, 0.0302511, -0.0864024, -0.040243, 1.475, -0.0414433, 0.0260978, -0.0871858, -0.87) + +[node name="fairylights" type="Node3D"] +script = SubResource("GDScript_2caij") +light_array = Array[Vector3]([Vector3(0, 0, 0), Vector3(0, 1, 0)]) + +[node name="wires" type="MeshInstance3D" parent="."] +material_override = SubResource("StandardMaterial3D_5ca5e") +mesh = SubResource("ImmediateMesh_u31or") +script = ExtResource("2_javfj") +points = Array[Vector3]([Vector3(0, 0, 0), Vector3(0, 1, 0)]) +start_thickness = 0.01 +end_thickness = 0.01 +use_global_coords = false +tile_texture = false + +[node name="diodes" type="MultiMeshInstance3D" parent="."] +multimesh = SubResource("MultiMesh_ic3h7") diff --git a/src/base-environments/youth_room/import/fairy_light.glb b/src/base-environments/youth_room/import/fairy_light.glb new file mode 100644 index 0000000..9db55f0 --- /dev/null +++ b/src/base-environments/youth_room/import/fairy_light.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74d30738973e1394e8fefd24b3f946f1ef755ff0f0c6f6c1b41c619ce67c4209 +size 7268 diff --git a/src/base-environments/youth_room/import/fairy_light.glb.import b/src/base-environments/youth_room/import/fairy_light.glb.import new file mode 100644 index 0000000..d107425 --- /dev/null +++ b/src/base-environments/youth_room/import/fairy_light.glb.import @@ -0,0 +1,57 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cat2o0tdxahiq" +path="res://.godot/imported/fairy_light.glb-23acffacc6593c5a8045d4a2c6c8f3f3.scn" + +[deps] + +source_file="res://base-environments/youth_room/import/fairy_light.glb" +dest_files=["res://.godot/imported/fairy_light.glb-23acffacc6593c5a8045d4a2c6c8f3f3.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={ +"materials": { +"emit": { +"use_external/enabled": true, +"use_external/path": "res://base-environments/youth_room/shaders/fairylight.material" +}, +"halo": { +"use_external/enabled": true, +"use_external/path": "res://base-environments/youth_room/shaders/fairylight_halo.material" +} +}, +"meshes": { +"fairy_light_diode": { +"generate/lightmap_uv": 0, +"generate/lods": 0, +"generate/shadow_meshes": 0, +"lods/normal_merge_angle": 60.0, +"lods/normal_split_angle": 25.0, +"save_to_file/enabled": true, +"save_to_file/make_streamable": "", +"save_to_file/path": "res://base-environments/youth_room/shaders/fairy_light_diode.res" +} +} +} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/src/base-environments/youth_room/import/textures/wires_albedo.png b/src/base-environments/youth_room/import/textures/wires_albedo.png new file mode 100644 index 0000000..05cc0e4 --- /dev/null +++ b/src/base-environments/youth_room/import/textures/wires_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0fdd70e286ea86b67ae82c759f18b25a5cace622171e90b6c51049d2d9bfb1c +size 15878 diff --git a/src/base-environments/youth_room/import/textures/wires_albedo.png.import b/src/base-environments/youth_room/import/textures/wires_albedo.png.import new file mode 100644 index 0000000..7f8554c --- /dev/null +++ b/src/base-environments/youth_room/import/textures/wires_albedo.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chisldkpt6bf5" +path.s3tc="res://.godot/imported/wires_albedo.png-e2ca1c0cfbd554203dfd9c0e487f3b1c.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://base-environments/youth_room/import/textures/wires_albedo.png" +dest_files=["res://.godot/imported/wires_albedo.png-e2ca1c0cfbd554203dfd9c0e487f3b1c.s3tc.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/src/base-environments/youth_room/import/textures/wires_normal.png b/src/base-environments/youth_room/import/textures/wires_normal.png new file mode 100644 index 0000000..0e030d7 --- /dev/null +++ b/src/base-environments/youth_room/import/textures/wires_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34452323e72ecbe69b53627b27150552214668bc4d9d271f05a095d5369ad148 +size 22811 diff --git a/src/base-environments/youth_room/import/textures/wires_normal.png.import b/src/base-environments/youth_room/import/textures/wires_normal.png.import new file mode 100644 index 0000000..2b2a41c --- /dev/null +++ b/src/base-environments/youth_room/import/textures/wires_normal.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://i75aktvgsdwg" +path.s3tc="res://.godot/imported/wires_normal.png-a1ed398b6f0bdd3bf06fa8d9f72a947e.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://base-environments/youth_room/import/textures/wires_normal.png" +dest_files=["res://.godot/imported/wires_normal.png-a1ed398b6f0bdd3bf06fa8d9f72a947e.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=1 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=1 +roughness/src_normal="res://base-environments/youth_room/import/textures/wires_normal.png" +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/src/base-environments/youth_room/shaders/fairy_light_diode.res b/src/base-environments/youth_room/shaders/fairy_light_diode.res new file mode 100644 index 0000000000000000000000000000000000000000..596929ba0cff94226b6322731e097cbb9cdbda5a GIT binary patch literal 14022 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 literal 0 HcmV?d00001 diff --git a/src/base-environments/youth_room/shaders/fairylight.material b/src/base-environments/youth_room/shaders/fairylight.material new file mode 100644 index 0000000000000000000000000000000000000000..a8d2bc1be5d53be995c07078bd17abfe5034ed74 GIT binary patch literal 1926 zcmV;12YL8XQ$s@n000005C8y>6953a1polA0RR9fwJ-f(01u5V04hQ-4MHGO(*^)c zfoK!VFbIqeAOYY#0b#oB?iP7<_mW??B_xU1%aue$db^v-{M*{vHfe0H%>aAbrbg+ORW3!W!I8eNEpV+q&8mE$)1SA^!qJVGb9WMd%}VWQ z7VAU&bDK17817Et*WX1PudY$&Y9+Qh;=cv_?@7Z;z}*eFz7xyr?gKnS?X?=O>D|4= z^KTkSbwW*d++K5c2VVL~dVC?a8`RidsQ1;|eithO|N1gRt09fjQuq>Yn;*OTiMyxp z05?o3@VEf*;qD?%)x%kpcr@_|=7_00BGR#iE>G4QM>y%};ld+n=*T8;4e za}htu%1q}|IW>-#tMjC%jMtuwxJjX|KeH}Q$R%synZ^#=3blNUt%Q$vu0O%EhOLzv z#kSO8yX6|OhNjo}N$}2@hBIL8aM=_|JLwfdN|+i9ibw2~cIcojOU^Olgp zYm-tNnBErFx8YrPW6EqcAr%&w1`EBa!k}0vEkuw|d6*I&OsGI{;-al~xm~34QnFX0 zw@ty`hKF5Eov=O~E!_%Gn$W8%>$0v;2gK2UFbw3mI2_FeyDsa3Y5@uqdR0Zmcqo^r zO-rIEib_GTGS|awERYA=d_J7Zb-ekBQ5-?91@bDce@SiR8(!bs4jHv=ue!zBQhAbHK| z8Fwr6N8t0CrkE;D44j)CQOBh%X14?lrT9=s9|LuqNLb?~^y?|?HOpaJVFL_ZNv>eA zw(?3Zud630X1WMQ%o?}KhpjAS)R*0h=sOadzaKb775uEhDS+fxOXdAt`g5iC}XuN1ab3Cub1HaaH>!sV)E_itxC& zu2#4T-|gCh7=`U18>$r`_|?WI&vLrSs)@F};$8*k1L7lrirP=SdO(0D_uAOhE%G*_ zP)EGGE4WsSTvvs}Vhf81yDSW;CyjfBG<1<6!k}bhzfV@V*w@P+M?EIc#9bUnSKCFH zs1f)FnjG9OV%W=L(2=F1Qw>ouBI3-*n~3T0(SOZJaA$&?3+5zvhkFIdBvA9!8vt%> zs$s|{#v+W@^CQbRL}BLR9bjudLz26tuG7NN=g^-IsP;4bmu_&KEPuS3(X|Xop5x(i zLDC=M5Q)hH{&@$R2P_-cJZxU}OP!g+9ZuY2Vh`UwBfZLzqa_t)rQ;ErwET1%GsUsF z&fai;v9)^KTNU)aI19J7-Y#5HiWG++GD4XSSK!JfN&g_QvhTF6lB^?q(5vplt zgVKn{doV>xGrNVr>+u#~b5iUJ6$tzel4`$_B7Xu>M_&`rzhTyqRaMfLI0OELN0od@ z3Yg&s@KY7yEu7;4b;E6@O_Kq2pOAOEOvq!X#)1)_7K#%Ae)$)uoVQrozsM>D z%CEqv$^UQ#Q>Z~zQgQ(WNlBV9;DV7M>k%-ap-P$!#hL-iq-8cDifLO=opOv zPLV#a{jcf?ARiZiXxfe0_eWR3U~gSb*QOGxF{lLz2b&B$L$XyVFiacVLy+}qSr+!q MA)bxpDpFHJLp{l$h5!Hn literal 0 HcmV?d00001 diff --git a/src/base-environments/youth_room/shaders/fairylight_halo.material b/src/base-environments/youth_room/shaders/fairylight_halo.material new file mode 100644 index 0000000000000000000000000000000000000000..4bdb3a651c3064613c73d3056e88f356df8ee1f7 GIT binary patch literal 1957 zcmV;W2U_@2Q$s@n000005C8z46aWBz1pojG0ssIgwJ-f(01u@r02cqpLLhU~0YFF; zkSYK!1k;M(AQ%=541_{|vbRiWWs>U;X>BKwC5nZ^K2by#mwt7`MonmQ%_&6UjQW?U z>)&71|K?Mq0IC4D0I+(~v(c4q?U;Zg?K!G`YCH#%emr?2N#GciW znHjLDW!APj>z2FLtGigenD_Ol0dCsxonJQ}^ywN}%)c!&pD=R@t~`F+IHAChm>GoU zleX_OVLQH(3T8gQ%mJ7=!^|Pf0VW)j4aY=-hENCu`g~SaJf2R~DY>*S(zDjXrqp2r zrY^61uhpiaB)1gsUpebL5;p4C)Lo>{HEz(pJ?);e@;v8N4zKU#Mfr*+e1-Fo`$buoQyXRgYZf528-X+ps9DMsbX zJNN$!UPgDn?<>{$-2ba>E9p&(nH{iw6N6p9AG0hO=fncl+rHebD_zV_)l;`Jqm7~e zjjDA2|)+EJRLrGCBO>=FJt~XuNG)-eLO%vmDjcS=s-dDeY)F1&MdU4WVM}`oQ2pBp< zBOeY%3Q!V6FPJ&x$UqUv2NEI|8xbO8L^)>6m?7grCIEpBAt5JJrg4S|DCvNM83aIP zfr?AT=PS9BmCp)+7pM_Ugp3T4h@>D%(g86AgedBqDtZ#&GAT>45M+iRLX0B8jF3>E zatfIa&YJtW)kCL?Rgal*0KU#~fl8hVN};7WF*rB&2nesV%XL-7B$N@^=kZoZWy6zM z`^n?}EOM|m__I}XRRf?E1?@Ov;X1N~uwNg90%pLQn<%h}smFic91d++e7%n%(4XTn zzCXp4K{zb>_$koiN|6Vod{uwdX@lOwfx@KtAW@}8C;xa+3Qs$aY15_QVRJuV;pV;e z8kV5-3kPp6(Ck{s{RjY>VuluSsHZE%*CuV7_Pm^eTn1OOq3Lk=@-IXGp(pe6oPe*J zi+zb6E_9e64cMAKPE=6>z9d~WVAN=pvx7~9E)-3a@1i`|IT$^WSeAQ9lfCfZRl(?wr-jh=8Hy5Bmb{g}8(_iGG!mpG}0lrPD_u%X^r#xVUAVE~k(cIu2(O25<87Q!+;|$zg_)W3TH+XLfV0|oARcLH;&{P}Nl{Wt z3}oF3{4~HRL3FB9q7$7Ggu&uMGXn*dBe>0?VgiImQgP(y&7uj3=-`;>rIlK(npG3c zGJ3J-B97suUaS%#yjX>SA66}Ns#OKQs%n>u&`~iQ($_ykx-sY9-`o%{{!3kicaQ#9M}xMQJ8;#W=k~q1!R`;TXd*VQDaj=K~j_~bFc!D zsjCMOfE|M91|_YG0m?`V=`cb;$X2_#nB%%-7I5EFF}n`~GoW>1)7A{U*I`WS`k{NP zCzUTzaN9qbYhdw_h7`GB@ioJC!{RHN8sJJb<)G}`mCNwX%Nr%zk@qo<$Xf~+^5%t& zVMG4t&Um{lPxuOrP7x&vRRlu-LHQF;Z!a|&bP>*vXgFv#qi)zWKm{I}4}Bcik2;Bt rVkziMzq9%YxD~XgEi(#^@a-Dm;bwKy`5