From ddc7aa104534538f575eaa756f26bd5520738c9f Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Wed, 26 Nov 2025 18:13:02 +0100 Subject: [PATCH] first commit --- .editorconfig | 4 +++ .gitattributes | 2 ++ .gitignore | 3 +++ icon.svg | 1 + icon.svg.import | 43 ++++++++++++++++++++++++++++++++ light.tscn | 9 +++++++ lights.gd | 39 +++++++++++++++++++++++++++++ lights.gd.uid | 1 + main.gd | 36 +++++++++++++++++++++++++++ main.gd.uid | 1 + main.tscn | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ project.godot | 16 ++++++++++++ 12 files changed, 220 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 light.tscn create mode 100644 lights.gd create mode 100644 lights.gd.uid create mode 100644 main.gd create mode 100644 main.gd.uid create mode 100644 main.tscn create mode 100644 project.godot diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..32d0e49 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dj13im0k1ydwf" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/light.tscn b/light.tscn new file mode 100644 index 0000000..afd1189 --- /dev/null +++ b/light.tscn @@ -0,0 +1,9 @@ +[gd_scene format=3 uid="uid://b6opad48icrl8"] + +[node name="SpotLight3D" type="SpotLight3D"] +transform = Transform3D(1, 0, 0, 0, -4.3711385e-08, 0.99999994, 0, -0.99999994, -4.3711385e-08, 0, 0, 0) +light_size = 0.3 +spot_range = 0.8 +spot_attenuation = 0.0 +spot_angle = 70.0 +spot_angle_attenuation = 3.2490098 diff --git a/lights.gd b/lights.gd new file mode 100644 index 0000000..bec7596 --- /dev/null +++ b/lights.gd @@ -0,0 +1,39 @@ +extends Marker3D +class_name Lights + +@export var light_count: int = 1 +@export var light_radius: float = 5.0 +@export var light_template: PackedScene +@export var pattern_repetition: int = 5 + +@export var light_color: Color = Color.WHITE +@export var light_intensity: float = 1.0 +@export var expected_rotation_delta: float = 0. + +func _ready() -> void: + for i in light_count: + var angle = (TAU / light_count) * i + var x = light_radius * cos(angle) + var z = light_radius * sin(angle) + var light_instance = light_template.instantiate() + light_instance.position = Vector3(x, 0, z) + add_child(light_instance) + +const BASE_DELTA: float = 16 + +var virtual_rotation: float = 0.0 + +const FULL_DARK_ROTATION_DELTA := .1 + +func _process(delta: float) -> void: + var frames_elapsed = delta / BASE_DELTA + virtual_rotation += expected_rotation_delta + var max_darkness = expected_rotation_delta / FULL_DARK_ROTATION_DELTA + var i := 0 + for light in get_children(): + if light is SpotLight3D: + var pattern_offset := ((i + int(virtual_rotation * pattern_repetition)) % pattern_repetition) / float(pattern_repetition) + light.light_color = light_color + light.light_energy = 1 - (1 - pattern_offset) * max_darkness + i += 1 + expected_rotation_delta = lerp(expected_rotation_delta, 0.0, frames_elapsed * 5) \ No newline at end of file diff --git a/lights.gd.uid b/lights.gd.uid new file mode 100644 index 0000000..d4442f8 --- /dev/null +++ b/lights.gd.uid @@ -0,0 +1 @@ +uid://cjmoj5kmiquip diff --git a/main.gd b/main.gd new file mode 100644 index 0000000..e6c8c97 --- /dev/null +++ b/main.gd @@ -0,0 +1,36 @@ +extends Node3D + +@onready var lights: Lights = %Lights +@onready var slider: HSlider = %HSlider +@onready var plane: MeshInstance3D = %Plane + +@export var light_rotation: float = 0.0 +@export var color_gradient: Gradient + +func _ready(): + slider.value_changed.connect(set_light_rotation) + +var error_correction := 0. + +func set_light_rotation(value: float) -> void: + value = wrapf(value, 0, 1) + + # get shortest diff including wrapping + var diff = light_rotation - value + var wrapped_diff = (value + 1) - light_rotation + if abs(wrapped_diff) < abs(diff): + diff = -wrapped_diff + wrapped_diff = (light_rotation + 1) - value + if abs(wrapped_diff) < abs(diff): + diff = wrapped_diff + + # ignore small movements until a bigger one occurs or until they accumulate enough, to avoid reseting the light movement + # diff += error_correction + # if diff < .05: + # error_correction = diff + # return + + lights.expected_rotation_delta = diff + light_rotation = value + lights.light_color = color_gradient.sample(value) + slider.value = value diff --git a/main.gd.uid b/main.gd.uid new file mode 100644 index 0000000..3b02429 --- /dev/null +++ b/main.gd.uid @@ -0,0 +1 @@ +uid://yxfetvyqh2t3 diff --git a/main.tscn b/main.tscn new file mode 100644 index 0000000..ae89cd0 --- /dev/null +++ b/main.tscn @@ -0,0 +1,65 @@ +[gd_scene load_steps=10 format=3 uid="uid://bfysabo18nycq"] + +[ext_resource type="Script" uid="uid://yxfetvyqh2t3" path="res://main.gd" id="1_h2yge"] +[ext_resource type="Script" uid="uid://cjmoj5kmiquip" path="res://lights.gd" id="1_ig7tw"] +[ext_resource type="PackedScene" uid="uid://b6opad48icrl8" path="res://light.tscn" id="2_0xm2m"] + +[sub_resource type="Gradient" id="Gradient_h2yge"] +offsets = PackedFloat32Array(0, 0.25, 0.5, 0.75, 1) +colors = PackedColorArray(0.8156863, 0.38431373, 1, 1, 5.1018596e-06, 0.6902809, 0.5935051, 1, 0.31225172, 0.8011136, 0, 1, 0.5515474, 0.79056466, 1, 1, 0.8171765, 0.38458148, 1, 1) + +[sub_resource type="CylinderMesh" id="CylinderMesh_0xm2m"] +top_radius = 1.0 +bottom_radius = 1.0 +height = 0.01 +cap_bottom = false + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7dm0k"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7dm0k"] + +[sub_resource type="Sky" id="Sky_ig7tw"] +sky_material = SubResource("ProceduralSkyMaterial_7dm0k") + +[sub_resource type="Environment" id="Environment_0xm2m"] +background_mode = 2 +sky = SubResource("Sky_ig7tw") + +[node name="Node3D" type="Node3D"] +script = ExtResource("1_h2yge") +color_gradient = SubResource("Gradient_h2yge") + +[node name="Plane" type="MeshInstance3D" parent="."] +unique_name_in_owner = true +mesh = SubResource("CylinderMesh_0xm2m") +surface_material_override/0 = SubResource("StandardMaterial3D_7dm0k") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_0xm2m") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 2, 0) + +[node name="Lights" type="Marker3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +gizmo_extents = 0.7 +script = ExtResource("1_ig7tw") +light_count = 20 +light_radius = 0.7 +light_template = ExtResource("2_0xm2m") + +[node name="HSlider" type="HSlider" parent="."] +unique_name_in_owner = true +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -150.0 +offset_top = -16.0 +offset_right = 150.0 +grow_horizontal = 2 +grow_vertical = 0 +max_value = 1.0 +step = 0.0 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..5c597b2 --- /dev/null +++ b/project.godot @@ -0,0 +1,16 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="ambientlightdemo" +run/main_scene="uid://bfysabo18nycq" +config/features=PackedStringArray("4.5", "Forward Plus") +config/icon="res://icon.svg"