Created
February 21, 2026 11:51
-
-
Save mrange/dbc92c3756df548cb73918281aacd1fd to your computer and use it in GitHub Desktop.
Spectre Playground Effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // "Nothing Special" shader by Mårten Rånge | |
| var terminal = new BrowserTerminal( | |
| AnsiConsole.Console, | |
| AnsiConsole.Profile.Width, | |
| AnsiConsole.Profile.Height); | |
| var renderer = new Renderer(terminal); | |
| var writer = AnsiConsole.Profile.Out.Writer; | |
| writer.Write("\x1b[?25l"); // Hide cursor | |
| var size = terminal.GetSize(); | |
| int W = size.Width, H = size.Height*2; | |
| for (int frame = 0;; frame++) | |
| { | |
| float time = frame * 0.05f; | |
| float halfW = W * 0.5f, halfH = H*0.5f; | |
| renderer.Draw((RenderContext ctx, TimeSpan elapsed) => | |
| { | |
| for (int y = 0; y < H; y+=2) | |
| { | |
| for (int x = 0; x < W; x++) | |
| { | |
| var color0 = GetColor(x,y, halfW, halfH, time); | |
| var color1 = GetColor(x,y+1, halfW, halfH, time); | |
| ctx.SetString(x, y/2, "\x2580", | |
| new Style(color0, color1), null); | |
| } | |
| } | |
| }); | |
| } | |
| writer.Write("\x1b[?25h"); // Show cursor | |
| Color GetColor(int x, int y, float halfW, float halfH, float time) | |
| { | |
| // Ray direction (normalized) | |
| float dx = x - halfW, dy = y - halfH, dz = (float)H; | |
| float len = MathF.Sqrt(dx * dx + dy * dy + dz * dz); | |
| dx /= len; dy /= len; dz /= len; | |
| float z = 0f, d; | |
| float ox = 0f, oy = 0f, oz = 0f; | |
| for (int i = 0; i < 66; i++) | |
| { | |
| // March along ray | |
| float px = z * dx; | |
| float py = z * dy; | |
| float pz = z * dz + time; | |
| float sx = px, sy = py, sz = pz; | |
| // Z-dependent domain rotation | |
| float c0 = MathF.Cos(0.4f * pz); | |
| float c1 = MathF.Cos(0.4f * pz + 11f); | |
| float c2 = MathF.Cos(0.4f * pz + 33f); | |
| float rx = c2 * py + c0 * px; | |
| float ry = c1 * px + c0 * py; | |
| px = rx; py = ry; | |
| // Fold into repeating unit cells | |
| px -= 0.5f; py -= 0.5f; pz -= 0.5f; | |
| px -= MathF.Round(px); | |
| py -= MathF.Round(py); | |
| pz -= MathF.Round(pz); | |
| // L8 norm SDF (approximates a rounded box) | |
| float qx = px * px, qy = py * py, qz = pz * pz; | |
| qx *= qx; qy *= qy; qz *= qz; | |
| float l8 = MathF.Sqrt(MathF.Sqrt(MathF.Sqrt( | |
| qx * qx + qy * qy + qz * qz))); | |
| d = MathF.FusedMultiplyAdd( | |
| 0.6f, MathF.Abs(l8 - 0.3f), 1e-3f); | |
| z += d; | |
| // Accumulate color based on proximity | |
| float v = MathF.FusedMultiplyAdd( | |
| 2f, MathF.Sqrt(sx * sx + sy * sy), 0.5f * sz); | |
| float invD = 1f / d; | |
| ox += invD * (1.1f + MathF.Sin(v + 2f)); | |
| oy += invD * (1.1f + MathF.Sin(v + 1f)); | |
| oz += invD * (1.1f + MathF.Sin(v)); | |
| } | |
| // Tone map with tanh | |
| ox *= 1e-4f; oy *= 1e-4f; oz *= 1e-4f; | |
| return new Color( | |
| (byte)(MathF.Tanh(ox) * 255), | |
| (byte)(MathF.Tanh(oy) * 255), | |
| (byte)(MathF.Tanh(oz) * 255)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment