参考链接 https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/geometry-of-a-triangle
1、Geometry of a Triangle
首先你得知道三角形法线怎么计算。
然后,按照惯例,左手坐标系中的z轴指向屏幕方向(当x轴指向右侧时)
如图1,A叉乘B和B叉乘A不一样,模相同,但是方向相反。
再如上图,ccw和cw分别指counter-clockwise order和clockwise order。三颜色线表示三轴,ccw,cw表示叉乘的方向,可见得到的结果是反向的。
如上图,三颜色为三坐标轴,相机方向沿着z周的负方向,相机可以认为是人眼,人眼射出来的光线(做个比喻,实际上人眼是接受光线)沿着z轴负方向。在左右手坐标系中render不同。
为了使render结果相同,需要做一个关于XoY平面的对称变换,这样使得相机的方向仍然和法线的方向相反。
Ray-Triangle Intersection: Geometric Solution
第一步,找到光线和三角形的交点p。
光源0,光的方向R,则光的参数等式可以表达为 P = O + tR. 其中t是光源到点p的距离。因此为了找到P,我们需要知道t。平面的法向量,可以通过这个公式来计算:Ax+By+Cz+D=0. 其中,(A,B,C)就是平面的法向量,D是原点到平面的距离,x,y,z是平面上任意一点。于是我们可以计算出t
当然有两种特殊情况,第一种是当光线和平面平行时,此时没交集。第二种是,当光源在三角形的背后时,此时公式仍然可以计算出t的,但是t时小于0的,此时这种情况也应该忽略。
第二步,p是否在三角形内
我们已经找到了光线和平面的交点P。仍需要判断是否在三角形内。
如上图所示,光线可能和三角形有交点也可能没有,这个判断方法也很简单,称作为inside-outside test。(栅格化时也能用到)。
如图所示,假设向量A已经和x轴对齐,A向量是三角形的一条边,由顶点v0v1确定。第二条边B,由V0V2确定,则,两个向量的叉积表示Z周,也就是三角形的法向量。
如果B的坐标不是(1,1,0)而是(1,-1,0),此时得到的C‘=(0,0,-1)此时N点成C为负. 这说明当叉积和两条边的叉积同号时,再同一个方向。看图
由此可见,当NC为正时,都是在自己的左侧。然后一圈下来,
当点都在人的左侧时,说明这个点就在内部。意思就是说当叉积全部为正(同向)时,这个点就在内部。(逆时针走遍)。另外还有射线法,拓扑法等多种方法来判断是不是在多边形内部,具体可参考 https://blog.csdn.net/gkingzheng/article/details/81836308 这篇文章。
接下来时讨论single-side or double-side, 用兴趣的可以参考原文,这里不讨论。
质心坐标
在CG中,质心坐标尤其重要。质心p(这里指光线和三角形的交点,它的uvw不知道,需要计算)可以通过下面的公式进行计算。 其中ABC时三角形的三个顶点,uvw就是质心坐标,它们时标量,切满足u+v+w = 1, uvw都是正数。当uvw是负数或者大于1时,说明点在三角形外。
质心坐标又称为区域坐标( areal coordinates),尽管不是很常用,但也暗示了uvw与局部三角形有关系,看下图
三个子三角形cpa abp bcp,可以通过下面的公式计算质心坐标
其中三角形的面积可以通过两个向量的叉积来计算,这样就很容易的计算出质心坐标。
Using Barycentric Coordinates
对于每个顶点,都会储存数据,这叫vertex data。现在我们假设你希望A点是红色,B点是绿色,C点是蓝色。
显然,当光线和三角形交点的是三角形顶点时,直接拿数据就行,最容易。但是当交点在三角形内部或者边上时就比较麻烦。此时可以使用质心作弊爱哦来插值像素数据,这对shading过程,比如交点处的normal非常有用。一个object的Normal可以定义为每个面或者每个顶点basis(也即是face normal 和 vertex normal)。如果被定义为每个顶点,我们可以使用这个插值技巧来模拟一个平滑的shading,当这个三角形在理论上恶认为时平坦的。(由于交点处的normal是由每个点的normal决定,所以要保证每个顶点的normal相同)对于纹理的插值,同样适合。
Optimizing The Computation Of Barycentric Coordinates
上述的计算过程也可以优化,具体表现为,判断点是否在内部时,已经计算过叉积,计算三角形面积时,因为是求面积的比例,所以这里叉积后可以不除以2.
即
First remember that N=AB×ACN=AB×AC. Therefore we can rewrite the above above formula as:
Möller-Trumbore algorithm
这里一定要看看,由于公式复杂,就不转载了,详情直接点击原链接
留言