本文是在学习《Ray Tracing in One Weekend》这本书时,为了方便所做的学习记录。
原文地址: https://github.com/RayTracing/raytracing.github.io
注意:本文不包含任何代码仅记录思路
总结
这是三部中的第一本,主要介绍如何用几何的方式绘制一个图形,然后给它加上材质让它更真实,最后介绍了一下散焦模糊,来模拟相机所能达到的效果。在介绍材质阶段用到了三种材质,分别用到了漫反射,反射和折射。
输出圆形
首先先从上到下从左到右输出颜色,颜色三通道值都为0-255,简单的输出成ppm格式,可用xnview去读这个图像,当然也可以用opencv直接输出图像。然后进行射线的构造 F(x)=A*x+B,在3维空间中,B是射线出发点的坐标,A是射线的方向向量,加上系数x,即可表示这条射线上所有的点。遍历屏幕上所有的像素点,用每个像素的横坐标/屏幕宽度,纵坐标/屏幕高度,求出当前位置的比例,用这两个值分别乘上横坐标和纵坐标再相加上左下角坐标即可得出目标点,与原点连线即可得到方向向量。
球的方程
(
x
−
c
x
)
2
+
(
y
−
c
y
)
2
+
(
z
−
c
z
)
2
=
R
2
(x-c_x)^2+(y-c_y)^2+(z-c_z)^2=R^2
(x−cx)2+(y−cy)2+(z−cz)2=R2用点来表示,P点代表在圆上的点,C点代表圆心,公式变成了
(
x
−
c
x
)
2
+
(
y
−
c
y
)
2
+
(
z
−
c
z
)
2
=
d
o
t
(
(
P
−
C
)
,
(
P
−
C
)
)
(x-c_x)^2+(y-c_y)^2+(z-c_z)^2=dot((P-C),(P-C))
(x−cx)2+(y−cy)2+(z−cz)2=dot((P−C),(P−C)) 即我们找一个在圆上的P点它与圆心之间的距离就是R,那么
d
o
t
(
(
P
−
C
)
,
(
P
−
C
)
)
=
R
2
dot((P-C),(P-C))=R^2
dot((P−C),(P−C))=R2现在我们要用光线找到这个圆,就是用射线与圆求交,即找到既满足射线方程又满足圆方程的点,这些点都可以用方程f表示,其中x代表系数
F
(
x
)
=
A
∗
x
+
B
F(x)=A*x+B
F(x)=A∗x+B假设当系数为t时圆与直线相交
d
o
t
(
(
A
∗
t
+
B
−
C
)
,
(
A
∗
t
+
B
−
C
)
)
=
R
2
dot((A*t+B-C),(A*t+B-C))=R^2
dot((A∗t+B−C),(A∗t+B−C))=R2
t
2
∗
d
o
t
(
B
,
B
)
+
2
t
∗
d
o
t
(
B
,
A
−
C
)
+
d
o
t
(
(
A
−
C
)
,
(
A
−
C
)
)
−
R
2
=
0
t^2*dot(B,B)+2t*dot(B,A-C)+dot((A-C),(A-C))-R^2=0
t2∗dot(B,B)+2t∗dot(B,A−C)+dot((A−C),(A−C))−R2=0 用一元二次函数的判别式
b
2
−
4
a
c
b^2-4ac
b2−4ac 来判别在圆内圆外还是圆上。到此时已经输出一个圆的形状。
加上材质
在完成与圆的求交之后,已经可以输出一个圆形,为了让它看起来更加真实,要增加材质。光线照射到物体上之后,光线会发生反射,折射等效果,这是有物体本身的属性决定的,材质就是一些物体属性的定义。
书中简单的举例:用-1到1之间的随机数来表示光线接触到物体反弹的方向,每次反弹衰减50%的能量。这里的50%就是定义的属性,把这些属性抽象出来就是材质。
lambertian材质
对于lambertian材质来说光线不是被散射就是被吸收,光线与物体交点加上物体当前法线在加上一个随机的得出的方向,这三者减去光线与物体的交点就是散射光,然后再定义一个物体的光线吸收率。
金属材质
而对于金属来说,表面是光滑的,所以能到达反射的效果,反射光的方向不是随机的,这里借用一下原图来推导反射的计算公式 红色的向量就是我们想求的反射向量,做出入射向量的延长线,这时反射向量的值为v+2B,B等于法线向量与入射光在标准化法线向量上的投影的乘积,由于入射光线的方向相反所以要取负值dot(v,n)*n,所以
反
射
向
量
=
v
−
2
∗
d
o
t
(
v
,
n
)
∗
n
反射向量=v-2*dot(v,n)*n
反射向量=v−2∗dot(v,n)∗n
在金属材质上还可以在反射的端点给一个圆的范围,来是反射的方向具有随机性打造一种模糊感。
介质材质
金属之后还有一种像玻璃,水,钻石之类的介质材料,这种材料可以把光线折射 ,折射公式 n ∗ s i n ( θ ) = n ’ ∗ s i n ( θ ’ ) n*sin(θ)=n’*sin(θ’) n∗sin(θ)=n’∗sin(θ’),其中n代表折射率。θ是折射角度。
散焦模糊(Defocus Blur)
散焦模糊,在摄影上又叫景深,增加了两个属性aperture(光圈),focus_dist(成像位置),光圈的增大会导致图片出现散焦而模糊,可以调节成像的位置,改变图片的清晰度,使图片尽可能清晰。实际上我们模拟的场景的光量是足够的,这里做散焦模糊只是为了模拟,产生散焦的效果。