From a59c4cd772f477ea0b3256a98cfc5e68e9e41d31 Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Tue, 11 Mar 2025 11:50:10 +0100 Subject: [PATCH 01/10] minor update --- examples/example_4.tscn | 2 +- examples/example_5.tscn | 2 +- examples/example_lenia_test.tscn | 4 +-- examples/example_mandelbrot.tscn | 4 +-- examples/example_psycho_seizure.tscn | 2 +- examples/neural pulse/neural_pulse.cpp | 44 +++++++++++++++++++++++ examples/neural pulse/neural_pulse.tscn | 16 +++++++++ examples/simple_circle/simple_circle.tscn | 4 +-- project.godot | 2 +- 9 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 examples/neural pulse/neural_pulse.cpp create mode 100644 examples/neural pulse/neural_pulse.tscn diff --git a/examples/example_4.tscn b/examples/example_4.tscn index 1d7e26f..c777972 100644 --- a/examples/example_4.tscn +++ b/examples/example_4.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://b2ip5eftk3aij"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_ke3fj"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_ke3fj"] [ext_resource type="Texture2D" uid="uid://2behgeplwycn" path="res://examples/grid_512x512.png" id="2_flqlh"] [node name="CompShadStudioEx4" type="Node2D"] diff --git a/examples/example_5.tscn b/examples/example_5.tscn index b1d6e72..43aa420 100644 --- a/examples/example_5.tscn +++ b/examples/example_5.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://cets11mlsd8hb"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_cogap"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_cogap"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_pm7bb"] diff --git a/examples/example_lenia_test.tscn b/examples/example_lenia_test.tscn index 118ec4d..6c2caef 100644 --- a/examples/example_lenia_test.tscn +++ b/examples/example_lenia_test.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=3 uid="uid://cljj33x767odp"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_wci4f"] -[ext_resource type="Script" uid="uid://jw3o2qu3a0pl" path="res://examples/LabelStepPass.gd" id="2_ndkd3"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_wci4f"] +[ext_resource type="Script" path="res://examples/LabelStepPass.gd" id="2_ndkd3"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="3_orsvs"] [node name="CompShadStudioEx3" type="Node2D"] diff --git a/examples/example_mandelbrot.tscn b/examples/example_mandelbrot.tscn index 1b0fb27..a5e532c 100644 --- a/examples/example_mandelbrot.tscn +++ b/examples/example_mandelbrot.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=3 uid="uid://d1hhshnvrt86e"] -[ext_resource type="Script" uid="uid://bib00xk6p8oo4" path="res://examples/example_mandelbrot.gd" id="1_5gp20"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_t5cx1"] +[ext_resource type="Script" path="res://examples/example_mandelbrot.gd" id="1_5gp20"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_t5cx1"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_dyrad"] [node name="example_mandelbrot" type="Node2D"] diff --git a/examples/example_psycho_seizure.tscn b/examples/example_psycho_seizure.tscn index 760210b..f1e07d4 100644 --- a/examples/example_psycho_seizure.tscn +++ b/examples/example_psycho_seizure.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://cdtqwwdxs783m"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_26wk6"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_26wk6"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_urrfs"] [node name="exeample_psycho_seizure" type="Node2D"] diff --git a/examples/neural pulse/neural_pulse.cpp b/examples/neural pulse/neural_pulse.cpp new file mode 100644 index 0000000..978dd59 --- /dev/null +++ b/examples/neural pulse/neural_pulse.cpp @@ -0,0 +1,44 @@ +void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y*WSX; + + // Normalize coordinates + vec2 fragCoord = vec2(float(x), float(y)); + vec2 r = vec2(float(WSX), float(WSY)); + + // Calculate time - using step as time + float t = float(step) * 0.05; + + vec3 c; + float l; + float z = t; + + for(int i=0; i<3; i++) { + vec2 uv, p = fragCoord/r; + uv = p; + p -= 0.5; + p.x *= r.x/r.y; + z += 0.07; + l = length(p); + + // Adding mouse interaction to the original shader + float mouseInfluence = 0.0; + if (mousex > 0 && mousey > 0) { + vec2 mousePos = vec2(float(mousex)/r.x, float(mousey)/r.y) - 0.5; + mousePos.x *= r.x/r.y; + float mouseDist = length(p - mousePos); + mouseInfluence = 0.5 * exp(-mouseDist * 4.0); + } + + uv += p/l * (sin(z + mouseInfluence) + 1.0) * abs(sin(l * 9.0 - z - z)); + c[i] = 0.01/length(mod(uv, 1.0) - 0.5); + } + + // Convert to RGBA color format for data_0 + int red = int(min(c.r * 255.0, 255.0)); + int green = int(min(c.g * 255.0, 255.0)); + int blue = int(min(c.b * 255.0, 255.0)); + + data_0[p] = int(0xFF000000 | (red << 16) | (green << 8) | blue); +} \ No newline at end of file diff --git a/examples/neural pulse/neural_pulse.tscn b/examples/neural pulse/neural_pulse.tscn new file mode 100644 index 0000000..697ae6e --- /dev/null +++ b/examples/neural pulse/neural_pulse.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3 uid="uid://dnva7w0gtcb6x"] + +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_osmo3"] +[ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_ec1t8"] + +[node name="NeuralPulse" type="Node2D"] + +[node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] +script = ExtResource("1_osmo3") +glsl_file = "res://examples/neural pulse/neural_pulse.cpp" +data = [NodePath("../Icon")] + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(579, 326) +scale = Vector2(8.75, 4.79688) +texture = ExtResource("2_ec1t8") diff --git a/examples/simple_circle/simple_circle.tscn b/examples/simple_circle/simple_circle.tscn index 8c68dd5..fc318d0 100644 --- a/examples/simple_circle/simple_circle.tscn +++ b/examples/simple_circle/simple_circle.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://c63rtjh0eurgm"] -[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_rlapi"] +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_rlapi"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_y7slp"] [node name="SimpleCircle" type="Node2D"] @@ -12,6 +12,6 @@ data = [NodePath("../Icon")] metadata/_custom_type_script = "uid://c8esqdv0y26yp" [node name="Icon" type="Sprite2D" parent="."] -position = Vector2(465.5, 268.5) +position = Vector2(580, 327) scale = Vector2(3.99219, 3.52344) texture = ExtResource("2_y7slp") diff --git a/project.godot b/project.godot index 1617345..725be9c 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="compute_shader_studio" run/main_scene="res://examples/example_1.tscn" -config/features=PackedStringArray("4.4", "Forward Plus") +config/features=PackedStringArray("4.3", "Forward Plus") config/icon="res://addons/compute_shader_studio/icon.png" [editor_plugins] From 2ba2e27e4939b10b82c302c4efce67b309b65e5d Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Sun, 16 Mar 2025 22:41:51 +0100 Subject: [PATCH 02/10] everything good & up to date --- examples/example_4.tscn | 2 +- examples/example_5.tscn | 2 +- examples/example_lenia_test.tscn | 4 +- examples/example_mandelbrot.tscn | 4 +- examples/example_psycho_seizure.tscn | 2 +- examples/neural pulse/neural_pulse.cpp | 265 ++++++++++++++++++++-- examples/neural pulse/neural_pulse.tscn | 2 +- examples/simple_circle/simple_circle.tscn | 2 +- project.godot | 2 +- 9 files changed, 250 insertions(+), 35 deletions(-) diff --git a/examples/example_4.tscn b/examples/example_4.tscn index c777972..1d7e26f 100644 --- a/examples/example_4.tscn +++ b/examples/example_4.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://b2ip5eftk3aij"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_ke3fj"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_ke3fj"] [ext_resource type="Texture2D" uid="uid://2behgeplwycn" path="res://examples/grid_512x512.png" id="2_flqlh"] [node name="CompShadStudioEx4" type="Node2D"] diff --git a/examples/example_5.tscn b/examples/example_5.tscn index 43aa420..b1d6e72 100644 --- a/examples/example_5.tscn +++ b/examples/example_5.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://cets11mlsd8hb"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_cogap"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_cogap"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_pm7bb"] diff --git a/examples/example_lenia_test.tscn b/examples/example_lenia_test.tscn index 6c2caef..118ec4d 100644 --- a/examples/example_lenia_test.tscn +++ b/examples/example_lenia_test.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=3 uid="uid://cljj33x767odp"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_wci4f"] -[ext_resource type="Script" path="res://examples/LabelStepPass.gd" id="2_ndkd3"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_wci4f"] +[ext_resource type="Script" uid="uid://jw3o2qu3a0pl" path="res://examples/LabelStepPass.gd" id="2_ndkd3"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="3_orsvs"] [node name="CompShadStudioEx3" type="Node2D"] diff --git a/examples/example_mandelbrot.tscn b/examples/example_mandelbrot.tscn index a5e532c..1b0fb27 100644 --- a/examples/example_mandelbrot.tscn +++ b/examples/example_mandelbrot.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=3 uid="uid://d1hhshnvrt86e"] -[ext_resource type="Script" path="res://examples/example_mandelbrot.gd" id="1_5gp20"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_t5cx1"] +[ext_resource type="Script" uid="uid://bib00xk6p8oo4" path="res://examples/example_mandelbrot.gd" id="1_5gp20"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_t5cx1"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_dyrad"] [node name="example_mandelbrot" type="Node2D"] diff --git a/examples/example_psycho_seizure.tscn b/examples/example_psycho_seizure.tscn index f1e07d4..760210b 100644 --- a/examples/example_psycho_seizure.tscn +++ b/examples/example_psycho_seizure.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://cdtqwwdxs783m"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_26wk6"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_26wk6"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_urrfs"] [node name="exeample_psycho_seizure" type="Node2D"] diff --git a/examples/neural pulse/neural_pulse.cpp b/examples/neural pulse/neural_pulse.cpp index 978dd59..90a8307 100644 --- a/examples/neural pulse/neural_pulse.cpp +++ b/examples/neural pulse/neural_pulse.cpp @@ -2,43 +2,258 @@ void main() { uint x = gl_GlobalInvocationID.x; uint y = gl_GlobalInvocationID.y; uint p = x + y*WSX; - + // Normalize coordinates vec2 fragCoord = vec2(float(x), float(y)); vec2 r = vec2(float(WSX), float(WSY)); + vec2 uv = fragCoord/r; + vec2 centered = uv - 0.5; + centered.x *= r.x/r.y; - // Calculate time - using step as time - float t = float(step) * 0.05; + // Time control + float t = float(step) * 0.03; - vec3 c; - float l; - float z = t; + // Generate random neuron centers + #define NEURON_COUNT 12 + vec2 neuronCenters[NEURON_COUNT]; + float neuronPhases[NEURON_COUNT]; + float neuronStrengths[NEURON_COUNT]; - for(int i=0; i<3; i++) { - vec2 uv, p = fragCoord/r; - uv = p; - p -= 0.5; - p.x *= r.x/r.y; - z += 0.07; - l = length(p); + // Initialize with pseudorandom positions using trig functions with different seeds + for (int i = 0; i < NEURON_COUNT; i++) { + // Use prime numbers and different bases to create "random" distribution + float randX = sin(float(i) * 12.9898 + t * 0.05) * 0.5; + float randY = cos(float(i) * 78.233 + t * 0.04) * 0.5; + + // Add some slow movement to neurons + randX += sin(t * 0.07 + float(i) * 0.5) * 0.1; + randY += cos(t * 0.05 + float(i) * 0.7) * 0.1; - // Adding mouse interaction to the original shader - float mouseInfluence = 0.0; - if (mousex > 0 && mousey > 0) { - vec2 mousePos = vec2(float(mousex)/r.x, float(mousey)/r.y) - 0.5; - mousePos.x *= r.x/r.y; - float mouseDist = length(p - mousePos); - mouseInfluence = 0.5 * exp(-mouseDist * 4.0); + neuronCenters[i] = vec2(randX, randY); + + // Random phase and firing strength for each neuron + neuronPhases[i] = t * (0.8 + sin(float(i) * 3.14) * 0.3) + float(i); + neuronStrengths[i] = 0.5 + sin(float(i) * 1.618 + t * 0.2) * 0.5; + } + + // ==== RANDOM CONNECTION DETERMINATION ==== + bool connections[NEURON_COUNT][NEURON_COUNT]; + for (int i = 0; i < NEURON_COUNT; i++) { + for (int j = 0; j < NEURON_COUNT; j++) { + // Use a deterministic but "random-looking" pattern for connections + // About 30% of possible connections will be active + float connectionSeed = sin(float(i) * 43.21 + float(j) * 12.345) * 0.5 + 0.5; + connections[i][j] = (i != j) && (connectionSeed < 0.3); + } + } + + // ==== NEURAL PATHWAY GENERATION ==== + float neuralStructure = 0.0; + float activationMap = 0.0; + float synapseMap = 0.0; + + for (int i = 0; i < NEURON_COUNT; i++) { + for (int j = 0; j < NEURON_COUNT; j++) { + if (connections[i][j]) { + // Create paths between connected neurons + vec2 startPos = neuronCenters[i]; + vec2 endPos = neuronCenters[j]; + vec2 pathDir = normalize(endPos - startPos); + + // Generate path with random variation + float pathLength = length(endPos - startPos); + float pathDist = 0.0; + + // Connection strength varies with distance + float connectionStrength = 1.0 - smoothstep(0.0, 0.7, pathLength); + + // Define path with random bezier curve + float t_path = clamp(dot(centered - startPos, pathDir) / pathLength, 0.0, 1.0); + + // Calculate bezier control point (randomly offset perpendicular to path) + float randOffset = sin(float(i) * 13.37 + float(j) * 42.42) * 0.15; + vec2 perp = vec2(-pathDir.y, pathDir.x); + vec2 controlPoint = mix(startPos, endPos, 0.5) + perp * randOffset; + + // Quadratic bezier formula + vec2 pathPos = mix( + mix(startPos, controlPoint, t_path), + mix(controlPoint, endPos, t_path), + t_path + ); + + // Add smaller random variations along path + float noiseScale = 10.0; + float noiseStrength = 0.01; + float pathNoise = sin(t_path * noiseScale + float(i+j)) * + cos(t_path * noiseScale * 1.5 + float(i-j)); + pathPos += perp * pathNoise * noiseStrength; + + // Calculate distance to path + pathDist = length(centered - pathPos); + + // Path thickness varies along length - thinner in middle + float baseThickness = 0.003 * connectionStrength; + float pathThickness = baseThickness * (1.0 + sin(t_path * 3.14) * 0.5); + + // Add some variation to thickness + pathThickness *= (0.8 + sin(t_path * 20.0 + float(i+j)) * 0.2); + + // Add neural structure to the map + float pathContribution = smoothstep(pathThickness, 0.0, pathDist); + neuralStructure = max(neuralStructure, pathContribution); + + // Define synapses near connection points + float synapseDist = length(centered - endPos); + float synapseSize = 0.01 + 0.005 * sin(float(j) * 7.77); + synapseMap = max(synapseMap, smoothstep(synapseSize, 0.0, synapseDist)); + + // ==== PULSE PROPAGATION ==== + float pulsePhase = neuronPhases[i]; + + // Pulses emit when source neuron fires (based on sin wave) + float firingThreshold = 0.7; + float neuronFiring = (sin(pulsePhase) * 0.5 + 0.5) > firingThreshold ? 1.0 : 0.0; + + if (neuronFiring > 0.0) { + // Create a pulse that travels from soma to terminal + float pulseSpeed = 1.0 + sin(float(i) * 0.7) * 0.2; // Slightly different speed per neuron + float pulseTiming = mod(t * pulseSpeed - t_path + 2.0, 1.0); + + // Only show pulse when it's on this segment + if (pulseTiming < 0.3) { + // Pulse shape (compact wave) + float pulseShape = smoothstep(0.0, 0.05, pulseTiming) * smoothstep(0.3, 0.1, pulseTiming); + + // Intensity varies with neuron strength and fades with distance + float pulseIntensity = pulseShape * neuronStrengths[i] * connectionStrength; + + // Only show pulse on the path + float activationContribution = pulseIntensity * smoothstep(pathThickness * 2.0, 0.0, pathDist); + activationMap = max(activationMap, activationContribution); + } + } + } } + } + + // ==== CELL BODIES (SOMAS) ==== + float somaBrightness = 0.0; + for (int i = 0; i < NEURON_COUNT; i++) { + float somaDist = length(centered - neuronCenters[i]); + + // Random variable cell body sizes + float somaSize = 0.01 + 0.008 * sin(float(i) * 9.23); + float somaShape = smoothstep(somaSize, 0.0, somaDist); + + // Firing effect - each neuron pulses with its own rhythm + float firingEffect = (sin(neuronPhases[i]) * 0.5 + 0.5) * neuronStrengths[i]; + somaBrightness = max(somaBrightness, somaShape * (0.4 + firingEffect)); + } + + // ==== ORGANIC BACKGROUND TEXTURE ==== + float bgNoise = 0.0; + for (int f = 1; f <= 4; f++) { + float scale = float(f) * 8.0; + // Use primes to get more chaotic patterns + bgNoise += (sin(centered.x * scale * 1.13 + t + sin(centered.y * scale * 0.97)) * + sin(centered.y * scale * 1.29 + t * 0.77 + sin(centered.x * scale * 1.37))) + * (0.4 / float(f)); + } + bgNoise = bgNoise * 0.5 + 0.5; // Normalize to 0-1 range + + // Mouse interaction - create a stimulation point + float mouseStimulation = 0.0; + if (mousex > 0 && mousey > 0) { + vec2 mousePos = vec2(float(mousex)/r.x, float(mousey)/r.y) - 0.5; + mousePos.x *= r.x/r.y; + float mouseDist = length(centered - mousePos); + + // Create spreading wave of activation + float waveSpeed = 0.5; + float waveRadius = mod(t * waveSpeed, 1.0) * 0.5; + float waveWidth = 0.02; + float activationRing = smoothstep(waveWidth, 0.0, abs(mouseDist - waveRadius)); + mouseStimulation = activationRing * exp(-waveRadius * 5.0); - uv += p/l * (sin(z + mouseInfluence) + 1.0) * abs(sin(l * 9.0 - z - z)); - c[i] = 0.01/length(mod(uv, 1.0) - 0.5); + // Excite nearby neurons + for (int i = 0; i < NEURON_COUNT; i++) { + float neuronDist = length(mousePos - neuronCenters[i]); + if (neuronDist < 0.2) { + float influence = (0.2 - neuronDist) * 5.0; + neuronPhases[i] += influence * 0.2; // Increase firing rate + neuronStrengths[i] = min(1.0, neuronStrengths[i] + influence * 0.1); // Increase strength + } + } } + // ==== VISUAL EFFECTS ==== + + // Base neural structure color with subtle variation + vec3 structureBase = vec3(0.02, 0.04, 0.12); + vec3 structureHighlight = vec3(0.1, 0.2, 0.4); + vec3 structureColor = mix( + structureBase, + structureHighlight, + neuralStructure + ); + + // Add subtle color variation based on position + structureColor += vec3(0.05, -0.02, 0.0) * sin(centered.x * 5.0 + t); + structureColor += vec3(-0.02, 0.0, 0.05) * sin(centered.y * 4.0 + t * 0.7); + + // Pulse color - electric blue/cyan + vec3 pulseBaseColor = vec3(0.0, 0.4, 0.8); + vec3 pulseBrightColor = vec3(0.2, 0.9, 1.0); + vec3 pulseColor = mix( + pulseBaseColor, + pulseBrightColor, + activationMap + ); + + // Soma color with random variations + vec3 somaBaseColor = vec3(0.3, 0.4, 0.6); + vec3 somaBrightColor = vec3(0.7, 0.8, 1.0); + vec3 somaColor = mix( + somaBaseColor, + somaBrightColor, + somaBrightness + ); + + // Synapse flashing + vec3 synapseColor = vec3(0.2, 0.6, 1.0); + + // Combine all elements + vec3 finalColor = vec3(0.0); + + // Add subtle background neural texture + finalColor += vec3(0.01, 0.02, 0.04) * bgNoise; + + // Add base neural structure + finalColor += structureColor * (neuralStructure * 0.6 + 0.3); + + // Add pulse effect with bright glow + finalColor += pulseColor * pow(activationMap * 1.5, 2.0) * 2.0; + + // Add soma glow + finalColor += somaColor * somaBrightness * 1.5; + + // Add synapse flash + finalColor += synapseColor * synapseMap * (sin(t * 3.0) * 0.5 + 0.7); + + // Add mouse stimulation with electric blue color + finalColor += vec3(0.0, 0.6, 1.0) * mouseStimulation * 2.0; + + // Overall glow effect + finalColor += structureColor * 0.1 * (sin(t * 0.5) * 0.3 + 0.7); + + // Enhance contrast and brightness + finalColor = pow(finalColor, vec3(0.85)); + // Convert to RGBA color format for data_0 - int red = int(min(c.r * 255.0, 255.0)); - int green = int(min(c.g * 255.0, 255.0)); - int blue = int(min(c.b * 255.0, 255.0)); + int red = int(min(finalColor.r * 255.0, 255.0)); + int green = int(min(finalColor.g * 255.0, 255.0)); + int blue = int(min(finalColor.b * 255.0, 255.0)); data_0[p] = int(0xFF000000 | (red << 16) | (green << 8) | blue); } \ No newline at end of file diff --git a/examples/neural pulse/neural_pulse.tscn b/examples/neural pulse/neural_pulse.tscn index 697ae6e..dbcdfa0 100644 --- a/examples/neural pulse/neural_pulse.tscn +++ b/examples/neural pulse/neural_pulse.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://dnva7w0gtcb6x"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_osmo3"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_osmo3"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_ec1t8"] [node name="NeuralPulse" type="Node2D"] diff --git a/examples/simple_circle/simple_circle.tscn b/examples/simple_circle/simple_circle.tscn index fc318d0..37db9b6 100644 --- a/examples/simple_circle/simple_circle.tscn +++ b/examples/simple_circle/simple_circle.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://c63rtjh0eurgm"] -[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_rlapi"] +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_rlapi"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_y7slp"] [node name="SimpleCircle" type="Node2D"] diff --git a/project.godot b/project.godot index 725be9c..1617345 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="compute_shader_studio" run/main_scene="res://examples/example_1.tscn" -config/features=PackedStringArray("4.3", "Forward Plus") +config/features=PackedStringArray("4.4", "Forward Plus") config/icon="res://addons/compute_shader_studio/icon.png" [editor_plugins] From 4ecf90e59b3c3ff009c3f83ed869e0bac6362501 Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Mon, 17 Mar 2025 21:23:36 +0100 Subject: [PATCH 03/10] fixed layout --- examples/circles/circles.tscn | 4 +- examples/neural pulse/neural_pulse.cpp | 318 +++++++----------------- examples/neural pulse/neural_pulse.tscn | 11 +- 3 files changed, 96 insertions(+), 237 deletions(-) diff --git a/examples/circles/circles.tscn b/examples/circles/circles.tscn index c66e724..6eac0e5 100644 --- a/examples/circles/circles.tscn +++ b/examples/circles/circles.tscn @@ -27,6 +27,6 @@ horizontal_alignment = 1 vertical_alignment = 1 [node name="Icon" type="Sprite2D" parent="."] -position = Vector2(605.5, 411) -scale = Vector2(5.63281, 3.17969) +position = Vector2(576, 323.5) +scale = Vector2(8.96875, 5.07031) texture = ExtResource("2_ntl1q") diff --git a/examples/neural pulse/neural_pulse.cpp b/examples/neural pulse/neural_pulse.cpp index 90a8307..7a3f696 100644 --- a/examples/neural pulse/neural_pulse.cpp +++ b/examples/neural pulse/neural_pulse.cpp @@ -13,242 +13,98 @@ void main() { // Time control float t = float(step) * 0.03; - // Generate random neuron centers - #define NEURON_COUNT 12 - vec2 neuronCenters[NEURON_COUNT]; - float neuronPhases[NEURON_COUNT]; - float neuronStrengths[NEURON_COUNT]; - - // Initialize with pseudorandom positions using trig functions with different seeds - for (int i = 0; i < NEURON_COUNT; i++) { - // Use prime numbers and different bases to create "random" distribution - float randX = sin(float(i) * 12.9898 + t * 0.05) * 0.5; - float randY = cos(float(i) * 78.233 + t * 0.04) * 0.5; - - // Add some slow movement to neurons - randX += sin(t * 0.07 + float(i) * 0.5) * 0.1; - randY += cos(t * 0.05 + float(i) * 0.7) * 0.1; + // Simple black background + vec3 finalColor = vec3(0.0, 0.0, 0.0); + + // Random lightning flashes with movement + for (int i = 0; i < 3; i++) { + // Basic flickering effect + float seed = float(i) * 3.14; + float flickerSpeed = 0.5 + float(i) * 0.1; - neuronCenters[i] = vec2(randX, randY); + // Multi-frequency flickering + float f1 = sin(t * flickerSpeed + seed * 13.37) * 0.5 + 0.5; + float f2 = sin(t * flickerSpeed * 2.7 + seed * 4.53) * 0.5 + 0.5; + float f3 = sin(t * flickerSpeed * 7.3 + seed * 27.71) * 0.5 + 0.5; + float flashTiming = f1 * 0.6 + f2 * 0.3 + f3 * 0.1; - // Random phase and firing strength for each neuron - neuronPhases[i] = t * (0.8 + sin(float(i) * 3.14) * 0.3) + float(i); - neuronStrengths[i] = 0.5 + sin(float(i) * 1.618 + t * 0.2) * 0.5; - } - - // ==== RANDOM CONNECTION DETERMINATION ==== - bool connections[NEURON_COUNT][NEURON_COUNT]; - for (int i = 0; i < NEURON_COUNT; i++) { - for (int j = 0; j < NEURON_COUNT; j++) { - // Use a deterministic but "random-looking" pattern for connections - // About 30% of possible connections will be active - float connectionSeed = sin(float(i) * 43.21 + float(j) * 12.345) * 0.5 + 0.5; - connections[i][j] = (i != j) && (connectionSeed < 0.3); + // Only show lightning when above threshold + float threshold = 0.7 + sin(t * 0.1 + seed) * 0.05; + if (flashTiming > threshold) { + // Calculate intensity + float progress = (flashTiming - threshold) / (1.0 - threshold); + float flashIntensity = pow(progress, 0.7) * 3.0; + + // Add micro-flickers + float microFlicker = sin(t * 30.0 + seed * 5.0) * 0.5 + 0.5; + flashIntensity = flashIntensity * (0.7 + 0.3 * microFlicker); + + // Movement paths for the lightning balls + // Starting point A + float startX = sin(seed * 12.34) * 0.8; + float startY = cos(seed * 43.21) * 0.5; + + // Ending point B + float endX = sin(seed * 12.34 + 3.14) * 0.8; + float endY = cos(seed * 43.21 + 3.14) * 0.5; + + // Speed factor (unique for each lightning ball) + // Range from fast to very fast + float speedFactor = 1.0 + sin(seed * 7.89) * 0.5 + 0.5; // Will range from 1.0 to 2.0 + + // Calculate position along path + float movementProgress = fract(t * speedFactor + seed); // Cycles from 0 to 1 + + // Apply easing for more natural movement + movementProgress = smoothstep(0.0, 1.0, movementProgress); + + // Current position + float posX = mix(startX, endX, movementProgress); + float posY = mix(startY, endY, movementProgress); + + // Add some orbit/wobble to the movement + posX += sin(t * 2.0 * speedFactor + seed * 9.87) * 0.1; + posY += cos(t * 1.7 * speedFactor + seed * 6.54) * 0.08; + + vec2 flashPos = vec2(posX, posY); + + // Distance to lightning center + float dist = length(centered - flashPos); + + // Core and outer glow - smaller size + float baseRadius = 0.08 + sin(t * 4.0 + seed) * 0.01; // Reduced from 0.15 + float glowRadius = baseRadius * (1.0 + flashIntensity * 0.3); + float coreSize = glowRadius * 0.3; + + float coreGlow = smoothstep(coreSize, 0.0, dist) * flashIntensity * 3.0; + float outerGlow = smoothstep(glowRadius, coreSize, dist) * flashIntensity * 0.7; + float glow = coreGlow + outerGlow; + + // Detail variation + float detail = sin(dist * 20.0 + t * 5.0) * 0.5 + 0.5; + glow = glow * (0.9 + detail * 0.1); + + // Speed-based color variation + vec3 outerColor = vec3(0.85, 0.9, 1.0); + vec3 coreColor = vec3(1.0, 1.0, 1.0); + + // Add speed trail effect + float trail = smoothstep(0.0, 0.3, movementProgress) * (1.0 - smoothstep(0.7, 1.0, movementProgress)); + float trailIntensity = trail * speedFactor * 0.5; + + // Add slight color variation based on speed + coreColor = mix(coreColor, vec3(1.0, 0.9, 0.8), (speedFactor - 1.0) * 0.5); + + vec3 lightningColor = mix(outerColor, coreColor, min(1.0, coreGlow * 0.5)); + + finalColor += lightningColor * glow * (1.0 + trailIntensity); } } - // ==== NEURAL PATHWAY GENERATION ==== - float neuralStructure = 0.0; - float activationMap = 0.0; - float synapseMap = 0.0; - - for (int i = 0; i < NEURON_COUNT; i++) { - for (int j = 0; j < NEURON_COUNT; j++) { - if (connections[i][j]) { - // Create paths between connected neurons - vec2 startPos = neuronCenters[i]; - vec2 endPos = neuronCenters[j]; - vec2 pathDir = normalize(endPos - startPos); - - // Generate path with random variation - float pathLength = length(endPos - startPos); - float pathDist = 0.0; - - // Connection strength varies with distance - float connectionStrength = 1.0 - smoothstep(0.0, 0.7, pathLength); - - // Define path with random bezier curve - float t_path = clamp(dot(centered - startPos, pathDir) / pathLength, 0.0, 1.0); - - // Calculate bezier control point (randomly offset perpendicular to path) - float randOffset = sin(float(i) * 13.37 + float(j) * 42.42) * 0.15; - vec2 perp = vec2(-pathDir.y, pathDir.x); - vec2 controlPoint = mix(startPos, endPos, 0.5) + perp * randOffset; - - // Quadratic bezier formula - vec2 pathPos = mix( - mix(startPos, controlPoint, t_path), - mix(controlPoint, endPos, t_path), - t_path - ); - - // Add smaller random variations along path - float noiseScale = 10.0; - float noiseStrength = 0.01; - float pathNoise = sin(t_path * noiseScale + float(i+j)) * - cos(t_path * noiseScale * 1.5 + float(i-j)); - pathPos += perp * pathNoise * noiseStrength; - - // Calculate distance to path - pathDist = length(centered - pathPos); - - // Path thickness varies along length - thinner in middle - float baseThickness = 0.003 * connectionStrength; - float pathThickness = baseThickness * (1.0 + sin(t_path * 3.14) * 0.5); - - // Add some variation to thickness - pathThickness *= (0.8 + sin(t_path * 20.0 + float(i+j)) * 0.2); - - // Add neural structure to the map - float pathContribution = smoothstep(pathThickness, 0.0, pathDist); - neuralStructure = max(neuralStructure, pathContribution); - - // Define synapses near connection points - float synapseDist = length(centered - endPos); - float synapseSize = 0.01 + 0.005 * sin(float(j) * 7.77); - synapseMap = max(synapseMap, smoothstep(synapseSize, 0.0, synapseDist)); - - // ==== PULSE PROPAGATION ==== - float pulsePhase = neuronPhases[i]; - - // Pulses emit when source neuron fires (based on sin wave) - float firingThreshold = 0.7; - float neuronFiring = (sin(pulsePhase) * 0.5 + 0.5) > firingThreshold ? 1.0 : 0.0; - - if (neuronFiring > 0.0) { - // Create a pulse that travels from soma to terminal - float pulseSpeed = 1.0 + sin(float(i) * 0.7) * 0.2; // Slightly different speed per neuron - float pulseTiming = mod(t * pulseSpeed - t_path + 2.0, 1.0); - - // Only show pulse when it's on this segment - if (pulseTiming < 0.3) { - // Pulse shape (compact wave) - float pulseShape = smoothstep(0.0, 0.05, pulseTiming) * smoothstep(0.3, 0.1, pulseTiming); - - // Intensity varies with neuron strength and fades with distance - float pulseIntensity = pulseShape * neuronStrengths[i] * connectionStrength; - - // Only show pulse on the path - float activationContribution = pulseIntensity * smoothstep(pathThickness * 2.0, 0.0, pathDist); - activationMap = max(activationMap, activationContribution); - } - } - } - } - } - - // ==== CELL BODIES (SOMAS) ==== - float somaBrightness = 0.0; - for (int i = 0; i < NEURON_COUNT; i++) { - float somaDist = length(centered - neuronCenters[i]); - - // Random variable cell body sizes - float somaSize = 0.01 + 0.008 * sin(float(i) * 9.23); - float somaShape = smoothstep(somaSize, 0.0, somaDist); - - // Firing effect - each neuron pulses with its own rhythm - float firingEffect = (sin(neuronPhases[i]) * 0.5 + 0.5) * neuronStrengths[i]; - somaBrightness = max(somaBrightness, somaShape * (0.4 + firingEffect)); - } - - // ==== ORGANIC BACKGROUND TEXTURE ==== - float bgNoise = 0.0; - for (int f = 1; f <= 4; f++) { - float scale = float(f) * 8.0; - // Use primes to get more chaotic patterns - bgNoise += (sin(centered.x * scale * 1.13 + t + sin(centered.y * scale * 0.97)) * - sin(centered.y * scale * 1.29 + t * 0.77 + sin(centered.x * scale * 1.37))) - * (0.4 / float(f)); - } - bgNoise = bgNoise * 0.5 + 0.5; // Normalize to 0-1 range - - // Mouse interaction - create a stimulation point - float mouseStimulation = 0.0; - if (mousex > 0 && mousey > 0) { - vec2 mousePos = vec2(float(mousex)/r.x, float(mousey)/r.y) - 0.5; - mousePos.x *= r.x/r.y; - float mouseDist = length(centered - mousePos); - - // Create spreading wave of activation - float waveSpeed = 0.5; - float waveRadius = mod(t * waveSpeed, 1.0) * 0.5; - float waveWidth = 0.02; - float activationRing = smoothstep(waveWidth, 0.0, abs(mouseDist - waveRadius)); - mouseStimulation = activationRing * exp(-waveRadius * 5.0); - - // Excite nearby neurons - for (int i = 0; i < NEURON_COUNT; i++) { - float neuronDist = length(mousePos - neuronCenters[i]); - if (neuronDist < 0.2) { - float influence = (0.2 - neuronDist) * 5.0; - neuronPhases[i] += influence * 0.2; // Increase firing rate - neuronStrengths[i] = min(1.0, neuronStrengths[i] + influence * 0.1); // Increase strength - } - } - } - - // ==== VISUAL EFFECTS ==== - - // Base neural structure color with subtle variation - vec3 structureBase = vec3(0.02, 0.04, 0.12); - vec3 structureHighlight = vec3(0.1, 0.2, 0.4); - vec3 structureColor = mix( - structureBase, - structureHighlight, - neuralStructure - ); - - // Add subtle color variation based on position - structureColor += vec3(0.05, -0.02, 0.0) * sin(centered.x * 5.0 + t); - structureColor += vec3(-0.02, 0.0, 0.05) * sin(centered.y * 4.0 + t * 0.7); - - // Pulse color - electric blue/cyan - vec3 pulseBaseColor = vec3(0.0, 0.4, 0.8); - vec3 pulseBrightColor = vec3(0.2, 0.9, 1.0); - vec3 pulseColor = mix( - pulseBaseColor, - pulseBrightColor, - activationMap - ); - - // Soma color with random variations - vec3 somaBaseColor = vec3(0.3, 0.4, 0.6); - vec3 somaBrightColor = vec3(0.7, 0.8, 1.0); - vec3 somaColor = mix( - somaBaseColor, - somaBrightColor, - somaBrightness - ); - - // Synapse flashing - vec3 synapseColor = vec3(0.2, 0.6, 1.0); - - // Combine all elements - vec3 finalColor = vec3(0.0); - - // Add subtle background neural texture - finalColor += vec3(0.01, 0.02, 0.04) * bgNoise; - - // Add base neural structure - finalColor += structureColor * (neuralStructure * 0.6 + 0.3); - - // Add pulse effect with bright glow - finalColor += pulseColor * pow(activationMap * 1.5, 2.0) * 2.0; - - // Add soma glow - finalColor += somaColor * somaBrightness * 1.5; - - // Add synapse flash - finalColor += synapseColor * synapseMap * (sin(t * 3.0) * 0.5 + 0.7); - - // Add mouse stimulation with electric blue color - finalColor += vec3(0.0, 0.6, 1.0) * mouseStimulation * 2.0; - - // Overall glow effect - finalColor += structureColor * 0.1 * (sin(t * 0.5) * 0.3 + 0.7); - - // Enhance contrast and brightness - finalColor = pow(finalColor, vec3(0.85)); + // Background ambient + float bgGlow = sin(t * 0.2) * 0.5 + 0.5; + bgGlow = pow(bgGlow, 5.0) * 0.05; + finalColor += vec3(0.7, 0.8, 1.0) * bgGlow; // Convert to RGBA color format for data_0 int red = int(min(finalColor.r * 255.0, 255.0)); diff --git a/examples/neural pulse/neural_pulse.tscn b/examples/neural pulse/neural_pulse.tscn index dbcdfa0..9eb4fc8 100644 --- a/examples/neural pulse/neural_pulse.tscn +++ b/examples/neural pulse/neural_pulse.tscn @@ -7,10 +7,13 @@ [node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] script = ExtResource("1_osmo3") +WSX = 1920 +WSY = 1080 glsl_file = "res://examples/neural pulse/neural_pulse.cpp" -data = [NodePath("../Icon")] +data = [NodePath("Icon")] +metadata/_custom_type_script = "uid://c8esqdv0y26yp" -[node name="Icon" type="Sprite2D" parent="."] -position = Vector2(579, 326) -scale = Vector2(8.75, 4.79688) +[node name="Icon" type="Sprite2D" parent="ComputeShaderStudio2D"] +position = Vector2(576, 324.5) +scale = Vector2(9, 5.05469) texture = ExtResource("2_ec1t8") From cf3af198c4a828885f0f30a4138f6701183e0960 Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Mon, 17 Mar 2025 21:59:54 +0100 Subject: [PATCH 04/10] car_in_the_nightcexample --- .../car_in_the_night/car_in_the_night.cpp | 186 ++++++++++++++++++ .../car_in_the_night.tscn} | 4 +- examples/circles/circles.cpp | 108 +++++++--- examples/example_psycho_seizure.tscn | 80 ++++++++ examples/neural pulse/neural_pulse.cpp | 115 ----------- 5 files changed, 349 insertions(+), 144 deletions(-) create mode 100644 examples/car_in_the_night/car_in_the_night.cpp rename examples/{neural pulse/neural_pulse.tscn => car_in_the_night/car_in_the_night.tscn} (86%) create mode 100644 examples/example_psycho_seizure.tscn delete mode 100644 examples/neural pulse/neural_pulse.cpp diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp new file mode 100644 index 0000000..daf25a8 --- /dev/null +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -0,0 +1,186 @@ +#define CAR_WIDTH 60.0 +#define CAR_HEIGHT 30.0 +#define WHEEL_RADIUS 8.0 +#define SPEED 2.0 +#define RAIN_DROPS 500 +#define SPLASH_PARTICLES 20 + +float hash(float n) { return fract(sin(n) * 43758.5453123); } + +void main() { + int x = int(gl_GlobalInvocationID.x); + int y = int(gl_GlobalInvocationID.y); + int p = x + y * int(WSX); + + // Position de la voiture basee sur le temps + float carPosX = mod(float(step) * SPEED, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + float carPosY = float(WSX) / 3.0; + + // Nuit - fond noir avec leger bleu + vec3 nightColor = vec3(0.02, 0.03, 0.08); + + // Route mouillée - gris fonce avec reflets + vec3 roadColor = vec3(0.05, 0.05, 0.07); + + // Couleur de base - nuit + data_0[p] = 0xFF000000 | (int(nightColor.r * 255.0) << 16) | (int(nightColor.g * 255.0) << 8) | int(nightColor.b * 255.0); + + // Route mouillée + if (y > int(carPosY) + 30) { + // Effet de route mouillée avec reflets + float reflectionFactor = 0.0; + + // Reflets de la lumière des phares sur la route + float distToFrontLight = length(vec2(float(x) - (carPosX + CAR_WIDTH * 0.9), float(y) - (carPosY + CAR_HEIGHT * 0.7))); + float frontLightFalloff = 1.0 / (1.0 + distToFrontLight * 0.015); + + // Intensité des reflets uniquement devant la voiture + if (float(x) > carPosX + CAR_WIDTH * 0.9) { + reflectionFactor = max(0.0, frontLightFalloff * 0.5 - 0.02); + } + + // Couleur de la route avec reflets + vec3 finalRoadColor = roadColor + vec3(1.0, 0.8, 0.5) * reflectionFactor; + + data_0[p] = 0xFF000000 | (int(finalRoadColor.r * 255.0) << 16) | (int(finalRoadColor.g * 255.0) << 8) | int(finalRoadColor.b * 255.0); + } + + // Faisceau des phares + float headlightX = carPosX + CAR_WIDTH * 0.9; + float headlightY = carPosY + CAR_HEIGHT * 0.7; + + // Forme conique du faisceau + if (float(x) > headlightX && float(y) > int(carPosY) + 30) { + float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); + float maxAngle = 0.3; + float minAngle = -0.3; + + if (angle >= minAngle && angle <= maxAngle) { + float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); + float maxDist = 250.0; + + if (dist < maxDist) { + float intensity = 1.0 - (dist / maxDist); + intensity = intensity * intensity * 0.6; // Atténuation quadratique + + vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; + + // Combiner la lumière avec la couleur existante + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = existingColor + lightColor; + finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + } + } + } + + // Dessiner la voiture + if (float(x) >= carPosX && float(x) < carPosX + CAR_WIDTH && + float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT) { + + // Couleur de la voiture - bleu foncé + vec3 carColor = vec3(0.1, 0.1, 0.3); + + // Vitres + if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && + float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT * 0.5) { + carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées + } + + data_0[p] = 0xFF000000 | (int(carColor.r * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.b * 255.0); + } + + // Phares avant + float frontLightX = carPosX + CAR_WIDTH * 0.9; + float frontLightY = carPosY + CAR_HEIGHT * 0.7; + float frontLightRadius = 4.0; + + if (length(vec2(float(x) - frontLightX, float(y) - frontLightY)) < frontLightRadius) { + vec3 lightColor = vec3(1.0, 0.9, 0.7); // Jaune chaud + data_0[p] = 0xFF000000 | (int(lightColor.r * 255.0) << 16) | (int(lightColor.g * 255.0) << 8) | int(lightColor.b * 255.0); + } + + // Feu arrière + float rearLightX = carPosX + CAR_WIDTH * 0.1; + float rearLightY = carPosY + CAR_HEIGHT * 0.7; + float rearLightRadius = 3.0; + + if (length(vec2(float(x) - rearLightX, float(y) - rearLightY)) < rearLightRadius) { + vec3 redLight = vec3(1.0, 0.1, 0.1); // Rouge + data_0[p] = 0xFF000000 | (int(redLight.r * 255.0) << 16) | (int(redLight.g * 255.0) << 8) | int(redLight.b * 255.0); + } + + // Roues + float frontWheelX = carPosX + CAR_WIDTH * 0.75; + float rearWheelX = carPosX + CAR_WIDTH * 0.25; + float wheelY = carPosY + CAR_HEIGHT; + + float distFrontWheel = length(vec2(float(x) - frontWheelX, float(y) - wheelY)); + float distRearWheel = length(vec2(float(x) - rearWheelX, float(y) - wheelY)); + + if (distFrontWheel <= WHEEL_RADIUS || distRearWheel <= WHEEL_RADIUS) { + vec3 wheelColor = vec3(0.1, 0.1, 0.1); // Noir + data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); + } + + // Ligne médiane de la route - moins visible dans la nuit sauf sous les phares + if (y > int(carPosY) + 40 && y < int(carPosY) + 43 && int(float(x) + float(step) * SPEED) % 70 < 40) { + float distToLight = length(vec2(float(x) - headlightX, float(y) - headlightY)); + float visibility = 0.2; + + if (float(x) > headlightX) { + visibility += 1.0 / (1.0 + distToLight * 0.03); + } + + vec3 lineColor = vec3(0.8, 0.8, 0.5) * min(visibility, 1.0); + data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); + } + + // Gouttes de pluie + for (int i = 0; i < 10; i++) { + float seed = hash(float(i) + float(x) * 0.01 + float(y) * 0.01); + float rainX = mod(float(x) + seed * 1000.0 + float(step) * (5.0 + seed * 10.0), float(WSX)); + float rainY = mod(float(y) + seed * 1000.0 + float(step) * (15.0 + seed * 10.0), float(int(WSX) * 3 / 4)); + + if (abs(float(x) - rainX) < 1.0 && abs(float(y) - rainY) < 3.0) { + float distToLight = length(vec2(rainX - headlightX, rainY - headlightY)); + float visibility = 0.2; + + if (rainX > headlightX) { + visibility += 1.0 / (1.0 + distToLight * 0.03); + } + + vec3 rainColor = vec3(0.7, 0.7, 0.9) * min(visibility, 1.0); + data_0[p] = 0xFF000000 | (int(rainColor.r * 255.0) << 16) | (int(rainColor.g * 255.0) << 8) | int(rainColor.b * 255.0); + } + } + + // Éclaboussures près des roues + if (y > int(wheelY) && y < int(wheelY) + 15) { + // Près de la roue avant + if (abs(float(x) - frontWheelX) < WHEEL_RADIUS * 1.5) { + float splashSeed = hash(float(x) + float(y) + float(step)); + if (splashSeed > 0.95) { + float splashIntensity = 0.5 + splashSeed * 0.5; + vec3 splashColor = vec3(0.8, 0.8, 0.9) * splashIntensity; + data_0[p] = 0xFF000000 | (int(splashColor.r * 255.0) << 16) | (int(splashColor.g * 255.0) << 8) | int(splashColor.b * 255.0); + } + } + + // Près de la roue arrière + if (abs(float(x) - rearWheelX) < WHEEL_RADIUS * 1.5) { + float splashSeed = hash(float(x) + float(y) + float(step) + 100.0); + if (splashSeed > 0.95) { + float splashIntensity = 0.5 + splashSeed * 0.5; + vec3 splashColor = vec3(0.8, 0.8, 0.9) * splashIntensity; + data_0[p] = 0xFF000000 | (int(splashColor.r * 255.0) << 16) | (int(splashColor.g * 255.0) << 8) | int(splashColor.b * 255.0); + } + } + } +} \ No newline at end of file diff --git a/examples/neural pulse/neural_pulse.tscn b/examples/car_in_the_night/car_in_the_night.tscn similarity index 86% rename from examples/neural pulse/neural_pulse.tscn rename to examples/car_in_the_night/car_in_the_night.tscn index 9eb4fc8..133f9ed 100644 --- a/examples/neural pulse/neural_pulse.tscn +++ b/examples/car_in_the_night/car_in_the_night.tscn @@ -3,13 +3,13 @@ [ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_osmo3"] [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_ec1t8"] -[node name="NeuralPulse" type="Node2D"] +[node name="car_in_the_night" type="Node2D"] [node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] script = ExtResource("1_osmo3") WSX = 1920 WSY = 1080 -glsl_file = "res://examples/neural pulse/neural_pulse.cpp" +glsl_file = "res://examples/car_in_the_night/car_in_the_night.cpp" data = [NodePath("Icon")] metadata/_custom_type_script = "uid://c8esqdv0y26yp" diff --git a/examples/circles/circles.cpp b/examples/circles/circles.cpp index 3dcaa32..3ae1d20 100644 --- a/examples/circles/circles.cpp +++ b/examples/circles/circles.cpp @@ -1,31 +1,85 @@ -#define RADIUS 40 +shader_type canvas_item; -void main() -{ - int x = int(gl_GlobalInvocationID.x); - int y = int(gl_GlobalInvocationID.y); - int p = x + y * int(WSX); +// Godot uniform variables +uniform vec2 resolution = vec2(1280.0, 720.0); +uniform float time_scale = 1.0; - // initial background is black & opac - if (step == 0) { - data_0[p] = 0xFF000000 + y; - } else { // draw a fading red circle - float dx = float(mousex - x); - float dy = float(mousey - y); - float dist = sqrt(dx*dx+dy*dy); - int pix = data_0[p]; - int col = pix & 0x00FFFFFF ; - float r = RADIUS + 10*sin(step/10.0f); - if( dist < r-1 ) { // interior - col = col + 0x04 ; - data_0[p] = 0xFF000000 + col ; - } - if( dist >= r-1 && dist <= r+1 ) { // perimeter - data_0[p] = 0xFF0000FF ; - } - if( dist > r + 1) { // ouside - if (col > 0) - data_0[p] = pix - 1; +// Helper function: Distance to a line segment +float lineSegmentDistance(vec2 p, vec2 a, vec2 b) { + vec2 ap = p - a; + vec2 ab = b - a; + float t = clamp(dot(ap, ab) / dot(ab, ab), 0.0, 1.0); + return length(ap - ab * t); +} + +void fragment() { + // Normalize screen coordinates + vec2 uv = FRAGCOORD.xy / resolution.xy; + uv -= 0.5; + uv.x *= resolution.x / resolution.y; // Fix aspect ratio + + // Time control + float t = TIME * time_scale; + + // Background color - adding a subtle gradient + vec3 finalColor = vec3(0.03, 0.03, 0.05) + 0.02 * vec3(1.0-length(uv)); + + // Define neuron positions (6 neurons in a hexagon pattern) + vec2 neurons[6]; + neurons[0] = vec2(-0.4, -0.3); + neurons[1] = vec2(0.0, -0.5); + neurons[2] = vec2(0.4, -0.3); + neurons[3] = vec2(-0.4, 0.3); + neurons[4] = vec2(0.0, 0.5); + neurons[5] = vec2(0.4, 0.3); + + // Draw neurons and connections + for (int i = 0; i < 6; i++) { + // Add some subtle movement to neurons + vec2 neuronPos = neurons[i] + vec2( + sin(t * 0.5 + float(i) * 0.5) * 0.02, + cos(t * 0.4 + float(i) * 0.7) * 0.02 + ); + + // Draw neurons (glowing red dots) + float distToNeuron = length(uv - neuronPos); + float neuronGlow = 0.03 / (distToNeuron + 0.01); + float neuronPulse = 0.5 + 0.5 * sin(t * 0.7 + float(i) * 1.1); + finalColor += vec3(1.0, 0.2, 0.2) * neuronGlow * neuronPulse; + + // Draw connections between neurons + for (int j = i + 1; j < 6; j++) { + vec2 neuronA = neuronPos; + vec2 neuronB = neurons[j] + vec2( + sin(t * 0.5 + float(j) * 0.5) * 0.02, + cos(t * 0.4 + float(j) * 0.7) * 0.02 + ); + + // Draw nerve fibers (blue lines) + float distToFiber = lineSegmentDistance(uv, neuronA, neuronB); + float fiberGlow = 0.002 / (distToFiber + 0.001); + finalColor += vec3(0.2, 0.2, 0.8) * fiberGlow * 0.3; + + // Animate impulses (yellow dots) along the fibers + float impulseSpeed = 0.8; + float impulseTime = fract(t * impulseSpeed + float(i * 3 + j) * 0.1); + vec2 impulsePos = mix(neuronA, neuronB, impulseTime); + float distToImpulse = length(uv - impulsePos); + float impulseGlow = 0.008 / (distToImpulse + 0.003); + finalColor += vec3(1.0, 1.0, 0.0) * impulseGlow * 2.0; + + // Add a secondary impulse going the other way + float impulseTime2 = fract(t * impulseSpeed * 0.7 + float(i * 5 + j * 2) * 0.15); + vec2 impulsePos2 = mix(neuronB, neuronA, impulseTime2); + float distToImpulse2 = length(uv - impulsePos2); + float impulseGlow2 = 0.008 / (distToImpulse2 + 0.003); + finalColor += vec3(0.0, 1.0, 0.8) * impulseGlow2 * 2.0; } } -} + + // Add some bloom effect + finalColor = pow(finalColor, vec3(0.7)); + + // Output to screen + COLOR = vec4(finalColor, 1.0); +} \ No newline at end of file diff --git a/examples/example_psycho_seizure.tscn b/examples/example_psycho_seizure.tscn new file mode 100644 index 0000000..d1fec1e --- /dev/null +++ b/examples/example_psycho_seizure.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=3 format=3 uid="uid://l25d0xyxbx72"] + +[ext_resource type="Script" uid="uid://c8esqdv0y26yp" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_26wk6"] +[ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_urrfs"] + +[node name="exeample_psycho_seizure" type="Node2D"] + +[node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] +script = ExtResource("1_26wk6") +WSX = 2000 +WSY = 2000 +GLSL_code = "#define red 0xFF0000FF +#define blue 0x000088FF +#define purple 0x880088FF +#define black 0xFF000000 + + + +float perlinNoise(vec2 p) { + return sin(p.x * 10.0) * sin(p.y * 10.0); +} + +/** + * Calculates the variation in shape based on the given angle, radius, and time. + * Uses Perlin noise to generate random values. + * + * @param angle The angle in radians. + * @param radius The radius of the shape. + * @param time The current time. + * @return The variation in shape. + */ +float shapeVariation(float angle, float radius, float time) { + float n = perlinNoise(vec2(cos(angle), sin(angle)) * time * 0.2); + float n2 = perlinNoise(vec2(sin(angle * 2.0), cos(angle * 2.0)) * time * 0.1); + return radius * (1.0 + 0.3 * n + 0.1 * n2); +} + + +/* Note that if you play with different WSX and WSY you might have nice results. + as a general rule try to play with every parameter to see the effect, it's quite fun! +*/ +void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + float time = float(step); + float angle, radius; + + // Center of the matrix + float centerX = float(WSX) / 2.0; + float centerY = float(WSY) / 2.0; + + //Converts the coordinates to polar coordinates. + float dx = float(x) - centerX; + float dy = float(y) - centerY; + angle = atan(dy, dx); + radius = sqrt(dx * dx + dy * dy); + + //create a dynamic shape + float variableRadius = shapeVariation(angle, radius, time); + + + if (radius <= variableRadius) { + data_0[p] = red; + /* if you want to blend colors use uncomment + float blend = (sin(time) + 1.0) / 2.0; + int(mix(float(blue), float(purple), blend)) + */ + } else { + //if you want to update the background color (here it's black) + data_0[p] = black;; + } +}" +data = [NodePath("../Icon")] + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(580, 333) +scale = Vector2(4.5625, 3.83594) +texture = ExtResource("2_urrfs") diff --git a/examples/neural pulse/neural_pulse.cpp b/examples/neural pulse/neural_pulse.cpp deleted file mode 100644 index 7a3f696..0000000 --- a/examples/neural pulse/neural_pulse.cpp +++ /dev/null @@ -1,115 +0,0 @@ -void main() { - uint x = gl_GlobalInvocationID.x; - uint y = gl_GlobalInvocationID.y; - uint p = x + y*WSX; - - // Normalize coordinates - vec2 fragCoord = vec2(float(x), float(y)); - vec2 r = vec2(float(WSX), float(WSY)); - vec2 uv = fragCoord/r; - vec2 centered = uv - 0.5; - centered.x *= r.x/r.y; - - // Time control - float t = float(step) * 0.03; - - // Simple black background - vec3 finalColor = vec3(0.0, 0.0, 0.0); - - // Random lightning flashes with movement - for (int i = 0; i < 3; i++) { - // Basic flickering effect - float seed = float(i) * 3.14; - float flickerSpeed = 0.5 + float(i) * 0.1; - - // Multi-frequency flickering - float f1 = sin(t * flickerSpeed + seed * 13.37) * 0.5 + 0.5; - float f2 = sin(t * flickerSpeed * 2.7 + seed * 4.53) * 0.5 + 0.5; - float f3 = sin(t * flickerSpeed * 7.3 + seed * 27.71) * 0.5 + 0.5; - float flashTiming = f1 * 0.6 + f2 * 0.3 + f3 * 0.1; - - // Only show lightning when above threshold - float threshold = 0.7 + sin(t * 0.1 + seed) * 0.05; - if (flashTiming > threshold) { - // Calculate intensity - float progress = (flashTiming - threshold) / (1.0 - threshold); - float flashIntensity = pow(progress, 0.7) * 3.0; - - // Add micro-flickers - float microFlicker = sin(t * 30.0 + seed * 5.0) * 0.5 + 0.5; - flashIntensity = flashIntensity * (0.7 + 0.3 * microFlicker); - - // Movement paths for the lightning balls - // Starting point A - float startX = sin(seed * 12.34) * 0.8; - float startY = cos(seed * 43.21) * 0.5; - - // Ending point B - float endX = sin(seed * 12.34 + 3.14) * 0.8; - float endY = cos(seed * 43.21 + 3.14) * 0.5; - - // Speed factor (unique for each lightning ball) - // Range from fast to very fast - float speedFactor = 1.0 + sin(seed * 7.89) * 0.5 + 0.5; // Will range from 1.0 to 2.0 - - // Calculate position along path - float movementProgress = fract(t * speedFactor + seed); // Cycles from 0 to 1 - - // Apply easing for more natural movement - movementProgress = smoothstep(0.0, 1.0, movementProgress); - - // Current position - float posX = mix(startX, endX, movementProgress); - float posY = mix(startY, endY, movementProgress); - - // Add some orbit/wobble to the movement - posX += sin(t * 2.0 * speedFactor + seed * 9.87) * 0.1; - posY += cos(t * 1.7 * speedFactor + seed * 6.54) * 0.08; - - vec2 flashPos = vec2(posX, posY); - - // Distance to lightning center - float dist = length(centered - flashPos); - - // Core and outer glow - smaller size - float baseRadius = 0.08 + sin(t * 4.0 + seed) * 0.01; // Reduced from 0.15 - float glowRadius = baseRadius * (1.0 + flashIntensity * 0.3); - float coreSize = glowRadius * 0.3; - - float coreGlow = smoothstep(coreSize, 0.0, dist) * flashIntensity * 3.0; - float outerGlow = smoothstep(glowRadius, coreSize, dist) * flashIntensity * 0.7; - float glow = coreGlow + outerGlow; - - // Detail variation - float detail = sin(dist * 20.0 + t * 5.0) * 0.5 + 0.5; - glow = glow * (0.9 + detail * 0.1); - - // Speed-based color variation - vec3 outerColor = vec3(0.85, 0.9, 1.0); - vec3 coreColor = vec3(1.0, 1.0, 1.0); - - // Add speed trail effect - float trail = smoothstep(0.0, 0.3, movementProgress) * (1.0 - smoothstep(0.7, 1.0, movementProgress)); - float trailIntensity = trail * speedFactor * 0.5; - - // Add slight color variation based on speed - coreColor = mix(coreColor, vec3(1.0, 0.9, 0.8), (speedFactor - 1.0) * 0.5); - - vec3 lightningColor = mix(outerColor, coreColor, min(1.0, coreGlow * 0.5)); - - finalColor += lightningColor * glow * (1.0 + trailIntensity); - } - } - - // Background ambient - float bgGlow = sin(t * 0.2) * 0.5 + 0.5; - bgGlow = pow(bgGlow, 5.0) * 0.05; - finalColor += vec3(0.7, 0.8, 1.0) * bgGlow; - - // Convert to RGBA color format for data_0 - int red = int(min(finalColor.r * 255.0, 255.0)); - int green = int(min(finalColor.g * 255.0, 255.0)); - int blue = int(min(finalColor.b * 255.0, 255.0)); - - data_0[p] = int(0xFF000000 | (red << 16) | (green << 8) | blue); -} \ No newline at end of file From f73a108aa9a394573242e71cc4570281dd3a115e Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Mon, 17 Mar 2025 22:36:56 +0100 Subject: [PATCH 05/10] moon and cloud added successfully for now --- .../car_in_the_night/car_in_the_night.cpp | 172 ++++++++++++------ 1 file changed, 120 insertions(+), 52 deletions(-) diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index daf25a8..732384b 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -4,9 +4,21 @@ #define SPEED 2.0 #define RAIN_DROPS 500 #define SPLASH_PARTICLES 20 +#define CAR_COUNT 8 float hash(float n) { return fract(sin(n) * 43758.5453123); } +float noise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + f = f*f*(3.0-2.0*f); + return mix( + mix(hash(i.x + i.y*157.0), hash(i.x+1.0 + i.y*157.0), f.x), + mix(hash(i.x + (i.y+1.0)*157.0), hash(i.x+1.0 + (i.y+1.0)*157.0), f.x), + f.y + ); +} + void main() { int x = int(gl_GlobalInvocationID.x); int y = int(gl_GlobalInvocationID.y); @@ -25,6 +37,67 @@ void main() { // Couleur de base - nuit data_0[p] = 0xFF000000 | (int(nightColor.r * 255.0) << 16) | (int(nightColor.g * 255.0) << 8) | int(nightColor.b * 255.0); +// Lune +float moonX = float(WSX) * 0.85; +float moonY = float(WSX) * 0.10; +float moonRadius = float(WSX) * 0.05; +float distToMoon = length(vec2(float(x) - moonX, float(y) - moonY)); + +if (distToMoon < moonRadius) { + // Créer un léger cratère sur la lune + float crater = noise(vec2(float(x), float(y)) * 0.1) * 0.2; + vec3 moonColor = vec3(0.95, 0.95, 0.85) - vec3(crater); + data_0[p] = 0xFF000000 | (int(moonColor.r * 255.0) << 16) | (int(moonColor.g * 255.0) << 8) | int(moonColor.b * 255.0); + + +} else if (distToMoon < moonRadius * 1.5) { + // Halo extérieur + float haloIntensity = 1.0 - ((distToMoon - moonRadius) / (moonRadius * 0.5)); + haloIntensity = haloIntensity * 0.3; // Atténuer l'intensité + vec3 haloColor = mix(nightColor, vec3(0.9, 0.9, 0.8), haloIntensity); + data_0[p] = 0xFF000000 | (int(haloColor.r * 255.0) << 16) | (int(haloColor.g * 255.0) << 8) | int(haloColor.b * 255.0); +} + +// Nuages +for (int i = 0; i < 5; i++) { + float cloudSeed = float(i) * 100.0; + float cloudX = mod(float(WSX) * hash(cloudSeed) + float(step) * 0.2, float(WSX)); + float cloudY = float(WSX) * 0.2 + float(i) * 15.0; + float cloudW = float(WSX) * (0.2 + hash(cloudSeed + 1.0) * 0.2); + float cloudH = float(WSX) * 0.05; + + // Forme du nuage avec bruit + float cloudNoise = noise(vec2(float(x) * 0.01 + cloudSeed, float(y) * 0.01 + cloudSeed + float(step) * 0.005)); + float cloudDist = length((vec2(float(x), float(y)) - vec2(cloudX, cloudY)) / vec2(cloudW, cloudH)); + cloudDist += cloudNoise * 0.5; + + if (cloudDist < 1.0) { + float cloudIntensity = (1.0 - cloudDist) * 0.3; + float moonInfluence = 0.0; + + // Nuages éclairés par la lune + float distToMoonFromCloud = length(vec2(cloudX - moonX, cloudY - moonY)); + if (distToMoonFromCloud < moonRadius * 5.0) { + moonInfluence = max(0.0, 0.5 - distToMoonFromCloud / (moonRadius * 10.0)); + } + + vec3 cloudColor = mix( + vec3(0.9, 0.9, 0.9), // Nuages clairs + vec3(0.6, 0.6, 0.7), // Nuages légèrement ombrés + moonInfluence + ); + + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = mix(existingColor, cloudColor, cloudIntensity); + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + } +} + // Route mouillée if (y > int(carPosY) + 30) { // Effet de route mouillée avec reflets @@ -80,12 +153,23 @@ void main() { } } +// Dessiner les voitures multiples +float carSpacing = (float(WSX) + CAR_WIDTH) / float(CAR_COUNT); +for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { + // Positions des voitures décalées, avec vitesses variées + float speedMultiplier = 0.8 + hash(float(carIdx) * 10.0) * 0.6; // Vitesse entre 0.8 et 1.4 fois SPEED + float carOffset = float(carIdx) * carSpacing / 1.5; + float carPosX = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + float carPosY = float(WSX) / 3.0 - float(carIdx % 2) * 5.0; // Légère variation de hauteur + // Dessiner la voiture if (float(x) >= carPosX && float(x) < carPosX + CAR_WIDTH && float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT) { - // Couleur de la voiture - bleu foncé - vec3 carColor = vec3(0.1, 0.1, 0.3); + // Couleur de la voiture - variée selon l'index + vec3 carColor = vec3(0.1 + hash(float(carIdx) * 42.0) * 0.2, + 0.1 + hash(float(carIdx) * 17.0) * 0.1, + 0.2 + hash(float(carIdx) * 29.0) * 0.3); // Variations de couleurs // Vitres if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && @@ -129,58 +213,42 @@ void main() { data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); } - // Ligne médiane de la route - moins visible dans la nuit sauf sous les phares - if (y > int(carPosY) + 40 && y < int(carPosY) + 43 && int(float(x) + float(step) * SPEED) % 70 < 40) { - float distToLight = length(vec2(float(x) - headlightX, float(y) - headlightY)); - float visibility = 0.2; - - if (float(x) > headlightX) { - visibility += 1.0 / (1.0 + distToLight * 0.03); - } - - vec3 lineColor = vec3(0.8, 0.8, 0.5) * min(visibility, 1.0); - data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); - } - - // Gouttes de pluie - for (int i = 0; i < 10; i++) { - float seed = hash(float(i) + float(x) * 0.01 + float(y) * 0.01); - float rainX = mod(float(x) + seed * 1000.0 + float(step) * (5.0 + seed * 10.0), float(WSX)); - float rainY = mod(float(y) + seed * 1000.0 + float(step) * (15.0 + seed * 10.0), float(int(WSX) * 3 / 4)); + // Faisceau des phares (uniquement pour la moitié des voitures pour éviter surcharge) + //if (carIdx % 2 == 0) { + float headlightX = carPosX + CAR_WIDTH * 0.9; + float headlightY = carPosY + CAR_HEIGHT * 0.7; - if (abs(float(x) - rainX) < 1.0 && abs(float(y) - rainY) < 3.0) { - float distToLight = length(vec2(rainX - headlightX, rainY - headlightY)); - float visibility = 0.2; + // Forme conique du faisceau + if (float(x) > headlightX && float(y) > int(carPosY) + 30) { + float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); + float maxAngle = 0.3; + float minAngle = -0.3; - if (rainX > headlightX) { - visibility += 1.0 / (1.0 + distToLight * 0.03); - } - - vec3 rainColor = vec3(0.7, 0.7, 0.9) * min(visibility, 1.0); - data_0[p] = 0xFF000000 | (int(rainColor.r * 255.0) << 16) | (int(rainColor.g * 255.0) << 8) | int(rainColor.b * 255.0); - } - } - - // Éclaboussures près des roues - if (y > int(wheelY) && y < int(wheelY) + 15) { - // Près de la roue avant - if (abs(float(x) - frontWheelX) < WHEEL_RADIUS * 1.5) { - float splashSeed = hash(float(x) + float(y) + float(step)); - if (splashSeed > 0.95) { - float splashIntensity = 0.5 + splashSeed * 0.5; - vec3 splashColor = vec3(0.8, 0.8, 0.9) * splashIntensity; - data_0[p] = 0xFF000000 | (int(splashColor.r * 255.0) << 16) | (int(splashColor.g * 255.0) << 8) | int(splashColor.b * 255.0); - } - } - - // Près de la roue arrière - if (abs(float(x) - rearWheelX) < WHEEL_RADIUS * 1.5) { - float splashSeed = hash(float(x) + float(y) + float(step) + 100.0); - if (splashSeed > 0.95) { - float splashIntensity = 0.5 + splashSeed * 0.5; - vec3 splashColor = vec3(0.8, 0.8, 0.9) * splashIntensity; - data_0[p] = 0xFF000000 | (int(splashColor.r * 255.0) << 16) | (int(splashColor.g * 255.0) << 8) | int(splashColor.b * 255.0); + if (angle >= minAngle && angle <= maxAngle) { + float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); + float maxDist = 250.0; + + if (dist < maxDist) { + // Intensité réduite pour les voitures multiples + float intensity = 1.0 - (dist / maxDist); + intensity = intensity * intensity * 0.3; // Atténuation plus forte + + vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; + + // Combiner la lumière avec la couleur existante + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = existingColor + lightColor; + finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + } } } - } + //} +} } \ No newline at end of file From af1caf831e67a6c5f4f652a39a441a53548a770b Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Mon, 17 Mar 2025 22:51:57 +0100 Subject: [PATCH 06/10] latest update --- examples/car_in_the_night/car_in_the_night.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index 732384b..791149b 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -29,10 +29,10 @@ void main() { float carPosY = float(WSX) / 3.0; // Nuit - fond noir avec leger bleu - vec3 nightColor = vec3(0.02, 0.03, 0.08); - + vec3 nightColor = vec3(0.05, 0.1, 0.25); // Nouvelle couleur + // Route mouillée - gris fonce avec reflets - vec3 roadColor = vec3(0.05, 0.05, 0.07); + vec3 roadColor = vec3(0.08, 0.08, 0.07); // Couleur de base - nuit data_0[p] = 0xFF000000 | (int(nightColor.r * 255.0) << 16) | (int(nightColor.g * 255.0) << 8) | int(nightColor.b * 255.0); From 10e0ba291b5e2dd20015f5945cd176944b29e3ad Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Mon, 17 Mar 2025 23:46:46 +0100 Subject: [PATCH 07/10] blue sky --- .../car_in_the_night/car_in_the_night.cpp | 215 +++++++++++++----- 1 file changed, 162 insertions(+), 53 deletions(-) diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index 791149b..2223b2b 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -26,15 +26,17 @@ void main() { // Position de la voiture basee sur le temps float carPosX = mod(float(step) * SPEED, float(WSX) + CAR_WIDTH) - CAR_WIDTH; - float carPosY = float(WSX) / 3.0; - // Nuit - fond noir avec leger bleu - vec3 nightColor = vec3(0.05, 0.1, 0.25); // Nouvelle couleur - + // Réduire la hauteur de la route - modification ici + float roadStart = float(WSX) / 2.2; // Position plus haute pour la route + float carPosY = roadStart - CAR_HEIGHT - 10.0; // Ajuster la position des voitures + + // Nuit - fond bleu foncé (corrigé) + vec3 nightColor = vec3(0.25, 0.1, 0.05); // En BGR pour obtenir un bleu foncé // Route mouillée - gris fonce avec reflets vec3 roadColor = vec3(0.08, 0.08, 0.07); - // Couleur de base - nuit + // Couleur de base - nuit (s'assurer que c'est bien bleu foncé) data_0[p] = 0xFF000000 | (int(nightColor.r * 255.0) << 16) | (int(nightColor.g * 255.0) << 8) | int(nightColor.b * 255.0); // Lune @@ -98,8 +100,8 @@ for (int i = 0; i < 5; i++) { } } - // Route mouillée - if (y > int(carPosY) + 30) { + // Route mouillée - modifier cette section pour réduire la hauteur + if (y > roadStart) { // Effet de route mouillée avec reflets float reflectionFactor = 0.0; @@ -116,6 +118,21 @@ for (int i = 0; i < 5; i++) { vec3 finalRoadColor = roadColor + vec3(1.0, 0.8, 0.5) * reflectionFactor; data_0[p] = 0xFF000000 | (int(finalRoadColor.r * 255.0) << 16) | (int(finalRoadColor.g * 255.0) << 8) | int(finalRoadColor.b * 255.0); + + // Ligne blanche discontinue au milieu de la route + float lineY = roadStart + (float(WSX) - roadStart) * 0.5; // Milieu de la route + float lineThickness = 2.0; + + if (abs(float(y) - lineY) < lineThickness) { + // Ligne discontinue - alternance de segments blancs et vides + float lineSegment = mod(float(x) + float(step) * SPEED, 40.0); + + if (lineSegment < 20.0) { + // Partie visible de la ligne + vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc + data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); + } + } } // Faisceau des phares @@ -123,7 +140,7 @@ for (int i = 0; i < 5; i++) { float headlightY = carPosY + CAR_HEIGHT * 0.7; // Forme conique du faisceau - if (float(x) > headlightX && float(y) > int(carPosY) + 30) { + if (float(x) > headlightX && float(y) > roadStart) { float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); float maxAngle = 0.3; float minAngle = -0.3; @@ -152,6 +169,100 @@ for (int i = 0; i < 5; i++) { } } } + +// Panneau routier indiquant "Brest" +float signX = float(WSX) * 0.6; +float signY = float(WSX) * 0.25; +float signWidth = float(WSX) * 0.15; +float signHeight = float(WSX) * 0.05; + +// Vérifier si le pixel est dans la zone du panneau +if (float(x) >= signX && float(x) <= signX + signWidth && + float(y) >= signY && float(y) <= signY + signHeight) { + + // Fond du panneau (vert foncé) + vec3 signColor = vec3(0.0, 0.25, 0.0); + + // Bordure blanche + float borderSize = 2.0; + if (float(x) < signX + borderSize || float(x) > signX + signWidth - borderSize || + float(y) < signY + borderSize || float(y) > signY + signHeight - borderSize) { + signColor = vec3(0.9, 0.9, 0.9); + } + + // Zone de texte "Brest" + if (float(x) >= signX + signWidth * 0.15 && float(x) <= signX + signWidth * 0.85 && + float(y) >= signY + signHeight * 0.25 && float(y) <= signY + signHeight * 0.75) { + + // Dessiner les lettres "BREST" (version très simplifiée) + float textPosX = (float(x) - (signX + signWidth * 0.15)) / (signWidth * 0.7); + float charWidth = 0.18; // Largeur d'un caractère en pourcentage de la zone de texte + + if (textPosX < charWidth) { + // 'B' + float relX = (textPosX / charWidth) * 2.0 - 1.0; + float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; + float bDist = min(length(vec2(relX - 0.5, relY - 0.5)) - 0.5, + length(vec2(relX - 0.5, relY + 0.5)) - 0.5); + if (relX < 0.0 || bDist < 0.4) signColor = vec3(1.0, 1.0, 1.0); + } + else if (textPosX < charWidth * 2.0) { + // 'R' + float relX = ((textPosX - charWidth) / charWidth) * 2.0 - 1.0; + float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; + if (relX < 0.0 || (relY < 0.0 && length(vec2(relX - 0.5, relY + 0.5)) - 0.5 < 0.4) + || (relY >= 0.0 && relX < 0.5 + relY * 0.5)) signColor = vec3(1.0, 1.0, 1.0); + } + else if (textPosX < charWidth * 3.0) { + // 'E' + float relX = ((textPosX - charWidth * 2.0) / charWidth) * 2.0 - 1.0; + float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; + if (relX < 0.0 || abs(relY) > 0.8 || abs(relY) < 0.2) signColor = vec3(1.0, 1.0, 1.0); + } + else if (textPosX < charWidth * 4.0) { + // 'S' + float relX = ((textPosX - charWidth * 3.0) / charWidth) * 2.0 - 1.0; + float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; + float sDist = abs(relY) - 0.8; + if (abs(relY) > 0.8 || abs(relY) < 0.2 || + (relY > 0.0 && relX < 0.0) || + (relY < 0.0 && relX > 0.0)) signColor = vec3(1.0, 1.0, 1.0); + } + else if (textPosX < charWidth * 5.0) { + // 'T' + float relX = ((textPosX - charWidth * 4.0) / charWidth) * 2.0 - 1.0; + float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; + if (abs(relY) > 0.8 || abs(relX) < 0.3) signColor = vec3(1.0, 1.0, 1.0); + } + } + + // Applique la couleur du panneau au pixel + data_0[p] = 0xFF000000 | (int(signColor.r * 255.0) << 16) | (int(signColor.g * 255.0) << 8) | int(signColor.b * 255.0); + + // Effet de réflexion des phares sur le panneau + for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { + float speedMultiplier = 0.8 + hash(float(carIdx) * 10.0) * 0.6; + float carOffset = float(carIdx) * ((float(WSX) + CAR_WIDTH) / float(CAR_COUNT)) / 1.5; + float thisCar_X = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + + // Si une voiture est proche du panneau (et venant de la gauche) + if (thisCar_X < signX && thisCar_X > signX - 150.0) { + float distToHeadlight = length(vec2(float(x) - (thisCar_X + CAR_WIDTH * 0.9), float(y) - (carPosY + CAR_HEIGHT * 0.7))); + float reflectionIntensity = 5.0 / (1.0 + distToHeadlight * 0.05); + reflectionIntensity = min(reflectionIntensity * 0.3, 0.8); // Limiter l'intensité + + vec3 reflectionColor = mix(signColor, vec3(1.0, 0.95, 0.8), reflectionIntensity); + data_0[p] = 0xFF000000 | (int(reflectionColor.r * 255.0) << 16) | (int(reflectionColor.g * 255.0) << 8) | int(reflectionColor.b * 255.0); + } + } + + // Support du panneau + if (float(x) >= signX + signWidth * 0.45 && float(x) <= signX + signWidth * 0.55 && + float(y) > signY + signHeight && float(y) < roadStart) { + vec3 poleColor = vec3(0.5, 0.5, 0.5); // Gris métallique + data_0[p] = 0xFF000000 | (int(poleColor.r * 255.0) << 16) | (int(poleColor.g * 255.0) << 8) | int(poleColor.b * 255.0); + } +} // Dessiner les voitures multiples float carSpacing = (float(WSX) + CAR_WIDTH) / float(CAR_COUNT); @@ -159,12 +270,12 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { // Positions des voitures décalées, avec vitesses variées float speedMultiplier = 0.8 + hash(float(carIdx) * 10.0) * 0.6; // Vitesse entre 0.8 et 1.4 fois SPEED float carOffset = float(carIdx) * carSpacing / 1.5; - float carPosX = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; - float carPosY = float(WSX) / 3.0 - float(carIdx % 2) * 5.0; // Légère variation de hauteur + float thisCar_X = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + float thisCar_Y = carPosY - float(carIdx % 2) * 5.0; // Légère variation de hauteur // Dessiner la voiture - if (float(x) >= carPosX && float(x) < carPosX + CAR_WIDTH && - float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT) { + if (float(x) >= thisCar_X && float(x) < thisCar_X + CAR_WIDTH && + float(y) >= thisCar_Y && float(y) < thisCar_Y + CAR_HEIGHT) { // Couleur de la voiture - variée selon l'index vec3 carColor = vec3(0.1 + hash(float(carIdx) * 42.0) * 0.2, @@ -172,8 +283,8 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { 0.2 + hash(float(carIdx) * 29.0) * 0.3); // Variations de couleurs // Vitres - if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && - float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT * 0.5) { + if (float(x) >= thisCar_X + CAR_WIDTH * 0.25 && float(x) < thisCar_X + CAR_WIDTH * 0.75 && + float(y) >= thisCar_Y && float(y) < thisCar_Y + CAR_HEIGHT * 0.5) { carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées } @@ -181,8 +292,8 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { } // Phares avant - float frontLightX = carPosX + CAR_WIDTH * 0.9; - float frontLightY = carPosY + CAR_HEIGHT * 0.7; + float frontLightX = thisCar_X + CAR_WIDTH * 0.9; + float frontLightY = thisCar_Y + CAR_HEIGHT * 0.7; float frontLightRadius = 4.0; if (length(vec2(float(x) - frontLightX, float(y) - frontLightY)) < frontLightRadius) { @@ -191,8 +302,8 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { } // Feu arrière - float rearLightX = carPosX + CAR_WIDTH * 0.1; - float rearLightY = carPosY + CAR_HEIGHT * 0.7; + float rearLightX = thisCar_X + CAR_WIDTH * 0.1; + float rearLightY = thisCar_Y + CAR_HEIGHT * 0.7; float rearLightRadius = 3.0; if (length(vec2(float(x) - rearLightX, float(y) - rearLightY)) < rearLightRadius) { @@ -201,9 +312,9 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { } // Roues - float frontWheelX = carPosX + CAR_WIDTH * 0.75; - float rearWheelX = carPosX + CAR_WIDTH * 0.25; - float wheelY = carPosY + CAR_HEIGHT; + float frontWheelX = thisCar_X + CAR_WIDTH * 0.75; + float rearWheelX = thisCar_X + CAR_WIDTH * 0.25; + float wheelY = thisCar_Y + CAR_HEIGHT; float distFrontWheel = length(vec2(float(x) - frontWheelX, float(y) - wheelY)); float distRearWheel = length(vec2(float(x) - rearWheelX, float(y) - wheelY)); @@ -213,42 +324,40 @@ for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); } - // Faisceau des phares (uniquement pour la moitié des voitures pour éviter surcharge) - //if (carIdx % 2 == 0) { - float headlightX = carPosX + CAR_WIDTH * 0.9; - float headlightY = carPosY + CAR_HEIGHT * 0.7; + // Faisceau des phares + float headlightX = thisCar_X + CAR_WIDTH * 0.9; + float headlightY = thisCar_Y + CAR_HEIGHT * 0.7; + + // Forme conique du faisceau + if (float(x) > headlightX && float(y) > roadStart) { + float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); + float maxAngle = 0.3; + float minAngle = -0.3; - // Forme conique du faisceau - if (float(x) > headlightX && float(y) > int(carPosY) + 30) { - float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); - float maxAngle = 0.3; - float minAngle = -0.3; + if (angle >= minAngle && angle <= maxAngle) { + float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); + float maxDist = 250.0; - if (angle >= minAngle && angle <= maxAngle) { - float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); - float maxDist = 250.0; + if (dist < maxDist) { + // Intensité réduite pour les voitures multiples + float intensity = 1.0 - (dist / maxDist); + intensity = intensity * intensity * 0.3; // Atténuation plus forte - if (dist < maxDist) { - // Intensité réduite pour les voitures multiples - float intensity = 1.0 - (dist / maxDist); - intensity = intensity * intensity * 0.3; // Atténuation plus forte - - vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; - - // Combiner la lumière avec la couleur existante - vec3 existingColor = vec3( - float((data_0[p] >> 16) & 0xFF) / 255.0, - float((data_0[p] >> 8) & 0xFF) / 255.0, - float(data_0[p] & 0xFF) / 255.0 - ); - - vec3 finalColor = existingColor + lightColor; - finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 - - data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); - } + vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; + + // Combiner la lumière avec la couleur existante + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = existingColor + lightColor; + finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); } } - //} + } } } \ No newline at end of file From 2e924092c84c7736f7cd547ec9ef396f4edcb670 Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Tue, 18 Mar 2025 00:20:15 +0100 Subject: [PATCH 08/10] =?UTF-8?q?R=C3=A9cup=C3=A9ration=20de=20car=5Fin=5F?= =?UTF-8?q?the=5Fnight.cpp=20depuis=20neural=5Fpulse=5FV1=5Fadrien?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../car_in_the_night/car_in_the_night.cpp | 778 +++++++++++------- 1 file changed, 489 insertions(+), 289 deletions(-) diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index 2223b2b..c110759 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -4,7 +4,8 @@ #define SPEED 2.0 #define RAIN_DROPS 500 #define SPLASH_PARTICLES 20 -#define CAR_COUNT 8 +#define CAR_COUNT 8 // Plus de voitures pour remplir les 4 voies +#define STAR_COUNT 200 // Nombre d'étoiles dans le ciel float hash(float n) { return fract(sin(n) * 43758.5453123); } @@ -19,345 +20,544 @@ float noise(vec2 p) { ); } +// Fonction pour créer un bruit fractal (FBM - Fractional Brownian Motion) +float fbm(vec2 p) { + float value = 0.0; + float amplitude = 0.5; + float frequency = 1.0; + // Additionner plusieurs octaves de bruit + for (int i = 0; i < 5; i++) { + value += amplitude * noise(p * frequency); + amplitude *= 0.5; + frequency *= 2.0; + } + return value; +} + void main() { int x = int(gl_GlobalInvocationID.x); int y = int(gl_GlobalInvocationID.y); int p = x + y * int(WSX); - // Position de la voiture basee sur le temps - float carPosX = mod(float(step) * SPEED, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + // Définir les limites des différentes zones - route descendue et ciel étoilé agrandi + float skyLimit = float(WSX) / 2.5; // Limite entre ciel et route (plus grande portion de ciel) + float laneY1 = skyLimit + 10.0; // Voie du haut (voitures vers la droite - lente) + float laneY4 = laneY1 + 115; // Voie du bas (voitures vers la gauche - lente) + float grassStart = laneY4 + 20.0; // Début de l'herbe après la route (portion d'herbe réduite) - // Réduire la hauteur de la route - modification ici - float roadStart = float(WSX) / 2.2; // Position plus haute pour la route - float carPosY = roadStart - CAR_HEIGHT - 10.0; // Ajuster la position des voitures - - // Nuit - fond bleu foncé (corrigé) - vec3 nightColor = vec3(0.25, 0.1, 0.05); // En BGR pour obtenir un bleu foncé - // Route mouillée - gris fonce avec reflets - vec3 roadColor = vec3(0.08, 0.08, 0.07); - - // Couleur de base - nuit (s'assurer que c'est bien bleu foncé) - data_0[p] = 0xFF000000 | (int(nightColor.r * 255.0) << 16) | (int(nightColor.g * 255.0) << 8) | int(nightColor.b * 255.0); + // Ciel nocturne avec étoiles + if (y < int(skyLimit)) { + // Dégradé pour le ciel nocturne (plus foncé en haut, plus clair vers l'horizon) + float skyGradient = float(y) / skyLimit; + vec3 skyColor = mix( + vec3(0.25, 0.1, 0.05), // Couleur du ciel en haut (bleu foncé) + vec3(0.28, 0.15, 0.08), // Couleur du ciel vers l'horizon (légèrement plus claire) + skyGradient + ); + + // Appliquer la couleur de base du ciel + data_0[p] = 0xFF000000 | (int(skyColor.r * 255.0) << 16) | (int(skyColor.g * 255.0) << 8) | int(skyColor.b * 255.0); + + // Ajouter des étoiles + for (int i = 0; i < STAR_COUNT; i++) { + float starSeed = float(i) * 42.758; + float starX = hash(starSeed) * float(WSX); + float starY = hash(starSeed + 7.3219) * skyLimit; + + // Distance à l'étoile + float distToStar = length(vec2(float(x) - starX, float(y) - starY)); + + // Taille variable des étoiles + float starRadius = 0.5 + hash(starSeed + 13.7) * 1.5; + + // Luminosité variable des étoiles + float starBrightness = 0.5 + hash(starSeed + 21.13) * 0.5; + + // Faire scintiller les étoiles avec le temps + float flicker = 0.7 + 0.3 * sin(float(step) * 0.05 + hash(starSeed) * 6.28); + starBrightness *= flicker; + + // Dessiner l'étoile avec un dégradé doux + if (distToStar < starRadius) { + float starIntensity = (1.0 - distToStar / starRadius) * starBrightness; + vec3 starColor = vec3(0.9, 0.95, 1.0) * starIntensity; // Blanc légèrement bleuté + + // Pour quelques étoiles, ajouter une teinte colorée + if (hash(starSeed + 33.97) > 0.85) { + // Rouge, bleu ou jaune selon le hash + float colorType = hash(starSeed + 50.31); + if (colorType < 0.33) { + starColor = mix(starColor, vec3(1.0, 0.7, 0.7), 0.4); // Rougeâtre + } else if (colorType < 0.66) { + starColor = mix(starColor, vec3(0.7, 0.7, 1.0), 0.4); // Bleuâtre + } else { + starColor = mix(starColor, vec3(1.0, 1.0, 0.7), 0.4); // Jaunâtre + } + } + + // Mélanger avec la couleur existante + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = existingColor + starColor; + finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + } + } + } -// Lune -float moonX = float(WSX) * 0.85; -float moonY = float(WSX) * 0.10; -float moonRadius = float(WSX) * 0.05; -float distToMoon = length(vec2(float(x) - moonX, float(y) - moonY)); - -if (distToMoon < moonRadius) { - // Créer un léger cratère sur la lune - float crater = noise(vec2(float(x), float(y)) * 0.1) * 0.2; - vec3 moonColor = vec3(0.95, 0.95, 0.85) - vec3(crater); - data_0[p] = 0xFF000000 | (int(moonColor.r * 255.0) << 16) | (int(moonColor.g * 255.0) << 8) | int(moonColor.b * 255.0); + // Zone d'herbe en bas + else if (y >= int(grassStart)) { + // Utiliser fbm pour créer une texture d'herbe + float grassNoise = fbm(vec2(float(x) * 0.05, float(y) * 0.05 + float(step) * 0.001)); + + // Couleur de base de l'herbe avec variation + vec3 grassColor = vec3(0.05 + grassNoise * 0.04, 0.2 + grassNoise * 0.1, 0.05 + grassNoise * 0.02); + + // Assombrir progressivement l'herbe en s'éloignant de la route + float distFromRoad = (float(y) - grassStart) / (float(WSX) - grassStart); + grassColor = mix(grassColor, vec3(0.02, 0.08, 0.02), distFromRoad * 0.7); + + // Ajouter quelques brins d'herbe plus clairs + if (hash(float(x) + float(y) * 73.1) > 0.97) { + grassColor = mix(grassColor, vec3(0.15, 0.3, 0.1), 0.5); + } + + data_0[p] = 0xFF000000 | (int(grassColor.r * 255.0) << 16) | (int(grassColor.g * 255.0) << 8) | int(grassColor.b * 255.0); + } + // Lune améliorée + float moonX = float(WSX) * 0.85; + float moonY = float(WSX) * 0.10; + float moonRadius = float(WSX) * 0.05; + float distToMoon = length(vec2(float(x) - moonX, float(y) - moonY)); -} else if (distToMoon < moonRadius * 1.5) { - // Halo extérieur - float haloIntensity = 1.0 - ((distToMoon - moonRadius) / (moonRadius * 0.5)); - haloIntensity = haloIntensity * 0.3; // Atténuer l'intensité - vec3 haloColor = mix(nightColor, vec3(0.9, 0.9, 0.8), haloIntensity); - data_0[p] = 0xFF000000 | (int(haloColor.r * 255.0) << 16) | (int(haloColor.g * 255.0) << 8) | int(haloColor.b * 255.0); -} - -// Nuages -for (int i = 0; i < 5; i++) { - float cloudSeed = float(i) * 100.0; - float cloudX = mod(float(WSX) * hash(cloudSeed) + float(step) * 0.2, float(WSX)); - float cloudY = float(WSX) * 0.2 + float(i) * 15.0; - float cloudW = float(WSX) * (0.2 + hash(cloudSeed + 1.0) * 0.2); - float cloudH = float(WSX) * 0.05; + // Rayon normalisé pour les effets de surface + float normalizedRadius = distToMoon / moonRadius; - // Forme du nuage avec bruit - float cloudNoise = noise(vec2(float(x) * 0.01 + cloudSeed, float(y) * 0.01 + cloudSeed + float(step) * 0.005)); - float cloudDist = length((vec2(float(x), float(y)) - vec2(cloudX, cloudY)) / vec2(cloudW, cloudH)); - cloudDist += cloudNoise * 0.5; - - if (cloudDist < 1.0) { - float cloudIntensity = (1.0 - cloudDist) * 0.3; - float moonInfluence = 0.0; - - // Nuages éclairés par la lune - float distToMoonFromCloud = length(vec2(cloudX - moonX, cloudY - moonY)); - if (distToMoonFromCloud < moonRadius * 5.0) { - moonInfluence = max(0.0, 0.5 - distToMoonFromCloud / (moonRadius * 10.0)); - } + if (distToMoon < moonRadius) { + // Utiliser FBM pour des détails de surface plus complexes + vec2 moonUV = vec2(float(x) - moonX, float(y) - moonY) / moonRadius; - vec3 cloudColor = mix( - vec3(0.9, 0.9, 0.9), // Nuages clairs - vec3(0.6, 0.6, 0.7), // Nuages légèrement ombrés - moonInfluence - ); + // Créer des cratères plus détaillés + float largeScale = fbm(moonUV * 5.0) * 0.15; // Grandes formations + float mediumScale = fbm(moonUV * 10.0) * 0.1; // Formations moyennes + float smallScale = fbm(moonUV * 20.0) * 0.05; // Petits détails + + // Combiner les échelles pour créer une surface complexe + float craterEffect = largeScale + mediumScale + smallScale; + + // Ajouter un léger effet de limbe (bord plus brillant) + float limb = smoothstep(0.8, 1.0, normalizedRadius) * 0.15; + + // Créer un dégradé du centre vers les bords pour donner plus de profondeur + float depthGradient = mix(0.15, 0.0, normalizedRadius * 0.7); + + // Couleur de base de la lune avec teinte légèrement bleutée + vec3 moonBaseColor = vec3(0.95, 0.95, 0.92); + // Appliquer les effets de surface et de profondeur + vec3 moonColor = moonBaseColor - vec3(craterEffect) + vec3(limb) - vec3(depthGradient); + + // Assurer que les valeurs restent dans une plage valide + moonColor = clamp(moonColor, vec3(0.0), vec3(1.0)); + + data_0[p] = 0xFF000000 | (int(moonColor.r * 255.0) << 16) | (int(moonColor.g * 255.0) << 8) | int(moonColor.b * 255.0); + } + else if (distToMoon < moonRadius * 2.0) { + // Halo extérieur amélioré avec gradient plus doux + float haloDistance = (distToMoon - moonRadius) / moonRadius; + float haloIntensity = pow(1.0 - haloDistance, 2.0) * 0.4; + + // Faire varier légèrement la couleur du halo + vec3 innerHaloColor = vec3(0.95, 0.95, 0.9); // Plus proche de la couleur de la lune + vec3 outerHaloColor = vec3(0.7, 0.75, 0.9); // Teinte bleutée pour l'extérieur du halo + + // Mélanger entre les couleurs intérieures et extérieures du halo + vec3 haloColor = mix(outerHaloColor, innerHaloColor, 1.0 - haloDistance); + + // Récupérer la couleur existante (ciel ou étoiles) vec3 existingColor = vec3( float((data_0[p] >> 16) & 0xFF) / 255.0, float((data_0[p] >> 8) & 0xFF) / 255.0, float(data_0[p] & 0xFF) / 255.0 ); - vec3 finalColor = mix(existingColor, cloudColor, cloudIntensity); - data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + // Mélanger avec la couleur de fond selon l'intensité + vec3 finalHaloColor = mix(existingColor, haloColor, haloIntensity); + + data_0[p] = 0xFF000000 | (int(finalHaloColor.r * 255.0) << 16) | (int(finalHaloColor.g * 255.0) << 8) | int(finalHaloColor.b * 255.0); } -} - // Route mouillée - modifier cette section pour réduire la hauteur - if (y > roadStart) { - // Effet de route mouillée avec reflets - float reflectionFactor = 0.0; + // Nuages + for (int i = 0; i < 5; i++) { + float cloudSeed = float(i) * 100.0; + float cloudX = mod(float(WSX) * hash(cloudSeed) + float(step) * 0.2, float(WSX)); + float cloudY = float(WSX) * 0.12 + float(i) * 15.0; + float cloudW = float(WSX) * (0.2 + hash(cloudSeed + 1.0) * 0.2); + float cloudH = float(WSX) * 0.05; - // Reflets de la lumière des phares sur la route - float distToFrontLight = length(vec2(float(x) - (carPosX + CAR_WIDTH * 0.9), float(y) - (carPosY + CAR_HEIGHT * 0.7))); - float frontLightFalloff = 1.0 / (1.0 + distToFrontLight * 0.015); + // Forme du nuage avec bruit + float cloudNoise = noise(vec2(float(x) * 0.01 + cloudSeed, float(y) * 0.01 + cloudSeed + float(step) * 0.005)); + float cloudDist = length((vec2(float(x), float(y)) - vec2(cloudX, cloudY)) / vec2(cloudW, cloudH)); + cloudDist += cloudNoise * 0.5; - // Intensité des reflets uniquement devant la voiture - if (float(x) > carPosX + CAR_WIDTH * 0.9) { - reflectionFactor = max(0.0, frontLightFalloff * 0.5 - 0.02); + if (cloudDist < 1.0) { + float cloudIntensity = (1.0 - cloudDist) * 0.3; + float moonInfluence = 0.0; + + // Nuages éclairés par la lune + float distToMoonFromCloud = length(vec2(cloudX - moonX, cloudY - moonY)); + if (distToMoonFromCloud < moonRadius * 5.0) { + moonInfluence = max(0.0, 0.5 - distToMoonFromCloud / (moonRadius * 10.0)); + } + + vec3 cloudColor = mix( + vec3(0.9, 0.9, 0.9), // Nuages clairs + vec3(0.6, 0.6, 0.7), // Nuages légèrement ombrés + moonInfluence + ); + + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = mix(existingColor, cloudColor, cloudIntensity); + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); } + } + + // Délimiter les voies - ajustées à la nouvelle position de la route + float laneY2 = laneY1 + 35; // Voie du haut (voitures vers la droite - rapide) + float laneY3 = laneY1 + 80; // Voie du bas (voitures vers la gauche - rapide) + + // Route mouillée + if (y >= int(skyLimit) && y < int(grassStart)) { + // Effet de route mouillée avec reflets + vec3 roadColor = vec3(0.08, 0.08, 0.07); - // Couleur de la route avec reflets - vec3 finalRoadColor = roadColor + vec3(1.0, 0.8, 0.5) * reflectionFactor; - - data_0[p] = 0xFF000000 | (int(finalRoadColor.r * 255.0) << 16) | (int(finalRoadColor.g * 255.0) << 8) | int(finalRoadColor.b * 255.0); + // Ajouter un peu de reflet pour la route mouillée + float reflectFactor = noise(vec2(float(x) * 0.02, float(y) * 0.02)) * 0.03; + roadColor = roadColor + vec3(reflectFactor); - // Ligne blanche discontinue au milieu de la route - float lineY = roadStart + (float(WSX) - roadStart) * 0.5; // Milieu de la route - float lineThickness = 2.0; + data_0[p] = 0xFF000000 | (int(roadColor.r * 255.0) << 16) | (int(roadColor.g * 255.0) << 8) | int(roadColor.b * 255.0); - if (abs(float(y) - lineY) < lineThickness) { - // Ligne discontinue - alternance de segments blancs et vides - float lineSegment = mod(float(x) + float(step) * SPEED, 40.0); - - if (lineSegment < 20.0) { - // Partie visible de la ligne + // Ligne entre les voies allant dans le même sens + if (y > int(laneY1) + 30 && y < int(laneY1) + 33) { + // Ligne pointillée pour voies allant dans le même sens (droite) + if (int(float(x) / 20.0) % 2 == 0) { vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); } } - } - - // Faisceau des phares - float headlightX = carPosX + CAR_WIDTH * 0.9; - float headlightY = carPosY + CAR_HEIGHT * 0.7; - - // Forme conique du faisceau - if (float(x) > headlightX && float(y) > roadStart) { - float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); - float maxAngle = 0.3; - float minAngle = -0.3; - - if (angle >= minAngle && angle <= maxAngle) { - float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); - float maxDist = 250.0; - - if (dist < maxDist) { - float intensity = 1.0 - (dist / maxDist); - intensity = intensity * intensity * 0.6; // Atténuation quadratique - - vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; - - // Combiner la lumière avec la couleur existante - vec3 existingColor = vec3( - float((data_0[p] >> 16) & 0xFF) / 255.0, - float((data_0[p] >> 8) & 0xFF) / 255.0, - float(data_0[p] & 0xFF) / 255.0 - ); - - vec3 finalColor = existingColor + lightColor; - finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 - - data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + + // Ligne centrale entre les deux sens (double ligne continue) + if ((y > int(laneY2) + 25 && y < int(laneY2) + 28) || + (y > int(laneY3) - 10 && y < int(laneY3) - 7)) { + vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc + data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); + } + + // Ligne entre les voies allant dans le même sens + if (y > int(laneY3) + 30 && y < int(laneY3) + 33) { + // Ligne pointillée pour voies allant dans le même sens (gauche) + if (int(float(x) / 20.0) % 2 == 0) { + vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc + data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); } } } - -// Panneau routier indiquant "Brest" -float signX = float(WSX) * 0.6; -float signY = float(WSX) * 0.25; -float signWidth = float(WSX) * 0.15; -float signHeight = float(WSX) * 0.05; - -// Vérifier si le pixel est dans la zone du panneau -if (float(x) >= signX && float(x) <= signX + signWidth && - float(y) >= signY && float(y) <= signY + signHeight) { - // Fond du panneau (vert foncé) - vec3 signColor = vec3(0.0, 0.25, 0.0); + // Stocker les positions des voitures pour calculer les distances entre elles + vec2 carPositions[CAR_COUNT]; + bool carDirections[CAR_COUNT]; - // Bordure blanche - float borderSize = 2.0; - if (float(x) < signX + borderSize || float(x) > signX + signWidth - borderSize || - float(y) < signY + borderSize || float(y) > signY + signHeight - borderSize) { - signColor = vec3(0.9, 0.9, 0.9); + // Premier parcours pour calculer les positions + for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { + // Déterminer la direction (droite ou gauche) et la voie (lente ou rapide) + bool goingRight = (carIdx < CAR_COUNT / 2); + carDirections[carIdx] = goingRight; + + // Les voitures avec indices pairs vont sur la voie "lente", les impaires sur la voie "rapide" + bool fastLane = (carIdx % 2 == 1); + + // Différentes vitesses selon la voie et avec variation individuelle + float baseSpeed = fastLane ? 1.4 : 0.8; // Les voies rapides sont 1.75x plus rapides + float speedMultiplier = baseSpeed + hash(float(carIdx) * 10.0) * 0.3; // Variation individuelle + + // Position Y selon la direction et la voie + float carPosY; + if (goingRight) { + carPosY = fastLane ? laneY2 - 10.0 : laneY1 - 10.0; + } else { + carPosY = fastLane ? laneY3 - 10.0 : laneY4 - 10.0; + } + + // Position X avec décalage et direction + float carOffset = float(carIdx % (CAR_COUNT/2)) * (float(WSX) + CAR_WIDTH) / float(CAR_COUNT/2) * 0.8; + float carPosX; + + if (goingRight) { + // Voitures allant de gauche à droite + carPosX = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + } else { + // Voitures allant de droite à gauche + carPosX = float(WSX) - mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH); + } + + // Stocker la position pour les calculs de proximité + carPositions[carIdx] = vec2(carPosX + CAR_WIDTH * 0.5, carPosY + CAR_HEIGHT * 0.5); } - // Zone de texte "Brest" - if (float(x) >= signX + signWidth * 0.15 && float(x) <= signX + signWidth * 0.85 && - float(y) >= signY + signHeight * 0.25 && float(y) <= signY + signHeight * 0.75) { - - // Dessiner les lettres "BREST" (version très simplifiée) - float textPosX = (float(x) - (signX + signWidth * 0.15)) / (signWidth * 0.7); - float charWidth = 0.18; // Largeur d'un caractère en pourcentage de la zone de texte - - if (textPosX < charWidth) { - // 'B' - float relX = (textPosX / charWidth) * 2.0 - 1.0; - float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; - float bDist = min(length(vec2(relX - 0.5, relY - 0.5)) - 0.5, - length(vec2(relX - 0.5, relY + 0.5)) - 0.5); - if (relX < 0.0 || bDist < 0.4) signColor = vec3(1.0, 1.0, 1.0); - } - else if (textPosX < charWidth * 2.0) { - // 'R' - float relX = ((textPosX - charWidth) / charWidth) * 2.0 - 1.0; - float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; - if (relX < 0.0 || (relY < 0.0 && length(vec2(relX - 0.5, relY + 0.5)) - 0.5 < 0.4) - || (relY >= 0.0 && relX < 0.5 + relY * 0.5)) signColor = vec3(1.0, 1.0, 1.0); + // Dessiner les voitures dans les deux sens + for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { + // Récupérer les informations déjà calculées + bool goingRight = carDirections[carIdx]; + + // Déterminer si c'est une voiture sur voie rapide + bool fastLane = (carIdx % 2 == 1); + + // Position Y selon la direction et la voie + float carPosY; + if (goingRight) { + carPosY = fastLane ? laneY2 - 10.0 : laneY1 - 10.0; + } else { + carPosY = fastLane ? laneY3 - 10.0 : laneY4 - 10.0; } - else if (textPosX < charWidth * 3.0) { - // 'E' - float relX = ((textPosX - charWidth * 2.0) / charWidth) * 2.0 - 1.0; - float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; - if (relX < 0.0 || abs(relY) > 0.8 || abs(relY) < 0.2) signColor = vec3(1.0, 1.0, 1.0); + + // Récupérer la vitesse et l'offset + float baseSpeed = fastLane ? 1.4 : 0.8; + float speedMultiplier = baseSpeed + hash(float(carIdx) * 10.0) * 0.3; + float carOffset = float(carIdx % (CAR_COUNT/2)) * (float(WSX) + CAR_WIDTH) / float(CAR_COUNT/2) * 0.8; + float carPosX; + + if (goingRight) { + carPosX = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; + } else { + carPosX = float(WSX) - mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH); } - else if (textPosX < charWidth * 4.0) { - // 'S' - float relX = ((textPosX - charWidth * 3.0) / charWidth) * 2.0 - 1.0; - float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; - float sDist = abs(relY) - 0.8; - if (abs(relY) > 0.8 || abs(relY) < 0.2 || - (relY > 0.0 && relX < 0.0) || - (relY < 0.0 && relX > 0.0)) signColor = vec3(1.0, 1.0, 1.0); + + // Dessiner la voiture + if (float(x) >= carPosX && float(x) < carPosX + CAR_WIDTH && + float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT) { + + // Couleur de la voiture - variée selon l'index + vec3 carColor = vec3(0.1 + hash(float(carIdx) * 42.0) * 0.2, + 0.1 + hash(float(carIdx) * 17.0) * 0.1, + 0.2 + hash(float(carIdx) * 29.0) * 0.3); + + // Vitres + if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && + float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT * 0.5) { + carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées + } + + data_0[p] = 0xFF000000 | (int(carColor.r * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.b * 255.0); } - else if (textPosX < charWidth * 5.0) { - // 'T' - float relX = ((textPosX - charWidth * 4.0) / charWidth) * 2.0 - 1.0; - float relY = ((float(y) - (signY + signHeight * 0.25)) / (signHeight * 0.5)) * 2.0 - 1.0; - if (abs(relY) > 0.8 || abs(relX) < 0.3) signColor = vec3(1.0, 1.0, 1.0); + + // Positions des phares et feux arrière selon la direction + float frontLightX, rearLightX; + if (goingRight) { + frontLightX = carPosX + CAR_WIDTH * 0.9; + rearLightX = carPosX + CAR_WIDTH * 0.1; + } else { + // Inversé pour les voitures allant vers la gauche + frontLightX = carPosX + CAR_WIDTH * 0.1; + rearLightX = carPosX + CAR_WIDTH * 0.9; } - } - - // Applique la couleur du panneau au pixel - data_0[p] = 0xFF000000 | (int(signColor.r * 255.0) << 16) | (int(signColor.g * 255.0) << 8) | int(signColor.b * 255.0); - - // Effet de réflexion des phares sur le panneau - for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { - float speedMultiplier = 0.8 + hash(float(carIdx) * 10.0) * 0.6; - float carOffset = float(carIdx) * ((float(WSX) + CAR_WIDTH) / float(CAR_COUNT)) / 1.5; - float thisCar_X = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; - - // Si une voiture est proche du panneau (et venant de la gauche) - if (thisCar_X < signX && thisCar_X > signX - 150.0) { - float distToHeadlight = length(vec2(float(x) - (thisCar_X + CAR_WIDTH * 0.9), float(y) - (carPosY + CAR_HEIGHT * 0.7))); - float reflectionIntensity = 5.0 / (1.0 + distToHeadlight * 0.05); - reflectionIntensity = min(reflectionIntensity * 0.3, 0.8); // Limiter l'intensité + + float lightY = carPosY + CAR_HEIGHT * 0.7; + float frontLightRadius = 4.0; + float rearLightRadius = 3.0; + + // Déterminer si la voiture est en croisement pour ajuster la couleur des phares + float headlightIntensity = 1.0; + + // Vérifier la proximité avec les voitures venant en sens inverse + for (int otherCarIdx = 0; otherCarIdx < CAR_COUNT; otherCarIdx++) { + if (otherCarIdx != carIdx && carDirections[otherCarIdx] != goingRight) { + float distBetweenCars = length(carPositions[carIdx] - carPositions[otherCarIdx]); + bool facingEachOther = false; + + if (goingRight) { + facingEachOther = (carPositions[otherCarIdx].x > carPositions[carIdx].x); + } else { + facingEachOther = (carPositions[otherCarIdx].x < carPositions[carIdx].x); + } + + if (facingEachOther && distBetweenCars < 250.0) { + float proximityFactor = distBetweenCars / 250.0; + headlightIntensity = min(headlightIntensity, 0.3 + proximityFactor * 0.7); + } + } + } + + // Phares avant (plus ou moins intenses selon le croisement) + if (length(vec2(float(x) - frontLightX, float(y) - lightY)) < frontLightRadius) { + // Couleur légèrement plus jaune/orange pour les feux de croisement + vec3 fullBeamColor = vec3(1.0, 0.9, 0.7); // Jaune chaud (pleins phares) + vec3 lowBeamColor = vec3(0.9, 0.8, 0.5); // Plus orange (feux de croisement) + vec3 lightColor = mix(lowBeamColor, fullBeamColor, headlightIntensity); - vec3 reflectionColor = mix(signColor, vec3(1.0, 0.95, 0.8), reflectionIntensity); - data_0[p] = 0xFF000000 | (int(reflectionColor.r * 255.0) << 16) | (int(reflectionColor.g * 255.0) << 8) | int(reflectionColor.b * 255.0); + data_0[p] = 0xFF000000 | (int(lightColor.r * 255.0) << 16) | (int(lightColor.g * 255.0) << 8) | int(lightColor.b * 255.0); } - } - - // Support du panneau - if (float(x) >= signX + signWidth * 0.45 && float(x) <= signX + signWidth * 0.55 && - float(y) > signY + signHeight && float(y) < roadStart) { - vec3 poleColor = vec3(0.5, 0.5, 0.5); // Gris métallique - data_0[p] = 0xFF000000 | (int(poleColor.r * 255.0) << 16) | (int(poleColor.g * 255.0) << 8) | int(poleColor.b * 255.0); - } -} - -// Dessiner les voitures multiples -float carSpacing = (float(WSX) + CAR_WIDTH) / float(CAR_COUNT); -for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { - // Positions des voitures décalées, avec vitesses variées - float speedMultiplier = 0.8 + hash(float(carIdx) * 10.0) * 0.6; // Vitesse entre 0.8 et 1.4 fois SPEED - float carOffset = float(carIdx) * carSpacing / 1.5; - float thisCar_X = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; - float thisCar_Y = carPosY - float(carIdx % 2) * 5.0; // Légère variation de hauteur - - // Dessiner la voiture - if (float(x) >= thisCar_X && float(x) < thisCar_X + CAR_WIDTH && - float(y) >= thisCar_Y && float(y) < thisCar_Y + CAR_HEIGHT) { - - // Couleur de la voiture - variée selon l'index - vec3 carColor = vec3(0.1 + hash(float(carIdx) * 42.0) * 0.2, - 0.1 + hash(float(carIdx) * 17.0) * 0.1, - 0.2 + hash(float(carIdx) * 29.0) * 0.3); // Variations de couleurs - - // Vitres - if (float(x) >= thisCar_X + CAR_WIDTH * 0.25 && float(x) < thisCar_X + CAR_WIDTH * 0.75 && - float(y) >= thisCar_Y && float(y) < thisCar_Y + CAR_HEIGHT * 0.5) { - carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées + + // Feux arrière (rouges) + if (length(vec2(float(x) - rearLightX, float(y) - lightY)) < rearLightRadius) { + vec3 redLight = vec3(1.0, 0.1, 0.1); // Rouge + data_0[p] = 0xFF000000 | (int(redLight.r * 255.0) << 16) | (int(redLight.g * 255.0) << 8) | int(redLight.b * 255.0); } - data_0[p] = 0xFF000000 | (int(carColor.r * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.b * 255.0); - } - - // Phares avant - float frontLightX = thisCar_X + CAR_WIDTH * 0.9; - float frontLightY = thisCar_Y + CAR_HEIGHT * 0.7; - float frontLightRadius = 4.0; - - if (length(vec2(float(x) - frontLightX, float(y) - frontLightY)) < frontLightRadius) { - vec3 lightColor = vec3(1.0, 0.9, 0.7); // Jaune chaud - data_0[p] = 0xFF000000 | (int(lightColor.r * 255.0) << 16) | (int(lightColor.g * 255.0) << 8) | int(lightColor.b * 255.0); - } - - // Feu arrière - float rearLightX = thisCar_X + CAR_WIDTH * 0.1; - float rearLightY = thisCar_Y + CAR_HEIGHT * 0.7; - float rearLightRadius = 3.0; - - if (length(vec2(float(x) - rearLightX, float(y) - rearLightY)) < rearLightRadius) { - vec3 redLight = vec3(1.0, 0.1, 0.1); // Rouge - data_0[p] = 0xFF000000 | (int(redLight.r * 255.0) << 16) | (int(redLight.g * 255.0) << 8) | int(redLight.b * 255.0); - } - - // Roues - float frontWheelX = thisCar_X + CAR_WIDTH * 0.75; - float rearWheelX = thisCar_X + CAR_WIDTH * 0.25; - float wheelY = thisCar_Y + CAR_HEIGHT; - - float distFrontWheel = length(vec2(float(x) - frontWheelX, float(y) - wheelY)); - float distRearWheel = length(vec2(float(x) - rearWheelX, float(y) - wheelY)); - - if (distFrontWheel <= WHEEL_RADIUS || distRearWheel <= WHEEL_RADIUS) { - vec3 wheelColor = vec3(0.1, 0.1, 0.1); // Noir - data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); - } - - // Faisceau des phares - float headlightX = thisCar_X + CAR_WIDTH * 0.9; - float headlightY = thisCar_Y + CAR_HEIGHT * 0.7; - - // Forme conique du faisceau - if (float(x) > headlightX && float(y) > roadStart) { - float angle = atan(float(y - int(headlightY)) / float(x - int(headlightX))); - float maxAngle = 0.3; - float minAngle = -0.3; - - if (angle >= minAngle && angle <= maxAngle) { - float dist = length(vec2(float(x) - headlightX, float(y) - headlightY)); - float maxDist = 250.0; + // Clignotants + bool shouldBlink = false; + bool blinkOn = false; + + // Déterminer si la voiture doit clignoter + // Les voitures sur voie rapide qui sont sur le point de sortir vont clignoter pour indiquer un changement de voie + if (fastLane) { + // Probabilité que la voiture veuille changer de voie + float changeLaneProbability = hash(float(carIdx) * 42.0 + float(step) * 0.01); - if (dist < maxDist) { - // Intensité réduite pour les voitures multiples - float intensity = 1.0 - (dist / maxDist); - intensity = intensity * intensity * 0.3; // Atténuation plus forte + // Vérifier si la voiture est sur le point de changer de voie + if (changeLaneProbability > 0.7) { + // Activer le clignotant + shouldBlink = true; + + // Séquence de clignotement (1 seconde allumé, 1 seconde éteint) + blinkOn = (int(float(step) / 30.0) % 2 == 0); + } + } + + if (shouldBlink && blinkOn) { + // Position du clignotant selon la direction + float blinkX, blinkY; + + if (goingRight) { + // Clignotant à droite pour voiture allant vers la droite (veut se rabattre à droite) + blinkX = carPosX + CAR_WIDTH * 0.9; + blinkY = carPosY + CAR_HEIGHT * 0.5; + } else { + // Clignotant à gauche pour voiture allant vers la gauche (veut se rabattre à gauche) + blinkX = carPosX + CAR_WIDTH * 0.1; + blinkY = carPosY + CAR_HEIGHT * 0.5; + } + + // Dessiner le clignotant + if (length(vec2(float(x) - blinkX, float(y) - blinkY)) < 3.0) { + vec3 blinkColor = vec3(1.0, 0.7, 0.0); // Orange + data_0[p] = 0xFF000000 | (int(blinkColor.r * 255.0) << 16) | (int(blinkColor.g * 255.0) << 8) | int(blinkColor.b * 255.0); + } + } + + // Roues + float frontWheelX, rearWheelX; + if (goingRight) { + frontWheelX = carPosX + CAR_WIDTH * 0.75; + rearWheelX = carPosX + CAR_WIDTH * 0.25; + } else { + // Inversé pour les voitures allant vers la gauche + frontWheelX = carPosX + CAR_WIDTH * 0.25; + rearWheelX = carPosX + CAR_WIDTH * 0.75; + } + + float wheelY = carPosY + CAR_HEIGHT; + + float distFrontWheel = length(vec2(float(x) - frontWheelX, float(y) - wheelY)); + float distRearWheel = length(vec2(float(x) - rearWheelX, float(y) - wheelY)); + + if (distFrontWheel <= WHEEL_RADIUS || distRearWheel <= WHEEL_RADIUS) { + vec3 wheelColor = vec3(0.1, 0.1, 0.1); // Noir + data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); + } + + // Faisceau des phares - direction dépendant du sens de circulation + float headlightX = frontLightX; + float headlightY = lightY; + + // Direction du faisceau (droite ou gauche selon le sens) + bool beamRight = goingRight; + + // Déterminer si une voiture est en face (croisement) + float beamIntensityMultiplier = 1.0; // Pleine puissance par défaut + float detectionDistance = 250.0; // Distance à laquelle les voitures détectent celles qui arrivent en face + + // Vérifier la proximité avec les voitures venant en sens inverse + for (int otherCarIdx = 0; otherCarIdx < CAR_COUNT; otherCarIdx++) { + if (otherCarIdx != carIdx && carDirections[otherCarIdx] != goingRight) { + // Calculer la distance entre les voitures + float distBetweenCars = length(carPositions[carIdx] - carPositions[otherCarIdx]); - vec3 lightColor = vec3(1.0, 0.9, 0.7) * intensity; + // Vérifier si les voitures sont face à face (pas seulement proches) + bool facingEachOther = false; - // Combiner la lumière avec la couleur existante - vec3 existingColor = vec3( - float((data_0[p] >> 16) & 0xFF) / 255.0, - float((data_0[p] >> 8) & 0xFF) / 255.0, - float(data_0[p] & 0xFF) / 255.0 - ); + if (goingRight) { + // Si la voiture actuelle va à droite, l'autre doit être devant elle + facingEachOther = (carPositions[otherCarIdx].x > carPositions[carIdx].x); + } else { + // Si la voiture actuelle va à gauche, l'autre doit être devant elle + facingEachOther = (carPositions[otherCarIdx].x < carPositions[carIdx].x); + } - vec3 finalColor = existingColor + lightColor; - finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + // Réduire l'intensité si les voitures sont proches et en face + if (facingEachOther && distBetweenCars < detectionDistance) { + // Réduction progressive de l'intensité des phares à l'approche + float proximityFactor = distBetweenCars / detectionDistance; + // Réduction entre 30% (feux de croisement) et 100% (pleins phares) + beamIntensityMultiplier = min(beamIntensityMultiplier, 0.3 + proximityFactor * 0.7); + } + } + } + + // Condition pour dessiner le faisceau dans la bonne direction + if ((beamRight && float(x) > headlightX) || (!beamRight && float(x) < headlightX)) { + float dx = float(x) - headlightX; + float dy = float(y) - headlightY; + + // Inverser l'angle pour les voitures allant vers la gauche + float angle; + if (beamRight) { + angle = atan(dy / dx); + } else { + angle = atan(dy / -dx); // Note le signe négatif pour dx + } + + // Ajuster l'angle du faisceau en fonction de l'intensité (feux de croisement plus étroits et vers le bas) + float maxAngle = mix(0.2, 0.3, beamIntensityMultiplier); + float minAngle = mix(-0.1, -0.3, beamIntensityMultiplier); + + if (angle >= minAngle && angle <= maxAngle) { + float dist = length(vec2(dx, dy)); + // Ajuster la portée en fonction de l'intensité + float maxDist = mix(80.0, 150.0, beamIntensityMultiplier); - data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + if (dist < maxDist) { + float intensity = 1.0 - (dist / maxDist); + // Appliquer le multiplicateur d'intensité pour les croisements + intensity = intensity * intensity * 0.4 * beamIntensityMultiplier; + + // Couleur légèrement plus jaune pour les feux de croisement + vec3 beamColor = mix(vec3(1.0, 0.8, 0.5), vec3(1.0, 0.9, 0.7), beamIntensityMultiplier); + vec3 lightColor = beamColor * intensity; + + // Combiner la lumière avec la couleur existante + vec3 existingColor = vec3( + float((data_0[p] >> 16) & 0xFF) / 255.0, + float((data_0[p] >> 8) & 0xFF) / 255.0, + float(data_0[p] & 0xFF) / 255.0 + ); + + vec3 finalColor = existingColor + lightColor; + finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + + data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); + } } } } -} } \ No newline at end of file From b59b6bb0a129b001c2fbc177fea0bdb5bcaa937e Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Tue, 18 Mar 2025 00:32:25 +0100 Subject: [PATCH 09/10] cars colors updated --- .../car_in_the_night/car_in_the_night.cpp | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index c110759..be506a1 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -347,10 +347,51 @@ void main() { if (float(x) >= carPosX && float(x) < carPosX + CAR_WIDTH && float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT) { - // Couleur de la voiture - variée selon l'index - vec3 carColor = vec3(0.1 + hash(float(carIdx) * 42.0) * 0.2, - 0.1 + hash(float(carIdx) * 17.0) * 0.1, - 0.2 + hash(float(carIdx) * 29.0) * 0.3); +// Couleur de la voiture - couleurs de voitures de sport +vec3 carColor; +// Ajouter un effet de reflet selon la position sur la carrosserie +float normalizedX = (float(x) - carPosX) / CAR_WIDTH; +float normalizedY = (float(y) - carPosY) / CAR_HEIGHT; +float reflectionIntensity = 0.15 * pow(sin(normalizedX * 3.14), 2.0) * pow(sin(normalizedY * 3.14), 2.0); +carColor = carColor + vec3(reflectionIntensity); + +// Limiter les valeurs de couleur pour éviter qu'elles ne dépassent 1.0 +carColor = min(carColor, vec3(1.0)); + +float carType = hash(float(carIdx) * 42.0); // Valeur aléatoire entre 0 et 1 + +if (carType < 0.15) { + // Rouge Ferrari + carColor = vec3(0.8, 0.1, 0.0); +} else if (carType < 0.3) { + // Jaune Lamborghini + carColor = vec3(0.95, 0.8, 0.0); +} else if (carType < 0.45) { + // Bleu Bugatti + carColor = vec3(0.0, 0.1, 0.6); +} else if (carType < 0.55) { + // Vert Jaguar Racing + carColor = vec3(0.0, 0.55, 0.27); +} else if (carType < 0.65) { + // Orange McLaren + carColor = vec3(1.0, 0.3, 0.0); +} else if (carType < 0.75) { + // Gris Aston Martin + carColor = vec3(0.4, 0.4, 0.45); +} else if (carType < 0.85) { + // Blanc nacré Porsche + carColor = vec3(0.95, 0.95, 0.97); +} else if (carType < 0.92) { + // Noir brillant Mercedes AMG + carColor = vec3(0.05, 0.05, 0.05); +} else { + // Violet Koenigsegg + carColor = vec3(0.35, 0.0, 0.35); +} + +// Ajout d'un effet métallisé léger +float metallic = 0.05 + hash(float(carIdx) * 29.0) * 0.1; +carColor = carColor + vec3(metallic); // Vitres if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && @@ -358,7 +399,7 @@ void main() { carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées } - data_0[p] = 0xFF000000 | (int(carColor.r * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.b * 255.0); + data_0[p] = 0xFF000000 | (int(carColor.b * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.r * 255.0); } // Positions des phares et feux arrière selon la direction From 3afc5ea2c4750e23f16825c5a7cac627ece1cabc Mon Sep 17 00:00:00 2001 From: Guessoum Abdenour Date: Tue, 18 Mar 2025 02:15:25 +0100 Subject: [PATCH 10/10] UTF-8 errors resolved --- examples/board/board.tscn | 1 - .../car_in_the_night/car_in_the_night.cpp | 186 +++++++++--------- .../car_in_the_night/car_in_the_night.tscn | 3 +- 3 files changed, 95 insertions(+), 95 deletions(-) diff --git a/examples/board/board.tscn b/examples/board/board.tscn index 0e30c27..4ceaf7a 100644 --- a/examples/board/board.tscn +++ b/examples/board/board.tscn @@ -7,7 +7,6 @@ [node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] script = ExtResource("1_7dugu") -WSX = 512 WSY = 256 glsl_file = "res://examples/board/board.cpp" GLSL_code = "" diff --git a/examples/car_in_the_night/car_in_the_night.cpp b/examples/car_in_the_night/car_in_the_night.cpp index be506a1..5274609 100644 --- a/examples/car_in_the_night/car_in_the_night.cpp +++ b/examples/car_in_the_night/car_in_the_night.cpp @@ -5,7 +5,7 @@ #define RAIN_DROPS 500 #define SPLASH_PARTICLES 20 #define CAR_COUNT 8 // Plus de voitures pour remplir les 4 voies -#define STAR_COUNT 200 // Nombre d'étoiles dans le ciel +#define STAR_COUNT 200 // Nombre d'etoiles dans le ciel float hash(float n) { return fract(sin(n) * 43758.5453123); } @@ -20,7 +20,7 @@ float noise(vec2 p) { ); } -// Fonction pour créer un bruit fractal (FBM - Fractional Brownian Motion) +// Fonction pour creer un bruit fractal (FBM - Fractional Brownian Motion) float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; @@ -39,63 +39,63 @@ void main() { int y = int(gl_GlobalInvocationID.y); int p = x + y * int(WSX); - // Définir les limites des différentes zones - route descendue et ciel étoilé agrandi + // Definir les limites des differentes zones - route descendue et ciel etoile agrandi float skyLimit = float(WSX) / 2.5; // Limite entre ciel et route (plus grande portion de ciel) float laneY1 = skyLimit + 10.0; // Voie du haut (voitures vers la droite - lente) float laneY4 = laneY1 + 115; // Voie du bas (voitures vers la gauche - lente) - float grassStart = laneY4 + 20.0; // Début de l'herbe après la route (portion d'herbe réduite) + float grassStart = laneY4 + 20.0; // Debut de l'herbe apres la route (portion d'herbe reduite) - // Ciel nocturne avec étoiles + // Ciel nocturne avec etoiles if (y < int(skyLimit)) { - // Dégradé pour le ciel nocturne (plus foncé en haut, plus clair vers l'horizon) + // Degrade pour le ciel nocturne (plus fonce en haut, plus clair vers l'horizon) float skyGradient = float(y) / skyLimit; vec3 skyColor = mix( - vec3(0.25, 0.1, 0.05), // Couleur du ciel en haut (bleu foncé) - vec3(0.28, 0.15, 0.08), // Couleur du ciel vers l'horizon (légèrement plus claire) + vec3(0.25, 0.1, 0.05), // Couleur du ciel en haut (bleu fonce) + vec3(0.28, 0.15, 0.08), // Couleur du ciel vers l'horizon (legerement plus claire) skyGradient ); // Appliquer la couleur de base du ciel data_0[p] = 0xFF000000 | (int(skyColor.r * 255.0) << 16) | (int(skyColor.g * 255.0) << 8) | int(skyColor.b * 255.0); - // Ajouter des étoiles + // Ajouter des etoiles for (int i = 0; i < STAR_COUNT; i++) { float starSeed = float(i) * 42.758; float starX = hash(starSeed) * float(WSX); float starY = hash(starSeed + 7.3219) * skyLimit; - // Distance à l'étoile + // Distance a l'etoile float distToStar = length(vec2(float(x) - starX, float(y) - starY)); - // Taille variable des étoiles + // Taille variable des etoiles float starRadius = 0.5 + hash(starSeed + 13.7) * 1.5; - // Luminosité variable des étoiles + // Luminosite variable des etoiles float starBrightness = 0.5 + hash(starSeed + 21.13) * 0.5; - // Faire scintiller les étoiles avec le temps + // Faire scintiller les etoiles avec le temps float flicker = 0.7 + 0.3 * sin(float(step) * 0.05 + hash(starSeed) * 6.28); starBrightness *= flicker; - // Dessiner l'étoile avec un dégradé doux + // Dessiner l'etoile avec un degrade doux if (distToStar < starRadius) { float starIntensity = (1.0 - distToStar / starRadius) * starBrightness; - vec3 starColor = vec3(0.9, 0.95, 1.0) * starIntensity; // Blanc légèrement bleuté + vec3 starColor = vec3(0.9, 0.95, 1.0) * starIntensity; // Blanc legerement bleute - // Pour quelques étoiles, ajouter une teinte colorée + // Pour quelques etoiles, ajouter une teinte coloree if (hash(starSeed + 33.97) > 0.85) { // Rouge, bleu ou jaune selon le hash float colorType = hash(starSeed + 50.31); if (colorType < 0.33) { - starColor = mix(starColor, vec3(1.0, 0.7, 0.7), 0.4); // Rougeâtre + starColor = mix(starColor, vec3(1.0, 0.7, 0.7), 0.4); // Rougeatre } else if (colorType < 0.66) { - starColor = mix(starColor, vec3(0.7, 0.7, 1.0), 0.4); // Bleuâtre + starColor = mix(starColor, vec3(0.7, 0.7, 1.0), 0.4); // Bleuatre } else { - starColor = mix(starColor, vec3(1.0, 1.0, 0.7), 0.4); // Jaunâtre + starColor = mix(starColor, vec3(1.0, 1.0, 0.7), 0.4); // Jaunatre } } - // Mélanger avec la couleur existante + // Melanger avec la couleur existante vec3 existingColor = vec3( float((data_0[p] >> 16) & 0xFF) / 255.0, float((data_0[p] >> 8) & 0xFF) / 255.0, @@ -103,7 +103,7 @@ void main() { ); vec3 finalColor = existingColor + starColor; - finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + finalColor = min(finalColor, vec3(1.0)); // Limiter a 1.0 data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); } @@ -112,13 +112,13 @@ void main() { // Zone d'herbe en bas else if (y >= int(grassStart)) { - // Utiliser fbm pour créer une texture d'herbe + // Utiliser fbm pour creer une texture d'herbe float grassNoise = fbm(vec2(float(x) * 0.05, float(y) * 0.05 + float(step) * 0.001)); // Couleur de base de l'herbe avec variation vec3 grassColor = vec3(0.05 + grassNoise * 0.04, 0.2 + grassNoise * 0.1, 0.05 + grassNoise * 0.02); - // Assombrir progressivement l'herbe en s'éloignant de la route + // Assombrir progressivement l'herbe en s'eloignant de la route float distFromRoad = (float(y) - grassStart) / (float(WSX) - grassStart); grassColor = mix(grassColor, vec3(0.02, 0.08, 0.02), distFromRoad * 0.7); @@ -130,34 +130,34 @@ void main() { data_0[p] = 0xFF000000 | (int(grassColor.r * 255.0) << 16) | (int(grassColor.g * 255.0) << 8) | int(grassColor.b * 255.0); } - // Lune améliorée + // Lune amelioree float moonX = float(WSX) * 0.85; float moonY = float(WSX) * 0.10; float moonRadius = float(WSX) * 0.05; float distToMoon = length(vec2(float(x) - moonX, float(y) - moonY)); - // Rayon normalisé pour les effets de surface + // Rayon normalise pour les effets de surface float normalizedRadius = distToMoon / moonRadius; if (distToMoon < moonRadius) { - // Utiliser FBM pour des détails de surface plus complexes + // Utiliser FBM pour des details de surface plus complexes vec2 moonUV = vec2(float(x) - moonX, float(y) - moonY) / moonRadius; - // Créer des cratères plus détaillés + // Creer des crateres plus detailles float largeScale = fbm(moonUV * 5.0) * 0.15; // Grandes formations float mediumScale = fbm(moonUV * 10.0) * 0.1; // Formations moyennes - float smallScale = fbm(moonUV * 20.0) * 0.05; // Petits détails + float smallScale = fbm(moonUV * 20.0) * 0.05; // Petits details - // Combiner les échelles pour créer une surface complexe + // Combiner les echelles pour creer une surface complexe float craterEffect = largeScale + mediumScale + smallScale; - // Ajouter un léger effet de limbe (bord plus brillant) + // Ajouter un leger effet de limbe (bord plus brillant) float limb = smoothstep(0.8, 1.0, normalizedRadius) * 0.15; - // Créer un dégradé du centre vers les bords pour donner plus de profondeur + // Creer un degrade du centre vers les bords pour donner plus de profondeur float depthGradient = mix(0.15, 0.0, normalizedRadius * 0.7); - // Couleur de base de la lune avec teinte légèrement bleutée + // Couleur de base de la lune avec teinte legerement bleutee vec3 moonBaseColor = vec3(0.95, 0.95, 0.92); // Appliquer les effets de surface et de profondeur @@ -169,25 +169,25 @@ void main() { data_0[p] = 0xFF000000 | (int(moonColor.r * 255.0) << 16) | (int(moonColor.g * 255.0) << 8) | int(moonColor.b * 255.0); } else if (distToMoon < moonRadius * 2.0) { - // Halo extérieur amélioré avec gradient plus doux + // Halo exterieur ameliore avec gradient plus doux float haloDistance = (distToMoon - moonRadius) / moonRadius; float haloIntensity = pow(1.0 - haloDistance, 2.0) * 0.4; - // Faire varier légèrement la couleur du halo + // Faire varier legerement la couleur du halo vec3 innerHaloColor = vec3(0.95, 0.95, 0.9); // Plus proche de la couleur de la lune - vec3 outerHaloColor = vec3(0.7, 0.75, 0.9); // Teinte bleutée pour l'extérieur du halo + vec3 outerHaloColor = vec3(0.7, 0.75, 0.9); // Teinte bleutee pour l'exterieur du halo - // Mélanger entre les couleurs intérieures et extérieures du halo + // Melanger entre les couleurs interieures et exterieures du halo vec3 haloColor = mix(outerHaloColor, innerHaloColor, 1.0 - haloDistance); - // Récupérer la couleur existante (ciel ou étoiles) + // Recuperer la couleur existante (ciel ou etoiles) vec3 existingColor = vec3( float((data_0[p] >> 16) & 0xFF) / 255.0, float((data_0[p] >> 8) & 0xFF) / 255.0, float(data_0[p] & 0xFF) / 255.0 ); - // Mélanger avec la couleur de fond selon l'intensité + // Melanger avec la couleur de fond selon l'intensite vec3 finalHaloColor = mix(existingColor, haloColor, haloIntensity); data_0[p] = 0xFF000000 | (int(finalHaloColor.r * 255.0) << 16) | (int(finalHaloColor.g * 255.0) << 8) | int(finalHaloColor.b * 255.0); @@ -210,7 +210,7 @@ void main() { float cloudIntensity = (1.0 - cloudDist) * 0.3; float moonInfluence = 0.0; - // Nuages éclairés par la lune + // Nuages eclaires par la lune float distToMoonFromCloud = length(vec2(cloudX - moonX, cloudY - moonY)); if (distToMoonFromCloud < moonRadius * 5.0) { moonInfluence = max(0.0, 0.5 - distToMoonFromCloud / (moonRadius * 10.0)); @@ -218,7 +218,7 @@ void main() { vec3 cloudColor = mix( vec3(0.9, 0.9, 0.9), // Nuages clairs - vec3(0.6, 0.6, 0.7), // Nuages légèrement ombrés + vec3(0.6, 0.6, 0.7), // Nuages legerement ombres moonInfluence ); @@ -233,24 +233,24 @@ void main() { } } - // Délimiter les voies - ajustées à la nouvelle position de la route + // Delimiter les voies - ajustees a la nouvelle position de la route float laneY2 = laneY1 + 35; // Voie du haut (voitures vers la droite - rapide) float laneY3 = laneY1 + 80; // Voie du bas (voitures vers la gauche - rapide) - // Route mouillée + // Route mouillee if (y >= int(skyLimit) && y < int(grassStart)) { - // Effet de route mouillée avec reflets + // Effet de route mouillee avec reflets vec3 roadColor = vec3(0.08, 0.08, 0.07); - // Ajouter un peu de reflet pour la route mouillée + // Ajouter un peu de reflet pour la route mouillee float reflectFactor = noise(vec2(float(x) * 0.02, float(y) * 0.02)) * 0.03; roadColor = roadColor + vec3(reflectFactor); data_0[p] = 0xFF000000 | (int(roadColor.r * 255.0) << 16) | (int(roadColor.g * 255.0) << 8) | int(roadColor.b * 255.0); - // Ligne entre les voies allant dans le même sens + // Ligne entre les voies allant dans le meme sens if (y > int(laneY1) + 30 && y < int(laneY1) + 33) { - // Ligne pointillée pour voies allant dans le même sens (droite) + // Ligne pointillee pour voies allant dans le meme sens (droite) if (int(float(x) / 20.0) % 2 == 0) { vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); @@ -264,9 +264,9 @@ void main() { data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); } - // Ligne entre les voies allant dans le même sens + // Ligne entre les voies allant dans le meme sens if (y > int(laneY3) + 30 && y < int(laneY3) + 33) { - // Ligne pointillée pour voies allant dans le même sens (gauche) + // Ligne pointillee pour voies allant dans le meme sens (gauche) if (int(float(x) / 20.0) % 2 == 0) { vec3 lineColor = vec3(0.9, 0.9, 0.9); // Blanc data_0[p] = 0xFF000000 | (int(lineColor.r * 255.0) << 16) | (int(lineColor.g * 255.0) << 8) | int(lineColor.b * 255.0); @@ -280,14 +280,14 @@ void main() { // Premier parcours pour calculer les positions for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { - // Déterminer la direction (droite ou gauche) et la voie (lente ou rapide) + // Determiner la direction (droite ou gauche) et la voie (lente ou rapide) bool goingRight = (carIdx < CAR_COUNT / 2); carDirections[carIdx] = goingRight; // Les voitures avec indices pairs vont sur la voie "lente", les impaires sur la voie "rapide" bool fastLane = (carIdx % 2 == 1); - // Différentes vitesses selon la voie et avec variation individuelle + // Differentes vitesses selon la voie et avec variation individuelle float baseSpeed = fastLane ? 1.4 : 0.8; // Les voies rapides sont 1.75x plus rapides float speedMultiplier = baseSpeed + hash(float(carIdx) * 10.0) * 0.3; // Variation individuelle @@ -299,28 +299,28 @@ void main() { carPosY = fastLane ? laneY3 - 10.0 : laneY4 - 10.0; } - // Position X avec décalage et direction + // Position X avec decalage et direction float carOffset = float(carIdx % (CAR_COUNT/2)) * (float(WSX) + CAR_WIDTH) / float(CAR_COUNT/2) * 0.8; float carPosX; if (goingRight) { - // Voitures allant de gauche à droite + // Voitures allant de gauche a droite carPosX = mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH) - CAR_WIDTH; } else { - // Voitures allant de droite à gauche + // Voitures allant de droite a gauche carPosX = float(WSX) - mod(float(step) * SPEED * speedMultiplier + carOffset, float(WSX) + CAR_WIDTH); } - // Stocker la position pour les calculs de proximité + // Stocker la position pour les calculs de proximite carPositions[carIdx] = vec2(carPosX + CAR_WIDTH * 0.5, carPosY + CAR_HEIGHT * 0.5); } // Dessiner les voitures dans les deux sens for (int carIdx = 0; carIdx < CAR_COUNT; carIdx++) { - // Récupérer les informations déjà calculées + // Recuperer les informations deja calculees bool goingRight = carDirections[carIdx]; - // Déterminer si c'est une voiture sur voie rapide + // Determiner si c'est une voiture sur voie rapide bool fastLane = (carIdx % 2 == 1); // Position Y selon la direction et la voie @@ -331,7 +331,7 @@ void main() { carPosY = fastLane ? laneY3 - 10.0 : laneY4 - 10.0; } - // Récupérer la vitesse et l'offset + // Recuperer la vitesse et l'offset float baseSpeed = fastLane ? 1.4 : 0.8; float speedMultiplier = baseSpeed + hash(float(carIdx) * 10.0) * 0.3; float carOffset = float(carIdx % (CAR_COUNT/2)) * (float(WSX) + CAR_WIDTH) / float(CAR_COUNT/2) * 0.8; @@ -355,10 +355,10 @@ float normalizedY = (float(y) - carPosY) / CAR_HEIGHT; float reflectionIntensity = 0.15 * pow(sin(normalizedX * 3.14), 2.0) * pow(sin(normalizedY * 3.14), 2.0); carColor = carColor + vec3(reflectionIntensity); -// Limiter les valeurs de couleur pour éviter qu'elles ne dépassent 1.0 +// Limiter les valeurs de couleur pour eviter qu'elles ne depassent 1.0 carColor = min(carColor, vec3(1.0)); -float carType = hash(float(carIdx) * 42.0); // Valeur aléatoire entre 0 et 1 +float carType = hash(float(carIdx) * 42.0); // Valeur aleatoire entre 0 et 1 if (carType < 0.15) { // Rouge Ferrari @@ -379,7 +379,7 @@ if (carType < 0.15) { // Gris Aston Martin carColor = vec3(0.4, 0.4, 0.45); } else if (carType < 0.85) { - // Blanc nacré Porsche + // Blanc nacre Porsche carColor = vec3(0.95, 0.95, 0.97); } else if (carType < 0.92) { // Noir brillant Mercedes AMG @@ -389,26 +389,26 @@ if (carType < 0.15) { carColor = vec3(0.35, 0.0, 0.35); } -// Ajout d'un effet métallisé léger +// Ajout d'un effet metallise leger float metallic = 0.05 + hash(float(carIdx) * 29.0) * 0.1; carColor = carColor + vec3(metallic); // Vitres if (float(x) >= carPosX + CAR_WIDTH * 0.25 && float(x) < carPosX + CAR_WIDTH * 0.75 && float(y) >= carPosY && float(y) < carPosY + CAR_HEIGHT * 0.5) { - carColor = vec3(0.2, 0.2, 0.3); // Vitres teintées + carColor = vec3(0.2, 0.2, 0.3); // Vitres teintees } data_0[p] = 0xFF000000 | (int(carColor.b * 255.0) << 16) | (int(carColor.g * 255.0) << 8) | int(carColor.r * 255.0); } - // Positions des phares et feux arrière selon la direction + // Positions des phares et feux arriere selon la direction float frontLightX, rearLightX; if (goingRight) { frontLightX = carPosX + CAR_WIDTH * 0.9; rearLightX = carPosX + CAR_WIDTH * 0.1; } else { - // Inversé pour les voitures allant vers la gauche + // Inverse pour les voitures allant vers la gauche frontLightX = carPosX + CAR_WIDTH * 0.1; rearLightX = carPosX + CAR_WIDTH * 0.9; } @@ -417,10 +417,10 @@ carColor = carColor + vec3(metallic); float frontLightRadius = 4.0; float rearLightRadius = 3.0; - // Déterminer si la voiture est en croisement pour ajuster la couleur des phares + // Determiner si la voiture est en croisement pour ajuster la couleur des phares float headlightIntensity = 1.0; - // Vérifier la proximité avec les voitures venant en sens inverse + // Verifier la proximite avec les voitures venant en sens inverse for (int otherCarIdx = 0; otherCarIdx < CAR_COUNT; otherCarIdx++) { if (otherCarIdx != carIdx && carDirections[otherCarIdx] != goingRight) { float distBetweenCars = length(carPositions[carIdx] - carPositions[otherCarIdx]); @@ -441,7 +441,7 @@ carColor = carColor + vec3(metallic); // Phares avant (plus ou moins intenses selon le croisement) if (length(vec2(float(x) - frontLightX, float(y) - lightY)) < frontLightRadius) { - // Couleur légèrement plus jaune/orange pour les feux de croisement + // Couleur legerement plus jaune/orange pour les feux de croisement vec3 fullBeamColor = vec3(1.0, 0.9, 0.7); // Jaune chaud (pleins phares) vec3 lowBeamColor = vec3(0.9, 0.8, 0.5); // Plus orange (feux de croisement) vec3 lightColor = mix(lowBeamColor, fullBeamColor, headlightIntensity); @@ -449,7 +449,7 @@ carColor = carColor + vec3(metallic); data_0[p] = 0xFF000000 | (int(lightColor.r * 255.0) << 16) | (int(lightColor.g * 255.0) << 8) | int(lightColor.b * 255.0); } - // Feux arrière (rouges) + // Feux arriere (rouges) if (length(vec2(float(x) - rearLightX, float(y) - lightY)) < rearLightRadius) { vec3 redLight = vec3(1.0, 0.1, 0.1); // Rouge data_0[p] = 0xFF000000 | (int(redLight.r * 255.0) << 16) | (int(redLight.g * 255.0) << 8) | int(redLight.b * 255.0); @@ -459,18 +459,18 @@ carColor = carColor + vec3(metallic); bool shouldBlink = false; bool blinkOn = false; - // Déterminer si la voiture doit clignoter + // Determiner si la voiture doit clignoter // Les voitures sur voie rapide qui sont sur le point de sortir vont clignoter pour indiquer un changement de voie if (fastLane) { - // Probabilité que la voiture veuille changer de voie + // Probabilite que la voiture veuille changer de voie float changeLaneProbability = hash(float(carIdx) * 42.0 + float(step) * 0.01); - // Vérifier si la voiture est sur le point de changer de voie + // Verifier si la voiture est sur le point de changer de voie if (changeLaneProbability > 0.7) { // Activer le clignotant shouldBlink = true; - // Séquence de clignotement (1 seconde allumé, 1 seconde éteint) + // Sequence de clignotement (1 seconde allume, 1 seconde eteint) blinkOn = (int(float(step) / 30.0) % 2 == 0); } } @@ -480,11 +480,11 @@ carColor = carColor + vec3(metallic); float blinkX, blinkY; if (goingRight) { - // Clignotant à droite pour voiture allant vers la droite (veut se rabattre à droite) + // Clignotant a droite pour voiture allant vers la droite (veut se rabattre a droite) blinkX = carPosX + CAR_WIDTH * 0.9; blinkY = carPosY + CAR_HEIGHT * 0.5; } else { - // Clignotant à gauche pour voiture allant vers la gauche (veut se rabattre à gauche) + // Clignotant a gauche pour voiture allant vers la gauche (veut se rabattre a gauche) blinkX = carPosX + CAR_WIDTH * 0.1; blinkY = carPosY + CAR_HEIGHT * 0.5; } @@ -502,7 +502,7 @@ carColor = carColor + vec3(metallic); frontWheelX = carPosX + CAR_WIDTH * 0.75; rearWheelX = carPosX + CAR_WIDTH * 0.25; } else { - // Inversé pour les voitures allant vers la gauche + // Inverse pour les voitures allant vers la gauche frontWheelX = carPosX + CAR_WIDTH * 0.25; rearWheelX = carPosX + CAR_WIDTH * 0.75; } @@ -517,39 +517,39 @@ carColor = carColor + vec3(metallic); data_0[p] = 0xFF000000 | (int(wheelColor.r * 255.0) << 16) | (int(wheelColor.g * 255.0) << 8) | int(wheelColor.b * 255.0); } - // Faisceau des phares - direction dépendant du sens de circulation + // Faisceau des phares - direction dependant du sens de circulation float headlightX = frontLightX; float headlightY = lightY; // Direction du faisceau (droite ou gauche selon le sens) bool beamRight = goingRight; - // Déterminer si une voiture est en face (croisement) - float beamIntensityMultiplier = 1.0; // Pleine puissance par défaut - float detectionDistance = 250.0; // Distance à laquelle les voitures détectent celles qui arrivent en face + // Determiner si une voiture est en face (croisement) + float beamIntensityMultiplier = 1.0; // Pleine puissance par defaut + float detectionDistance = 250.0; // Distance a laquelle les voitures detectent celles qui arrivent en face - // Vérifier la proximité avec les voitures venant en sens inverse + // Verifier la proximite avec les voitures venant en sens inverse for (int otherCarIdx = 0; otherCarIdx < CAR_COUNT; otherCarIdx++) { if (otherCarIdx != carIdx && carDirections[otherCarIdx] != goingRight) { // Calculer la distance entre les voitures float distBetweenCars = length(carPositions[carIdx] - carPositions[otherCarIdx]); - // Vérifier si les voitures sont face à face (pas seulement proches) + // Verifier si les voitures sont face a face (pas seulement proches) bool facingEachOther = false; if (goingRight) { - // Si la voiture actuelle va à droite, l'autre doit être devant elle + // Si la voiture actuelle va a droite, l'autre doit etre devant elle facingEachOther = (carPositions[otherCarIdx].x > carPositions[carIdx].x); } else { - // Si la voiture actuelle va à gauche, l'autre doit être devant elle + // Si la voiture actuelle va a gauche, l'autre doit etre devant elle facingEachOther = (carPositions[otherCarIdx].x < carPositions[carIdx].x); } - // Réduire l'intensité si les voitures sont proches et en face + // Reduire l'intensite si les voitures sont proches et en face if (facingEachOther && distBetweenCars < detectionDistance) { - // Réduction progressive de l'intensité des phares à l'approche + // Reduction progressive de l'intensite des phares a l'approche float proximityFactor = distBetweenCars / detectionDistance; - // Réduction entre 30% (feux de croisement) et 100% (pleins phares) + // Reduction entre 30% (feux de croisement) et 100% (pleins phares) beamIntensityMultiplier = min(beamIntensityMultiplier, 0.3 + proximityFactor * 0.7); } } @@ -565,28 +565,28 @@ carColor = carColor + vec3(metallic); if (beamRight) { angle = atan(dy / dx); } else { - angle = atan(dy / -dx); // Note le signe négatif pour dx + angle = atan(dy / -dx); // Note le signe negatif pour dx } - // Ajuster l'angle du faisceau en fonction de l'intensité (feux de croisement plus étroits et vers le bas) + // Ajuster l'angle du faisceau en fonction de l'intensite (feux de croisement plus etroits et vers le bas) float maxAngle = mix(0.2, 0.3, beamIntensityMultiplier); float minAngle = mix(-0.1, -0.3, beamIntensityMultiplier); if (angle >= minAngle && angle <= maxAngle) { float dist = length(vec2(dx, dy)); - // Ajuster la portée en fonction de l'intensité + // Ajuster la portee en fonction de l'intensite float maxDist = mix(80.0, 150.0, beamIntensityMultiplier); if (dist < maxDist) { float intensity = 1.0 - (dist / maxDist); - // Appliquer le multiplicateur d'intensité pour les croisements + // Appliquer le multiplicateur d'intensite pour les croisements intensity = intensity * intensity * 0.4 * beamIntensityMultiplier; - // Couleur légèrement plus jaune pour les feux de croisement + // Couleur legerement plus jaune pour les feux de croisement vec3 beamColor = mix(vec3(1.0, 0.8, 0.5), vec3(1.0, 0.9, 0.7), beamIntensityMultiplier); vec3 lightColor = beamColor * intensity; - // Combiner la lumière avec la couleur existante + // Combiner la lumiere avec la couleur existante vec3 existingColor = vec3( float((data_0[p] >> 16) & 0xFF) / 255.0, float((data_0[p] >> 8) & 0xFF) / 255.0, @@ -594,7 +594,7 @@ carColor = carColor + vec3(metallic); ); vec3 finalColor = existingColor + lightColor; - finalColor = min(finalColor, vec3(1.0)); // Limiter à 1.0 + finalColor = min(finalColor, vec3(1.0)); // Limiter a 1.0 data_0[p] = 0xFF000000 | (int(finalColor.r * 255.0) << 16) | (int(finalColor.g * 255.0) << 8) | int(finalColor.b * 255.0); } diff --git a/examples/car_in_the_night/car_in_the_night.tscn b/examples/car_in_the_night/car_in_the_night.tscn index 133f9ed..3809820 100644 --- a/examples/car_in_the_night/car_in_the_night.tscn +++ b/examples/car_in_the_night/car_in_the_night.tscn @@ -4,6 +4,7 @@ [ext_resource type="Texture2D" uid="uid://demftcowdd5c6" path="res://examples/icon.svg" id="2_ec1t8"] [node name="car_in_the_night" type="Node2D"] +scale = Vector2(1978.73, -1431.95) [node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] script = ExtResource("1_osmo3") @@ -14,6 +15,6 @@ data = [NodePath("Icon")] metadata/_custom_type_script = "uid://c8esqdv0y26yp" [node name="Icon" type="Sprite2D" parent="ComputeShaderStudio2D"] -position = Vector2(576, 324.5) +position = Vector2(576, 323.5) scale = Vector2(9, 5.05469) texture = ExtResource("2_ec1t8")