https://raytracing.github.io/books/RayTracingInOneWeekend.html
《Ray Tracing In One Weekend》 由Peter Shirley(图形学虎书作者)所编写的的软渲光追三部曲第一本, 篇幅不多, 一共只有54页。

“近视眼版”

“我的近视治好了版”
开篇,我们软渲染要生成一张图片,原文使用了 一个非常简单的图片格式,一看就懂,我之前做软光栅化渲染器的时候做了一些 PPM 图片格式的笔记。
但是在 Jai 编程语言中, stb_image 就在标准模块中,我们可以非常方便的使用它写入 png 图片。参数分别是文件名,宽和高像素,组件数,数据指针和图片一行字节数。
stbi_write_png :: (filename: *u8, w: s32, h: s32,
comp: s32,
data: *void,
stride_in_bytes: s32)
-> s32 #foreign stb_image_write;
#import "Basic";
#import "stb_image_write";
width, height :: 512;
Pixel_Color :: struct { r, g, b : u8; }
main :: () {
pixels := NewArray(width * height, Pixel_Color);
count := 100;
for y: 0..height-1 {
for x: 0..width-1 {
color := *pixels[y * width + x];
color.r = cast(u8)(x * 255.99 / (width - 1));
color.g = cast(u8)(y * 255.99 / (height - 1));
color.b = 0;
}
}
stbi_write_png("test.png", width, height, 3, pixels.data, width * 3);
}

从摄像机到图片的每一个像素中心位置射出一条射线,射线如果与球面相交就渲染青色,否则就还是背景颜色。那么问题变成了如何确定光线是否与球面相交。
其实就是把射线方程代入球面方程,最后得到一个关于参数 t 的二次方程。

我还是更加喜欢把射线方程的原点叫作 O,原文使用的是 Q
整理后,我们得到 $\Delta$ 的各项。
$$ \begin{aligned} a &= \mathbf{d} \cdot \mathbf{d} \\ b &= -2\mathbf{d} \cdot (\mathbf{C} - \mathbf{Q}) \\ c &= (\mathbf{C} - \mathbf{Q}) \cdot (\mathbf{C} - \mathbf{Q}) - r^2 \end{aligned} $$

直线的射线检测是返回 bool ,现在改为 float ,返回最近的交点的对应参数 t 。这样从圆心到点 P ,就是法向量的方向,再进行单位化,映射到颜色。