Raster¶
Namespace Nfty.Model.Render in assembly Nfty.Model.
The software rasterizer: transforms a Mesh by a Camera's view-projection, clips against the near plane, culls back faces, resolves visibility with a z-buffer, samples the texture with nearest-neighbor filtering, and shades with flat, quantized, camera-relative lighting — the whole rendering pipeline the spec lists (see docs/superpowers/specs/2026-09-22-model-preview-design.md, "Rendering"). Pure CPU pixel arithmetic: it renders identically headless and on screen, which is the entire reason this exists instead of a GPU control (`Avalonia.Headless` has no GL context).
Remarks¶
Single-threaded by design: the z-buffer is shared state, so the pixel loop is not a ParallelWork candidate. Allocates nothing per call — the transformed vertices live in a pooled array and the texels are read in place (or from a pooled copy).
Methods¶
DrawEdges(Mesh, Camera, RenderTarget)¶
Draws the outline of every visible quad over what Raster.Render() already put in target, one pixel wide: the wireframe display. A risen mesh is made of quads (four vertices, six indices each), so the outlines are the greedy faces' and walls' own edges, not the triangle diagonals. An outline is drawn only where it lies on the surface the z-buffer holds (a small relative tolerance), so edges behind the solid stay hidden, and it changes only a pixel's color, never its alpha or depth. The ink is white on a dark pixel and black on a light one, so it reads on any texture. A quad with a corner behind the near plane is skipped whole rather than clipped; the camera never enters the solid's box, so this only shows when zoomed to the surface.
Parameters
mesh(Mesh) - The solid, already rendered intotarget.camera(Camera) - The camera that rendered it.target(RenderTarget) - The surface to draw on.
Render(Mesh, Image<Rgba32>, Camera, RenderTarget)¶
Draws every triangle of mesh, sampling texture nearest-neighbor, into target, as seen by camera. The projection is built here from target's own size, so it can never disagree with the surface it is drawn on. Does not clear target first — the caller owns the background and calls RenderTarget.Clear() itself.
Parameters
mesh(Mesh) - The mesh to draw.texture(Image<Rgba32>) - The face atlas the mesh was built against.camera(Camera) - The view to draw it from.target(RenderTarget) - The surface to draw into.
Returns. How many SOURCE triangles (index triples) survived clipping and culling and were rasterized; one split in two by the near plane counts once.
Exceptions
ArgumentException-textureis not the size of the art the mesh was risen from — the same ruleModelWriterapplies.