跳轉到內容

GLSL 程式設計/逐片段操作

來自華夏公益教科書,開放的書籍,開放的世界

逐片段操作是 OpenGL (ES) 2.0 管線 的一部分,它包含一系列測試和操作,這些操作可以在片段著色器生成的片段顏色寫入幀緩衝區中的對應畫素之前修改片段顏色。如果任何測試失敗,片段將被丟棄。(此規則的例外是模板測試,它可以配置為即使片段未透過模板測試和/或深度測試,也可以更改畫素的模板值。)

在逐片段操作的概述中,藍色方塊代表資料,灰色方塊代表可配置的逐片段操作。


片段資料(顏色和深度) 片段著色器的輸出
畫素所有權測試 應用程式無法自定義
剪刀測試 如果片段位於指定(剪刀)矩形之外,則測試失敗
Alpha 測試 僅在 OpenGL 中,不在 OpenGL ES 2.x 中;結果取決於片段的 alpha 值(不透明度)、參考 alpha 值和配置的 alpha 測試
模板測試 結果取決於對應畫素處的模板緩衝區中的值和配置的模板測試
深度測試 結果取決於片段的深度、對應畫素處的深度緩衝區中的深度以及配置的深度測試
混合 結果取決於片段顏色(包括其不透明度)、幀緩衝區中對應畫素的顏色以及配置的混合方程
抖動 通常無法由應用程式自定義
邏輯運算 僅在 OpenGL 中,不在 OpenGL ES 2.x 中;結果取決於片段的顏色、幀緩衝區中對應畫素的顏色以及配置的邏輯(按位)運算
幀緩衝區(顏色、深度和模板值) 可以停用對幀緩衝區的寫入,針對各個通道


具體的逐片段操作

[編輯 | 編輯原始碼]

一些逐片段操作尤為重要,因為它們有已知的應用

  • 深度測試用於以正確的遮擋關係渲染不透明的圖元(例如三角形)。這是透過將片段的深度與之前渲染的最前面片段的深度(儲存在深度緩衝區中)進行比較來完成的。如果片段更遠,則深度測試失敗,片段將被丟棄。否則,該片段將成為新的最前面片段,其深度將儲存在深度緩衝區中。
  • 混合用於透過混合(即合成)片段的顏色與已儲存在幀緩衝區中的顏色來渲染半透明圖元(玻璃、火焰、耀斑等)。這通常與停用寫入深度緩衝區相結合,以避免半透明圖元遮擋其他圖元。
  • 模板測試通常用於將渲染限制在螢幕的某些區域,例如鏡子、視窗或 3D 場景中更一般的“門戶”。它還具有用於某些演算法(例如陰影體積)的更高階的用途。

有關特定逐片段操作的更多詳細資訊可以在特定平臺的教程中找到,因為這取決於平臺,以及操作是如何配置的。

關於逐片段操作順序的說明

[編輯 | 編輯原始碼]

雖然 OpenGL 的規範對逐片段操作施加了特定的順序,但 GPU 可以更改這些操作的順序,只要這樣做不會改變結果即可。事實上,GPU 會在儘可能的情況下甚至在執行片段著色器之前執行許多測試。在這種情況下,如果片段未透過其中一項測試,則不會為該片段執行片段著色器。(一個例子是所謂的“早期深度測試”。)這可以帶來顯著的效能提升。

逐片段操作的可程式設計性

[編輯 | 編輯原始碼]

逐片段操作通常是可配置的,但不可程式設計的,即可以以某些方式配置各種測試,但不能編寫程式來計算測試。然而,這種情況正在改變。例如,OpenGL ES 2.0 不提供 alpha 測試,因為可以透過片段著色器中的條件丟棄操作來實現相同的功能,這實際上是可程式設計的 alpha 測試。另一個例子是(多廠商)OpenGL ES 擴充套件 GL_EXT_shader_framebuffer_fetch,它提供可程式設計混合。(此擴充套件在大多數(如果不是全部)iOS 6 裝置上受支援。在 iOS 6 的測試版中,該擴充套件稱為 GL_APPLE_shader_framebuffer_fetch。在配備 Nvidia Tegra 晶片的裝置上,類似的擴充套件 GL_NV_shader_framebuffer_fetch 通常可用。)

進一步閱讀

[編輯 | 編輯原始碼]

OpenGL ES 2.0 的逐片段操作在“Khronos OpenGL ES API 登錄檔”中提供的“OpenGL ES 2.0.x 規範”的第 4 章中詳細定義。

Addison-Wesley 出版了 Aaftab Munshi、Dan Ginsburg 和 Dave Shreiner 合著的書籍“OpenGL ES 2.0 程式設計指南”的第 11 章給出了更易懂的描述(參見 其網站)。


< GLSL 程式設計

除非另有說明,否則此頁面上的所有示例原始碼均歸屬公有領域。
華夏公益教科書