參考資料:
book:[電腦圖形學]
book:[DirectX9.03D遊戲開發編程基礎-13攝像機]
http://wenku.baidu.com/view/a08bf9ee4afe04a1b071decc.html(繞任意軸旋轉)
http://wenku.baidu.com/view/700512d5360cba1aa811da70.html(視口矩陣)
http://blog.csdn.net/popy007/article/details/1797121(投影矩陣)
http://blog.csdn.net/popy007/article/details/4091967(投影矩陣)
http://blog.csdn.net/popy007/article/details/5556639(紋理映射)
http://blog.csdn.net/popy007/article/details/5570803(紋理映射透視糾正)
http://hi.baidu.com/tinya/blog/item/37f0ffdeea8dd85ecdbf1a6b.html
http://www.chrishecker.com/Miscellaneous_Technical_Articles
http://blog.csdn.net/popy007/article/details/5556639
http://zoomquiet.org/res/scrapbook/ZqFLOSS/data/20100709102006/
5.20 搭建應用程式架構(api畫點)
5.20 向量和矩陣定義
5.20 頂點定義
5.20 三角形定義
5.20 WVP矩陣變換
5.20 vp空間變換
5.21 直線繪製(畫線)
5.21 三角形填充(畫面)
5.21 資料結構調整(調整資料結構定義,方便計算。)
5.22 blinn-phong光照模型(光照)
5.22 模型定義(渲染Cube)
5.23 模型空間到世界空間的變換(仿射變換基礎實現)
5.23 gouraud著色(漸層填充)
5.23 貼圖定義(暫時用png貼圖)
5.23 紋理映射
5.24 透視糾正
5.24 介面修正(從基於三角形的,改成基於頂點的,再考慮批量處理頂點和面檢索相關,為裁剪打基礎)
5.24 背面剔除(定義攝像機的朝向)
5.24 CVV裁剪
5.24 vp裁剪
***5.25 隱藏面消除(Z-buffer) [有效率問題,暫時關閉了]
5.25 攝像機操作
5.28 建立SVN倉庫
5.28 排查uv錯位
5.28 2D直線裁剪演算法[不行,即使裁剪了,確定新線段的方法也過於複雜,可能想錯了](使用插值所有像素點的cvv座標,判斷-1,1範圍內的點)
5.28 排查矩陣相關計算錯誤---1、vec4*mat44寫錯了,實現的是列主矩陣計算。
5.29 排查矩陣相關計算錯誤---2、vp矩陣[1,1]寫錯了,多取了一次反;
5.29 排查背面剔除錯誤(背面剔除需要在透視除法之後再做)
5.29 整理基礎資料結構,由class改為struct。
5.29 增加TestUnit的UI
***5.29 非常近的時候,uv計算會出錯[]
5.30 增加profile工具,查效能問題
5.30 Profile資料群組織
5.30 Profile資料顯示
5.31 加profile,分析具體效能問題(繪製640*480個點效率低下)
5.31 引入ddraw surface做對照實驗[沒弄好,先弄GDI的方式吧].
5.31 修改GDI方式畫點的流程,寫入記憶體塊,然後整體拷貝到rendertarget。(因為這裡有個lock顯存的問題)(290ms)
6.01 讓ddraw surface可用,完成對照組。(200ms,比gdi稍微快一點)
6.01 提高繪製點的效率(採用鎖一輩子離屏表面的方式,效率從200ms-->57ms)
6.01 修正顏色值錯誤
6.01 最佳化填充三角面時的資料結構(效率上沒明顯變化,資料量太少,最多480)
6.01 最佳化貼圖採樣(減少了22ms)
***6.01 最佳化線性插值(減少是減少了,13ms,但是結果不正確)
關於透視投影紋理映射我有幾個問題:
1、在視口空間做的uv插值計算的結果,怎麼能對應到某個像素點呢?一個是(x(float),y(int))這個點得出的uv, 一個是vp空間裡光柵化的點(x(int),y(int));
2、假設直接視為這個uv就為光柵化的像素的uv座標,那行掃描的時候,整行的像素的uv座標全部關於x線性插值嗎?感覺這也不對啊,難道是關於1/z?
3、(理解的對不對?)計算出一個像素點的uv座標之後([0,1]),乘以貼圖的尺寸,從而轉換到貼圖空間,這時要偏(-0.5,-0.5),用於uv座標和螢幕座標組齊[疑惑4],然後就是貼圖採樣點事情了?
4、如果要-0.5, 那假設有個像素的u座標為0.0,轉換到貼圖空間後還是0.0, 當-0.5之後,如果貼圖採用環繞定址方式,豈不是對應的不是0圖素的顏色值,而是9.5(貼圖寬度為10)圖素的顏色值了?
5、採用-0.5位移的計算體系裡,使用的是上取整,所以應該是10這個顏色值? 如果是下取整,豈不是9了,和0差的更遠了啊?
6、(理解的對不對?)找出uv座標組應的圖素之後,使用貼圖採樣演算法,比如取左右2個點做3點平均/上下左右4個點做5點平均嗎?
7、這就是所謂的2x採樣,4x採樣?
8、如果像素點的u座標為0.0,採用哪個圖素?0號還是10號呢? 如果是1.0呢?
頂點資料裡有uv, 這個是在生產階段就有的,美術稱為稱展uv。
uv在頂點做 wvp /w vp 變換的時候,值不變。一直帶到光柵化步驟
插值可得出每像素的uv,根據這個uv計算貼圖圖素,再和光照顏色*,得出最終顏色。
c#的賦值,真暈人
我的矩陣壞了...x 朝左...貌似變成右手座標系了。
正在學習矩陣推導,準備修好它
使用的是應該是dx文檔裡的矩陣。不知道為什麼會這樣。
[ 2012-05-25 ]
kun(小龍) 00:38:30
我知道哪錯了,我把攝像機的 right,up,look 和 觀察座標系的uvn 搞混了。 也就是把觀察座標系各軸向(uvn)在全局座標系裡的表達(U(x,y,z),V(x,y,z),N(x,y,z))搞混了,實際上我還沒定義攝像機的朝向,只是定義了uvn在xyz座標下的表達。
所以讓我以為 look是朝向的時候, 我讓它朝螢幕裡面看..就是unit_z, 結果把整個觀察座標系反向了,相當於繞Y軸旋轉了180度,而我的投影矩陣是按左手座標系推導的,所以投影過來的東西都反了。
)
kun(小龍) 00:42:11
uvn在xyz座標下的表達==>uvn單位向量在xyz座標下的表達.
kun(小龍) 09:16:19
裁剪是個大坑啊.....
一些穿過frumst的面或者直線,如果不在3D空間做裁剪,會被投影,就像投影到虛投影面上一樣。這時再做2D裁剪,已經來不及了。必須在CVV那步處理好,確保所有參與計算的頂點的座標都在 -1,1 之間,不然就會出虛投影(我自己的叫法)的問題。
一個3個頂點都在CVV外面的三角面大概(沒仔細算)最多能被cvv裁出6個頂點,需要用這些頂點再構成三角面,同時保持和原三角面的法向量一致。如果是gouraud著色,同時還需要插值出新頂點的光照顏色。
e... 這樣的話2D裁剪豈不是沒用了。。所以肯定我哪有錯...但是虛投影肯定存在。
也許是這樣:如果一個面,或者線段,有頂點落在了虛frusmt(frusmt的反向延長體)的空間內,就必然得計算新頂點,不然就讓它投影,交給2D去做。因為2D更好算。
==,好像還和裁剪平面有關係。
我用的是最最基本的逐點判斷法做2D裁剪,就是看是不是在視窗內。
結論剛才試出來了:
在view空間(還沒變換成cvv的那個),如果有點在eye的後方(n軸),就必須做3D裁剪,否則會出虛投影問題。
我的做法是,在cvv裡,判斷下z值,如果z<-1,就不要這個點了---超級簡陋的3D裁剪。
kun(小龍) 09:16:40
結果正確。攝像機隨便移動也不會出現虛投影了。
kun(小龍) 10:13:49
還有個問題,我的cube在螢幕邊緣變形嚴重...應該哪有問題
kun(小龍) 10:14:13
就好像不是線性一樣。
kun(小龍) 10:18:40
cube這東西貼了紋理後,不做遮擋面消除沒法看....各種穿插
kun(小龍) 10:18:47
眼睛都花了..
kun(小龍) 12:18:23
各種坑啊...貼圖出來的紋理很詭異.... 像素不是均勻分布的,中間密度比兩邊大。。。
kun(小龍) 12:18:47
肯定和cube在螢幕邊緣變形嚴重是一個問題
kun(小龍) 12:18:51
同樣的矩陣
kun(小龍) 12:24:01
哦,fov ,應該用 aspect 計算。 呵呵,想起來以前查的BUG了
.牛頓頓- 12:39:34
變形嚴重,估計是 view matrix錯了。
kun(小龍) 14:00:57
哭死了...掃描行顏色插值的時候,我增加了 y0 = y1 情況下的處理,把 按x 插值的代碼拷貝了一份。。結果替換(x,y)的時候...只替換了一部分....實在是太多x,y了,眼睛瞎了..
kun(小龍) 14:03:11
關係就變成 y = 1/x 了, 所以 中間像素特集中...
kun(小龍) 14:04:14
數學怎麼都是一致哦,連錯誤也是,如果早能意識到是倒數,直接查線性插值的地方就應該能法線
kun(小龍) 14:27:50
光8個頂點,沒辦法完美表達uv, 貌似需要更多的頂點,或者加入多層UV特性,才能讓一個圖片在6個面都顯示的一樣。
是不是 face 上有個屬性, 決定頂點啟用哪套uv座標呢
kun(小龍) 14:34:10
和邱確認了,沒有~ 加點吧
kun(小龍) 15:40:05
我的攝像機沒記錄旋轉,結果搞亂了view空間的座標軸,變成不是和xyz軸向平行的了
kun(小龍) 15:40:19
結果viewMatrix無情的錯了
kun(小龍) 16:00:43
你看我理解的對不對:
記camera的旋轉 : Rx, Ry,Rz 為繞x,繞y,繞z的旋轉量。
每次旋轉都只轉一個分量(Rx+角度a, Rx')
然後按 Rx' Ry' Rz' 的順序對 攝像機的 look,和right軸進行旋轉,up由look.corssprodect(right)得出。
這樣?
kun(小龍) 16:02:06
一次性構造矩陣,只能構造“按 Rx' Ry' Rz' 的順序” 這3個旋轉矩陣吧。位置什麼貌似不需要啊,旋
投影到2D的三角形被裁剪後,最多會產生6個邊,假設頂點編號為123456,怎麼確定各個邊的,比如 是 1-2 3-4 5-6 2-3 4-5 6-1 而不是 1-3 2-4 5-1 6-2呢?點的分布需要有規則吧,一般這個規則是什麼?
想明白了,由法線。因為正面是 v0->v1 和 v0->v2確定出來的,所以切出來的新頂點也滿足一定的排列順序 . 和v0,v1,v2的值無關,只和順序有關
我想的辦法特別麻煩,需要根據N種情況作判斷
kun(小龍) 14:00:34
新端點為123456,新線段則為 2-3,4-5,6-1。
以2-3線段舉例,情況可能為
不包含角:線段為2-3
包含1個角:左上、右上,左下,右下,線段為2-角,角-3
包含2個角:左(上下),右(上下),上(左右),下(左右),線段為:
2-角1,角1-角2,角2-3.
這樣就能得到新線段了。