A scene with no vertices
The neon tunnel has no mesh, no vertex buffer, and no triangles at all. The entire corridor exists only as a mathematical function, evaluated fresh for every pixel, every frame, inside a GLSL fragment shader running on the graphics card. This style of rendering, raymarching, is what lets a scene this geometrically rich - endless repeating rings, glowing gradients, a moving camera - run in real time from a few dozen lines of shader code instead of a modelled 3D asset.
Signed distance fields: a formula that measures emptiness
The shader describes the tunnel’s walls with a signed distance function (SDF): a formula that, given any point in space, returns how far that point is from the nearest surface - positive if the point is outside the geometry, negative if it is inside. For a simple cylindrical tunnel of radius r, the distance from a point at radial distance rho from the tunnel’s central axis is just:
float sdTunnel(vec3 p, float r) {
float rho = length(p.xy); // radial distance from the tunnel's axis
return r - rho; // positive outside the wall, negative inside it
}
Sphere tracing: safe jumps instead of brute force
For every pixel, the shader casts one ray from the virtual camera through that pixel into the scene and repeatedly asks the SDF, "how far am I from the nearest surface right now?" Because that distance is guaranteed to be a safe radius with nothing closer, the ray can jump forward by exactly that amount without any risk of skipping through a wall - this technique is called sphere tracing. Repeating the step-and-query loop, typically 50 to 100 times per pixel, marches the ray steadily closer to a surface until the returned distance drops below a tiny threshold, at which point the shader treats that point as a hit and shades it.
float t = 0.0;
for (int i = 0; i < MAX_STEPS; i++) {
vec3 p = rayOrigin + rayDir * t;
float d = sceneSDF(p);
if (d < EPSILON) break; // close enough - treat as a hit
t += d; // safe jump: nothing is closer than d
}
Polar coordinates make the rings, modulo makes them infinite
The individual glowing rings come from converting a point's position around the tunnel’s circumference into a polar angle, then using a periodic function like sine or a repeating step pattern of that angle to carve bright and dark bands. The illusion of endless depth comes from a much simpler trick: before evaluating the distance field, the shader applies the modulo operator to the point’s position along the tunnel’s length, folding the entire infinite axis back into one short repeating segment. The scene geometry only ever needs to describe a single ring’s worth of tunnel; the modulo makes every segment reuse it, so the camera can fly forward forever through what is, underneath, a handful of lines of arithmetic.
Realistic Glow Simulation
Real neon glow comes from light scattering in the surrounding air and glass, which is expensive to simulate properly. The cheap approximation used here is to accumulate a small amount of extra brightness on every step of the raymarch based on how close that step's SDF value came to zero, even on steps that were not close enough to count as an actual hit. Points that pass near a bright ring’s edge without technically touching it still contribute a soft haze, and summing that contribution across all the marching steps for a pixel produces a convincing glow gradient at a fraction of the cost of true volumetric light scattering.
Frequently asked questions
Що таке raymarching і як він відрізняється від ray tracing?
Обидва запускають промінь з камери в сцену на піксель, але класичний ray tracing розв’язує точне перетин з вираженою геометрією, такою як трикутники або сфери. Raymarching замість цього робить кроки вздовж променя за допомогою підписаної функції відстані, яка вказує, наскільки безпечно стрибати без проходження крізь щось, повторюючи це до тих пір, поки не буде досягнуто достатньої близькості до поверхні, щоб вважати її ударом. Це добре підходить для сцен, описаних математичними формулами, а не полігональними сітками.
Чому тунель виглядає безмежним, хоча це простий повторюваний об’єкт?
Шейдер застосовує операцію modulo до відстані променя вздовж осі тунелю перед оцінкою поля відстаней, що згортає нескінченний ряд простору в один короткий повторюваний сегмент. Сцена повинна лише описувати один кільце, але оскільки кожен сегмент вздовж осі використовує одну й ту ж геометрію, результатом рендерингу виглядає так, ніби воно продовжується назавжди.
Як шейдер створює світлове світіння без реального джерела світла?
Замість освітлення сцени за допомогою змодельованого джерела світла та обчислення тіней, шейдер додає яскравість пікселю на основі того, наскільки близько пройдений raymarched шлях до яскравої поверхні, навіть на кроках, які не технічно влучали в неї. Точки, що проходять біля краю кільця, накопичують м’яке світіння пропорційне цій близькій відстаті, що значно дешевше справжнього розсіювання світла та дає характерний м’який неоновий туман.
Спробуйте наживо
Усе, що вище, працює прямо у вашому браузері — відкрийте Neon Tunnel і змінюйте параметри під час роботи. Нічого не встановлюється, нічого не завантажується на сервер, уся модель живе в одній вкладці.
▶ Відкрити симуляцію Neon Tunnel