Convert Figma logo to code with AI

zauonlok logorenderer

A shader-based software renderer written from scratch in C89

2,451
273
2,451
1

Top Related Projects

A brief computer graphics / rendering course

3,271

3D line art engine.

Tiny but powerful single file wavefront obj loader

60,541

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

26,312

stb single-file public domain libraries for C/C++

4,879

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

  1. 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;
}
  1. 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);
  1. 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

  1. Clone the repository:

    git clone https://github.com/zauonlok/renderer.git
    
  2. Build the project:

    cd renderer
    make
    
  3. 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.

3,271

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.

60,541

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
26,312

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.

4,879

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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

SceneCommand
Viewer blinn azura
Viewer blinn centaur
Viewer blinn craftsman
Viewer blinn elfgirl
Viewer blinn kgirl
Viewer blinn lighthouse
Viewer blinn mccree
Viewer blinn nier2b
Viewer blinn phoenix
Viewer blinn vivi
Viewer blinn whip
Viewer blinn witch
Viewer pbr assassin
Viewer pbr buster
Viewer pbr crab
Viewer pbr dieselpunk
Viewer pbr drone
Viewer pbr helmet
Viewer pbr horse
Viewer pbr junkrat
Viewer pbr ornitier
Viewer pbr ponycar
Viewer pbr robot
Viewer pbr sphere
Viewer pbr spheres

References

Rendering pipeline

Physically based rendering

File formats

Miscellaneous

License

MIT License