Architecture Overview
This project intentionally uses a small architecture: one executable, a short rendering pipeline, explicit data ownership, and no workflow or AI control frameworks in the repository.
Design Principles
- One binary, one job -
ray_tracerbuilds scenes, launches kernels, and writes a PPM image. - CPU orchestrates, GPU executes - scene setup, BVH construction, and CLI parsing stay on the host; intersection and shading stay on the device.
- Modules by responsibility - code is organized by rendering concerns, not by abstract patterns or framework layers.
- Prefer deletion over knobs - remove dead branches and duplicate pathways instead of keeping rarely used switches alive.
- Explicit data flow - upload scene data once, render, download the framebuffer once.
System Flow
Module Boundaries
| Module | Responsibility | Keep it limited to |
|---|---|---|
include/core/ | Math primitives and CUDA helpers | vec3, rays, constants, CUDA error utilities, random helpers |
include/geometry/ | Spatial queries and hit data | AABB, BVH, primitive intersection, hit records |
include/rendering/ | Rendering algorithms | camera, materials, lights, shading, kernels, validation |
include/scene/ | Scene assembly | scene containers and built-in scene factories |
include/image/ | Output formatting | tone mapping and PPM writing |
src/ | Program entry | CLI parsing and top-level orchestration only |
tests/ | Behavioral verification | unit and property tests |
Core Features Kept
- Blinn-Phong shading
- Monte Carlo path tracing
- BVH acceleration
- Ray sorting for the supported Phong single-sample path
- Built-in demo, Cornell, and random scenes
- PPM output and tone mapping
Explicitly Out of Scope
- AI workflow frameworks or repository-side agent control layers
- Duplicate architecture tracks for the same rendering step
- Secondary changelog systems outside the root
CHANGELOG.md - Half-integrated features that are neither tested nor documented
- Configuration-heavy abstractions that do not improve performance or clarity
Refactoring Rules
- Put new logic in an existing module unless a new boundary is clearly justified.
- Prefer plain structs and free functions over indirection-heavy abstractions.
- Reuse existing scene, material, and geometry types before adding variants.
- Handle CUDA failures explicitly with
CUDA_CHECK()/CUDA_CHECK_LAST(). - Remove dead code instead of hiding it behind unused flags.
- Update tests and documentation when behavior changes.
- Record project history only in the root
CHANGELOG.md.
Data Ownership
- Host code owns CLI parsing, scene construction, BVH construction, and file output.
- Device code owns the hot rendering path.
- Scene buffers are copied to the GPU before rendering.
- The framebuffer is copied back once rendering is complete.
Practical Guidance
- If a feature does not improve image quality, performance, or maintainability, do not add it.
- If two code paths solve the same problem, converge on one.
- If a document describes a system that no longer exists, delete or rewrite it.