(个人笔记,由于刚开始学习再加上英语不太好,所以有的地理解的可能不太对,望指正)
Chapter 4 Ray Tracing
渲染的就是将一系列对象作为输入,产生像素输出的过程,由此可以将这个过程分成两种不同的处理方式:
- object-order rendering:每个对象决定影响的像素
- image-order rendering:每个像素决定影响它的对象
4.1 The Basic Ray-Tracing Algorithm
基本的光线追踪器包含三个部分:
- ray generation:光线的起点和方向
- ray intersection:相交的物体
- shading
4.2 Perspective
最简单的投影方式是平行投影(parallel projection),3D顶点沿着投射方向直到到达投影平面,它产生的结果是根据投射方向和投影平面决定的:如果投射方向与投影平面垂直则是正交(orthographic)否则是斜交(oblique)。
平行投影通常用于机械和建筑方面,它保持平行关系,另一种投影是透视投影(perspective projection)
4.3 Computioning Viewing Rays
在3D场景中从观察点 e e e发出的到投影面上的一点 s s s的3D参数直线方程是:
p ( t ) = e + t ( s − e ) p(t) = e + t(s - e) p(t)=e+t(s−e)
光线是在摄像机坐标中产生的
4.3.1 Orthographic Views
对于正交视图,光线的方向是 − w -w −w。正交视图的范围定义如左图所示:
位于 ( i , j ) (i,j) (i,j)位置的像素位于光栅图像的位置的计算方法:
u = l + ( r − l ) ( i + 0.5 ) / n x v = n + ( t − b ) ( j + 0.5 ) / n y ( 4.1 ) u = l + (r - l)(i + 0.5)/n_x \ \ \ \\ v = n + (t - b)(j + 0.5)/n_y \ \ \ (4.1) u=l+(r−l)(i+0.5)/nx v=n+(t−b)(j+0.5)/ny (4.1)
在正交视图中,可以使用以下流程进行ray generation:
通过4.1计算u,v
ray.direction = -w
ray.origin = e + uU + vV
其中e为原点,{U,V}为基
4.3.2 Perspective Views
正交视图的定义如右图所示:
ray generation的流程与正交视图类似
通过4.1计算u,v
ray.direction = -dw + uU + vV
ray.origin = e
4.4 Ray-Object Intersection
光线的方程是 e + t d e+td e+td,所以要找到相交的物体就是找到一个t>0时的交点,如果要找最近的相交物体,就是从 t 0 = 0 , t 1 = + ∞ t_0=0,t_1=+\infty t0=0,t1=+∞开始循环逐步缩小范围,最终确定相交物体。
4.4.1 Ray-Sphere Intersection
给定一个光线
p
(
t
)
=
e
+
t
d
p(t)=e+td
p(t)=e+td和一个隐式圆的表达式
f
(
p
)
=
0
f(p)=0
f(p)=0,可以通过
f
(
e
+
t
d
)
f(e+td)
f(e+td)来获取交点。
如果圆的圆心位于
c
=
(
x
c
,
y
c
,
z
c
)
c=(x_c,y_c,z_c)
c=(xc,yc,zc),半径为
R
R
R的圆,它的表达式为:
( p − c ) ( p − c ) − R 2 = 0 (p-c)(p-c) - R^2 = 0 (p−c)(p−c)−R2=0
所以求交点也就是求:
( e + t d − c ) ( e + t d − c ) − R 2 = 0 (e+td-c)(e+td-c) - R^2 = 0 (e+td−c)(e+td−c)−R2=0
的解。
4.4.2 Ray-Triangle Intersection
要求光线与平面的交点,就是求
e + t d = f ( u , v ) e+td=f(u,v) e+td=f(u,v)
的解,结合三角形的重心坐标系,可以得到
e + t d = a + β ( b − a ) + γ ( c − a ) e+td=a+\beta(b-a)+\gamma(c-a) e+td=a+β(b−a)+γ(c−a)
只有当 β > 0 , γ > 0 \beta>0,\gamma>0 β>0,γ>0并且 β + γ < 1 \beta+\gamma<1 β+γ<1时光线才与三角形相交。
4.4.3 Ray-Polygon Intersection
如果光线与多边形所在平面相交,如何确定交点在多边形内,可以将交点和多边形投影到xy平面,之后通过2维平面中点与多边形位置关系(做射线检查交点个数)的方法就可以确定交点与多边形的关系。也可以将多边形分解成多个三角形来进行处理。
4.4.4 Intersecting a Group of Objects
将光线与所有物体相交,找到t值最小的一个即为相交物体。
4.5 Shading
4.5.1 Lambertian Shading
Lambertain Shading是观察方向无关的。
公式:
L = k d I m a x ( 0 , n ∙ l ) L = k_dImax(0, n\bullet l) L=kdImax(0,n∙l)
4.5.2 Blinn-Phong Shading
h = v + l ∣ ∣ v + l ∣ ∣ h = \frac{v+l}{||v+l||} h=∣∣v+l∣∣v+l
如果h与n的夹角越小,高光反射应该越强。
L = k d I m a x ( 0 , n ∙ l ) + k s I m a x ( 0 , n ∙ h ) p L = k_dImax(0, n\bullet l) + k_sImax(0, n\bullet h)^p L=kdImax(0,n∙l)+ksImax(0,n∙h)p
4.5.3 Ambient Shading
为了防止没有光直接照射的物体显示为完全黑色的问题,可以添加一个默认的环境光。
L = k a I a + k d I m a x ( 0 , n ∙ l ) + k s I m a x ( 0 , n ∙ h ) p L = k_aI_a + k_dImax(0, n\bullet l) + k_sImax(0, n\bullet h)^p L=kaIa+kdImax(0,n∙l)+ksImax(0,n∙h)p
4.5.4 Multiple Point Lights
光的一个重要性质是可以叠加的所以有:
L = k a I a + ∑ i = 1 N [ k d I i m a x ( 0 , n ∙ l i ) + k s I i m a x ( 0 , n ∙ h i ) p ] L = k_aI_a + \sum_{i=1}^{N}[k_dI_imax(0, n\bullet l_i) + k_sI_imax(0, n\bullet h_i)^p] L=kaIa+i=1∑N[kdIimax(0,n∙li)+ksIimax(0,n∙hi)p]
4.6 A Ray-Tracing Program
根据之前说明的如何创建一条射线,如果判断与射线相交的对象以及如何对相交点进行着色的内容可以得到伪代码:
for each pixel do
compute view ray
if (ray hits an object with t∈[0, ∞)) then
Compute n
Evaluate shading model and set pixel to that color
else
set pixel color to background color
4.6.1 Object-Oriented Design for a Ray-Tracing Program
4.7 Shadows
4.8 Ideal Specular Reflection
反射方向公式:
r = d − 2 ( d ∙ n ) n r = d - 2(d\bullet n)n r=d−2(d∙n)n
在现实世界中,光在反射之后会有能量的损耗,不同颜色的光的损耗量不同,可以通过递归调用:
c o l o r c = c + k m r a y c o l o r ( p + s r , ϵ , ∞ ) color c = c + k_mraycolor(p+sr,\epsilon, \infty) colorc=c+kmraycolor(p+sr,ϵ,∞)
为了防止无限递归,可以增加一个最大深度。