quosa / minity

minimal 3d game engine

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

minity

Minity is a minimal 3d game engine.

Minity spinning a Utah teapot wireframe

Minity spinning a shaded Utah teapot

The main purpose is to do a fun project to re-learn modern C++ and try to follow the new guidelines. SDL2 is used to get a simple canvas to draw to (setPixel(x, y)) and input handling. Math is written all by hand to re-learn vector and matrix operations. Write all graphics pipeline operations by hand to understand what the GPU does for us and compare them with metal API](https://developer.apple.com/metal/) results. Dear ImGui is used for adding a statistics window to the rendered area.

Design choices for the software renderer:

  • matrices are in row-major order to align with maths notation (unlike OpenGL!)
  • coordinate system and rotation follow the right-hand rule like OpenGL
    • axis rotation follows the right-hand rule: right thumb to positive axis and fingers point to positive rotation
  • camera is watching towards the negative Z-axis
  • screen coordinates are top-left (0,0) to bottom-right (screen-width, screen-height)
  • texture coordinates are top-left (0,0) to bottom-right (1,1) when flipped vertically on load
  • model faces are defined in clockwise winding order faces follow the LEFT-hand rule: e.g. center > up > right and LEFT-thumb points front

Working:

  • simple scene object with light, camera, and model (no entity hierarchy)
  • object loading from a simple obj file (vertices, faces, normals, and texture coordinates)
  • object scaling, rotation, and movement (translation)
  • rudimentary input handling for
    • moving the target (arrow-keys, +, -)
    • rotate target with (wasd)
      • no z-rotation as q is currently for quit
  • orthographic perspective correction with fixed FoV, field-of-view
  • rudimentary clipping (TODO: proper clipping)
  • back-face culling: face normal check to discard hidden triangles
  • draw wireframe, normals, point cloud, and axes
  • global face color
  • flat shading for models without pre-calculated normals (teapot)
  • Phong-shading with normals for a smooth surface
  • textures with perspective-corrected model texture coordinates
  • basic math tests with Catch2
  • z-buffer check (instead of z-sorting the vertices before rendering)
  • rendering on metal API
  • simple util for generating a cube

TODO:

  • proper clipping (zoom in and the entire face is removed if clipped)
  • input handling:
    • z-rotation with q/e but move quit
    • map all keys
    • re-implement fps camera movement (now we move the target)
    • camera movement is not good for exploration
    • cannot change the target between mesh/camera/light
  • re-implement a simple util for generating a sphere
  • split scene header to smaller parts and have corresponding tests
  • wire-frame line color (done) > painting (done) > texturing (done) > anti-aliasing
  • vertex/face color from model
  • jump from classic make to CMake
  • consider clang-format
  • add address/thread/memory sanitizer

Main influences:

Gallery

Tilted yellow sphere with 50 meridians and parallels in basic global illumination: Minity showing a yellow sphere

Simple statistics window (turn on with [F1]) to get basic fps and library information: Minity showing statistics window

Head model with texture (incomplete mesh split and no eye/lash textures) Minity showing a textured head

Texture with perspective-correct interpolation (no dent in face)

Minity showing texture perspective correct interpolation

Rendering differences between software rasterizer and metal API

Minity software rendered textured head

Minity metal API rendered textured head

About

minimal 3d game engine

License:MIT License


Languages

Language:C++ 65.0%Language:C 34.2%Language:Makefile 0.4%Language:Shell 0.2%Language:Metal 0.1%