I made a small wireframe renderer module named Wyreframe.
It works by treating each point as a node in 3D space and connecting nodes based on nearest-neighbor distance, producing a lightweight (unless you are trying to render a mesh with more than ~1000 verts.) wireframe without requiring mesh generation.
It’s useful for visualizing procedural shapes, graphs, or debugging spatial logic.
The connections are based on nearest neighbors rather than predefined topology, which keeps it simple and flexible.
Limitations
- Neighbor connections are computed using distance checks with a time complexity of O(n²) in standard mode, or O(n) on average when spatial binning is enabled (v1.2r1).
- Worst-case complexity for spatial mode may still degrade to O(n²) if vertices are extremely dense within a single region.
- This does not produce a true wireframe of a mesh, only an approximation based on point proximity.
- Best suited for procedural shapes, math visuals, and debugging.
Documentation
Wireframe.new(vertices, parent, config?)
Creates a wireframe structure by connecting nearby vertices using Beams.
Parameters
vertices({Vector3})
Array of vectors describing point directions from the center.parent(Instance)
Parent for the generated outputModel.config(table?)
Returns
Wireframe– object containing the generated Model and update methods.
Wireframe:Update(position, radius, rotation?)
Updates the wireframe positions, useful for animation.
Parameters
position(Vector3)
World position of the wireframe.radius(number)
Scale applied to each vertex.rotation(CFrame?)
Optional rotation (rotation-only CFrame).
Configuration Options
| Name | Type | Default | Description |
|---|---|---|---|
BeamWidth |
number | 0.1 | Thickness of beam connections |
BeamFaceCam |
boolean | true | Beams face the camera |
BeamColor |
Color3 | white | Beam color |
BeamLightEm |
number | 1 | Beam light emission |
NeighborCount |
number | 3 | How many nearest neighbors each point connects to |
PointSize |
number | 0.001 | Size of vertex parts |
PointTransparency |
number | 1 | Vertex visibility |
PointShape |
Enum.PartType | Enum.PartType.Ball | Shape of vertex parts |
PointCanCollide |
boolean | false | Collision setting |
PointColor |
Color3 | white | Vertex color |
OutputGroupName |
string | “WireframeOutput” | Name of output model |
LOD_Enabled |
boolean | true | Enables spatial rendering for large vertex counts |
LOD_Threshold |
number | 550 | Vertex count threshold before spatial mode is used |
Streaming_Enabled |
boolean | true | Spreads work across frames to prevent frame drops |
Time_Budget |
number | 0.002 | Max seconds spent per frame when streaming |
Example Script:
local Wireframe = require(game.ReplicatedStorage.Wyreframe)
local RunService = game:GetService("RunService")
local vertices = {
Vector3.new(1, 0, 0),
Vector3.new(-1, 0, 0),
Vector3.new(0, 1, 0),
Vector3.new(0, -1, 0),
Vector3.new(0, 0, 1),
Vector3.new(0, 0, -1),
}
-- Create wireframe object
local wf = Wireframe.new(vertices, workspace, {
OutputGroupName = "ExampleWireframe",
NeighborCount = 3,
})
local position = Vector3.zero
local radius = 25
RunService.RenderStepped:Connect(function(t)
wf:Update(
position,
radius,
CFrame.fromEulerAnglesXYZ(0, t, 0)
)
end)
Changelog
This is the changelog, Version is formatted as “M.mr” (M = major, m = minor, r = release)
1.1r1
The first release of Wyreframe. Download at Github.
- Initial Release
1.1r2
The second release of Wyreframe. Download at Github.
- New function (
:getVersion()) - Fixed potential bug in
.render() - Changed
.update()parameter format (model, config : {GroupRotation, GroupRadius, GroupPosition}) - Made
cflocal variable in.update()explicitly rotation-only - Config values in
.render()now cached innCtable (for readability’s sake) - Boolean handling fixed
1.2r1
The third release of Wyreframe, Download at Github.
- Added spatial binning–based neighbor search for large vertex counts
- Average neighbor computation complexity reduced to O(n) in spatial mode
- Added streaming renderer with configurable per-frame time budget
- Added LOD system to automatically select rendering strategy
- Internal refactors for performance and readability
1.2r2 (Latest)
- Fixed 2 bugs (
.SqMagnitudenot existing) - Updated vTable
Sharing it here in case it’s useful to anyone else :]



