From c0465113d07893c046b73fe7ed70bfea653058cc Mon Sep 17 00:00:00 2001 From: zeefaad Date: Sun, 28 Dec 2025 11:09:01 +0100 Subject: [PATCH] GPU processing --- main.c | 44 ++++++++++++++++++++++++++++++---- michelson.fs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 michelson.fs diff --git a/main.c b/main.c index cfc48e9..2d5f267 100644 --- a/main.c +++ b/main.c @@ -41,7 +41,7 @@ void DrawLaserBeam(Vector2 start, Vector2 end, Color color, float thickness) { DrawLineEx(start, end, thickness, color); } -void DrawInterferenceView(Michelson *mic, Rectangle rec) { +void DrawInterferenceViewCPU(Michelson *mic, Rectangle rec) { DrawRectangleRec((Rectangle){rec.x - 4, rec.y - 30, rec.width + 8, rec.height + 34}, COLOR_PANEL); //DrawText("ECRAN", rec.x, rec.y - 30, 20, WHITE); DrawText("ECRAN", rec.x, rec.y - 26, 20, COLOR_TEXT_DIM); @@ -93,6 +93,40 @@ void DrawInterferenceView(Michelson *mic, Rectangle rec) { DrawLine(cx, cy - 10, cx, cy + 10, Fade(WHITE, 0.5f)); } +void DrawInterferenceViewGPU(Michelson *mic, Rectangle rec, Shader shader) { + + DrawRectangleRec((Rectangle){rec.x - 4, rec.y - 30, rec.width + 8, rec.height + 34}, COLOR_PANEL); + DrawText("ECRAN", rec.x, rec.y - 26, 20, COLOR_TEXT_DIM); + + // Shader glsl + float centerX = rec.x + rec.width / 2.0f; + float centerY = rec.y + rec.height / 2.0f; + float center[2] = { centerX, centerY }; + float scrHeight = (float)GetScreenHeight(); + + // + SetShaderValue(shader, GetShaderLocation(shader, "center"), center, SHADER_UNIFORM_VEC2); + SetShaderValue(shader, GetShaderLocation(shader, "screenHeight"), &scrHeight, SHADER_UNIFORM_FLOAT); + + SetShaderValue(shader, GetShaderLocation(shader, "d1"), &mic->d1, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, GetShaderLocation(shader, "d2"), &mic->d2, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, GetShaderLocation(shader, "lambda"), &mic->lambda, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, GetShaderLocation(shader, "angleM1"), &mic->angleM1, SHADER_UNIFORM_FLOAT); + + // GPU + BeginShaderMode(shader); + DrawRectangleRec(rec, WHITE); + EndShaderMode(); + + DrawRectangleLinesEx(rec, 1, Fade(COLOR_ACCENT, 0.3f)); + DrawRectangleLinesEx(rec, 2, COLOR_PANEL); + + int cx = rec.x + rec.width / 2; + int cy = rec.y + rec.height / 2; + DrawLine(cx - 10, cy, cx + 10, cy, Fade(WHITE, 0.5f)); + DrawLine(cx, cy - 10, cx, cy + 10, Fade(WHITE, 0.5f)); +} + void DrawMichelsonSchema (Michelson *mic) { Vector2 c = mic->center; Color laserColor = WavelengthToColor(mic->lambda); @@ -231,6 +265,8 @@ int main () { InitWindow(1920, 1080, "Interferometre de Michelson"); SetTargetFPS(144); + Shader shader = LoadShader(0, "michelson.fs"); + Michelson mic = {0}; mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f }; mic.d1 = 250.0f; @@ -245,12 +281,12 @@ int main () { BeginDrawing(); ClearBackground(COLOR_BG); // Grille fond - for(int i=UI_WIDTH; i<1920; i+=100) DrawLine(i, 0, i, 1080, Fade(WHITE, 0.05f)); - for(int i=0; i<1080; i+=100) DrawLine(UI_WIDTH, i, 1920, i, Fade(WHITE, 0.05f)); + for(int i = UI_WIDTH; i < 1920; i += 100) DrawLine(i, 0, i, 1080, Fade(WHITE, 0.05f)); + for(int i = 0; i < 1080; i += 100) DrawLine(UI_WIDTH, i, 1920, i, Fade(WHITE, 0.05f)); DrawMichelsonSchema(&mic); DrawControlPanel(&mic); - DrawInterferenceView(&mic, screenViewBounds); + DrawInterferenceViewGPU(&mic, screenViewBounds, shader); EndDrawing(); } CloseWindow(); diff --git a/michelson.fs b/michelson.fs new file mode 100644 index 0000000..3d8cca1 --- /dev/null +++ b/michelson.fs @@ -0,0 +1,68 @@ +#version 330 + +// Entrées (de Raylib) +in vec2 fragTexCoord; +in vec4 fragColor; + +out vec4 finalColor; + +uniform vec2 center; +uniform float screenHeight; +uniform vec2 resolution; +uniform float d1; +uniform float d2; +uniform float lambda; +uniform float angleM1; + +const float PI = 3.14159265359; + +vec3 WavelengthToRGB(float l) { + float r = 0.0; float g = 0.0; float b = 0.0; + if (l >= 380.0 && l < 440.0) { r = -(l - 440.0) / (440.0 - 380.0); b = 1.0; } + else if (l >= 440.0 && l < 490.0) { g = (l - 440.0) / (490.0 - 440.0); b = 1.0; } + else if (l >= 490.0 && l < 510.0) { g = 1.0; b = -(l - 510.0) / (510.0 - 490.0); } + else if (l >= 510.0 && l < 580.0) { r = (l - 510.0) / (580.0 - 510.0); g = 1.0; } + else if (l >= 580.0 && l < 645.0) { r = 1.0; g = -(l - 645.0) / (645.0 - 580.0); } + else if (l >= 645.0 && l <= 780.0) { r = 1.0; } + + float factor = 1.0; + if (l >= 380.0 && l < 420.0) factor = 0.3 + 0.7 * (l - 380.0) / (420.0 - 380.0); + else if (l >= 380.0 && l <= 645.0) factor = 1.0; + else if (l > 700.0 && l <= 780.0) factor = 0.3 + 0.7 * (780.0 - l) / (780.0 - 700.0); + + return vec3(r * factor, g * factor, b * factor); +} + +void main() { + float pixelX = gl_FragCoord.x; + float pixelY = screenHeight - gl_FragCoord.y; + + // Diff de marche du à l'axe (2 * e) + micro -> nano + float deltaLnm = 2.0 * (d1 - d2) * 1000.0; + + float relX = (pixelX - center.x); + float relY = (pixelY - center.y); + + vec3 baseColorVec = WavelengthToRGB(lambda); + + // r^2 + float radiusSq = relX * relX + relY * relY; + + // Diff de marche lamme d'air 2 * e cos(i) mais petits angles => cos(i) ~ 1 - i^2/2 mais i ~ r/f et r^2 = x^2 + y^2 + float ringFactor = radiusSq * 0.065; + + // Diff de marche du au coin d'air + float wDelta = relX * angleM1 * 200.0; + + float currDelta = deltaLnm - ringFactor + wDelta; + + // Formule de Fresnel : I = I_0 * cos^2(phi) + float K = PI / lambda; + float phase = currDelta * K; + float intensity = cos(phase); + intensity = intensity * intensity; + + vec3 finalVec = baseColorVec * intensity; + + finalColor = vec4(finalVec, 1.0); +}