-
Whitted-Style Ray Tracing
-
Why Ray Tracing?
光栅化不能解决全局特效的问题:
– 很难做到软阴影
– Glossy这种材质很难模仿
– 间接光照难以做到
光栅化很快,但是质量相对较低
光线追踪是精确的,但是时间非常慢
– 光栅化:实时 光线追踪:离线
– 1帧 ~= 10K CPU hours
-
Basic Ray-Tracing Algorithm
Light Rays
– 光沿着直线传播
– 光与光不会碰撞
– 光路可逆的,即眼睛可以发射出可逆的光线(当你凝视深渊的时候,深渊也在凝视着你)
光线追踪其实就是从相机出发,去还原世界的图像。
Ray Casting
Ray Casting – Generate Eye Rays
– 我们认为人眼是针孔摄像机
– 我们认为反射是完美反射
– 只考虑最近的交点(完美的解决了深度测试)
Ray Casting – Shading Pixels
从摄像机发射光线,找到最近的交点,连接交点与光源,判断是否在阴影中,然后再屏幕上着色。
光线需要弹射很多次怎么算呢?
Recursive(Whitted-Style) Ray Tracing
一条光线弹射多次的颜色都会叠加到一个像素上去。
-
Ray-Surface Intersection
Ray Equation
Ray Intersection With Sphere
点又在球上,又在光线上,所以需要满足两个方程:
t有1个解则相切,2个解相交,无解相离。
Ray Intersection With Implicit Surface
解出t值之后,交点就在o+td
Ray Intersection With Triangle Mesh
通过光线和三角形求交点,可以判断点是否在物体内,如果是奇数个交点,那么在物体内,偶数个交点在物体外。
这里有一个问题,遍历所有三角形太慢?如何加速这个检测的过程?留着以后讲。
如何去做光线和三角形的交点?
首先如何做光线与平面的相交。
首先定义平面,平面是一个法线和一个点。
只要P点满足下面的公式,那么P点在平面上。
那么光与平面的交点一定在光线上,也一定在平面上。
记得检测t是否大于0。
接下来通过叉乘求点是否在三角形内。
那么有没有更简单的方法一次性判断点是否在三角形内呢?
Moller Trumbore Algorithm
用重心坐标可以表示三角形内的任意一个点。
这里我们假定解下面的公式很简单,那么得到了答案以后怎么办?
判断解值是否合理:t是否大于0,1-b1-b2,b1,b2都是非负数
通过上面的公式,可以一次性将光线和三角形求交算出来。
-
Accelerating Ray-Surface Intersection
对于复杂场景,遍历三角形求交点基本上是不可能的。
如何加速?
这里有一个很重要的概念,包围盒
Bounding Volumes
类似于Unity中的碰撞体。
如果一个物体连包围盒都碰不到,那么更加碰不到物体了。
长方体是什么?长方体是三个对面形成的交集。
光线如何与一个包围盒求交?
我们可以轻松得到光线什么时候进入各个对面(tmin),什么时候离开对面(tmax)。
那么如何判断光线与盒子的关系呢?求交集!
我们接下来来看三维的情况:
光线进入所有对面,才算是进入盒子,光线离开任意一个对面,则算是离开盒子。即进入的时间求最大值,离开的时间求最小值。
如果进入的时间小于离开的时间,那么则是有交点。
这里需要处理时间的问题。因为光线是射线,而不是直线。
如果对面垂直于坐标轴,那么计算会更加简单,我们直接考虑光线在各个分量上的速度即可。