代码地址:
目标
- 正确实现光线生成部分,并且能够看到图像中的两个球体。
- 需要对
Renderer.cpp
中的Render()
为每个像素生成一条对应的光 线,然后调用函数castRay()
来得到颜色,最后将颜色存储在帧缓冲区的相应像素中。
- 需要对
- 光线与三角形相交,正确实现Moller-Trumbore 算法,并且能够看到图像中的地面。
- 在
Triangle.hpp
中的rayTriangleIntersect()
使用课上推导的 Moller-Trumbore 算法来更新的参数。
- 在
光线生成
参考资料:
光线的生成是从原点开始,经过像素的中点,然后到达物体表面,由于给定的x、y坐标是像素的坐标即光栅化空间的,我们需要将它从光栅化空间转换到屏幕空间然后再转换到世界空间。这样才能计算光线与三角面相交。
由于默认原点在中心即(0,0),首先将像素缩放到(-1,1),然后将他映射到屏幕空间,过程如图所示:
代码如下:
由于y是从上往下的,而屏幕空间的y是从下往上的,要将代码中的y乘以-1。
1 | float x = (2 * ((i + 0.5) / scene.width) - 1) * scale * imageAspectRatio; |
使用fopen函数需要在属性->C/C++->预处理器->预处理器定义中添加以下宏
_CRT_SECURE_NO_WARNINGS
Moller-Trumbore 算法
只要对着之前的公式敲就可以了,要注意的是判断浮点数相等的非常不准确的一件事情,由于相交的条件为t>=0,正确的写法是加上一个eps,即tnear + epsilon > 0。
1 | bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig, |
最终结果如图: