纹理映射:透视纹理映射

本文只涉及平面纹理映射,文章中提到多边形都是平面多边形.

  透视纹理映射可以根据多边形距离观察者远近而进行相应调整从而产生比仿射纹理映射更真实效果我们可以把纹理定义成为个 2维其中每个元素代表个颜色值幅位图定义为纹理是最直观最简便思路方法我们也可用纹理来定义纹理这样可以产生动态效果但这不是本文讨论范围我们把纹理所在 2维空间称为纹理空间或u, v空间其中可以把u看成是纹理空间x坐标v是y坐标般我们定义u, v范围在0到1的间虽然u, v可以为任何数般都将其定义在0到1的间这可以简化对些问题处理纹理映射就是把纹理空间坐标系映射到多边型坐标系这里我来解释下多边形坐标系两条不共线向量可以定义个坐标系, 如果这两个向量不垂直则将使该空间内图形产生倾斜效果而当这两个向量长度不相等时, 则会拉伸或压缩该空间内图形.我们在个3维空间多边形上取两个不共线向量, 则这两个向量可以定义个多边形坐标系,然后就可以写出这个3维空间平面方程了 (2维或n维空间平面方程也可同理求得).现在我举例介绍说明. 我们在个平面上取两点M1和M2可以得到个向量M=M1-M2, 在取两点N1和N2可以得到另个向量N=N1-N2, 最后再在该平面上取个点P1作为该平面空间原点. 将该点和视见坐标系原点相减 (如果你3D引擎没通过视见坐标系变换则和世界坐标系原点相减) 得到个向量W=P1-(0,0,0).则该平面方程为Ma+Nb+W,其中a,b为任何实数. 如果用矩阵表示话如下其中矩阵我称其为矩阵T) 
(x,y,z) =(a,b,1)× |Mx,My,Mz|
|Nx,Ny,Nz|
|Wx,Wy,Wz|

  如果我们用纹理空间u,v来代替a,b则可以得到纹理空间到多边形映射关系其中(Mx,My,Mz)对应纹理空间(1,0)点 (Nx,Ny,Nz)对应纹理空间(0,1)点(Wx,Wy,Wz)对应纹理空间(0,0)点 

(x,y,z)=(u,v,1)×T

  如此便完成了纹理到多边形映射.看起来很简单,但实际上我们工作还没完, 在大多数情况下我们是在用扫描线法来填充多边形同时完成纹理映射, 所以我们想知道在多边形经过透视投影后其在屏幕坐标系上和纹理映空间坐标系映射关系其关系可通过如下几步求得.首先视见坐标系或世界坐标系y 轴方向和屏幕坐标系y轴方向相反所以矩阵T应变换为如下形式 第步: | Mx, My, Mz|
|-Nx,-Ny,-Nz|
| Wx, Wy, Wz|

第 2步: (k*x/z,k*y/z,k)=(k*u/z,k*v/z,k/z)×T (等式1) 
  这里将x,y,z乘以k/z是做投影变换如果需要话我会写篇有关文章 
第 3步: (k*x/z,k*y/z,k)×T'=(k*u/z,k*v/z,k/z)×T×T' (等式2) 
  其中T'为T逆矩阵则第 3步等式可转换为如下形式
(k*x/z,k*y/z,k)×T'=(k*u/z,k*v/z,k/z) (等式3) 
  T'=T*/|T|所以等式3可变换为:
(k*x/z,k*y/z,k)×T*=|T|*(k*u/z,k*v/z,k/z) (等式4) 
  其中T*为T伴随矩阵|T|为T行列式上列等式又可转换成如下形式
(k*x/z,k*y/z,k)×T*=(k*|T|*u/z,k*|T|*v/z,k*|T|/z)

  由此可以看出求透视纹理映射关键就是T*矩阵些Internet上资料将该矩阵行称为magic value或magic vextor. 现在我给出T*形式(如果你不知道是如何得出可参考任何本线性代数书) 


|WyNz-NyWz, WyMz-MyWz, MyNz-NyMz|
|WzNx-NzWx, MxWz-WxMz, MxNz-NxMz|
|WxNy-NxWy, WxMy-MxWy, MyNx-NyMx|
  我们用其他符号来表示该矩阵各个项使该矩阵看其来更整洁些 

|Hx,Hy,Hz|
|Vx,Vy,Vz|
|Ox,Oy,Oz|
其中:Hx=WyNz-NyWz, Hy=WyMz-MyWz, Hz=MyNz-NyMz 
Vx=WzNx-NzWx, Vy=MxWz-WxMz, Vz=MxNz-NxMz 
Ox=WxNy-NxWy, Oy=WxMy-MxWy, Oz=MyNx-NyMx 
  如此等式4可变换成下列形式 

k*x/z*Hx +k*y/z*Vx+k*Ox=k*u*|T|/z
k*x/z*Hy+k*y/z*Vy+k*Oy=k*v*|T|/z 
k*x/z*Hz+k*y/z*Vz+k*Oz=k*|T|/z
  上诉等式两边同时除以k得到等式: 

x/z*Hx +y/z*Vx+Ox=u*|T|/z
x/z*Hy+y/z*Vy+Oy=v*|T|/z 
x/z*Hz+y/z*Vz+Oz=|T|/z
  如此我们便得到了多边形屏幕坐标和纹理空间映射关系将纹理空间规化(即除以|T|/z)后得到: 

u= (x/z*Hx +y/z*Vx+Ox)/ (x/z*Hz+y/z*Vz+Oz)
v= (x/z*Hy+y/z*Vy+Oy)/( x/z*Hz+y/z*Vz+Oz)
  这便是我们最后要求得等式了如果你作为纹理位图是128×128大小指向该位图指针是p,则对应该纹理上点为p[128×u][128×v]这里还有种特殊情况需要介绍说明就是又时多边形上点对应纹理空间坐标会大于1,这时我们希望能将这点对应到纹理空间内来具体做法就是去掉整数部分保留小数部分举个例子如果多边形上点对应纹理空间坐标是(1.1,2.137)则经过处理后其坐标为(0.1,0.137)这种处理称为u或v wrap到此平面纹理映射解释完了至于曲面纹理映射则不在本文介绍范围内了下面我将介绍下纹理反走样处理由于多边形坐标不点垂直也不定在长度上相等所以纹理空间点可能对应多边形上多个点或多边形上点对应纹理空间内多个点这会使纹理贴到多边形上后产生失真解决思路方法是纹理空间上颜色值用这点周围颜色平均值来表示 

B B B
B A B
B B B
  其中A点颜色值用周围B点颜色值平均值来表示这样就可以减少失真
Tags:  端口映射 照片纹理映射 纹理映射

延伸阅读

最新评论

发表评论