Log inGet started
·
renderfeature · drop-in viewer
asset⌬ renderfeaturerenderFeatureprimary: init.luau·originates fromworld 07158574-5…

debugViz.renderFeature

Draws the batched geometry buffer that `@builtin::modules.debugViz` rebuilds every edit-mode tick from every registered provider — bounds boxes, camera frustums, and any further gizmo the debugViz core gains. One Draw pass over the core-owned vertex/index buffer pair, rasterized…

byzero-proxy @ DESKTOP-DB3UJOJ·posted 2mo ago
What it does

debugViz render feature

Draws the batched geometry buffer that @builtin::modules.debugViz rebuilds every edit-mode tick from every registered provider — bounds boxes, camera frustums, and any further gizmo the debugViz core gains. One Draw pass over the core-owned vertex/index buffer pair, rasterized as GPU lines through the shared vertex-colour unlit material (@builtin::shaders.debugGeometry). An empty state (no providers with geometry yet, or the driving DebugViz component not yet awake) enqueues nothing.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

Debug-viz render feature — draws what @builtin::modules.debugViz rebuilds every active tick from every registered provider. Two kinds of draw share the core-owned anchor entity and the one static sequential index buffer: * the batched line soup (bounds boxes, frustums, bones, colliders, wireframe) through the vertex-colour line material, and * one triangle-list pass per registered icon — camera-facing billboards through that icon's debugBillboard material. An empty state (no geometry yet, or the overlay cleared) enqueues nothing.

render(ctx: ?) → void

argtypedescription
ctx?

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

24items
▣
module · born here
❒asset
# debugViz The shared edit-mode debug-visualization core. Owns the ONE anchor entity, the ONE vertex-colour line material, the ONE batched vertex/index compute-buffer pair, and the ONE render feature that every debug-visualization gizmo draws through. Individual gizmos (bounds boxes, camera frustums, ...) are **providers** — small modules that append their own geometry into the shared batch every tick, instead of each owning their own GPU state. ```lua entity.spawn("DebugViz"):component.add("DebugViz") ``` ## How it fits together - `DebugViz.component` owns the lifecycle: registers the built-in providers and calls `debugViz.update(dt)` every edit-mode tick; `onDisable`/`onDestroy` call `debugViz.teardown()`. - `debugViz.registerProvider(name, fn)` registers `fn(emit)` under `name`. Registering an existing name replaces its function. - `debugViz.update(dt)` clears the batch, calls every registered provider with an `emit` handle, then rebuilds and uploads the combined vertex/index buffers (grow-only capacity — a stable geometry count costs one buffer write per tick, not a recreate). - `debugViz.state()` returns the latest `{ vtx, idx, anchor, indexCount }` for the render feature to draw. - `@builtin::renderFeatures.debugViz` reads `state()` every frame and draws the batch through one Draw pass, using `@builtin::shaders.debugGeometry` — a solid-colour shader that reads each vertex's baked colour, so every provider can use its own colour in the same draw call. The draw needs an anchor entity with an IDENTITY world transform and a render-object (so the Draw pass has a valid instance slot and a material to override) — this module owns one, spawned lazily, internal so it stays out of the inspector and excluded from scene saves. ## Writing a provider ```lua local debugViz = require("@builtin::modules.debugViz") local function tick(emit) emit.box({ x = -1, y = -1, z = -1 }, { x = 1, y = 1, z = 1 }, { 1, 0, 1, 1 }) emit.line({ x = 0, y = 0, z = 0 }, { x = 0, y = 5, z = 0 }, { 1, 0, 1, 1 }) end debugViz.registerProvider("my_gizmo", tick) ``` `emit.box(min, max, color?)` and `emit.line(a, b, color?)` append world-space geometry into the shared batch for this tick; `color` is an `{r, g, b, a}` array baked per-vertex (defaults to amber if omitted). A provider that needs to exclude the shared anchor entity from its own scene queries reads `debugViz.anchorId()`. ## API - `debugViz.registerProvider(name, fn)` — register (or replace) a provider. `fn(emit)` runs once per edit-mode tick. - `debugViz.anchorId()` — the anchor entity's id, or `nil` before the first tick. - `debugViz.update(dt)` — clear the batch, run every provider, rebuild and upload the combined geometry. - `debugViz.state()` — the latest batched draw, or `nil` before the first tick. - `debugViz.teardown()` — tear down the feature, material, buffers, and anchor entity. Registered providers stay registered. - `debugViz.MATERIAL` — the registry key of the shared vertex-colour line material the render feature draws with.
▲ 0↑ born
·
other · born here
▤file
▲ 0↑ born
△
mesh · born here
❒asset
▲ 0↑ born
✦
shader · born here
❒asset
▲ 0↑ born
✦
shader · born here
❒asset
# debugBillboard Camera-facing billboard shader for the debug overlay's icon sprites. Each instance renders a procedural glyph (camera, light, audio, reflection probe, player) selected by glyph id — drawn analytically in the fragment shader, so icons stay crisp at any zoom with no texture atlas. Consumed by the debugViz icon system.
▲ 0↑ born
▣
module · born here
❒asset
# debugDraw Procedural geometry builders for GPU debug visualization — wireframe boxes, spheres, capsules, crosses, octahedra, line segments, and camera-facing icon billboards. Pure geometry: every builder appends packed vertex bytes to a caller-supplied accumulator and returns how many vertices it added. Line geometry is a non-indexed **line soup** (each line is two consecutive vertices) and billboards are a **triangle soup** (each quad is six consecutive vertices), so both draw through one static, grow-only sequential index buffer (0,1,2,…) that never needs re-uploading per frame — the topology comes from the material. Nothing here touches `compute.*` or `renderer.*` — callers own the buffers and the Draw pass. ```lua local debugDraw = require("@builtin::modules.debugDraw") local vtxParts = {} local verts = 0 verts += debugDraw.appendBox(vtxParts, bounds.min, bounds.max, { 1, 0.8, 0, 1 }) verts += debugDraw.appendLine(vtxParts, a, b, { 0, 1, 1, 1 }) local vtxBytes = debugDraw.buildVertexBytes(vtxParts) local vtx = substrate.createBuffer({ name = "my.vtx", type = "f32", len = math.ceil(#vtxBytes / 4), kind = "gpu", usage = { "vertex" }, }) vtx:writeBytes(vtxBytes) -- One static sequential index buffer, grown only when the vertex count does. local idx = substrate.createBuffer({ name = "my.idx", type = "f32", len = verts, kind = "gpu", usage = { "index" }, }) idx:writeBytes(debugDraw.buildSequentialIndexBytes(verts)) ``` ## Vertex layout Every packed vertex matches the engine's standard `Vertex` layout (position, normal, uv, joints, weights, node_index, tangent, color — 92 bytes, little-endian) so the resulting buffer draws through the ordinary vertex pipeline via a Draw pass. Debug geometry only needs position + color; every other field is filled with a default. ## API Each builder appends line-soup vertices to `vtxParts` and returns the vertex count it added: - `appendLine(vtxParts, a, b, color?)` — one segment (2 verts). - `appendBox(vtxParts, min, max, color?)` — axis-aligned box, 12 edges (24 verts). - `appendOrientedBox(vtxParts, center, rotation, halfExtents, color?)` — a posed box. - `appendWireSphere(vtxParts, center, radius, color?)` — three orthogonal rings. - `appendWireCapsule(vtxParts, center, rotation, radius, halfHeight, color?)` — two rings + connectors. - `appendCross(vtxParts, center, size, color?)` — a 3-axis marker (6 verts). - `appendOctahedron(vtxParts, center, size, color?)` — a diamond marker (12 edges). - `appendBillboard(vtxParts, center, color?)` — one camera-facing quad (6 triangle-soup verts) at `center`; every corner stores `center` and its uv corner, and the `debugBillboard` surface shader expands it toward the camera. Helpers: - `packVertex(x, y, z, color)` — pack one vertex; for building cached geometry blobs. - `packVertexUV(x, y, z, u, v, color)` — pack one vertex carrying an explicit uv (for billboard quads). - `quatRotate(q, v)` — rotate a vector by a unit quaternion. - `buildVertexBytes(vtxParts)` — concatenate the packed vertices into buffer bytes. - `buildSequentialIndexBytes(count)` — the fixed `0,1,2,…,count-1` line-list index buffer. - `VERTEX_STRIDE` — 92, the byte stride of one packed vertex. See `@builtin::modules.debug_bounds` for a caller and `@builtin::renderFeatures.debugViz` for the Draw pass that renders the batch.
▲ 0↑ born
·
other · born here
▤file
▲ 0↑ born
·
zmsh · born here
▤file
▲ 0↑ born
·
other · born here
▤file
▲ 0↑ born
·
other · born here
▤file
▲ 0↑ born

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.