Skip to content

deya-eldeen/Solar2D-3D-Renderer

Repository files navigation

Simple OBJ Renderer (Solar2D)

A minimal Solar2D sample that renders a 3D OBJ mesh into a single display.newSnapshot() using 2D meshes. The scene stays as one display object while the renderer projects and shades faces each frame.

Renderer Preview

Features

  • OBJ loader (vertices + faces), triangulation, negative indices support
  • Flat shaded faces with multiple lights
  • Optional two-sided rendering
  • Per-frame depth sorting (painter's algorithm)
  • Background color inside the snapshot
  • Separate orientation and animation control (local/global)
  • Optional scale pulse

Project layout

  • main.lua - demo scene
  • renderer/renderer.lua - renderer and OBJ loader
  • renderer/transformations/rotation.lua - rotation helpers
  • renderer/transformations/scale.lua - scale pulse helpers
  • obj/wrench.obj - sample model

Usage

local renderer = require("renderer.renderer")

local snap = renderer.newSnapshot{
    width = 128,
    height = 128,
    modelScale = 0.9,
    distance = 8.0,
    fovScale = 110,
    zoom = 0.8,
    objPath = "obj/wrench.obj",
    faceColor = { 0.20, 0.55, 1.00 },
    backgroundColor = { 0.0, 0.0, 0.0, 1.0 },
    useLighting = true,
    lightDirs = {
        { x = -0.4, y = -0.7, z = -1.0 },
        { x = 0.6, y = -0.2, z = -0.5 },
        { x = 0.0, y = 0.8, z = -0.3 }
    },
    twoSided = true
}

snap:orientObject({ x = 1.7, y = 0.8, z = 0.5, space = "local" })

snap:applyAnimation({
    spin = 0.5,
    rotationAxis = "z",
    scalePulse = { amplitude = 0.01, speed = 8.0 },
    space = "global",
    additive = true
})

API reference

renderer.newSnapshot(opts)

Core options:

  • width, height - snapshot size in pixels
  • modelScale - base model scale (world units)
  • distance - camera distance (world units)
  • fovScale - projection scale in pixels
  • zoom - projection multiplier (default 1)
  • objPath - OBJ path (resource directory)
  • faceColor - {r,g,b} for flat shading
  • backgroundColor - {r,g,b[,a]} for snapshot background
  • originX, originY - shift projected coordinates inside snapshot

Lighting options:

  • useLighting - boolean
  • lightDirs - array of {x,y,z} light directions
  • ambient - minimum clamp (default 0.15)
  • twoSided - render backfaces and light both sides

Normals/winding options:

  • autoOrient - auto-flip winding from signed volume (default true)
  • invertWinding / flipNormals - force flip all faces
  • invertFirstFace / flipFirstFace - flip only first face

Animation/orientation options:

  • spin + rotationAxis - spin rate on axis preset (x, y, z, xy, xz, yz, xyz)
  • spinX, spinY, spinZ - per-axis spin rates
  • scalePulse - { amplitude, speed, phase } or true
  • orientation - { x, y, z, space="local|global" }
  • animationSpace - "local" or "global" (defaults to orientation space)

snapshot:orientObject(opts)

Sets a base orientation, separate from animation.

Options:

  • x, y, z - radians
  • space - "local" or "global"
  • additive - if true, adds to the current orientation

snapshot:applyAnimation(opts)

Applies animation parameters.

Options:

  • spin + rotationAxis, or spinX / spinY / spinZ
  • scalePulse
  • space - "local" or "global"
  • additive - if true, adds to existing spin rates

Notes and limitations

  • OBJ parsing supports v and f lines. Texture/normal indices are ignored.
  • Faces are triangulated in fan order. Keep models triangulated for best results.
  • No z-buffer; faces are sorted by depth each frame.
  • Camera is at origin looking down +Z, so models must be in front (positive Z after translation).

About

A minimal Solar2D sample that renders a 3D OBJ mesh into a single display.newSnapshot() using 2D meshes.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages