Subroutine Logo
Subroutine
← Back to Articles Physics & Math Advanced 6 min read

Ray Tracing vs. Rasterization: The 3D Rendering Pipeline

Comparing GPU polygon projection and Z-buffering against Monte Carlo path tracing and BVH bounding volume hierarchies.

Published: 2026-08-09
#Graphics#Ray Tracing#GPU#C++#Rust#Physics#Math

Rendering realistic 3D scenes requires resolving a core question in computer graphics: how does light interact with geometric surfaces before entering the camera viewport?

For decades, real-time graphics engines (DirectX, Vulkan, OpenGL) relied almost exclusively on Rasterization. However, the advent of hardware-accelerated RT cores (NVIDIA RTX, Vulkan RT) enabled real-time Path Tracing.


1. Summary & Key Architectural Tradeoffs

Rendering ParadigmGPU RasterizationPath Ray Tracing
ComplexityO(Triangles+Pixels)O(\text{Triangles} + \text{Pixels})O(Rays×log2(BVH Triangles))O(\text{Rays} \times \log_2(\text{BVH Triangles}))
ReflectionsScreen-space approximations (SSR)Physically exact recursive reflection rays
Global IlluminationStatic baked lightmapsReal-time Monte Carlo bounce sampling
Hardware RequirementStandard GPU Raster PipelineDedicated Hardware Acceleration (RT Cores)

2. Interactive Ray Tracing vs. Rasterization Simulation

Test light ray propagation, reflection bounces, and object occlusion in the interactive optical scene below:

3D Graphics Rendering Pipeline

GPU Rasterization (Z-Buffer) vs. Monte Carlo Ray Tracing

Ray Bounces:3 Bounces
Ray Count:16 Rays
Optical Ray Bounces Active

3. GPU Graphics Pipelines

graph TD
    subgraph Raster["GPU Rasterization Pipeline"]
    V["3D Mesh Vertices"] --> VS["1. Vertex Shader"]
    VS --> RAST["2. Triangle Rasterizer (NDC)"]
    RAST --> FS["3. Fragment Shader & Z-Buffer"]
    FS --> FB["4. 2D Framebuffer"]
    end

    subgraph RayTrace["Path Ray Tracing Pipeline"]
    CAM["Camera Pixel Ray"] --> BVH["1. BVH Tree Traversal"]
    BVH --> HIT["2. Geometry Ray Intersect"]
    HIT --> REF["3. Spawn Reflection / Shadow Rays"]
    REF --> ACC["4. Accumulate Radiant Energy"]
    end

4. Multi-Language Renderer Code Implementation

Ray-Geometry Intersection Code
raytracer.cpp
C++20 (Ray-Sphere Intersect)
#include <cmath>

struct Vec3 {
    float x, y, z;
    float dot(const Vec3& v) const { return x * v.x + y * v.y + z * v.z; }
    Vec3 operator-(const Vec3& v) const { return {x - v.x, y - v.y, z - v.z}; }
};

struct Ray {
    Vec3 origin;
    Vec3 direction;
};

struct Sphere {
    Vec3 center;
    float radius;
    
    bool intersect(const Ray& ray, float& t_hit) const {
        Vec3 oc = ray.origin - center;
        float a = ray.direction.dot(ray.direction);
        float b = 2.0f * oc.dot(ray.direction);
        float c = oc.dot(oc) - radius * radius;
        float discriminant = b * b - 4 * a * c;
        
        if (discriminant < 0) return false;
        t_hit = (-b - std::sqrt(discriminant)) / (2.0f * a);
        return t_hit > 0.001f;
    }
};

5. Optics Math: Specular Reflection Equation

When a light ray D\mathbf{D} hits a surface with unit normal vector N\mathbf{N}, the reflected ray direction R\mathbf{R} is:

R=D2(DN)N\mathbf{R} = \mathbf{D} - 2(\mathbf{D} \cdot \mathbf{N})\mathbf{N}