Rendering Overview

Home | GPU Pipeline →

</blockquote>

Architecture

Trinyx uses a Visibility Buffer (VizBuffer) architecture. The hardware rasterizer outputs a minimal 64-bit payload (InstanceID + PrimitiveID). Material evaluation, lighting, and transparency are deferred to a zero-overdraw full-screen compute pass. This integrates directly with the engine's SoA temporal ring buffers via Vulkan Buffer Device Address (BDA).

ArchitectureFlowKey Problem
Traditional Deferred (G-Buffer)Rasterize → Write Fat G-Buffer → Light16–32 bytes/pixel destroys VRAM bandwidth; overdraw wastes ALU
Industry VisBuffer (e.g. UE5 Nanite)Rasterizer → Skinny VisBuffer → Compute Material/LightHigh baseline overhead; translucency requires costly clustered forward or RT any-hit
Trinyx VizBufferHW Rasterizer → 64-bit VisBuffer → Opaque Resolve → Hybrid RT/Compute Gather → Global Radix Sort → Alpha AccumulationDesigned for worst-case VFX overdraw with bounded VRAM and early ALU exit

Current State (Shipped 2026-03)

Phase 1 of the full pipeline is operational:

  • Raw Vulkan — volk 1.4.304 + VMA 3.3.0 (vk::raii::)
  • Slang shaderspredicate.slang, prefix_sum.slang, scatter.slang, cube.vert, cube.frag
  • Buffer Device AddressGpuFrameData struct holds all BDAs; no per-frame descriptor set updates
  • 3-pass compute pipeline — predicate → prefix_sum → scatter (see GPU Pipeline)
  • 5 PersistentMapped field slabs — cycle independently from 2 GPU frame-in-flight slots, decoupling Logic from VSync
  • **DrawIndexedIndirect** — driven by the scatter pass DrawArgs.instanceCount
  • Dirty-bit-driven partial upload — only modified entities uploaded per frame (see Dirty Bit Upload)

Full Target Pipeline (6 Phases)

Phase 1 — Compute Culling & Predicate

predicate.slang acts as a task shader equivalent: evaluates frustum culling and tests entity bounds against the t-1 Hierarchical Z-Buffer (HZB), then outputs indirect draw commands for opaque and alpha-tested geometry.

Currently implemented: active-flag predication only. Frustum culling and HZB test are pending.

Phase 2 — Raster & HZB Generation

Graphics queue opaque pass: Early-Z minimalist rasterization, HZB build, late culling pass for newly-occluded objects. Outputs a R32G32_UINT VisBuffer and depth target. Alpha-tested foliage uses the pre-built depth to guarantee Early-Z hardware culling.

Phase 3 — Material Resolve & Light Grid

Light build: A compute pre-pass bins dynamic lights into a 3D Froxel Grid / Screen-Space Cascade Grid.

Material evaluation: Full-screen compute reads the 64-bit VisBuffer, fetches BDA vertices, reconstructs barycentrics analytically, applies Compute-Based Variable Rate Shading (VRS) via subgroup shuffle (2×2 quads with matching PrimitiveID share one material evaluation), and writes the lit opaque HDR target.

Also planned here: True sub-frame motion blur — evaluating Bézier curves from t−8 to t using the 512Hz logic history for cinematic curved blur.

Phase 4 — Hybrid Transparency Gather

Two sources feed the same GlobalPixelQueue SSBO:

  • Volumetrics (Source A): Smoke, fire, and particles use atomicAdd to push into the queue. A strict per-pixel atomic 9-layer limit hard-caps VRAM use and immediately drops occluded particles.
  • RT solids (Source B): A full-screen compute shader fires inline ray queries (OpRayQueryKHR) to resolve glass, water, and refractive surfaces. Hit data is packed into the same queue — no Any-Hit shader stalls on volumetrics.

Phase 5 — Global Radix Sort & Mega-Dispatch

Sort: GPU Radix Sort on 64-bit keys: [Tile ID (16) | ReverseDepth (32) | Payload (16)]. The tile prefix groups threads into 32×32 screen tiles for ~90% L1/L2 cache hit rate during the final dispatch.

Dispatch: A single indirect dispatch evaluates the sorted queue, blends materials front-to-back, and exits threads early once a pixel's accumulated alpha reaches 0.99 — saving ALU on occluded smoke layers.

Phase 6 — Post-Process & Reconstruction

TAA, native DLSS/FSR 3 reconstruction (1080p internal → 4K output), and motion blur using render-to-render motion vectors from the decoupled HistorySlab.


Core Constraints

ConstraintReason
64-bit VisBuffer — strictly 64 bitsMinimize VRAM bandwidth. Barycentrics and normals reconstructed analytically.
64-bit transparency sort keyFront-to-back ordering + spatial grouping for cache locality.
Inline RT onlyOpRayQueryKHRNo Any-Hit shaders; they stall the pipeline on volumetric geometry.
Atomic transparency limit — 9 layers per pixelPrevents unbounded VRAM growth under heavy VFX.
BDA everywhereNo per-frame descriptor set updates. All slab data via Buffer Device Address.
Unified GI / audio cascadesThe same Cascaded Lighting Grid drives GPU Global Illumination and CPU-side Physically Based Audio propagation.

Transparency Performance Targets (1440p)

Transparency frame budget goal: **< 4.0 ms** within a 16.6 ms frame.

ScenarioNaive ScalingVizBuffer Behavior
Heavy RT solids (glass city)VRAM/ALU scales linearly with overdrawO(1) CPU, O(N) GPU RT — BVH traversal on RT cores
10× volumetric overdraw (smoke)VRAM bandwidth explodes; ROPs saturateBounded VRAM via atomic gather limit; alpha early-exit terminates occluded ALU lanes
Interwoven solids + volumetrics (boss fight)Depth sort fails across passes or RT Any-Hit stallsO(N log N) sort with high cache coherency from tiled sort key

Remaining Work

ItemStatus
Frustum culling + HZB test in predicate passPending
State-sorted rendering (64-bit sort keys, GPU radix sort)Designed
VizBuffer raster pass + HZB generationDesigned
Material resolve compute passDesigned
Hybrid transparency gather (Phase 4)Designed
Global radix sort + mega-dispatch (Phase 5)Designed
TAA / DLSS / FSR 3 reconstructionPending
Slang runtime compilation for hot-reloadPending