Share via


樣板緩衝區

樣板緩衝區會用來遮罩影像中的像素,以產生特殊效果。 該遮罩會控制是否要繪製像素。 相關特殊效果會包含合成、印花、溶解、淡化及撥動、外框及剪影,以及雙面樣板。 下方提供了幾個比較常見的效果。

樣板緩衝區可啟用或停用繪製,透過以像素為基礎的方式來轉譯目標表面。 最基本的樣板緩衝區,可讓應用程式遮罩所轉譯影像的區段,好讓其不會顯示。 通常,應用程式會使用樣板緩衝區來轉譯特殊效果,例如溶解、印花和外框。

樣板緩衝區資訊會內嵌於 z 緩衝區資料中。

樣板緩衝區的運作方式

Direct3D 會對樣板緩衝區的內容執行以像素為基礎的測試。 針對目標表面中的每個像素,它會使用在樣板緩衝區中的對應值、樣板參考值和樣板遮罩值來執行測試。 如果測試通過,Direct3D 就會執行動作。 測試會使用下列步驟執行。

  1. 使用樣板遮罩執行樣板緩衝區參考值的位元 AND 運算。
  2. 使用樣板遮罩為目前的像素執行樣板緩衝區值的位元 AND 作業。
  3. 使用比較函式來比較步驟 1 的結果和步驟 2 的結果。

上述步驟會以下列程式碼行顯示:

(StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)
  • StencilRef 代表樣板參考值。
  • StencilMask 代表樣板遮罩的值。
  • CompFunc 為比較函式。
  • StencilBufferValue 為目前像素的樣板緩衝區內容。
  • & 符號代表位元 AND 運算。

如果樣板測試通過,目前的像素就會寫入目標表面,如果未通過,則會遭到忽略。 無論每個位元作業的結果為何,預設比較行為都會寫入像素。您可以變更列舉類型的值,以識別想要的比較函式,藉此變更這個行為。

您的應用程式可以自訂樣板緩衝區作業。 它可設定比較函式、樣板遮罩和樣板參考值。 此外,它也能控制 Direct3D 在樣板測試通過或未通過時,所採取的行動。

合成

您的應用程式可以使用樣板緩衝區,將 2D 或 3D 影像合成到 3D 場景中。 樣板緩衝區中的遮罩會用來遮蔽轉譯目標表面中的區域。 隨後,所儲存的 2D 資訊 (例如文字或點陣圖) 可寫入至遭到遮蔽的區域。 或者,應用程式也能將額外的 3D 原始物件轉譯為所所轉譯目標表面的樣板遮罩區域。 它甚至可以轉譯整個場景。

遊戲通常會將多個 3D 場景合而為一。 舉例來說,賽車遊戲通常會顯示後照鏡。 後照鏡會呈現駕駛後方的 3D 場景檢視畫面。 就本質上而言,後照鏡為合成至駕駛前方檢視畫面的第二個 3D 場景。

印花

Direct3D 應用程式會使用印花來控制特定原始物件影像的哪個像素會繪製至轉譯目標表面。 應用程式會將印花套用至原始物件的影像,好讓共面多邊形能正確轉譯。

舉例來說,將輪胎標記和黃色線條套用至道路時,標記應直接出現在道路上方。 不過,標記和道路的 z 值則完全相同。 因此,深度緩衝區可能不會在兩者之間產生明確的區隔。 後方原始物件中的部分像素可能會轉譯至前方原始物件的上方,反之亦然。 所產生的影像會在畫面格之間閃爍。 這個效果就是所謂的 z 衝突或閃現

若要解決這個問題,請使用樣板來遮罩後方原始物件上使用印花的部分。 請關閉 Z 緩衝,並將前方原始物件的影像轉譯至轉譯目標表面的關閉遮罩的區域。

雖然多重紋理混合可用來解決這個問題,此舉會限制應用程式能產生之其他特殊效果的數量。 使用樣板緩衝區來套用印花,可釋出紋理混合階段,以做為其他效果之用。

溶解、淡化和撥動

越來越多應用程式會使用電影和影片中常用的特殊效果,例如溶解、撥動和淡化。

在溶解中,某個影像會在順暢的一系列畫面格中,遭另一個影像逐漸取代。 雖然 Direct3D 會提供使用多重紋理混合的方法,以達到相同的效果,使用樣板緩衝區溶解的應用程式,可望在進行溶解期間,使用紋理混合功能來進行其他效果。

應用程式執行溶解時,必須轉譯兩個不同的影像。 它會使用樣板緩衝區來控制來自每個影像的哪個像素會繪製到轉譯目標表面。 您可以定義一系列的樣板遮罩,並將其複製至後續畫面格的樣板緩衝區中。 或者,您可以定義第一個畫面格的基礎樣板遮罩,並對其進行漸進式變更。

溶解開始時,應用程式會設定樣板功能和樣板遮罩,好讓開始影像的像素能通過樣板測試。 結束影像的像素應該不會通過樣板測試。 在後續的畫面格上,樣板遮罩會做出更新,以減少開始影像中通過測試的像素。 隨著畫面格進行,結束畫面上未通過測試的像素也會越來越少。 這樣一來,應用程式就能使用任意溶解模式來執行溶解。

淡入和淡出為溶解的特殊案例。 但入時,樣板緩衝區會用來從黑白影像溶解為 3D 場景的轉譯。 淡出則與之相反,應用程式會先著手轉譯 3D 場景,並溶解為黑白影像。 淡化可使用您想要運用的任何任意模式完成。

Direct3D 應用程式會使用類似的技術來進行撥動。 舉例來說,當應用程式執行從左到右的撥動時,結束影像會在開始畫面上,顯示為從左到右逐漸滑動。 如同在溶解中一樣,您必須定義一系列的樣板遮罩,以載入至後續畫面格的樣板緩衝區,或於後續修改開始樣板遮罩。 樣板遮罩會用來停用開始影像的像素寫入,並啟用結束影像的像素寫入。

撥動則比溶解更加複雜,因為應用程式必須透過與撥動相反的順序,以讀取結束影像的像素。 這表示,如果撥動會從左到右移動,應用程式就必須透過從右到左的方式讀取結束影像的像素。

外框和剪影

您可以使用樣板緩衝區進行更抽象的效果,例如外框和剪影。

如果應用程式將樣板遮罩套用至原始物件的影像,而該影像具有相同的形狀,但比較小,所產生的影像僅會包含基本物件的外框。 隨後,應用程式可以使用純色來填滿樣板遮罩的影像區域,繼而賦予原始物件浮凸外觀。

如果樣板遮罩的大小和形狀與您轉譯的原始物件相同,則產生的影像就會包含應為原始物件的洞。 隨後,您的應用程式可使用黑色填滿整個洞,以產生原始物件的剪影。

雙面樣板

陰影體會用來使用樣板緩衝區繪製陰影。 應用程式會透過遮蔽幾何、運算剪影邊緣,以及將其從光線立體化為一組 3D 體積,藉此運算陰影體轉換。 隨後,這些體積會轉譯兩次,以轉譯至樣板緩衝區。

第一次轉譯會繪製正向多邊形,並遞增樣板緩衝區值。 第二次轉譯會繪製陰影體的反向多邊形,並遞減樣板緩衝區值。 一般而言,所有遞增和遞減值會相互抵銷。不過,場景已使用一般幾何產生,造成某些像素無法隨著陰影體轉譯來通過 z 衝突測試。 樣板緩衝區中剩餘的值會對應至陰影中的像素。 這些剩餘的樣板緩衝區內容會做為遮罩使用,以將大型、包含所有項目的黑色四邊形 Alpha 混色至場景中。 使用樣板緩衝區做為遮罩的結果,會讓陰影中的像素變暗。

這表示,陰影幾何會依照光源來繪製兩次,進而對 GPU 的頂點輸送量增添壓力。 雙面樣板功能的設計用意,在於緩解上述情況。 這個方法包含兩組樣板狀態 (名稱如下所示),其中一組會針對正向三角形來設定,另一組則針對反向三角形。 這樣一來,每個陰影體就只會根據燈光來繪製單一傳遞。

深度和樣板緩衝區