diff --git a/examples/wind/ventSimulation.cpp b/examples/wind/ventSimulation.cpp new file mode 100644 index 0000000..e98b33e --- /dev/null +++ b/examples/wind/ventSimulation.cpp @@ -0,0 +1,101 @@ +void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + // Position et taille de l'obstacle (cercle au centre) + vec2 center = vec2(float(WSX) * 0.5, float(WSY) * 0.5); + float radius = float(min(WSX, WSY)) * 0.1; // 10% de la taille de l'écran + + // Position actuelle + vec2 pos = vec2(float(x), float(y)); + + // Vecteur du centre vers le point actuel + vec2 toPoint = pos - center; + + // Distance à l'obstacle + float distToObstacle = length(toPoint) - radius; + + // Couleur par défaut - fond noir + uint color = 0x000000AA; + + // Vérifier si le pixel est à l'intérieur de l'obstacle + if (distToObstacle <= 0.0) { + // Couleur de l'obstacle - gris foncé + color = 0x555555AA; + } else { + // Vérifier si nous sommes dans la zone d'ombre de l'obstacle + bool inShadow = false; + + // Si nous sommes à droite de l'obstacle + if (toPoint.x > 0.0) { + // Longueur totale de la zone d'ombre + float shadowLength = radius * 3.0; + + // Distance horizontale depuis le bord droit de l'obstacle + float shadowDistX = toPoint.x; + + if (shadowDistX < shadowLength) { + // Progression normalisée le long de la zone d'ombre (0 au début, 1 à la fin) + float t = shadowDistX / shadowLength; + + // Hauteur de la zone d'ombre, qui diminue progressivement et s'arrondit vers la fin + float shadowHeight; + + if (t < 0.7) { + // Première partie: hauteur constante + shadowHeight = radius; + } else { + // Dernière partie: réduction progressive avec courbe + // Utiliser une courbe pour créer un effet arrondi + float transition = (t - 0.7) / 0.3; // 0 au début de la transition, 1 à la fin + shadowHeight = radius * (1.0 - transition * transition); + } + + // Vérifier si nous sommes dans la zone d'ombre à cette position + if (abs(toPoint.y) < shadowHeight) { + inShadow = true; + // Dans la zone d'ombre, simplement noir (pas d'effet d'air) + color = 0x000000AA; + } + } + } + + // Si nous ne sommes pas dans la zone d'ombre, flux d'air normal + if (!inShadow) { + // Créer des lignes horizontales denses pour l'écoulement d'air + // Réduire la hauteur des lignes à 2 pixels (au lieu de 4) + // et réduire l'espacement à 2.5 pixels (au lieu de 5) + if (mod(float(y), 2.5) < 2.0) { + // Position x modifiée par step pour animation + float xAnimated = float(x) - float(step) * 1.5; + + // Déterminer si cette ligne est en contact avec l'obstacle + // Vérifier si la ligne traverse le même niveau Y que l'obstacle + bool lineHitsObstacle = (abs(pos.y - center.y) < radius); + + // Motif alterné pour rendre le mouvement visible + if (mod(xAnimated, 20.0) < 10.0) { + if (lineHitsObstacle && pos.x > center.x) { + // Après contact avec l'obstacle - rouge + color = 0xFF0000AA; // Rouge vif + } else { + // Bleu vif lumineux typique des logiciels de simulation + color = 0x3366FFAA; // Bleu vif lumineux + } + } else { + if (lineHitsObstacle && pos.x > center.x) { + // Après contact avec l'obstacle - rouge clair + color = 0xFF5555AA; // Rouge clair + } else { + // Version plus claire du même bleu + color = 0x66AAFFAA; // Bleu clair lumineux + } + } + } + } + } + + // Stocker la couleur + data_0[p] = int(color); +} \ No newline at end of file diff --git a/examples/wind/wind.tscn b/examples/wind/wind.tscn new file mode 100644 index 0000000..4b36b47 --- /dev/null +++ b/examples/wind/wind.tscn @@ -0,0 +1,85 @@ +[gd_scene load_steps=3 format=3 uid="uid://ch5rc8sw7pkvs"] + +[ext_resource type="Script" path="res://addons/compute_shader_studio/compute_shader_studio_2d.gd" id="1_1g222"] +[ext_resource type="Texture2D" uid="uid://byqwe7hublowc" path="res://icon.svg" id="2_4cfqx"] + +[node name="Node2D" type="Node2D"] + +[node name="ComputeShaderStudio2D" type="Node" parent="." node_paths=PackedStringArray("data")] +script = ExtResource("1_1g222") +GLSL_code = "void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + vec2 center = vec2(float(WSX) * 0.5, float(WSY) * 0.5); + float radius = float(min(WSX, WSY)) * 0.1; + + vec2 pos = vec2(float(x), float(y)); + + vec2 toPoint = pos - center; + + float distToObstacle = length(toPoint) - radius; + + uint color = 0x000000AA; + + if (distToObstacle <= 0.0) { + color = 0x555555AA; + } else { + bool inShadow = false; + + if (toPoint.x > 0.0) { + float shadowLength = radius * 3.0; + + float shadowDistX = toPoint.x; + + if (shadowDistX < shadowLength) { + float t = shadowDistX / shadowLength; + + float shadowHeight; + + if (t < 0.7) { + shadowHeight = radius; + } else { + float transition = (t - 0.7) / 0.3; + shadowHeight = radius * (1.0 - transition * transition); + } + + if (abs(toPoint.y) < shadowHeight) { + inShadow = true; + color = 0x000000AA; + } + } + } + + if (!inShadow) { + if (mod(float(y), 2.5) < 2.0) { + float xAnimated = float(x) - float(step) * 1.5; + + bool lineHitsObstacle = (abs(pos.y - center.y) < radius); + + if (mod(xAnimated, 20.0) < 10.0) { + if (lineHitsObstacle && pos.x > center.x) { + color = 0xFF0000AA; + } else { + color = 0x3366FFAA; + } + } else { + if (lineHitsObstacle && pos.x > center.x) { + color = 0xFF5555AA; + } else { + color = 0x66AAFFAA; + } + } + } + } + } + + data_0[p] = int(color); +}" +data = [NodePath("../Icon")] + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(561, 297.25) +scale = Vector2(8.75, 4.65235) +texture = ExtResource("2_4cfqx")