C++ rendering computational photography

Rendering & Computational Photography

Physically-Based Rendering: Refractive Caustics

Caustics render 1 Caustics render 2

The scene was chosen specifically to stress-test the hardest light transport problems: caustics from curved refractive surfaces, color filtering through liquid, and frosted glass that diffuses while staying transparent.

The core implementation is a full photon mapping system: 25 million photons emitted from a targeted spotlight, stored in a KD-tree for O(log n) nearest-neighbor queries, and reconstructed with cone filter weighting. A rough dielectric BSDF handles the frosted bottle using GGX microfacet distribution. Final images combine Intel OIDN denoising with a custom bilateral filter to preserve caustic sharpness.

Flash/No-Flash Imaging

Flash/No-Flash result 1 Flash/No-Flash result 2

Flash photography is a trade-off: the ambient frame keeps the warmth and mood of the scene but is noisy, while the flash frame is sharp but kills the lighting. This project reimplements the flash/no-flash framework of Petschnigg et al. (SIGGRAPH 2004) from scratch in Python, using the flash frame to guide an edge-preserving denoise of the ambient rather than replacing it. Scenes were captured on a Canon EOS Rebel T7 specifically to stress-test each stage of the pipeline.

Beyond the core implementation, the paper's shadow test was found to fail under our radiometric setup (flagging 87% of one scene as shadow) and was replaced with a luminance-based reformulation. Additional extensions include a guided filter detail layer that removes the gradient-reversal halos the bilateral filter produces near strong edges, and an interactive continuous-flash slider that adjusts flash intensity after capture.