Top Related Projects
A brief computer graphics / rendering course
3D line art engine.
Tiny but powerful single file wavefront obj loader
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
stb single-file public domain libraries for C/C++
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Quick Overview
The zauonlok/renderer repository is a software renderer implemented in C. It's a lightweight, cross-platform 3D graphics renderer that doesn't rely on hardware acceleration, making it suitable for learning and experimentation with computer graphics concepts.
Pros
- Educational tool for understanding 3D graphics rendering pipelines
- Cross-platform compatibility (Windows, macOS, Linux)
- Minimal dependencies, making it easy to set up and use
- Implements various rendering techniques, including rasterization and ray tracing
Cons
- Limited performance compared to hardware-accelerated renderers
- May not be suitable for real-time applications or complex scenes
- Lacks some advanced features found in modern graphics APIs
- Documentation could be more comprehensive for beginners
Code Examples
- Creating a window and initializing the renderer:
#include "platform.h"
#include "graphics.h"
int main(void) {
window_t *window;
framebuffer_t *framebuffer;
window = window_create("Renderer", 800, 600);
framebuffer = framebuffer_create(800, 600);
while (!window_should_close(window)) {
// Rendering code here
window_draw_buffer(window, framebuffer);
}
framebuffer_release(framebuffer);
window_destroy(window);
return 0;
}
- Loading and rendering a 3D model:
#include "model.h"
#include "scene.h"
model_t *model = model_load("path/to/model.obj");
scene_add_model(scene, model);
scene_draw(scene, framebuffer);
- Implementing a simple ray tracer:
#include "raytracer.h"
void trace_ray(ray_t *ray, scene_t *scene, color_t *color) {
intersection_t intersection;
if (scene_intersect(scene, ray, &intersection)) {
// Calculate lighting and shading
color_set(color, 1, 1, 1); // White for simplicity
} else {
color_set(color, 0, 0, 0); // Black background
}
}
Getting Started
-
Clone the repository:
git clone https://github.com/zauonlok/renderer.git
-
Build the project:
cd renderer make
-
Run the example:
./build/renderer
This will compile and run a basic example using the renderer. You can modify the example code in main.c
to experiment with different rendering techniques and 3D models.
Competitor Comparisons
A brief computer graphics / rendering course
Pros of tinyrenderer
- More comprehensive tutorial-style approach with detailed explanations
- Focuses on software rendering fundamentals from scratch
- Easier to follow for beginners in computer graphics
Cons of tinyrenderer
- Less feature-rich compared to renderer
- Primarily educational, not optimized for performance
- Limited to basic rendering techniques
Code Comparison
tinyrenderer:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
bool steep = false;
if (std::abs(x0-x1)<std::abs(y0-y1)) {
std::swap(x0, y0);
std::swap(x1, y1);
steep = true;
}
// ... (rest of the function)
}
renderer:
void draw_line(int x0, int y0, int x1, int y1, uint32_t color) {
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2;
// ... (rest of the function)
}
Both repositories implement line drawing algorithms, but renderer uses a more optimized approach with integer arithmetic, while tinyrenderer focuses on clarity and educational value.
3D line art engine.
Pros of ln
- Written in Go, offering better performance and concurrency support
- Provides a more extensive set of geometric primitives and operations
- Includes built-in support for SVG output
Cons of ln
- Less focus on photorealistic rendering compared to renderer
- Lacks some advanced shading and lighting techniques
- More limited in terms of material properties and texturing capabilities
Code Comparison
renderer:
void rasterize_triangle(const float *v1, const float *v2, const float *v3,
int width, int height, unsigned char *framebuffer) {
// Triangle rasterization code
}
ln:
func (p *Path) BoundingBox() Box {
// Bounding box calculation for paths
}
Summary
renderer is a C-based software renderer focusing on photorealistic rendering techniques, while ln is a Go-based 3D line rendering library emphasizing geometric operations and vector output. renderer offers more advanced shading and lighting capabilities, whereas ln provides better performance and a wider range of geometric primitives. The choice between the two depends on the specific requirements of the project, such as desired output format, rendering style, and performance needs.
Tiny but powerful single file wavefront obj loader
Pros of tinyobjloader
- Specialized for loading OBJ files, providing efficient and focused functionality
- Widely used and well-maintained, with regular updates and community support
- Header-only library, making it easy to integrate into existing projects
Cons of tinyobjloader
- Limited to OBJ file format, while renderer supports multiple 3D model formats
- Lacks rendering capabilities, focusing solely on loading 3D models
- May require additional libraries or code for full 3D rendering pipeline
Code Comparison
tinyobjloader:
tinyobj::ObjReader reader;
reader.ParseFromFile("model.obj");
auto& attrib = reader.GetAttrib();
auto& shapes = reader.GetShapes();
auto& materials = reader.GetMaterials();
renderer:
model_t *model = load_model("model.obj");
mat4_t scale = mat4_scale(1.0f, 1.0f, 1.0f);
mat4_t translation = mat4_translate(0, 0, 0);
mat4_t model_matrix = mat4_mul_mat4(scale, translation);
draw_model(context, model, model_matrix);
tinyobjloader is focused on efficiently loading OBJ files, while renderer provides a more comprehensive 3D rendering solution with support for multiple file formats and rendering capabilities.
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
Pros of imgui
- Widely adopted and battle-tested in production environments
- Extensive documentation and community support
- Cross-platform compatibility with multiple backends
Cons of imgui
- Focused solely on GUI creation, not a full rendering engine
- Steeper learning curve for beginners due to its extensive feature set
Code Comparison
imgui:
ImGui::Begin("My Window");
ImGui::Text("Hello, world!");
ImGui::Button("Click me");
ImGui::End();
renderer:
scene_t *scene = scene_create();
model_t *model = model_load("model.obj");
scene_add_model(scene, model);
renderer_draw_scene(renderer, scene);
Key Differences
- imgui is primarily for creating immediate mode GUIs, while renderer is a software 3D renderer
- renderer focuses on 3D graphics rendering, while imgui is for creating user interfaces
- imgui has a more extensive feature set for UI creation, whereas renderer provides basic 3D rendering capabilities
Use Cases
- imgui: Ideal for creating debug interfaces, tools, and simple GUIs in games or applications
- renderer: Suitable for learning 3D graphics concepts or creating simple 3D renderers from scratch
Community and Support
- imgui: Large community, frequent updates, and extensive third-party extensions
- renderer: Smaller project with fewer contributors, primarily for educational purposes
stb single-file public domain libraries for C/C++
Pros of stb
- Broader scope with multiple single-file libraries for various tasks (image loading, font rendering, etc.)
- More mature and widely adopted in the industry
- Designed for easy integration into existing projects
Cons of stb
- Less focused on 3D rendering specifically
- May require more setup and configuration for 3D graphics tasks
- Potentially steeper learning curve due to its broader scope
Code Comparison
renderer:
void draw_triangle(float *zbuffer, vec4 clip_coords[3], vec3 varying_tri[3][MAX_VARYING], shader_struct *shader) {
// Triangle rasterization and shading code
}
stb:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes) {
// PNG writing implementation
}
Summary
renderer is a focused 3D software renderer, while stb is a collection of single-file libraries for various tasks. renderer is more specialized for 3D graphics, while stb offers a broader range of utilities. stb is more widely adopted and easier to integrate, but may require more setup for specific 3D rendering tasks. The code comparison shows renderer's focus on 3D graphics operations, while stb provides utility functions for tasks like image writing.
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Pros of pbrt-v3
- More comprehensive and feature-rich physically-based renderer
- Extensively documented with accompanying textbook
- Larger community and wider adoption in academia and industry
Cons of pbrt-v3
- Steeper learning curve due to complexity
- Heavier resource requirements for compilation and execution
- Less suitable for beginners or quick prototyping
Code Comparison
pbrt-v3:
Spectrum Li(const RayDifferential &ray, const Scene &scene,
Sampler &sampler, MemoryArena &arena, int depth = 0) const {
ProfilePhase p(Prof::SamplerIntegratorLi);
Spectrum L(0.f);
// ... (implementation details)
}
renderer:
void shader_fragment(void *varyings, void *uniforms, void *output) {
fragment_varyings *v = (fragment_varyings*)varyings;
fragment_uniforms *u = (fragment_uniforms*)uniforms;
vec4_t *color = (vec4_t*)output;
// ... (implementation details)
}
Summary
pbrt-v3 is a more advanced and feature-complete physically-based renderer, ideal for research and production use. It offers extensive documentation and community support but requires more resources and expertise. renderer, on the other hand, is simpler and more accessible, making it suitable for learning and quick prototyping. The code comparison highlights the difference in complexity and language choice between the two projects.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Software Renderer
This is a shader-based software renderer written from scratch in C89 with minimal dependencies, available for Windows, macOS, and Linux.
Features
- Cross platform
- Minimal dependencies
- Shader based
- Homogeneous clipping
- Back-face culling
- Perspective correct interpolation
- Depth testing
- Alpha testing
- Alpha blending
- Cubemapped skybox
- Skeletal animation
- Tangent space normal mapping
- Shadow mapping
- ACES tone mapping
- BlinnâPhong reflection model
- Physically based rendering (PBR)
- Metallic-roughness workflow
- Specular-glossiness workflow
- Image-based lighting (IBL)
- Orbital camera controls
- PBR material inspector
Download
Pre-built binaries for Windows, macOS, and Linux are available for download from the Releases page.
Build
To build the software renderer from source, a C89 compiler and development files for your window system are required.
Windows
Install Visual Studio
with C++ support and run build_win32.bat
.
macOS
Install Command Line Tools for Xcode with the command below and
run build_macos.sh
.
xcode-select --install
Linux
Install GCC and Xlib with the following commands and run build_linux.sh
.
Ubuntu / Debian
sudo apt install gcc libx11-dev
Fedora / RHEL
sudo dnf install gcc libX11-devel
openSUSE / SUSE
sudo zypper install gcc libX11-devel
Bonus
A CMakeLists.txt
file is provided for generating project files using
CMake (see examples below).
Visual Studio
mkdir build
cd build
cmake -G "Visual Studio 16 2019" ..
start Renderer.sln
Xcode
mkdir build
cd build
cmake -G Xcode ..
open Renderer.xcodeproj
Makefile
mkdir build
cd build
cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ..
make
Usage
Launch
If the software renderer is launched without arguments, one of the available scenes will be chosen randomly. To display a specific scene (see below), additional arguments should be supplied. The command line syntax is:
Viewer [test_name [scene_name]]
Controls
- Orbit: left mouse button
- Pan: right mouse button
- Zoom: mouse wheel
- Rotate lighting: A D S W
- Reset everything: Space
Inspector
For PBR scenes, a material inspector that is very similar to the layers view of Marmoset Viewer is provided. Double click to bring it up.
Screenshots
References
Rendering pipeline
Physically based rendering
File formats
Miscellaneous
- Homogeneous clipping
- Barycentric coordinates
- Perspective correct interpolation
- Skeletal animation
- Tangent space normal mapping
- Ambient occlusion
- ACES tone mapping
- Orbital camera controls
- Xlib programming guide
- Type-safe dynamic array
License
Top Related Projects
A brief computer graphics / rendering course
3D line art engine.
Tiny but powerful single file wavefront obj loader
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
stb single-file public domain libraries for C/C++
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot