基于SQL的光线追踪器
摘要
完全使用ClickHouse SQL查询实现的光线追踪器,无需任何外部代码或UDF即可将图像渲染为PNG格式。演示了程序化地形、CSG几何体以及并行像素计算。
查看缓存全文
缓存时间: 2026/07/01 17:01
ClickHouse/RayTracer
来源:https://github.com/ClickHouse/RayTracer
RayTracer — 基于 ClickHouse SQL 的光线追踪器
ClickHouse 覆盖在 Perlin 噪声地形上
一个完全用 ClickHouse SQL 查询 编写的路径追踪器,通过 ClickHouse 的 PNG 输出格式直接渲染为 PNG 图片。无需用户自定义函数(UDF)和外部代码——单个 SELECT 语句即可计算每个像素。
它渲染出 ClickHouse 这个词,呈现为玻璃质感的铬色字母——灵感来源于 Andrew Kensler 著名的皮克斯名片式光线追踪器——并且在上图中,它悬浮在程序生成的景观之上,反射地形并在山丘上投下阴影。
另请参阅:
- NoiSQL — 用 SQL 查询生成音乐 (https://github.com/ClickHouse/NoiSQL)
- SQL Mandelbrot Benchmark (https://github.com/ClickHouse/sql-mandelbrot-benchmark)
- Click-V: 用 ClickHouse SQL 构建的 RISC-V 模拟器 (https://github.com/SpencerTorres/Click-V)
- DOOMHouse 是一个“类 Doom”的游戏引擎,完全使用 ClickHouse SQL 渲染 3D 图形 (https://github.com/arniwesth/DoomHouse)
工作原理
整个渲染器位于一个查询中:
- 像素对应行。
numbers_mt(width * height * samples)为每个(pixel, sample)生成一行;使用GROUP BY pixel对样本进行平均,输出列r, g, b(取值范围[0, 1])加上显式的x, y坐标列(pixel % width,intDiv(pixel, width))被写入PNG输出格式。显式坐标让写入器能按位置放置每个像素,因此行无需ORDER BY,且每个像素的重计算工作在所有核心上保持并行。 - 元组上的3D数学。 向量表示为
Tuple(Float64, Float64, Float64);dotProduct、L2Normalize、tuplePlus、tupleMultiplyByNumber等完成线性代数运算,包装在简短的 lambda 别名(va、vs、vm、vd、vn、vc、vref)中。 - 弹跳循环是
arrayFold。 每条光线在range(maxDepth)上的每一步折叠步骤中只进行一次镜面反弹——每个行内部有一个循环,因此行保持独立,渲染在所有 CPU 核心上并行。(第一个版本使用的是WITH RECURSIVECTE——参见下面的查询。) - 通过
arrayMap实现let绑定。 ClickHouse 的WITHlambda 是按名调用的,因此将值作为参数传递会重新展开表达式并使查询树膨胀。因此,中间变量通过arrayMap(x -> body, [expr])[1]这种单元素数组的“let”进行按值绑定。
几何体(构造实体几何,CSG)
- 圆柱体——用于直笔画的带平顶的圆杆(字母
l、i、k、H、u、e的横杠)。 - 环面(Tori)——圆形字母(
C、c、o、u、s、e),通过其符号距离场进行光线步进(ray-marching);C/c/s/e的开口是从环中减去一个方盒得到的。 - 球体——
i上的点,以及一个铬色“星球”,它是一个球体减去另一个球体。 - 定向盒 / 平行六面体——可用于平面笔画的形状。
因此场景涵盖了盒体、圆柱体、环面和球体,并使用了 CSG 的并集、差集(星球和字母开口)以及光线步进的距离场(环面)。
地形
高度场 z = amp · fBm(x, y),其中 fBm 对几个倍频程的晶格值噪声求和。相机光线通过光线步进与地形相交——步进跳过空旷的空气(它从射线首次下降到地形最大高度处开始),并线性插值表面交叉点,因此既快速又无步进条带效应。地形着色使用高度颜色渐变(水面→沙地→草地→岩石→雪地),加上暖色太阳和冷色天空环境光模型,步进阴影(地形自阴影以及字母投射的阴影),以及向天空方向的距离雾。
图库
ClickBulb——一个完全由球体构成的台灯跳入画面,跃至横幅后方,将光线穿过字母间隙,然后探头望向观众。每一帧都是相同的 ClickHouse SQL 查询,逐帧运行(全高清视频)。
| 皮克斯致敬 | CSG 图元 |
| 皮克斯致敬——字母由球体图元并集构成,铬色材质位于棋盘格之上。 | CSG 图元——字母由圆柱体、环面和球体雕刻而成。 |
| Perlin 地形 | ClickHouse 叠加地形 |
| Perlin 地形——独立的射线步进高度场。 | 组合——ClickHouse 叠加在地形上(上方的主图)。 |
运行方式
queries/ 目录中的每个文件都是完整且自包含的,并且参数化:图像尺寸来自 ClickHouse 的图像输出设置(在 SQL 中通过 getSetting 读取),每像素采样数来自 {SAMPLES:UInt32} 查询参数——一个查询即可渲染任意分辨率。使用以下命令渲染:
clickhouse local --output_format_image_width 2560 --output_format_image_height 1200 \
--param_SAMPLES 8 --queries-file queries/clickhouse_terrain.sql > out.png
| 查询 | 场景 | 分辨率 |
|---|---|---|
clickhouse_raytracer.sql | 皮克斯致敬,使用 WITH RECURSIVE 弹跳循环 | 640 × 256 |
clickhouse_raytracer_loop.sql | 相同场景,使用 arrayFold 循环(并行,更快) | 640 × 256 |
clickhouse_raytracer_primitives.sql | 从 CSG 图元雕刻的字母 | 1280 × 512 |
terrain.sql | Perlin 噪声地形 | 896 × 504 |
clickhouse_terrain.sql | ClickHouse 叠加在地形上(主图) | 2560 × 1200 |
这些查询由 generators/ 中的 Python 生成器生成;场景和弹跳深度在生成时编译进去,而图像尺寸和每像素采样数保持为所生成查询的运行时参数。例如,重新创建主图:
python3 generators/gen_combined.py 2560 1200 8 2 > scene.sql # 深度 2;W/H/采样数为运行时参数
clickhouse local --output_format_image_width 2560 --output_format_image_height 1200 \
--param_SAMPLES 8 --queries-file scene.sql > scene.png
渲染任意文本
球体横幅生成器(gen.py 和更快的 gen_fold.py)接受可选的第五个参数:要渲染的文本。文本根据 generators/font.py 中的 7 行位图字体(大写 A-Z、数字和常用标点符号;原始的混合大小写“ClickHouse”字形得以保留,因此默认渲染不变)进行布局,相机、光源和铬色球体会自动重新居中于横幅。
python3 generators/gen_fold.py 640 256 16 4 "HELLO SQL" > hello.sql
clickhouse local --output_format_image_width 640 --output_format_image_height 256 \
--param_SAMPLES 16 --queries-file hello.sql > hello.png
无需渲染即可预览 ASCII 艺术横幅:python3 generators/font.py "HELLO SQL"。
在其他数据库上尝试
- 🐛 CedarDB:可运行,但慢 33 倍且有 bug:https://github.com/cedardb/issues/issues/71
- ☠️ DuckDB:无法运行,尝试了多种方法——使用数组和递归 CTE,但它连最小分辨率的图像都无法处理。
参见基准测试。
致谢
灵感来源于 Andrew Kensler 的 名片式光线追踪器 和 Paul Heckbert 的最小光线追踪器——重新构想为纯 ClickHouse SQL。
许可证
Creative Commons Attribution-NonCommercial-ShareAlike 4.0,与 ClickBench (https://github.com/ClickHouse/ClickBench) 相同的许可证。
相似文章
Show HN: 从零编写C++光线追踪器,无AI依赖
一位开发者从零构建了Luz,这是一个零依赖的C++20路径追踪器,具备蒙特卡洛路径追踪、全局光照、BVH加速以及Blender到Luz导出器功能。
@raydistributed: 在Snowflake上试用基于Ray的批量推理
Snowflake现在支持基于Ray的作业级批量推理,通过单一API调用即可在数百万非结构化数据点上执行分布式GPU,从而扩展模型推理。
让一个Rust数据库在游戏GPU的RT核心上运行空间查询,击败了H100
SedonaDB 0.4引入了RayBooster,它利用GPU光线追踪核心加速空间连接,性能超越H100;该研究成果已被VLDB 2026接收。
World Tracing:超越可见的生成式像素对齐几何
World Tracing 引入了一种生成式像素对齐几何表示,它在预测与观测像素对齐的3D点的同时,补全被遮挡的表面。它使用一个经过像素空间流匹配训练的扩散Transformer,在物体、场景和动态基准测试中的可见表面重建和完整几何生成上取得了强劲性能。
完整的 ClickHouse OLAP 引擎,编译为 WebAssembly
chDB 是一个完整的 ClickHouse OLAP 引擎,编译为 WebAssembly,可通过 wasm.chdb.io 的 SQL 终端直接在浏览器中执行 SQL 查询。