Crappy Blackhole!

By Kunyu (Leo) Li

This project augments A3: Raytracing with a simplified Schwarzschild black hole lensing renderer. Each pixel’s viewing ray is treated as a null geodesic in Schwarzschild spacetime. The renderer integrates the ray using RK4 and determines the color based on:

Event horizon capture (black) Accretion disk crossing (emissive ring with a hot inner rim and orange outer region) Escape to background (black)

The implementation is intentionally modular: the geodesic “physics engine,” disk appearance, and background rendering are separated into small units for clarity and tuning.

Please note that this picture’s resolution is 1280 720, which took a long time to render on CPU. The default resolution is set to 320 180, and can be changed easily in main.cpp.

Features Added

1. Schwarzschild Null-Geodesic Integration

A small “physics engine” that models light-like trajectories around a Schwarzschild black hole using normalized units (G = c = 1).

2. Accretion Disk Crossing Test with Hit Point Output

The accretion disk is assumed to lie on the equatorial plane. Crossing detection checks sign changes across the plane and validates that the hit lies within [disk_r1, disk_r2], also returning an approximate hit point used for coloring.

3. Emissive Disk Shading (White-hot Inner → Orange Outer)

A simple movie-inspired (Interstellar) color ramp that produces a bright inner rim and warmer outer disk.

4. Parameter Abstraction for Fast Tuning

All integration and disk control values are grouped into a single parameter struct.

5. Main Pipeline Integration

The existing camera + viewing_ray(...) are reused to generate one ray per pixel. The shading call is swapped from raycolor(...) to raycolor_bh(...).

Acknowledgements

This project was inspired by the mathematical approach to black hole lensing in C++:

https://github.com/kavan010/black_hole

Also see kavan010’s YouTube video:

https://www.youtube.com/watch?v=8-B6ryuBkCM

While the core geodesic logic is conceptually aligned, the overall code structure, abstractions, and integration into the A3 pipeline are independently implemented.