code wiki / (root) / nx_vertex_pipeline.nx

nx_vertex_pipeline.nx

buildroot/runtime/nx_vertex_pipeline.nx

12646 B280 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_vertex_pipeline.nx -- world-space vertex -> screen-space vertex. The missing glue between mesh-emitter output and rasterizer input. nx_voxel_mesh (game-engine) emits world-space vertices in Q14. nx_raster_triangle (this repo) consumes screen-space vertices in pixel coords + Q14 depth. This primitive bridges them: applies an MVP matrix, perspective divide, viewport mapping. Generic substrate -- any 3D pipeline (CAD viewer, scientific visualisation, voxel game, raymarched fractal-explorer) needs this transform. Lives in nishi-core per the placement cardinal. Vertex layout in both input and output (matches nx_voxel_mesh + nx_raster_triangle exactly so the buffers compose directly): verts[i*4 + 0] = x in Q14 verts[i*4 + 1] = y in Q14 verts[i*4 + 2] = z in Q14 verts[i*4 + 3] = packed_color (u32 RGBA in low 32 bits) On output: x_pixel = (ndc_x + 1) * viewport_w / 2 y_pixel = (1 - ndc_y) * viewport_h / 2 (Y flipped for screen) z_depth = (ndc_z + 1) * Q / 2 (Q14, in [0, Q]) color unchanged (per-vertex passthrough) Perspective-divide guard: vertices behind the camera (w <= 0) get flagged via out-of-screen pixel coords (-1, -1) so the rasterizer's existing bounding-box clip silently drops them. Per cardinal `feedback-honest-perf-verdict`, a proper near-plane clip is the v2 follow-up (currently named in the loss audit below). Loss audit: - Perspective divide is integer-division of two Q14 values to a Q14 result. Loses 14 fractional bits per step. Acceptable for voxel-block-aligned geometry where pixel-edge precision is chunky by design. - Viewport map uses integer division at the final stage; sub-pixel centroid drift up to 0.5 pixel. - W <= 0 vertices are coarse-dropped (no Sutherland-Hodgman clip). Triangles spanning the near plane will have wrong rasterization.

dependencies 2 imports · 1 importers

nx_syscalls.nx nx_tier.nx nx_vertex_pipeline.nx nx_render_pass.nx

imports: nx_syscalls.nxnx_tier.nx

imported by: nx_render_pass.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nx_vertex_pipeline_transfo sys_mmap ↻ _vp_mat4_mul_vec4 nx_vertex_pipeline_transfo nx_vertex_pipeline_transfo ↻

structs

none

consts

57const NX_VP_Q: nx_int = 16384
60const NX_VP_VERT_STRIDE: nx_int = 4
63const NX_VP_OFF_X: nx_int = 0
64const NX_VP_OFF_Y: nx_int = 1
65const NX_VP_OFF_Z: nx_int = 2
66const NX_VP_OFF_COLOR: nx_int = 3
71const NX_VP_OFFSCREEN_X: nx_int = -100000
72const NX_VP_OFFSCREEN_Y: nx_int = -100000

functions

82func _vp_mat4_mul_vec4(m: *i64, x: nx_int, y: nx_int, z: nx_int, w: nx_int, out: *i64)
94func nx_vertex_pipeline_transform_one(
146func nx_vertex_pipeline_transform(
169func main() -> i64