Stage3D運作原理

本文為此文章的中文重點翻譯:How Stage3D works

3D技術的突破

在過去幾年中,開發人員已經用FLASH創造了許多3D工具,如Papervision3D,Away3D和Alternativa3D,以及所有類似的3D引擎,顯示Flash對即時3D渲染的強烈需求。

過去Flash 3D的渲染是在不使用3D硬件加速的情況下進行的。 事實上,所有在Flash Player 11之前版本的3D渲染是依靠CPU的完成,我稱之為軟件模式(software mode)。 軟件模式是緩慢的,不能用來呈現細緻的3D場景。 到目前為止,軟件模式不能渲染出我們今天3D遊戲中常見的高級的圖形效果。

隨著Flash Player 11的發布,新的可能性已被實現。 開發人員可以利用3D硬件(顯卡)加速,而不是僅僅依靠計算機的CPU渲染。在新的渲染模式中Flash可以使用一個被稱為圖形處理單元(GPU)的副處理器。 GPU是設計完全用來圖形渲染的物理硬件。Stage3D API的公佈對Flash開發者是一個重大的事件。 在Flash中使用3D加速,使許多以前不能實現的Flash遊戲和Flash應用成為可能。

回顧過往,硬件加速的來到,永遠改變了世界上3D編碼方式。 遊戲質量和複雜性成倍增加。 硬件加速使得3D遊戲畫面渲染能力大大提高,迅速的渲染複雜的模型,逼真的效果,低延遲的遊戲體驗都成為可能。

使用3D硬件加速(hardware acceleration)

3D硬件加速利用現代普通PC就包含的GPU進行渲染。 GPU完全致力於圖形渲染和呈現3D內容的任務。通過這種方法,各類軟件以及你的Flash應用程序,只需要定義一個3D場景。 通過將3D場景定義數據送到GPU,GPU就能渲染出指定場景。 這個過程比使用軟件模式(software mode)通過CPU渲染3D內容快得多。

下面我們將花點時間比較軟件模式(software mode)和硬件模式(hardware mode)渲染的差異。

一般來說3D場景定義為一組3D幾何形狀或稱網格(meshes)。 每個幾何形狀又是一組三角形,對於每個三角形,又是一個由3個頂點組成的集合。 因此,一個3D場景只需要定義一個頂點集和一些相關的渲染信息,例如紋理或頂點著色。當您使用以前的軟件模式(software mode)時,3D引擎(如Away3D)就會收到這個頂點流。 它會計算三角形的屏幕位置,然後逐個通過一些填充操作(drawTriangles(),fill()) 驅動Flash Player在舞台上顯示這些三角形。即使3D引擎編碼優秀,這個過程仍然是極其緩慢的。 在某些情況下渲染的結果還不是特別準確。 3D內容顯現是按每個三角形為最小單位,而不是每個像素。 這將引起深度排序錯誤。 渲染後的三角形有時會出現在錯誤的地方或在錯誤的深度上。

在可接受的腳本運行幀數下,Flash Player 10軟件模式(software mode)通常呈現最多4000三角形的場景。

使用最新的Stage3D API後。 在3D硬件加速下開發者只需定義幾何形狀,然後將數據傳遞到GPU。 幾何形狀將到上載到GPU顯存(這片數據記憶空間充當GPU數據存儲空間)。 GPU將處理接收到的數據,完成渲染3D內容的整個工作。

由於只需要將渲染參數上載到GPU,基於此的應用將變得更有效。 例如:程序只需要在三維場景中指定觀測點(3D場景中攝像機位置),設置場景中的燈光位置以及其他影響3D呈現對象的細節。接收上載數據後, 它通過從分析頂點流開始,開始一個接一個渲染(由頂點流描述)三角形。 GPU將渲染最終在用戶屏幕上顯示的圖像,這一切步驟都是封閉在顯卡物理硬件內部完成的。

GPU的渲染速度遠遠高於CPU的軟件模式(software mode)。 這是因為GPU設計的重點著眼於一個非常具體的任務:計算頂點集和渲染由頂點集合所表述的三角形。由於這是一個非常具體的任務,3D硬件渲染過程是非常高效迅速的。相比之下CPU是通用處理器。 它不對呈現三角形的具體任務進行優化。因此軟件模式要低效的多。

通過統計對比,使用硬件加速渲染包含幾百萬個三角形的情況並不在少數。 相比在軟件模式(software mode)下提供的4000個三角形可是一個顯著的改善

3D rendering pipeline

3D rendering pipeline的作用是將渲染操作轉化為一組基本數據操作。GPU邏輯上由許多功能明確的功能區塊組成,每一塊對應著某種基本數據操作。在一條流水線中,這些區塊設置為一連續的操作,也就是說上一個區塊的輸出結果作為下一個區塊的輸入。最簡單的3D圖形渲染管線被叫做固定功能管線。稱之為固定是有原因的,因為該管線是不可不可編碼的,固定管線所以顯得有些僵化,因為它只是把輸入的形狀數據經過管線(一系列級聯的區塊)處理後成為用來顯示的最終圖像。

螢幕快照 2014-01-30 下午1.03.12

固定功能管線以以下參數作為輸入:幾何描述(頂點集合和三角形)、幾何形狀所應用的紋理數據、3D場景的幾何結構位置和方向,攝像機的位置和方向,光線數據(每組光線的顏色、位置、強度等等數據),和一些設置管線如何渲染呈現的額外參數。換句話說,你只要提供頂點集合、三角形、紋理數據,硬件就可以完成渲染。固定功能管線通過一個坐標變換和光照區塊(transform and lighting),把頂點集合從模型(model)本地坐標轉換為屏幕舞台坐標。這個區塊也負責處理頂點照明,緊接著的區塊是視角剪裁區塊(viewport clipping),主要負責對上一個區塊處理後場景數據進行剪裁(關係到是否參與此區塊以後的渲染和是否在可見等)以符合實際顯示視角的需要。

這部份的3D運算原理的詳細說明,可看這篇文章:初探Stage3D(一) 3D渲染基礎原理

經過處理和剪裁場景數據將送入下一個被稱為光柵器(rasterizer)的區塊,這個區塊除了執行紋理映射(texture mapping),也對模型進行霧化,透明通道混合效果和以深度排序的順序呈現三角形像素所需的深度緩衝測試。固定功能管線已經應用多年,但隨著時間的推移渲染過程僵化的缺點就暴露出來。 特別是關於光照的處理,渲染被限制使用標準著色器模型,如基本Goraud和Phong著色模型。 固定功能管線不夠靈活以至於開發人員不能添加更多創造性和有趣的效果, 在管線的渲染下大多數產品效果看上去是相似的。

隨著技術發展,可編碼圖形渲染管線被開發出來,下面是可編碼圖形渲染管線的邏輯流程圖:

螢幕快照 2014-01-30 下午1.03.21
頂點著色器(Vertex Shader)和片段著色器(Fragment Shader)的引入帶來了巨大的變革。當你使用可編碼渲染管線時,開發者可以寫一些被稱之為著色器(Shaders)的代碼片段,這些代碼片段將會影響管線中的渲染過程。

著色器的應用這一看似小小的改變,使得3D渲染髮生了天翻地覆的變化,通過編寫影響頂點轉換和修改的頂點著色器(Vertex Shaders)和填充三角形每個像素呈現的片段著色器(Fragment Shaders),我們將有能力創造之前無法體驗的美妙效果。例如:使用著色器你運用各種光照手段甚至自定義有特性的應用,而不是使用預設的管線照明模型。 著色器使模型陰影成為可能,並加速了骨骼系統,很酷的效果也變得司空見慣了。

使用Stage3D的優勢

開始創建一個基於DirectX和OpenGL的3D應用程序不是一件容易的事。 的確渲染一個簡單的三角形是十分容易的,但使用C++編寫一個成熟的3D應用程序則需要相當的技巧。 對於經驗尚淺的程序員來說無疑是很艱巨的任務。創建一個本地3D應用程序的困難之一是使用標準的DirectX和OpenGL API。為了保證利用圖形硬件的全部能力,項目必須支持全部硬件特性的選項。

原生API是專門針對硬件的。項目的開發工作不得不包括對特定GPU性能的優化(如同現在的遊戲開發商要同時支持nVIDIA和ATI顯卡一樣).通過大量的調整代碼,使項目能夠充分發揮硬件的強大能力。這對開發者是很有誘惑的,因為你將憑藉最強大的硬件創造最絢麗的特效.但同時這也意味著,應用程序必須進行調整和測試以適應不同的硬件。

在使用Stage3D工作時情況並非如此。開發者只需面向Stage3D對象如Context3D和Program3D編程,你創建的應用程序將運行在每一個支持Flash Player或AIR的平台上。

在某種程度上,Stage3D比原生API更抽象也離特定硬件更遙遠一點。 因此Stage3D更容易使用,這一點當然也是能算是一種缺點,為了多平台性,Stage3D不得不放棄針對特定硬件編碼。這樣做的一大好處是:使用Stage3D可以用同一個應用程序把3D硬件加速和功能強大且易用的普通2D FLASH創作結合起來.

一個基於原生API的3D應用,2D UI往往需要定製的解決方案,很少有像FLASH這般靈活的創作工具。在新API下,原先的2D顯示對象和Stage3D對象可以共存。 所以你會保留所有Flash的優點同時你也可以使用經過3D渲染的內容。 開發者可以選擇創建一個由3D場景作為背景的應用,也可以將3D對象嵌入往常的2D內容中

Stage3D應用可以運行在多種平台。 Stage3D也被應用於AIR應用程序中就像由Flash Player運行一樣。此功能意味著開發者可以使用Stage3D創建桌面3D應用程序(AIR)就像開發標準3D的PC遊戲一樣。 在iOS和Android移動平台上亦可使用相同的代碼。

認識Stage3D的限制

主要缺點是針對多平台開發應用程序的能力。 由於使用一個統一的基於多平台API,Stage3D無法應用當下最先進的3D圖形渲染特性。為了確保應用程序可跨多平台,Stage3D必須針對一個抽象的3D硬件設備操作,而為了面面俱到這個抽象層硬件僅僅包含所有硬件圖形特性的公共部分。例如:現代GPU支持Shader Model(頂點和片段著色器使用的標準)4.0版。 然而Stage3D僅僅支持Shader Model 2.0版本。

這代表當我們使用Stage3D編碼時將會遇到一些限制,各個不同的GPU可能有其擅長的優勢,這些將不會被使用到。 例如: AGAL可以使用的著色寄存器將相當有限。 您可以使用最多8個臨時寄存器,而基於Shader Model 4.0的GLSL最多可使用的寄存器為4096個。

Stage3D著色器代碼長度只能包含最多200操作碼,而Shader Model 4.0支持4096個。又如 Shader Model3.0和4.0支持循環和條件語義,而Stage3D不支持。換句話說,Stage3D著色器代碼設計的將是比較簡單的程序,而不是面向更先進的硬件和Shader Model的編碼。 因此在今天的AAA遊戲中使用的著色器代碼和一些高級效果可能無法應用於Stage3D。

另外Stage3D的技術在下面這些平台上可能無法正常運作:Stage3D unsupported chipsets, drivers | Flash Player 11, AIR 3

Stage3D:舞台背後的「舞台」

螢幕快照 2014-01-30 下午10.41.32

一組Stage3D舞台位於主Flash舞台後面。 這意味著每個Stage3D創建3D內容分別呈現在各自的Stage3D的矩形視野中,而普通2D 顯示對象都呈現在3D內容上面。 你可以試想如何兩全其美:你應用3D場景渲染使用硬件加速,而2D的顯示對象在最上面(如遊戲UI)。 UI可以使用強大的FLASH直接創建,而不是一些特殊定製的UI創建工具。

開發者可以使用多個Stage3D. 每個Stage3D擁有自己的矩形視界(簡單說就是width,height和x,y)。這意味著你可以在屏幕一部分區域添加一個Stage3D,然後在另一個地方添加另一個,最後傳統的2D顯示對象顯示在最上層。 每一個Stage3D和StageVideo層可以部分(甚至完全)重疊。 然而現在我們的Stage3D版本不支持層與層之間的混合模式。 因此上層的Stage3D覆蓋下層的Stage3D,你只能夠看到頂層和下面一層的未被遮擋部分內容。

參考文章

  1. Stage3D vs WebGL 性能較量
  2. 初探Stage3D(一) 3D渲染基礎原理
  3. Stage3D unsupported chipsets, drivers | Flash Player 11, AIR 3
  4. How Stage3D works