Nation0 Effect Anatomy · fn_3c124 / fn_380e8 / fn_37dac / fn_332b6 @ 0x3c124

Inside the 3D Cube/Torus Morph & Env Mapping.

How Nation0 achieves real-time 3D geometry morphing between a subdivided cube and a torus, computes dynamic sphere environment mapping (chrome reflection) from rotated surface normals, sorts triangular facets, and rasterizes affine texture spans using fixed-point arithmetic in DOS Mode 13h.

Timeline: ~02:30 in Demo (Captures 750..800) Geometry: Original Mesh: 384 Vertices · 768 Triangles Morph Math: Dual-Stream 16-Bit Fixed-Point Linear Blend Texture Engine: 256×256 Chrome Environment Map @ FS:[0] Rasterizer: Affine Span DDA with Sub-Pixel Stepping (fn_332b6)
About this illustration

The interactive preview uses the original executable’s 384 vertices, 768 triangles, and vertex correspondence. Coordinate interpolation uses the original separate signed shifts and 511-complement. Shading normals, RGB environment texture, rotation timing, and average-Z sorting remain illustrative; they are not the original rendering pipeline. Its depth view colors visible facets by camera distance; no Z-buffer is used.

Interactive Pipeline Inspector

COMPOSITE · CHROME ENVIRONMENT MAPPED 3D MORPH
Screen Pos (X, Y) 160, 100
Env Map (U, V) U: 128, V: 128
Morph State (t) Cube: 50% / Torus: 50%
Sampled Color (0, 0, 0)
MORPH: t = 256 (50%)
Active Inspection: Full textured mode. Notice how the metallic chrome reflections ripple across the surface as the sharp 8-corner cube seamlessly bends and inflates into a smooth donut ring.

Rendering Pipeline Stages

Click a stage to inspect its specific math and memory registers.

01

Dual-Stream Vertex & Normal Morphing

Every frame, the CPU blends vertex positions and surface normals between the cube coordinates at 0x34592 and torus coordinates at 0x32a92 using fixed-point weights t and (511 - t).

resumeFn3c124FrameIteration @ 0x3c2b1 · Weights DS:[0x3bdc1]
02

3×3 Matrix Rotation & Composition

Generates yaw, pitch, and roll rotation matrices (`fn_37a2a`) and composes them into a composite 3× 3 transformation matrix (`fn_37b68`).

fn_37a2a & fn_37b68 @ 0x37a2a · Angles DS:[0x36295..0x36297]
03

Environment Map (U, V) Coordinate Derivation

Transforms the lookup vectors using patched fixed-point coefficients and adds the packed 0x8080 center bias before texture addressing.

fn_37cf7 @ 0x37cf7 · Output UV Table DS:[0x323a8]
04

Backface Culling & Depth Sorting

Culls backward-facing triangles via 2× 2 determinant test, computes distance sort keys (K = ((−Σ(X² + Y² + Z²) + 65535) mod 2³²) >> 8), and emits records and distance keys for the render queue.

fn_37dac @ 0x37dac · visible facet records and distance keys
05

Affine Scanline Span Texture Rasterizer

Rasterizes each visible triangle scanline-by-scanline, linearly interpolating (U, V) and fetching texels from segment `FS:[V·256 + U]`.

fn_332b6 @ 0x332b6 · Texture Buffer FS:[0x0000]

Dual-Stream 16-Bit Vertex & Normal Morphing fn_3c124 @ 0x3c2b1

Nation0 represents both the Cube and the Torus with an identical topological vertex mesh (corresponding coordinate and lookup streams). In each frame, the engine interpolates both the 3D coordinates and the surface normal vectors:

1. Fixed-Point Linear Blend 0x3c2c5
P_{morph} = ⌊ ( P_{cube} · t ) / 512 ⌋ + ⌊ ( P_{torus} · (511 - t) ) / 512 ⌋ N_{morph} = ⌊ ( N_{cube} · t ) / 512 ⌋ + ⌊ ( N_{torus} · (511 - t) ) / 512 ⌋
The blend parameter t ∈ [0, 511] is stored at DS:[0x3bdc1]. The original complement is 0x1ff − t; each signed product is shifted separately by 9. The preview reverses the UI weight to keep 0 = torus and 511 = cube; the original first stream is the torus. It preserves the 511 complement and each separate signed shift.
2. Matched Vertex Topology
Original stream A (torus): 0x33392 + offset ↔ Stream B (cube): 0x34e92 + offset Offsets run from −0x900 through −2 (1,152 signed words) Lookup stream bases come from pointers at DS:[0x3611a] and DS:[0x360e2]
Because the two meshes share identical facet index lists, no polygon stitching or dynamic vertex allocation is needed at runtime.

Sphere Environment Mapping (Chrome Reflection) fn_37cf7 @ 0x37cf7

Environment mapping creates the illusion of a polished chrome surface reflecting a surrounding room. Rather than tracing rays, Nation0 derives texture (U, V) directly from rotated vertex normal vectors:

1. Camera-Space Normal Transformation 0x37d20
N_{x,cam} = R_{00} · N_x + R_{01} · N_y + R_{02} · N_z N_{y,cam} = R_{10} · N_x + R_{11} · N_y + R_{12} · N_z
Transforms the surface normal into camera coordinates using the same 3 × 3 matrix that rotates the 3D model.
2. Direct Reflection UV Projection with 0x8080 Bias 0x37d40
U = packed transformed lookup low byte + center bias // 0x8080 center bias V = packed transformed lookup high byte + center bias // 256×256 texture map
The original uses patched fixed-point matrix coefficients, byte packing, and a word addition of 0x8080; the preview uses scaled floating-point normals. The (X, Y) components of the camera-space normal directly index the pre-rendered metallic sphere map.

The x86 Scanline Affine Texture Rasterizer Loop fn_332b6 @ 0x332b6

For each visible triangle, fn_332b6 divides the shape into top and bottom trapezoids, steps sub-pixel edge gradients (dX/dY, dU/dY, dV/dY), and executes an ultra-tight inner span loop reading from segment FS:[0]:

Conceptual affine span (pseudocode, not verbatim assembly):
for each covered scanline:
    find left/right X, U and V from triangle edges
    for each covered pixel:
        write texture[(V_integer & 255) * 256 + (U_integer & 255)]
        advance interpolated U and V
1. FS Segment Selector Trick

By mapping the 64KB (256 × 256) texture to segment FS, the high 8 bits of BX index the row V and the low 8 bits index column U with zero shift or multiplication instructions!

2. Aspect Ratio Scaling (470 / 512)

In fn_37dac, projected Y coordinates are multiplied by 0x1d6 (470) and shifted right by 9 (512), correcting for the non-square 1.2:1 pixel aspect ratio of VGA Mode 13h (320 × 200).

3. Backface Determinant

A signed determinant selects the accepted winding (the original accepts a nonnegative result): (X₁ - X₀)(Y₂ - Y₀) - (Y₁ - Y₀)(X₂ - X₀) < 0, rejecting facets with the discarded winding; the proportion varies with geometry and pose.

Complete Morph & Render Pipeline Overview

1. Vertex Morph Blend Dual-Stream Tables
with Weight t ∈ [0, 511]
resumeFn3c124FrameIteration
2. 3×3 Matrix Rotate Compose Euler Angles
& Multiply Vertices/Normals
fn_37a2a & fn_37b68
3. Env UV Projection Map Rotated Normal (Nₓ, Nᵧ)
to (U, V) + 0x8080
fn_37cf7 @ 0x37cf7
4. 3D Project & Sort Aspect Scaling (470/512)
& Distance Sort Keys
fn_37dac @ 0x37dac
5. Affine Rasterizer Draw Textured Spans
from Segment FS:[0]
fn_332b6 @ 0x332b6