3D BD 小註解

3D BD 的 video 的壓縮格式是 H.264 的附錄 H, 也就是 H.264 MVC (Multi-view Video Coding).

為了和傳統的 2D 電視相容, 有一個主視頻碼流專門放左眼或是右眼的訊號, 另外再用一個輔助視頻碼流來儲存擴展的資訊.

輔視頻流採用了 inter-view prediction 的方式, 也就是左右眼可以互相預測. 這使得輔視頻流的碼率可以降到主視頻流的一半左右.

Note: 50 Hz 系統用於歐洲. (本圖取材自藍光白皮書)

從上表可以看到 3D 光碟裡面會有哪些 bit stream? 有趣的地方是, 為什麼有一個主視頻流, 一個輔視頻流, 又有一個主視頻流+輔視頻流呢?不能簡化一點嗎?

事實上, 它們只是表達方式的不同. 一個表示成主輔兩個碼流 (附檔名 m2ts, stream 目錄下), 另一個表示為混合的單一碼流 (附檔名 ssif, steam\ssif 目錄下). 

網路上有人反應他的 BD 光碟中, m2ts 和 ssif 文件的大小加起來竟然比一片 BD 的容量更大!就是被 file system 給騙了. 其實, 文件實體在 m2ts, ssif 只是 m2ts 的鏡像. Data 只有一份.

SSIF 是 Stereoscopic interleaved file 的縮寫. 它交錯地把主輔視頻切成小段存放. 在3D 播放時, 就直接讀取整個 bit stream. 2D 播放時, 只要根據索引適時跳過輔助碼流的部份, 就可以選擇性地播出主視頻流, 達到與 2D 電視相容的效果.

另外, 網路上有些破解教學, 教大家如何用主視頻流和輔視頻流的 m2ts, 生出左右眼完整的兩個 bit stream. 然後再用 tool 做成 Frame Sequential 的方式 (左一張, 右一張), 或者品質差一點, 做成 side-by-side 或是 top-bottom. 如此一來, 就算 player 看不懂 SSIF, 也都播得出 3D.

呃, 壞的不要學, 知道原理就好.

看來賣 3D 眼鏡或 TV, 還是比賣 3D BD 保險. 至少沒有人在破解眼鏡…

[ref]

1. 英语的藍光白皮書
2. 家用3D视频格式(一)数据存储格式

3D Object Culling 小註解

假設要畫出 3D image, 那麼只能在單個眼睛成像的近物就不用畫出來, 因為畫了也不會有立體感, 這個砍掉無用訊號的步驟就叫做 culling.

假設綠色線表是兩眼的距離, 紅色線表示螢幕的寬度. Z 要砍到哪裡呢? 根據我女兒在國二學的數學, 左上和右下的兩個三角形 (或是左下和右上) 符合三個角都相等 (AAA) 的相似三角形.

所以

Z / (I / 2) = (D - Z) / (W / 2)

Z / I = (D-Z) / W

Z = D / (1 + W/ I)

對於近在眼前而 “跳出螢幕" 的 object, 只需要畫出藍色的三角形. 螢幕 (W) 超大的時候, Z 可以忽略不計 (case A). 有嚴重的鬥雞眼 (I 0), Z 也會隨之減小 (case B).

不過照公式, 兩眼近到等效只有一隻眼睛的時候, Z 趨近於 0, 反而全部 object 都要畫. 但是此時已經沒有所謂的立體感了 (兩隻眼睛才有立體感), 大家有看出哪裡不對嗎?

我想: case A 中, 交叉點隨著螢幕變大而往左移,  case B 中是眼睛往交叉點移, 所以並沒有多畫. :P

3D graphic 的演進

昨天聽了台大簡韶逸教授的演講, 對 3D graphic 又多了一點認識. 先前我自修了幾個小時的 3D,  但是還是比不上聽 2 個小時的演講.

3D Graphic 的技術基本上是硬體愈做愈多, 但軟體卻也沒有愈做愈少. 假設 3D 技術可分為 Transform and Lighting ( T&L – 幾何轉換及光源), Rasterize, Texture, Blend and Z-buffer 這幾個單元的話, 早期的 3D graphic card 只包含 Texture 和 Z-buffer 這兩部分 (1998 年以前).

Milestone 1:

3dfx 的巫毒卡 (VOODOO), 我聽說它效能很讚, 也去敗了一張. 這張卡的特色就是把整張圖切細, 比方說用 4 個 sub-frame 來計算整個畫面, 最後再接起來. 因為這個技巧的確有效, 所以它也紅了一陣子.

Milestone 2:

1999 年的下半年, NVIDIA 的GeForce 256,首次支援硬體的 T&L. 這樣一來,  CPU 就不用算很多浮點數了, 效能自然是大大地增強. 可惜 Voodoo 不知道在堅持什麼? 始終都不支援 T&L, 最後就被 NVIDIA 給併購了.

2001 年, NVIDIA 引進 programmable vertex / pixel shader 的觀念. 所謂 vertex shader 就是 T&L 的進階版,  pixel shader 或是 fragment shader 就是 texture 的進階版. 怎樣進階呢? 就是把原本寫死的硬體, 做成可以程式化的巨量運算單元, 再以程式來控制想要輸出的 vertex 或 pixel 運算. 這個概念影響了 Direct X 8 的方向, 使得新版的 Direct X 都伴隨著 shader model 的更新.

老師的講法, programmable pixel shader 在 2002-2003 才出現. 但網路上的說法, pixel shader 和 vertex shader 應該都是 2001 年的 Geforce 3 的發明.

Milestone 3:

2002 年, ATI 推出 Radeon 9700 這顆 IC. 裡面用到的新技術還頗不少, 比方說這是第一顆 flip chip 的 IC, 對於散熱問題有了不少改善. 在驅動程式方面也產生了很大的突破, 由於可程式化的技術已經相進步; Wiki 上說它執行抗鋸齒(AA)和各異向性過濾(AF)運算時,在所有情況下,它能比 GeForce 4 的 Ti 4600快上40-100%。這顆 IC 因為效能遠勝 NVIDIA 而大賣了 3 年.


Milestone 4:

2006 年 11 月, NVIDIA 再度推出具有 unified shader 概念的 GeForce 8800. 所謂 unified shader 就是把 vertex shader 和 pixel shader 整合在一起. 同一個 shader 既可以做 vertex shader, 也可以做 pixel shader.

網路上的講法說, unified shader 就是 steam processor. 但是簡教授認為的 stream processor 至少要有 register 的概念, 才比較像 processor. 這是發生在 2007 年.

Milestone 5:

2008年2月, NVIDIA 收購 AGEIA, 推出 CUDA 語言, 使得顯示卡變身為平行處理電腦. 這邊就算是 GPGPU (general purpose GPU) 的起點吧!

綜合以上資料, 應該有一個 milestone 是把所有的 buffer (Vertex buffer, Texture buffer, Z-buffer) 整合成 unified buffer. 但是哪一顆 IC 率先推出這個改進就不得而知了.

總之, 搞繪圖卡的這些人頭腦還挺不錯的. 在激烈的競爭之下, 大家接力地推出可以徹底打敗敵人的招數. 目前 ATI, NVIDIA, Intel 雖然表現出三雄鼎立的架勢, 但誰可以在下一個階段勝出呢? 真是很有趣的一個問題. 繪圖卡愈來愈像小型 super computer, 到時候應該要比誰對軟體的支援最強吧?

另一個觀察的角度是: 當局者迷. 事後看來, 後面發展的路徑好像是顯而易見的, 但是十年前的人也都那麼聰明, 為何他們都想不到呢? 最好的解釋或許是人們不喜歡質變, 由量變過渡到質變的話則可以逐漸接受. 有誰一次想太遠的話, 只會被當作瘋子~~

Ref:

[1] 物竞天择适者生存!显卡10年技术漫谈

[2] http://zh.wikipedia.org/zh-tw/Radeon_R300

3D 繪圖速成小筆記

我希望自己在最短的時間之內, 就把 3D 基本觀念搞懂. 最好只花一個 page 就可以複習. 以下就是我的筆記.

3D 繪圖方式有三種, 第一種是用線的觀念. 可以想像一個視線從投射面回溯到光源, 這稱之為 Ray-tracing. 第二種方式是把圖的表面 (surface) 分解成小塊 (patch). 而每個 patch 都有自己的光照圖 (light map), 並且輻射周圍的 patch. 這稱之為 Radiosity, 聽起來有 iteration 的感覺.

第三種方法,  稱之為 Rasterizing (光柵化), 也就是唯一適用於硬體加速的演算法. 簡單地說, 就是先得到頂點 (vertex), 然後把點連成網眼 (mesh), 其中的基本圖形是點, 線, 與三角形, 三者合稱為 primitive.

假設我們要畫的東西是一個剛體, 不會隨便就變得軟趴趴的, 那麼每個 vertex 都可以有一個相對座標值. 要把這個 object coordinate 轉到整張圖上的座標位置 world coordinate, 這就是第一個轉換. 轉到 world coordinate 還是不夠的, 因為觀察者視角的關係, 這個位體還要轉到 eye coordinate. 就好像一個魔術方塊, 不可能讓我們同時看到六個面, 座標位置當然與觀察者的角度有關.

轉完之後, 開始打光, 包括 R, G, B, alpha 四個值決定紅, 綠, 藍和透明的強度.

畫好之後, 剛才的魔術方塊又出現了. 被擋到的東西不用畫, 也不能畫. 所以要再次轉到裁切座標 (clip coordinate). 在最上層的東西, 才會畫到螢幕上 screen coordinate.

以上可以得知哪些 vertex 位於螢幕之內或是之外. 凡是落在螢幕之外的 vertex, 我們只需要畫到螢幕邊緣就好. 但任意多邊形並不是 primitive, 所以那些形狀不齊的四邊形會被分割成兩個三角形.

現在有了一堆轉換過的頂點, 接著就要把頂點所包圍的畫素 (pixel) 都找出來. 這個過程就是光柵化 (Rasterize). 還在 vertex 階段的處理稱為 front-end, pixel 等級的處理稱為 back-end.

在 pixel 的操作包括下面三者: texture (紋理), blending (混色), filtering (濾鏡), 總之就要給每個 pixel 最合理的顏色. 原先在 vertex 階段所配置的特性如何用在 pixel 上呢? 大致就是內插法. 所以原先幫每個 vertex 打光的工程, 就不需要詳細到 pixel 等級上那麼累! 真是聰明哪!

下一個階段就是要把畫好的圖貼進 frame buffer 了. 比方說要畫個眼睛在臉上, 眼睛總不能大過臉, 又不是海綿寶寶的蟹老闆. 因此要在可以畫眼睛的範圍以外塗上框框, 這個框就是模板 (stencil). 其次當然不脫後景不蓋前景, 需要更新的區域才更新等基本限制, 在真正畫出去之前, 要先做這類的測試. 例如 scissor test, alpha test, depth and stencil test 等等.

測完之後可能還有一點事情要做, 比方說 alpha belnding, 千辛萬苦之後, 一個點好不容易才可以進到 frame buffer.

講完硬體之後, 再講一點點軟體. 繪圖的 API 包括 OpenGL, 這是 ARB 推的. 還有 Direct3D, 這是 Microsoft 推的.

OpenGL 的指令分為兩種, 一種是給定 vertex 與顏色等等, 以產生圖像. 另外一種是設定對上述資料的操作. 甚至是先做一些 transform 以取得新 vertex 的座標.  基本就是只做 rendering.  

[reference]

http://www.ategpu.com/2009/05/29/interactivecomputergraphics.html

說 reference 也太牽強了, 我根本是濃縮再製版.

http://zh.wikipedia.org/wiki/OpenGL

因為不太懂又沒有時間, 所以我花 2 個小時, 寫了這個快速學習備忘錄. 謬誤之處, 請多多見諒. 等我有所成長, 再來修正這裡的不足.