Skip to content

AnotherSubatomo/kosmos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kosmos

[Experimental] Platform-agnostic, 3D graphics software rasterizer written in Luau

Last Commit License: MPL-2.0


kosmos is a minimal, single-file, software rasterizer written in pure Luau, that doesn't depend on any specific runtime (platform-agnostic). Renderers for both the web and Roblox are available.

See it in action with the YouTube video below:

Library Showcase

Usage

Upon requiring kosmos, it will return a function with two arguments for width and height respectively.

local WIDTH, HEIGHT = 320, 240
local kosmos = require("path/to/kosmos")(WIDTH, HEIGHT)

Upon supplementing its parameters, the function will then return the entire library for manipulating the rasterizer's runtime state. Do note that every invocations of the function returns a unique runtime state.

You can register object assets like meshes and textures via .mesh() and .texture(). These functions will return a stable ID that represent the asset you pass onto the function.

local obloid = kosmos.mesh(obloid_mesh)
local cube = kosmos.mesh(cube_mesh)
local earth = kosmos.texture(earth_texture)
local mars = kosmos.texture(mars_texture)
-- `obloid`, `cube`, `earth`, & `mars` are numbers because
-- they hold IDs that point to the assets they represent.

These IDs for meshes and textures can then be passed onto .object() to create distinct instances of the mesh and texture they represent. This function also returns a stable ID that represent the object they point to.

local earth_object = kosmos.object(obloid, earth)
local mars_object = kosmos.object(obloid, mars)

These IDs for objects can then be passed onto setter functions for object properties, which are exhaustively showcased by the example snippet below:

kosmos.setObjectPosition(earth_object, vector.create(0.5, 0.5, 0.5))
kosmos.setObjectRotation(earth_object, math.pi, 0, 0)
-- If I wanted the earth object to look like Mars, I can do:
kosmos.setObjectTexture(earth_object, mars)
-- If I wanted the earth object to take the shape of cube, I'd do:
kosmos.setObjectMesh(earth_object, cube)
-- If I wanted the earth object to stop rendering, I can set its
-- texture to `0xFFFF`, which means "no texture ID". Since there's
-- no texture, there's nothing to render.
kosmos.setObjectTexture(earth_object, 0xFFFF)

To render a single frame onto the image buffer, you simply call .render(). To get a continuous video render, simply call .render() 60 times per second, or to whatever FPS you target. Another function, .clear(), then clears the image buffer—it is recommended that you call this function before every render call to prevent "ghosting" artifacts.

Q&A

  • Why did you start this project?
    • To see how far I can go with implementing a custom 3D graphics engine in pure Luau (and for it to be able to run smoothly on Roblox)
    • To be able to mimic hailtododongo's custom rendering pipeline for the N64 (was actually more inefficient for machines that aren't N64, which makes sense)
    • Because I like tsoding (a word coined by Mr. Zozin, which means "programming for fun")

About

[Experimental] Platform-agnostic 3D renderer written in Luau

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors