Open-source project
ssloy/tinyrenderer avatar
ssloy/tinyrenderer

ssloy/tinyrenderer: a software rasterizer course in 500 lines of C++

A brief computer graphics / rendering course

24,313 stars2,301 forksC++NOASSERTION

At a glance

What is it?
tinyrenderer is a C++ course that builds an OpenGL-like software renderer from scratch, with no third-party graphics libraries. It is teaching material, not a rendering engine you ship.
Who is it for?
Adopt tinyrenderer if you want to understand what a graphics API does for you and you are willing to write the rasterizer yourself; the README states plainly that using the author's code directly is not recommended. Skip it if you need a renderer for production output, GPU work, or anything with a window, because it produces images and nothing else.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 63 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What tinyrenderer is actually for

The README opens with a blunt disclaimer: "The code itself is of little interest." tinyrenderer is a set of fourteen written lectures that walk through writing a simplified clone of OpenGL, Vulkan, Metal, and DirectX, and the repository exists to support those lectures. The stated audience is people who struggle with the initial hurdle of learning a 3D graphics API. After the course, according to the README, students can produce quite capable renderers.

The scope is narrow on purpose. The input is a 3D model made of a triangulated mesh plus textures. The output is an image file. There is no window, no event loop, no GPU. The README describes the finished program as a software renderer and says the author does not intend to show how to write GPU applications, only how they work. If you arrived looking for a library to link against, you are in the wrong repository: the deliverable is your own understanding, not an artifact.

The rendering pipeline you build, stage by stage

The lecture list is effectively the architecture. It starts with Bresenham's line drawing algorithm, moves to triangle rasterization, then a primer on barycentric coordinates. Hidden faces come next via a z-buffer, followed by two camera lectures (a naive approach first, then better camera handling), then shading. Textures and tangent space normal mapping come after that, then shadow mapping, indirect lighting with SSAO, and a bonus on toon shading.

That ordering matters. Each stage depends on the previous one being implemented and working, so you cannot jump to shadow mapping without a working z-buffer and a camera. The repository layout mirrors the split: tgaimage.cpp and tgaimage.h handle images, geometry.h holds the vector and matrix types, model.cpp and model.h load the mesh, our_gl.cpp and our_gl.h contain the rasterizer you write, and main.cpp wires it together. The README notes that the only functionality provided at the start, beyond loading and saving images, is setting the color of a single pixel. Everything else, including line and triangle drawing, is written by hand.

Building it and producing your first image

The README gives a single compile-and-run sequence. It clones the repository, configures a build directory with CMake, builds it, and then runs the binary against two OBJ files from the obj/ directory. The rendered image is written to framebuffer.tga.

sh
git clone https://github.com/ssloy/tinyrenderer.git &&
cd tinyrenderer &&
cmake -Bbuild &&
cmake --build build -j &&
build/tinyrenderer obj/diablo3_pose/diablo3_pose.obj obj/floor.obj

After the build finishes you should find framebuffer.tga in the working directory. It is a TGA file, so you need a viewer that reads that format; the Dockerfile in the repository installs imagemagick, which is one way to open or convert it. Note that the sample command passes a model and a floor mesh, so the obj/ directory needs to be present where you run the binary.

The README also points at the starting point for students: an earlier commit containing only the TGA class and a main function that sets three pixels and writes a 64x64 image. That snippet defines colors as TGAColor constants and warns in a comment that the channel order is BGRA, not RGBA. Getting that wrong is a common first surprise, since red and blue swap silently.

Where tinyrenderer stops being the right tool

The most important limitation is stated by the author, not inferred: this is training material that only loosely follows the structure of modern 3D graphics libraries. It is not a rendering engine. There is no scene graph, no material system, no windowing, and no GPU path. If your goal is a shippable renderer, a game, or anything that needs to hit a frame budget, tinyrenderer gives you none of that.

The second limitation is pedagogical rather than technical. The README says the author provides his own source code but does not recommend using it directly, because doing the work yourself is essential to understanding the concepts. Copying our_gl.cpp and moving on defeats the purpose of the course. The README also puts a time cost on the work: students typically need 10 to 20 hours of programming to start producing such renderers. That estimate is for the course as taught, and it assumes you are writing the code rather than reading it.

There is also a practical gap around assets and output. The program takes OBJ paths and writes TGA, and the README does not document error handling for missing or malformed models, nor any rollback or recovery behavior. If a model fails to load, the README does not say what the binary does.

How it differs from a ray tracer or a GPU API

The related searches around tinyrenderer point at tinyraytracer, Raytracing in C, and Scratchapixel, and the contrast is worth making explicit. A ray tracer traces rays from the camera into the scene and asks what each ray hits; tinyrenderer rasterizes, projecting triangles onto the image plane and filling the pixels they cover. Those are different mental models with different failure modes, and the rasterization path is the one that maps onto how OpenGL and DirectX actually work.

Against a GPU API, the difference is where the code runs. The README frames the whole exercise as demonstrating how OpenGL, Vulkan, Metal, and DirectX work by writing a simplified clone from scratch, with no third-party libraries, especially graphics-related ones. When you call a draw call in a real API, the driver does the rasterization on hardware; here you write that rasterization yourself in C++ and it runs on the CPU. That is exactly why the course is useful for people who find the API opaque, and exactly why its output is not competitive with a GPU for anything real.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-07-29. The course is self-contained: the lectures live on the homepage, the code is in the repository, and there is no dependency tree to track because the README states the task uses no third-party libraries, especially graphics-related ones. That makes the upgrade surface unusually small. There are no retrieved releases, so there is no versioned upgrade path to plan around; you follow the master branch or a specific commit. The README itself points to a pinned commit for the student starting point, which is the more reproducible way to work through the lectures.

The licence is recorded as NOASSERTION, which means the repository's LICENSE.txt was not matched to a standard identifier by the tooling that produced this metadata. The README does not discuss licensing, and the file itself is not reproduced here. If you intend to reuse any of the code beyond private study, read LICENSE.txt directly and decide for yourself; that is the only authoritative source in the repository.

Editorial conclusion

Adopt tinyrenderer if you want to understand what a graphics API does for you and you are willing to write the rasterizer yourself; the README states plainly that using the author's code directly is not recommended. Skip it if you need a renderer for production output, GPU work, or anything with a window, because it produces images and nothing else. Before starting, verify two things: that your toolchain can run the CMake build, and that you have the obj/ assets the sample command expects.

Frequently asked questions

What is tinyrenderer used for?

It is a computer graphics course. The README says the author aims to demonstrate how OpenGL, Vulkan, Metal, and DirectX work by writing a simplified clone from scratch, taking a triangulated mesh and textures as input and producing an image as output.

What is the difference between OpenGL and software rendering in tinyrenderer?

In tinyrenderer the rasterization runs on the CPU in C++ code you write yourself, while OpenGL performs it on the GPU through a driver. The README describes the project as a software renderer and says the author does not intend to show how to write GPU applications, only how they work.

What is the difference between software rendering and GPU rendering?

The README states tinyrenderer is a software renderer that loosely follows the structure of modern 3D graphics libraries, so the same stages (rasterization, depth testing, shading) are implemented in ordinary C++ rather than on graphics hardware. The output is a TGA image file, not a displayed frame.

What does graphics rendering mean in the context of tinyrenderer?

The README treats rendering as turning a 3D model composed of a triangulated mesh and textures into an image. There is no graphical interface; the program simply generates a TGA file such as framebuffer.tga.

Official sources

  1. Issues
  2. Project website
  3. README
  4. ssloy/tinyrenderer on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ssloy-tinyrenderer.svg)](https://hysenlabs.com/projects/ssloy-tinyrenderer)