气态巨行星天文漫谈 · 第 3 轨道
脉冲星 PSR B1919+21 · 轨道半径 19.8 万 km · 3 颗卫星 · 行星环
在浏览器里渲染一个黑洞
银心那个会把光线掰弯的黑洞是怎么画出来的?从史瓦西半径讲到光线步进,以及吸积盘为什么一边亮一边暗。
- 发布
- 字数
- 697
- 阅读
- 2 分钟
银河中心那个黑洞,大概是这个博客里最耗算力的东西。它不是一张贴图,而是在着色器里对每一个像素,模拟一束光线在弯曲时空中的轨迹。
史瓦西半径
一个不旋转、不带电的黑洞,由它的质量唯一确定。它的事件视界半径叫做史瓦西半径:
太阳如果被压缩成黑洞,史瓦西半径只有大约 3 公里。银河系中心的人马座 A*,质量约为 400 万个太阳,史瓦西半径约 1200 万公里。
光线为什么会弯
在广义相对论里,光沿着时空的“直线”(测地线)运动,而质量会让时空弯曲。对于史瓦西黑洞,光子轨迹可以写成一个很简洁的形式。令 为角动量,光子受到的“等效加速度”是:
这个式子的好处是:可以直接用来做数值积分。
光线步进
对屏幕上的每个像素,从相机发出一条光线,然后一小步一小步地往前推:
vec3 pos = rayOrigin;
vec3 vel = rayDir;
float h2 = dot(cross(pos, vel), cross(pos, vel));
for (int i = 0; i < 300; i++) {
float r = length(pos);
if (r < rs) { captured = true; break; } // 掉进视界
float dt = clamp(0.08 * r, 0.02 * rs, 0.6 * rs); // 越靠近步子越小
vec3 acc = -1.5 * rs * h2 * pos / pow(r, 5.0);
vec3 prev = pos;
vel += acc * dt;
pos += vel * dt;
if (prev.y * pos.y < 0.0) {
// 穿过了吸积盘所在的平面,累加吸积盘的颜色
}
}逃逸出去的光线,按最终方向去采样背景;掉进视界的光线,就是那片纯黑的阴影。
吸积盘:一边亮一边暗
吸积盘里的气体以接近光速绕黑洞旋转。朝我们运动的一侧,光被多普勒增亮;远离我们的一侧则变暗、变红。多普勒因子为:
再乘上引力红移 ,吸积盘就呈现出那种标志性的、不对称的光环。
为什么能看到黑洞“背后”的吸积盘
光线从吸积盘的远端出发,绕过黑洞上方弯向我们,所以我们会在黑洞的上方和下方看到一道弯曲的光弧——那其实是吸积盘的背面。电影《星际穿越》里的“卡冈图雅”让这个画面家喻户晓。
最内侧那一圈极细的亮环叫光子环:那是绕黑洞转了一圈甚至好几圈才逃出来的光。
下次飞到银心的时候,可以慢慢绕着它转一圈,看看光环是怎么随着视角变化的。