PN-Traniger

    首先先从Bezier说起:

一条直线上有两个端点,P0和P1,那么直线可以写成 y = kx+b ,其实也就是P(t) = (1-t)P0 + P1 (这是个插值函数),(小注,我时常把这两个东西系数写反,其实代入0和1就不会弄错了)T的值范围定义为[0,1]的话,就是这线段上所有的点了(集合)

当然P是(x,y)或(x,y,z)是向量,(1-t)和t是权(高中时候和另外一个同学被椭圆和直线之类的题目折磨的痛不欲生,后来发现了公式,不过自己忘了,反正很有意思的,快速求解数学题目…..)

两个点可以定义一条直线,曲线是什么了,利用微积分的思想,曲线是无穷直线的集合.如何通过几个点,给上0-1的参数求出位于这条曲线上的其他点了?还是老办法,插值.Paul De Casteliau发明了插值方法,是三个点的,加速有P1,P2,P3三点,一方面,我们希望这三个点都应该影响插值后点,但是上面那个式子只是两个点的,于是我们两两求点,然后对中间结果再做插值是再显然不过的了

Temp1 = (1-t)P0+tP1 Temp2 = (1-t)P1+tP2 然后result = (1-t)Temp1 + t Temp2,这是一种很自然的想法,化简下这个式子,把P0,P1,P2整合到同一个式子中:

P(t) = (1-t)^2 P0 + 2t(1-t) P1 + t^2 P2

    这是三个点,很显然的,我们可以以此类推,四个点,五个点,系数就是杨辉三角系数,或者C(m,n) ,(a+b)^n a是(1-t) ,b是t ,n是点数-1

    (WORD文档不会输入公式,懒得从网上找图,n阶的就不写了)

    然后代入t从0到1,生成了一系列的点,结果非常之好啊,如下图:

    PN-Traniger

    这东西就是Bezier曲线,这东西有个非常好的特性,假设我们要做对这曲线仿射变换(具体概念请搜索) ,那么有两种方案

        第一种,变换原来的点,然后再来进行插值计算

        第二种,变换插值计算后的点(数量变多了)

    第一种是可行的,因为Bezier的特性保证了,具体证明可代入计算(代入证明即可)

 

    前文已经说过,这只是一种很自然的想法,当然,还有别的插值方法 比如说我们可以利用系数的导数,这也是可行的!

        学过高数忘得不太惨的同学,一定能记得求导(微分)出来就是切向量()

        P(t)' = d/dt()(P(t)) ,当t=0和1时,分别是P0和P1的切向量(Bezier曲线的切向量)

        假设有四个控制点的话,那么

        P(0)' = 3(P1-P0)

        P(1)' = 3(P3-P2)

    我们可以利用这个导数(斜率不是吗) P1和P2可以分别通过P0和P3球

    当然,这样球出来的曲线和Bezier曲线是一样的,只是式子不同(最终化简还是一样的)

    最关键的是,我们可以自己选择 切向量的求法,比如说用Pi-1和Pi+1之间定义Pi处的切向量

    同理,还有Bezier表面,(四个点) 在横向上求两次插值,然后对这两次插值的结果求插值(注意,这里有两个系数,横向用系数u,纵向用系数v)

    同理,可以扩展为3X3的点4X4的点

    前文已经说完,让我们进入正文,三角形怎么进行插值?系数又有几个了,有一种很自然的思维方式同样存在(重心坐标系)

        P = uA+vB+wC;     (u+v+w=1) (u,v,w为对应面积比(http://www.cnblogs.com/leohawke/archive/2014/03/08.html 此文已讨论重心坐标)

    当定义非共面的三角形时,增加三个点即可(二阶) 三阶为下图这种, 三角形中也存在控制点

        PN-Traniger

    PN三角形(point-normal) 是采用Bezier三角形,加上了法线的考虑(来球控制点).假设三角形有三个点(每个点有自己的法线,通过球平均而来,所以可能是不同的)

        假设改变上有一点P21 = 2/3 A + 1/3B 即在AB的1/3处,然后将P21投影至A处的切平面(A有切线Na),就可以得到一个控制点P210

        切平面垂直于A点,且沿着Na 投影,其实也就是将向量 B-A/3 投影至Na上,我们可以得到投影长度,然后变可以得到在Na上的那部分

        为什么要减,我是不清楚的(如图)

        PN-Traniger

    图上成的钝角,我们可以设V21 = - (Na*(B-A)/3)Na (钝角乘出来是负的,反之) ,于是控制点

        P210 = P21+V21(P21 = 2/3 A + 1/3B)

    还有一个控制点,系数自然是2/3,只不过法线是B的法线(更靠近B),同理可以新增加6个点.中间那个点就等于(所有新生成的点相加除以4 减掉 原来的除以6)

        设V = A+B+C/3

        设E = P210+P120+…./6 中心点P111 = E+ (E-V)/2

    P下标的含义很有意思,就是Bezie三次曲线对应的幂 http://www.cnblogs.com/mikewolf2002/archive/2012/08/21/2648421.html 具体代码参加此文

    构造法线并没有使用三阶公式,过于复杂,于是只需要生成三个新法线,对点和法线使用同样的参数进行插值就行了

    生成控制法线用原来的平均值是个不错的想法,不过有时会造成错误.比如下图:

    PN-Traniger正确的法线应该是斜的才对,

    我们可以求 P1和P2的法线(存在这样一个平面 Np = Norm(P1-P2) )然后将平均法线 视为一个入射光,法线是Np(入射平面是P1和P2所成平面)求出反射向量,即是我们要求得控制法线了

    至于求反射,HLSL提供了内置函数

你可能感兴趣的:(tr)