Skip to content

Latest commit

 

History

History
185 lines (133 loc) · 9.34 KB

File metadata and controls

185 lines (133 loc) · 9.34 KB

Methods & Techniques

A technical overview of the algorithms, tools, and rendering techniques used in the Hyperspace Tunnel demo.

Language & Toolchain

Component Technology
Language Fortran 2018 (gfortran 13+, nvfortran compatible)
Graphics API OpenGL 3.3+ Core Profile via iso_c_binding
Windowing GLFW 3 (cross-platform window + input)
Shaders GLSL 330 (loaded from files at runtime)
Build Single build.sh script, no CMake/Make needed

All OpenGL and GLFW calls go through hand-written iso_c_binding interfaces — roughly 140 function bindings covering shaders, buffers, textures, framebuffers, and input. No third-party Fortran-GL wrappers.

Rendering Pipeline

┌─────────────────────────────────────────────────────────────┐
│  CPU (Fortran)                                              │
│  ┌──────────┐  ┌────────┐  ┌──────────┐  ┌──────────────┐  │
│  │ Timeline │→ │ Camera │→ │ Tunnel   │→ │ Particles    │  │
│  │ evaluate │  │ update │  │ rebuild  │  │ spawn+update │  │
│  └──────────┘  └────────┘  └──────────┘  └──────────────┘  │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│  GPU (OpenGL / GLSL)                                        │
│  ┌──────────────┐   ┌────────────┐                          │
│  │ Tunnel draw  │ + │ Particles  │ → HDR Scene FBO          │
│  │ (triangles)  │   │ (GL_LINES) │   (RGBA16F)              │
│  └──────────────┘   └────────────┘                          │
│           │                                                 │
│           ▼                                                 │
│  ┌─────────────────────────────────────────────┐            │
│  │ Post-Processing Chain (fullscreen passes)   │            │
│  │                                             │            │
│  │  Bright Pass → Bloom Pyramid (3 levels)     │            │
│  │  → Separable Gaussian Blur (H + V)          │            │
│  │  → Final Composite:                         │            │
│  │     Chromatic Aberration                     │            │
│  │     Radial Motion Blur                       │            │
│  │     Bloom Combine                            │            │
│  │     Vignette                                 │            │
│  │     ACES Filmic Tonemap                      │            │
│  │     Film Grain                               │            │
│  │     Gamma Correction                         │            │
│  └─────────────────────────────────────────────┘            │
│           │                                                 │
│           ▼                                                 │
│      Backbuffer (screen)                                    │
└─────────────────────────────────────────────────────────────┘

Key Algorithms

1. Catmull-Rom Splines (Tunnel Path)

The tunnel centerline is a parametric 3D curve defined by 64 control points. Each point is computed from a sum of sines and cosines at different frequencies (Lissajous-style), creating a smoothly winding path through 3D space.

The standard Catmull-Rom formula with tension tau = 0.5:

P(t) = 0.5 * [(2*P1) + (-P0 + P2)*t + (2*P0 - 5*P1 + 4*P2 - P3)*t² + (-P0 + 3*P1 - 3*P2 + P3)*t³]

The camera follows this spline with a look-ahead offset for smooth orientation.

2. Parallel-Transport Frames (Tube Geometry)

The tunnel is a swept tube: a circle extruded along the centerline. To avoid the twisting artifacts of Frenet frames (which become unstable on straight segments), we use parallel transport: at each step, the previous normal vector is projected onto the plane perpendicular to the new tangent, then renormalized.

n_new = normalize(n_prev - dot(n_prev, tangent_new) * tangent_new)

This produces a twist-free tube even through tight curves and near-straight segments.

3. Simplex Noise / FBM (Wall Energy)

The tunnel walls use 3D simplex noise (Ashima/McEwan public-domain GLSL implementation) layered with Fractional Brownian Motion (summing octaves at doubling frequency and halving amplitude). Two FBM layers at different scales create the plasma effect:

  • Primary plasma: 3 octaves, scrolling along tunnel depth
  • Turbulence overlay: 2 octaves, faster, finer detail
  • Domain-warped arcs: Noise used to distort the input coordinates of another noise evaluation, creating flowing energy arcs

4. Hexagonal Grid (Wall Detail)

A hexagonal tiling pattern is computed analytically in the fragment shader:

float hexDist(vec2 p) {
    p = abs(p);
    return max(dot(p, vec2(0.866025, 0.5)), p.y);
}

Overlaid at low opacity on the tunnel walls for the "Star Trek subspace conduit" look.

5. Ring-Buffer Particle Pool (Speed Lines)

12,000 particles in a CPU-side ring buffer. Each particle is a position + velocity + color + lifetime. New particles spawn ahead of the camera along the tunnel, distributed at random angles and radii within the tube.

Rendered as GL_LINES with two vertices per particle: the head (bright) and a velocity-stretched tail (dim). Additive blending (GL_SRC_ALPHA, GL_ONE) makes them glow.

6. Bloom (Post-FX)

Multi-level bloom using a downsample pyramid:

  1. Bright pass: Extract pixels above a luminance threshold with a soft-knee curve
  2. Downsample: 3 levels, each half the previous resolution
  3. Separable Gaussian blur: Horizontal + vertical pass at each level (9-tap kernel)
  4. Combine: Additively blend all bloom levels back into the scene

7. ACES Filmic Tonemap

The scene is rendered in HDR (RGBA16F framebuffers, values above 1.0). The final pass applies the Narkowicz 2015 ACES fitted curve:

vec3 aces(vec3 x) {
    float a=2.51, b=0.03, c=2.43, d=0.59, e=0.14;
    return clamp((x*(a*x+b)) / (x*(c*x+d)+e), 0.0, 1.0);
}

This compresses HDR values into displayable range with a filmic shoulder and toe, avoiding harsh clipping.

8. Chromatic Aberration

RGB channels are offset radially from screen center. The offset increases quadratically with distance from center:

float aberr = strength * dist_from_center²;
color.r = texture(scene, uv + dir * aberr).r;
color.b = texture(scene, uv - dir * aberr).b;

9. Keyframe Timeline System

17 parameters (speed, FOV, bloom, aberration, palette, etc.) are driven by sorted keyframe arrays. Each parameter track is independently interpolated using smoothstep for organic transitions:

t = clamp((x - edge0) / (edge1 - edge0), 0, 1)
smoothstep = t * t * (3 - 2t)

Over 50 keyframes choreograph the 30-second demo across five acts.

10. Shader Hot-Reload

Every 0.5 seconds, the engine checks shader file sizes on disk. If a change is detected, the shader is recompiled and linked. On failure, the old shader is kept. This enables live editing of any .frag or .vert file while the demo runs.

Color Palettes

Four hand-crafted 256-entry color ramps:

  1. Cold Hyperspace — Deep blue → cyan → white (default)
  2. Hot Wormhole — Orange → magenta → violet → white
  3. Subspace — Dark green → teal → white
  4. Rainbow — Full HSV spectrum sweep

Palettes are sampled by depth + time for a scrolling effect, and the timeline blends between palettes during transitions.

Fortran 2018 Features Used

  • iso_c_binding for all OpenGL/GLFW interop (c_ptr, c_loc, c_int, c_float, c_size_t)
  • block constructs for scoped local variables
  • implicit none everywhere
  • pure functions for all math operations
  • Allocatable arrays with target attribute for GPU data upload
  • newunit specifier for file I/O
  • command_argument_count / get_command_argument for CLI flags
  • Module-based architecture (one module per file)

Performance Notes

The demo targets 1440p @ 120 FPS on an RTX 3070 (~8ms frame budget):

  • Tunnel mesh: 200 segments x 48 radial = 9,600 quads (trivial)
  • Particles: 12K line segments, CPU update + single glBufferSubData per frame
  • Post-FX: 3-level bloom pyramid + single composite pass
  • Total VRAM: < 100 MB

On WSLg with Mesa software rendering, expect ~20 FPS at 1440p. On native GPU drivers, the budget is comfortable.