Loading

Games101-作业5

说明

本次作业主要实现Whitted-光线追踪,作业框架只需要我们编写两个部分,一个是求解观测光线--从摄像机到每个像素的向量;第二个是判断射线与三角形的交点。

求解观测光线

需要对每个像素求解在实际物体空间中的向量,然后利用从摄像机到该像素位置定义一条入射光线。
首先需要知道光栅化屏幕大小是\(width*height\),而物体所进行的变换是从实际空间变为(-1,-1,-1)3D空间,再变换投影到(0,1)2D平面,最后根据(0,1) 到 (width,height)的转换进行光栅化。
现在是已知(width,height)上一点,求解该点对应实际物体的位置。

  1. 变换到(0,1)范围,这一步就是简单的数值缩放处理,以x为例

\[\begin{align} 0<x<width \\ 0<\frac{x}{width}<1 \end{align} \]

  1. 变换到(-1,-1)空间,这一步x与y稍微有点区别,在于x的(0,1)范围是沿着x正向的,而y的(0,1)范围是沿着y负向的,所以为了最后得到的图像方向朝上,需要使用-y

\[\begin{align} -1 < 2\cdot \frac{x}{width}-1 < 1\\ -1 < 1-2\cdot \frac{y}{height} < 1 \end{align} \]

  1. (-1,-1)变换到实际的投影平面即(x,y)并不一定是一个正方形,利用宽高比\(ratio = \frac{x}{y}\)来求解

\[\begin{align} -ratio < (2\cdot \frac{x}{width}&-1)\cdot ratio < ratio\\ -1 < 1-2\cdot &\frac{y}{height} < 1 \end{align} \]

  1. 利用FOV求解y在znear上的实际位置,在代码中假设了eyepos到znear的距离为1
Vector3f dir = Vector3f(x, y, -1);  == Vector3f(x, y, -1)-eyepos

所以有

\[\begin{align} -x < (2\cdot \frac{x}{width}&-1)\cdot ratio\cdot scale(FOV) < x \\ -y < (1-2\cdot &\frac{y}{height}) \cdot scale(FOV) < y \end{align} \]

最终该部分代码就是

x = (2.0*(i+0.5)/scene.width-1.0)*scale*(1.0*imageAspectRatio);
y = (1.0-2.0*(j+0.5)/scene.height)*scale;
Vector3f dir = Vector3f(x, y, -1); // Don't forget to normalize this direction!
dir = normalize(dir);

判断射线与三角形的交点

image
根据计算出来的\(t,b_1,b_2\)判断点是否在三角形内,

if(tnear>=0 && u >=0 && v >=0 && (1-u-v)>=0) return true;

tnear 即为射线o+td的t

posted @ 2024-03-12 11:41  XTG111  阅读(136)  评论(0)    收藏  举报