在光线追踪中一个重要的步骤就是从屏幕上投射出一道光线,并求解其与3D物体的焦点并执行反射/折射等过程然后继续反射或折射,关键问题是如何求出这道光线与3D物体(空间三角形)的焦点?因为只有求出焦点之后才方便求出其贴图坐标以及该点的法线,很好的一个方法就是用重心坐标系来表示该焦点坐标。 首先介绍一下重心坐标系(BaryCentric Coordinates)。
在三角形ΔABC中,P点可以用ABC三点来表示,即P=sA+qB+rC 且s+q+r=1。实际上在由ABC三点所定义的平面上的任意点P都可以用ABC三点来表示,当0<s<1 0<q<1 0<r<1时点P落在三角形内部,即射线与三角形相交。 求解点P。
先前看过一个解法,来自MIT Open Course的Ray Tracing(Fall 2003)课程,大致方法如下: 因为 s+q+r=1,故有s=1-q-r,由此得P(q,r) = (1-q-r)A+qB+rC,化简得P(q,r) = A–(B-A)q+(C-A)r,现假设眼睛(射线起点)位置坐标围R,观察(射线)方向为D,则此射线上任意一点可以表示为P(t)=R+tD,假如三角形上的一点与射线相交,则有P(t)=P(q,r),即R+tD=A-(B-A)q+(C-A)r,将三个坐标分量带进去可得线性方程组: Rx+tDx=Ax-(Bx-Ax)q+(Cx-Ax)r Ry+tDy=Ay-(By-Ay)q+(Cy-Ay)r Rz+tDz=Az-(Bz-Az)q+(Cz-Az)r 写成矩阵形式即 由克莱姆法则即可求解三个变量 当q+r<1 且q>0r>0时交点即在三角形内部。 |A|=-[(A-B)ⅹ(C-A)]·D 当|A|>10-5 And |A|<105时返回 但是在实践中我发现一个问题,就是由s=1-q-r求出的s存在精度不高的问题,由克莱姆求解过程中涉及太多的乘法导致数据精度损失过大的问题,最终实际上s+q+r≠1,大约是s+q+r=1.000005,所以我们应该由三个方程变量分别为s,q,r构成的方程组来求出精度会比较高,并且尽量减少乘法的次数以保证精度。 用面积来求s,q,r: 由上面的知识我们知道s=Ts/T,q=Tq/T,r=Tr/T,而由给定射线及三角形三顶点可以直接求出焦点坐标。 1.射线上任意一点P(t) = R+tD; 2.假如P(t)在三角形平面上,则应满足平面方程(PX-X0)A+(PY-Y0)B+(PZ-Z0)C=0; 3.其中该平面的法线N=(NA,NB,NC),(X0,Y0,Z0)是平面上任意点; 4.将P(t)=R+tD带进方程即可得 (NARX+NBRY+NCRZ)+(NAtDX+NBtDY+NCtDZ)-(NACX+NBCY+NCCZ)=0; 5.或者表示为N·R+N·tD-N·C=0; 6.所t=(N·C-N·R)/N·D,法线N可由(A-B)ⅹ(A-C)求得,此方法并不会执行背面剔出因为法线方向不确定。 7.因为A×B=|A||B|sinθ=SΔABC/2 8.所以Ts/2=Normalize((B-P)ⅹ(C-P)); 9.s=Ts/Normalize(AⅹB) 9.用类似的方法还可以单独求出Tq,Tr 因为是后来才看到《实时计算机图形学》上关于射线三角形相交的算法介绍,相比较于后面自己弄出来的面积算法效率要高不少,乘法运算次数更少,在求解t的时候我已经消耗掉3个点乘,但是还是作为自己思考的一个结果写出来吧。这个方法不仅在光线追踪中很重要而且在实时游戏中也扮演重要角色,用途很广。 |
空间三角形与射线相交并求交点的重心坐标系表示
最新推荐文章于 2022-01-31 12:45:22 发布
空间三角形与射线相交并求交点的重心坐标系表示
2008-05-05 13:41