日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CG笔记之一——透视投影

發布時間:2024/10/8 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CG笔记之一——透视投影 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以前以為投影也就投影了,并不了解投影也可視作坐標變換,而且也是一個齊次坐標(Homogeneous Coordinate)系的坐標變換。因此書中的介紹一開始也不明白——它說透視投影會把直線映射成曲線,還特地驗證一下,發現投影為2D空間(攝像機平面)并不會發生這種情況,在仔細一看才知道,它指的是映射到3D空間,在z方向發生了畸變。而后逐漸了解,原來z方向的位置信息(depth)在渲染級模塊處(所謂的Z-Buffer)有特殊用處(直線上每個點的depth均通過直線兩端的點線性插值完成,因此可能造成depth位序異常)。當然這個問題在某些場合是不會發生的,例如完全基于光線跟蹤算法的渲染并不是這樣形成depth的。

于是,投影事實上成了投影變換。投影變換需要滿足兩個基本要求[1]
  1.保持depth的位序;
  2.將直線變換為直線。
  在x和y方向仍根據投影方法定義(投射在攝像機平面上的坐標),而在z方向上,需要引入偽距離映射(pseudo-distance),數學上,透視投影的偽距離映射具有形式z' = A + B / z。假設z方向截斷分別為n和f = 1 / rf,截斷分別映射為pnpf。于是列寫方程式1
  pn = A + B / n?? (式1)
  pf = A + B * rf (式2)
  解得:
  A = (n * rf - pf) / (n * rf - 1)?(式3)
  B = n * (pf - pn) / (n * rf - 1) (式4)
  可以證明,相應的齊次坐標變換矩陣為:
  [ d, 0, 0, 0;
  ? 0, d, 0, 0;
  ? 0, 0, A, B;
  ? 0, 0, 1, 0]???
(式5)
  一個很賞心悅目的方案是將n=d(目屏距)映射為0,而將rf=0(無窮遠處)映射為1,這種情況下:A=1, B=-d。然而事實上,為了能夠提供較好的depth分辨效果,n和f的選擇(尤其是f)非常重要,f必須能容納所有需要關心的物體,需要足夠大,但是過大的話會導致depth分辨率的相對降低;而pn和pf則主要取決于為depth分配的位數,通常,現代顯卡為depth配置了32位定點數。而透視投影的偽距離映射的一個較好的性質是,它對較近的物體提供了較大的分辨率,較遠的物體則即使由于分辨率低而發生錯誤也是可以接受的。
  然而在OpenGL中,用一個錐形頂點在圓點,截平面與z = 0平面平行的平截頭體(frustum)向任意矩形映射的方式定義透視投影。它是一種更一般的透視投影形式。
  列寫關系式:
  px = kx * x / z + dx??? (式6)
  py = ky * y / z + dy??? (式7)
  pz = kz / z + dz   (式8)
  可以導出齊次線性變換矩陣為:
  P = [ kx, ?0, dx, 0;
  ?????? 0, ky, dy, 0;
  ???????0,??0, dz, kz;
  ???????0,? 0,? 1, 0]
??? (式9)
  注意到:
??? M = [ 1, 0, 0, dx;
????????? 0, 1, 0, dy;
????????? 0, 0, 1,?dz;
????????? 0, 0, 0,?1]

??? A = [?kx, 0,? 0, 0;
?????????? 0, ky, 0, 0;
???????????0, 0,? 0, kz;
???????????0, 0,? 1, 0]
 
 有P = M * A??? (式10)
  即P變換矩陣由投影(A矩陣)和屏幕平移(M矩陣)兩部分變換組成。
  
根據映射關系:
  (x0, ?, z0) -> (px0, ?, pz0), (x1, ?, z0) -> (px1, ?, pz0)??? (式11)
  (?, y0, z0) -> (?, py0, pz0), (?, y1, z0) -> (?, py1, pz0)??? (式12)
  (?, ?, z0) -> (?, ?, pz0), (?, ?, z1) -> (?, ?, pz1)??? (式13)
  可以解得:
  kx = z0 * (px1 - px0) / (x1 - x0), dx = (x1 * px0 - x0 * px1) / (x1 - x0)??? (式14)
  ky = z0 * (py1 - py0) / (y1 - y0), dy = (y1 * py0 - y0 * py1) / (y1 - y0)??? (式15)
  kz = z0 * (pz0 - pz1) / (1 - z0 / z1 ), dz = (pz1 - pz0 * z0 / z1) / (1 - z0 / z1)??? (式16)
  注意到,kz是小于0的,這使得式8給出的偽距離映射是合法的。

注釋
1 本筆記采用傳統的z軸,即從眼睛指向屏幕,x從左至右,y從上至下(符合光柵掃描順序),因此它仍是右手系的。

參考文獻
[1] 3-D Computer Graphics, A Mathematical Introduction with OpenGL, Samuel R. Buss

轉載于:https://www.cnblogs.com/quanben/archive/2007/04/08/3129011.html

總結

以上是生活随笔為你收集整理的CG笔记之一——透视投影的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。