Open-source project
ssloy/tinyrenderer avatar
ssloy/tinyrenderer

tinyrenderer: 500 lines of CPU rendering built to explain what a graphics API hides

A brief computer graphics / rendering course

24,520 stars2,312 forksC++NOASSERTION

At a glance

What is it?
A bare C++ software rasterizer with no graphics libraries, paired with fourteen course notes that rebuild lines, triangles, a z-buffer, shading and shadows by hand, aimed at programmers who cannot yet read OpenGL code.
Who is it for?
Read the notes and write the code yourself if you are trying to understand a rasterization pipeline, and treat the repository as a teaching text rather than a renderer to ship. Do not reach for it when you need windowed output, interactive camera control, or GPU execution, because none of those are in the project.
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 108 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • ssloy/tinyrenderer24,520 ★ · +237
Star history
Repository2026-09-222026-11-14
ssloy/tinyrenderer24.3k24.5k

237 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The only starting point is a class that sets one pixel at a time

Everything here runs on the CPU. The task is set out with a hard constraint: using no third-party libraries, especially graphics related ones, generate an image from a 3D model composed of a triangulated mesh and textures. There is no graphical interface, the program simply generates an image. To keep the dependency list short there is a single class for handling TGA files, described as one of the simplest formats supporting RGB, RGBA and grayscale images, and it serves as the foundation for all image manipulation. At the beginning the only available functionality, besides loading and saving, is the ability to set the color of a single pixel. There are no built-in functions for drawing line segments or triangles. Every primitive in the finished renderer exists because somebody wrote it, which is exactly why the whole thing fits in about 500 lines.

Fourteen course notes carry the content, not the source file

The author opens by saying the code itself is of little interest and points readers to a sequence of lectures hosted on haqr.eu. Reading them in order gives you Bresenham line drawing, triangle rasterization, a primer on barycentric coordinates, hidden faces removal with a z-buffer, then camera handling split across two notes, a crude but simple approach first and a better one after it. The remaining notes cover shading, textures, tangent space normal mapping, shadow mapping, indirect lighting through screen space ambient occlusion, a bonus chapter on toon shading, and an afterword. The order matters, because each note assumes the rasterizer from the previous one exists.

The build takes an OBJ mesh path on the command line

There is no installer and no configuration file. You clone, point CMake at a build directory, compile in parallel, and hand the binary one or more model paths:

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

The result lands in a file named framebuffer.tga. The top level holds main.cpp, model.cpp and model.h for loading geometry, tgaimage.cpp and tgaimage.h for the image class, our_gl.cpp and our_gl.h, geometry.h, a CMakeLists.txt, and an obj directory holding the sample models. Two files exist for remote work rather than for rendering: .gitpod.yml and a Dockerfile that starts from gitpod/workspace-full and installs imagemagick.

It cannot show you a window, so every change ends in a file you open yourself

Look for anything resembling an interactive program and you will not find it. The project has no window, no camera controls bound to mouse or keyboard, no real time preview, no animation loop, no on screen overlay and no video output, because the program has no graphical interface and simply generates an image. If you want a different viewpoint you edit the camera code, rebuild and run again, then open the resulting TGA in an image viewer to judge the result. Formats other than TGA are out of scope too, since the writer only knows how to save TGA, and any conversion is left to an external tool such as the imagemagick package the Dockerfile installs. The consequence for a learner is that iteration is slow and visual feedback is indirect, so budget time for build, run and inspect cycles.

The starting point for students lives at one pinned commit

The finished source is on GitHub, but the author writes that he does not recommend using it directly, since doing the work yourself is essential to understanding the concepts. The initial source he hands to his students is kept separately, at the commit 706b2dfecff65daeb93de568ee2c2bd87f277860, and that snapshot is where the pixel setting class and the three test points still sit without any drawing code. Practically, that means a plain clone of master hands you the completed renderer while the pinned tree hands you the blank exercise, and mixing the two is the easiest way to skip the part that teaches anything. One more check before you build on it: the project carries no asserted license identifier, so LICENSE.txt is the file to read before reusing code from it.

TGA stores color components in BGRA order, and the first constants say so

The opening exercise declares its colors as constants and the comment on the first line is the warning: attention, BGRA order. The framebuffer is constructed as TGAImage framebuffer(width, height, TGAImage::RGB) at a fixed 64 by 64, and three points named ax, ay, bx, by, cx and cy are each written through the single pixel setter, producing the small framebuffer.tga that the course notes scale up for readability. If you are used to another library's struct layout and swap the channels, your output will be wrong in ways that look like a rasterization bug rather than a format bug.

A software renderer by design, and the top of the page says so

The strongest statement in the project is its warning: this is training material that loosely follows the structure of modern 3D graphics libraries, it is a software renderer, and the author does not intend to show how to write GPU applications. His stated aim is to demonstrate how OpenGL, Vulkan, Metal and DirectX work by writing a simplified clone from scratch, on the grounds that understanding this is essential for writing efficient applications using 3D libraries. Read that as a boundary, not a footnote. Finishing the notes gives you a mental model of the pipeline and the vocabulary to follow API documentation, but nothing in the repository teaches you a driver, a shader language, buffer management or command submission, so those still have to be learned elsewhere.

No releases and no tags, so the code only moves when master moves

The repository publishes no GitHub releases, which means there is no version number to pin and no changelog to read when something shifts. The last recorded commit is dated July 29, 2026, and the project is not archived, so work is still landing on the default branch. Without a release to hold onto, a commit hash is the only stable reference you have, and the student starting commit is one of them. The practical consequence is that a lesson written against one snapshot can quietly stop matching the source after an update, so record the hash you built along with each note you follow, and expect to read the current files yourself rather than trusting an older tutorial transcript.

Editorial conclusion

Read the notes and write the code yourself if you are trying to understand a rasterization pipeline, and treat the repository as a teaching text rather than a renderer to ship. Do not reach for it when you need windowed output, interactive camera control, or GPU execution, because none of those are in the project.

Frequently asked questions

What is rendering software like tinyrenderer actually used for?

In this course the input is a 3D model composed of a triangulated mesh and textures, and the output is a rendering. The program has no graphical interface and simply generates an image, saved as framebuffer.tga. The author uses the project as training material so students can see how 3D graphics libraries are put together.

What is the difference between OpenGL and a software renderer such as tinyrenderer?

The series writes a simplified clone from scratch in order to demonstrate how OpenGL, Vulkan, Metal and DirectX work. A warning at the top states that it is a software renderer and that the author does not intend to show how to write GPU applications, so the clone models the structure rather than the hardware path.

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

The renderer ships no graphics libraries and has no built-in functions for drawing line segments or triangles, so every primitive is implemented manually. It loosely follows the structure of modern 3D graphics libraries, which is why the course notes read like a simplified version of a real API pipeline.

What does graphics rendering mean in tinyrenderer?

It means turning a triangulated mesh and textures into an image file. Fourteen course notes walk from Bresenham line drawing through rasterization, barycentric coordinates, hidden face removal, camera handling, shading, normal mapping, shadow mapping and indirect lighting, and the finished program writes the result to 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)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/ssloy-tinyrenderer.svg)](https://hysenlabs.com/projects/ssloy-tinyrenderer)

Was this useful?