Skip to content
Tech News
← Back to articles

Ray Tracer in SQL

read original more articles
Why This Matters

This innovative project demonstrates how complex graphics rendering, typically reliant on specialized software and external code, can be achieved entirely within SQL queries. It highlights the potential for leveraging SQL's parallel processing capabilities for advanced computational tasks, potentially inspiring new approaches to data-driven graphics and simulations within the database ecosystem.

Key Takeaways

RayTracer — a ray tracer in ClickHouse SQL

A path tracer written entirely as ClickHouse SQL queries, rendering straight to a PNG via ClickHouse's PNG output format. No UDFs and no external code — a single SELECT computes every pixel.

It renders the word ClickHouse as glassy, chrome lettering — in the spirit of Andrew Kensler's famous Pixar business-card ray tracer — and, in the scene above, sets it floating over a procedurally generated landscape, reflecting the terrain and casting shadows on the hills.

See also:

How it works

The whole renderer lives in one query:

Pixels are rows. numbers_mt(width * height * samples) produces one row per (pixel, sample) ; samples are averaged with GROUP BY pixel , and the output columns r, g, b (in [0, 1] ) plus explicit x, y coordinate columns ( pixel % width , intDiv(pixel, width) ) are written to the PNG output format. The explicit coordinates let the writer place each pixel by its position, so the rows need no ORDER BY and the heavy per-pixel work stays parallel across all cores.

produces one row per ; samples are averaged with , and the output columns (in ) plus explicit coordinate columns ( , ) are written to the output format. The explicit coordinates let the writer place each pixel by its position, so the rows need no and the heavy per-pixel work stays parallel across all cores. 3D math on tuples. Vectors are Tuple(Float64, Float64, Float64) ; dotProduct , L2Normalize , tuplePlus , tupleMultiplyByNumber , … do the linear algebra, wrapped in short lambda aliases ( va , vs , vm , vd , vn , vc , vref ).

Vectors are ; , , , , … do the linear algebra, wrapped in short lambda aliases ( , , , , , , ). The bounce loop is arrayFold . Every ray is advanced exactly one mirror bounce per fold step over range(maxDepth) — a loop inside each row, so rows stay independent and the render parallelizes across all CPU cores. (The first version used a WITH RECURSIVE CTE instead — see the queries below.)

Every ray is advanced exactly one mirror bounce per fold step over — a loop inside each row, so rows stay independent and the render parallelizes across all CPU cores. (The first version used a CTE instead — see the queries below.) let -bindings via arrayMap . ClickHouse WITH lambdas are call-by-name, so passing a value as a parameter re-expands the expression and blows up the query tree. Intermediates are therefore bound by value with arrayMap(x -> body, [expr])[1] , a one-element-array "let".

... continue reading