Library / SDK
keith2018/SoftGLRender avatar
keith2018/SoftGLRender

SoftGLRender: one scene rendered three ways, one of them in software

Tiny C++ Software Renderer / Rasterizer, and implements OpenGL and Vulkan renderers for comparison

1,152 stars166 forksC++MIT

At a glance

What is it?
SoftGLRender is a small C++ rasteriser that implements the GPU pipeline on the CPU, and then implements the same pipeline again with OpenGL and Vulkan so you can switch between them at runtime and compare. Its stated purpose is to be a starting point for developers learning modern graphics programming.
Who is it for?
Adopt SoftGLRender if you are learning modern graphics programming and want a pipeline you can read end to end, with a real GPU path to compare against and a viewer that loads GLTF assets so there is something to look at. Do not adopt it as a rendering engine for a product, because a CPU rasteriser is the wrong tool the moment frame time matters, and the OpenGL and Vulkan paths exist here to be compared, not to replace a mature engine.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 96 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 October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The point is comparison, not speed

SoftGLRender is described as a tiny C++ software renderer and rasteriser that implements the main steps of the GPU rendering pipeline, and the second half of that sentence matters more than it first appears. The project also adds OpenGL and Vulkan renderer implementations, and you can switch between them, Software, OpenGL or Vulkan, in real time while running. That single feature is the reason the repository exists. The stated purpose is to provide a starting point for developers who want to learn about modern graphics programming, and the way that is achieved is by writing the pipeline once by hand and then writing it twice more against real APIs so that the output can be compared frame by frame. The software path covers point, line and polygon rasterization, texture mapping, depth testing and colour blending, and it emulates vertex shaders and fragment shaders in C++ rather than running them on a GPU. Three-dimensional models in GLTF format are loaded by Assimp, and GLM is used as the math library. The repository is MIT licensed, has no GitHub releases, and the last push was on 2026-07-20, with CI workflows for CMake builds on macOS, Windows and Linux.

The software pipeline, stage by stage

The feature list for the software renderer is a checklist of the standard pipeline, and reading it in order is the best short course available. It starts with vertex shading, then view frustum culling for lines and triangles, then perspective correct interpolation, then back-front face culling. After the geometry stage comes point, line and triangle rasterization, followed by fragment shading, and the shader derivatives dFdx and dFdy are supported so that screen-space texture filtering works in the same way it does on a GPU. The depth and blending stage lists depth test and alpha blending, and also early Z test and reversed Z, which are the two tricks a modern engine uses to avoid shading fragments that will be discarded. On top of that sits MSAA 4x. Two optimisations are named. Rasterization is block based with multi-threading support, and there is SIMD work in barycentric coordinate calculation and in the shader's varying interpolation. What makes this list pedagogically valuable is that each item is a real concept from a modern GPU, and each is implemented in code you can read in the same repository as the equivalent hardware path.

Texture mapping with mipmaps, filtering and storage layouts

Texture handling is where a naive rasteriser usually falls short, and the section on texture mapping is correspondingly detailed. Mipmaps generation and sampling are supported, and the sample parameters Lod, Bias and Offset are exposed, which are the three knobs that control how a texture is sampled at a given derivative. All kinds of texture filtering and wrapping mode are implemented. The last group of features is the one most people would not expect in a teaching project: image storage tiling and swizzling, with three described layouts. Linear means pixel values are stored line by line, commonly used as an image RGBA buffer. Tiled means block base storage, where inside the block pixels are stored as Linear. Morton means block base storage, where inside the block pixels are stored in a morton pattern, described as similar to zigzag. The reason to support them is that they are what a GPU's texture memory actually does, and a renderer that cannot read a tiled or swizzled image cannot consume the compressed and packed formats that modern assets ship in. The viewer also supports a skybox in both cube map and equirectangular form, and shadow mapping.

One abstract Renderer, three implementations

The architectural centre of the project is an abstract renderer class that all three backends implement, and the class definition in the README is the clearest statement of the design. It is a factory-shaped interface. You create a frame buffer with createFrameBuffer and an offscreen flag, a texture with createTexture taking a TextureDesc, a vertex array object from a VertexArray, a shader program, and pipeline states from a RenderStates. You create uniform blocks and samplers by name, and then drive the frame with beginRenderPass taking a frame buffer and clear states, setViewPort, setVertexArrayObject, setShaderProgram, setShaderResources, setPipelineStates, draw, and endRenderPass. The separation is what makes the runtime switching possible, since the viewer code above the abstraction never learns which backend it is talking to. The directory layout matches it exactly, with src/Render holding the abstraction and the vertex, texture, uniform and framebuffer types, with the Software, OpenGL and Vulkan implementations each in their own subdirectory.

Building it, and the Vulkan environment it needs

The prerequisites are short: CMake 3.10 or higher, and a compiler environment with C++11 support. If you want the Vulkan renderer, the documentation asks for the Vulkan SDK from the official website, installed on your system, with the installation process varying by operating system, and then the environment variables VULKAN_SDK, VK_ICD_FILENAMES and VK_LAYER_PATH set to the path where you installed the SDK. Getting the code is the usual pair of options, a clone or a ZIP download:

bash
git clone https://github.com/keith2018/SoftGLRender.git

Then you configure and build, and the build produces the executable and copies assets into a bin directory:

bash
mkdir build
cmake -B ./build -DCMAKE_BUILD_TYPE=Release
cmake --build ./build --config Release

and you run it from the output directory:

bash
cd bin/Release
./SoftGLRender

The third-party list is what tells you what kind of project this is: assimp for asset loading, glfw for the window, glm for math, glslang for shader compilation, imgui for the config panel, json11 for the asset index, stb_image for image loading, and vma, the Vulkan Memory Allocator. The repository vendors these under third_party/, and the asset side lives under assets/ with GLTF models and skybox textures and an assets.json index of all model and skybox materials.

The viewer, and the parts that are not about rasterising

The Viewer directory is where the project becomes a program you can actually use rather than a library, and it contains the parts that have nothing to do with rasterisation. There is GLTF loading based on Assimp, the camera and its controller, the config panel, and render pass management. The config panel is based on imgui, which is how the software, OpenGL and Vulkan backends get switched at runtime, and there is an orbit camera controller so you can move around a loaded model. The shading models listed are Blinn-Phong, PBR and IBL, and the image pipeline has FXAA anti-aliasing and RenderDoc in-application frame capture, which is a genuinely useful feature for a learning project because you can inspect exactly what your rasteriser produced frame by frame. The shader sources are split in two, with Shader/GLSL holding the GLSL code for the OpenGL and Vulkan renderers and Shader/Software holding the C++ simulation of vertex shaders and fragment shaders, so the two paths can be compared by reading the same algorithm twice in two languages.

Where SoftGLRender is the wrong tool

The limits are obvious from the purpose, but they are worth stating because a software rasteriser is sometimes mistaken for an embedded or headless rendering solution. This one is not, because the optimisation work, the block-based multithreaded rasterisation and the SIMD paths exist to make a teaching implementation legible and reasonably quick, not to make it competitive with a GPU. If your requirement is to render at interactive rates on hardware without a GPU, this is the wrong project, and you would want a rasteriser designed for that rather than one whose OpenGL and Vulkan backends exist to be compared against. The second limit is asset scope. The bundled models and skyboxes are there so the project runs out of the box, and the assets.json index is how the viewer finds them, but there is no asset pipeline, no compression handling and no content pipeline, so anything beyond the bundled set is your problem. The third is the packaging. There are no GitHub releases, the build is a source build with a vendored third_party tree, and the C++11 floor plus the C++ standard library dependency mean you are compiling a real project rather than installing a package. The fourth is that the project is a teaching artefact in the sense that it prioritises showing the pipeline clearly over shipping features, so a team looking for a renderer to build on should expect to write a great deal themselves.

Editorial conclusion

Adopt SoftGLRender if you are learning modern graphics programming and want a pipeline you can read end to end, with a real GPU path to compare against and a viewer that loads GLTF assets so there is something to look at. Do not adopt it as a rendering engine for a product, because a CPU rasteriser is the wrong tool the moment frame time matters, and the OpenGL and Vulkan paths exist here to be compared, not to replace a mature engine. Before you build, install CMake 3.10 or newer with a C++11 compiler, set VULKAN_SDK, VK_ICD_FILENAMES and VK_LAYER_PATH if you want the Vulkan backend, and expect to supply your own assets since the bundled models and skyboxes live under assets/ with assets.json as their index.

Frequently asked questions

What is SoftGLRender?

It is a tiny C++ software renderer and rasteriser that implements the main steps of the GPU rendering pipeline, including point, line and polygon rasterization, texture mapping, depth testing and color blending, emulating vertex and fragment shaders in C++. It also implements OpenGL and Vulkan renderers you can switch to at runtime.

Why does the project have both a software and a GPU renderer?

The stated purpose is to give developers a starting point for learning modern graphics programming, and the three backends share one abstract Renderer class. Switching between Software, OpenGL and Vulkan while running lets you compare your own pipeline against the hardware path.

What do I need to build SoftGLRender?

CMake 3.10 or higher and a compiler environment with C++11 support. For the Vulkan renderer you also need the Vulkan SDK installed, with VULKAN_SDK, VK_ICD_FILENAMES and VK_LAYER_PATH set to the SDK path. The build uses `mkdir build`, `cmake -B ./build -DCMAKE_BUILD_TYPE=Release` and `cmake --build ./build --config Release`, and the executable runs from bin/Release as ./SoftGLRender.

Which third party libraries does SoftGLRender use?

assimp for 3D model loading, glfw for the window, glm as the math library, glslang for shader compilation, imgui for the config panel, json11, stb_image for image loading, and vma, the Vulkan Memory Allocator. They are vendored under third_party/ in the repository.

What licence is SoftGLRender released under?

The MIT License, with the LICENSE file at the repository root. The repository publishes no GitHub releases, and the last push to it was on 2026-07-20, with CI workflows for CMake builds on macOS, Windows and Linux.

Official sources

  1. Issues
  2. keith2018/SoftGLRender on GitHub
  3. License: MIT
  4. README
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/keith2018-softglrender.svg)](https://hysenlabs.com/projects/keith2018-softglrender)

Was this useful?