提要

经过上次的学习,我们已经可以建立一个简单的光线追踪的场景,接下来,我们继续我们的征程。

今天要得到的最终效果如下:



光线与物体求交

在光线追踪算法中,最重要的就是求光线与物体的相交,也就是实现IntersectResult Object::isIntersected(CRay _ray)方法。  因为我求得交点之后就可以对该点的像素进行计算,然后显示,后续的很多效果(透明,反射....)还有算法的优化加速,都是在对相交算法的改进。

之前已经讨论了光线与球体的相交,今天讨论平面,三角形和多个物体,且不考虑折射和反射。

平面

平面在空间几何中可以用一个向量(法向量)和平面中的一点P0来表示。

平面就是满足下式的点集:n.(P-P0)=0

得到:n.P=d;d=n.P0;


给定射线p(t)=p0+tu,平面方程为n.p+d=0,将p(t)带入到平面方程,最后求得t:

t=(-d-(n.p0))/(n.u)


三角形

渲染中的基本图元 包括点,线,还有三角形,建模中多面体大部分都是用三角形的拼接来表示。

首先来看一下空间三角形的表示。

假设用空间上a,b,c三点来表示一个三角形。


则三角平面内的任意一点可以表示为




法线向量表示为

将光线向量= e + td带入,得到:

当B>0,r>0且B+r<1的时候,P在三角形内。
对方程进行变换并改写成矩阵的形式:




由克莱莫法则求得B,r,t



其中
 

则三角形和光线求交的伪代码可以表示为:

boolean raytri (ray r, vector3 a, vector3 b, vector3 c, interval [t0 , t1 ]) compute t if (t < t0 ) or (t > t1 ) then     return false compute γ     if (γ < 0) or (γ > 1) then return false compute β if (β < 0) or (β > 1 

0

收藏

拳四郎

404篇文章,22W+人气,0粉丝