《圖形著色器:理論與實踐(第2版)》詳細闡述了與著色器程序設計相關的高效解決方案及相應的數據結構和算法,主要包括固定功能管線、OpenG著色器的發展、著色器基本概念、使用glman、GLSL著色器語言、光照、頂點著色器、片元著色器和表面外觀、片元著色器中的表面紋理、噪聲、基于著色器的圖像處理、幾何著色器的概念和示例、細分著色器、GLSLAPI、基于著色器的科學可視化計算以及著色器應用等內容。此外,《圖形著色器:理論與實踐(第2版)》還提供了相應的算法、代碼以及偽代碼,以幫助讀者進一步理解相關方案的實現過程。
下面的漫畫作品是否喚起了你的某些回憶?
你的腦海中是否縈繞著許多偉大、創新的理念卻苦于無法實現?那么,你就是我們正在尋找的人,本書專門為你而打造。
歡迎閱讀《圖形著色器 ——理論與實踐(第 2版)》。顧名思義,本書將討論著色器理論以及實踐過程,并輔以大量的實現代碼。為了方便讀者閱讀,本書采用全彩印刷,亦即多數示例均配以效果圖像,以便于讀者深入理解相關概念。因此,放慢你的腳步,靜下心來開始閱讀,并從中獲得極大的享受吧!
與第 1版相比,本書增加了 100多幅圖像。除此之外,本書還對以下內容進行了改版:
(1)本書遵循 OpenGL最新規范,即 OpenGL 4.x和GLSL 4.x0。
(2)全部示例代碼根據最新 GLSL語言標準加以編寫。
(3)新增了與細分著色器相關的部分章節(及其示例代碼)。
(4)各章增加了示例和練習。
(5)修改了大量的示意圖,并將 GLSL功能級別調整至 4.x0。
(6)OpenGL架構評審委員會( ARB)棄用了 OpenGL中的某些功能,但尚未將其完全去除。本書將對此加以闡述且對應代碼集中體現了這一重要變化。另外,本書全部示例代碼均遵循這一理念。在該策略的引導下,讀者還可向 OpenGL ES 2.0實現平穩過渡。
(7)本書附錄添加了與著色器對應的 C++類,進而簡化 OpenGL著色器應用程序的編寫過程,并對上述棄用策略提供某種支持。
可編程圖形著色器經歷了一段有趣的發展歷程。在以往的歲月中,計算機圖形內容均需要通過編程實現,相信某些讀者對此仍有清晰的記憶。鑒于圖像創建過程中存在可編程選項,這也意味著 “可編程 ”往往包含某種貶義成分 ——事實并非如此。若期望生成某種圖像結果,除了親自動手編寫程序之外,別無他法。
對于大多數圖形實踐者而言,計算機圖形 API可在一定程度上改變這一現狀。優秀的 API使得程序設計人員可輕松并出色地完成圖形程序設計任務,期間, API功能項可掌控大部分圖形處理操作。然而,程序設計人員也為此付出了一定的代價,即放棄 API無法處理的某些功能項,如表面著色技術。當時( 20世紀 90年代),大多數 API僅支持簡單的平滑光照表面操作。
然而,無論是計算機圖形開發社區還是高級圖形程序員,對此都難以感到滿意,這種滿意度的欠缺分別來自軟件和硬件方面。隨著圖形處理器的不斷發展,基于特定功能的程序設計逐漸打破固定功能圖形 API這一桎梏,此類功能項逐漸形成自己的標準,包括隸屬于 OpenGL標準的 GLSL著色器語言。可編程圖形著色器已成為計算機圖形學的關鍵特征,其中,程序可載入圖形處理器,并執行早期固定功能管線標準之外的相關操作。
在教學以及學習過程中,計算機圖形學也可采用并行方式實現。初學者通常會通過相關標準(如 OpenGL)了解計算機圖形學。當前,初學者還應理解可編程著色器所飾演的角色,并嘗試編寫和使用著色器。值得注意的是,基于著色器的程序設計往往會使我們重返昔日時光,并重新審視某些古老的圖形學問題(例如,某些問題出現于 20世紀 70年代)。時至今日,讀者可在 OpenGL的全力支持下實現頂點和獨立像素操作,這種體驗往往來自于游戲、科學可視化計算以及通用圖形計算。
本書可用于傳統的教學課程中,其內容自成一體,向學生全面闡述了計算機圖形學著色器程序設計。同時,本書還可作為基于固定功能 API(尤其是 OpenGL)的輔助讀物。本書從整體上系統地講述了著色器程序設計,并重點講解了 GLSL著色器語言。除此之外,本書還介紹了靈活、易用的編程工具 glman,以幫助讀者在應用程序外部開發、調試著色器。
本書可作為本科、研究生層次計算機圖形學課程的高級教程,并假設讀者已了解 OpenGL以及相關圖形學知識。本書重點討論 GLSL語言并統一使用 OpenGL術語,對應內容同樣適用于其他圖形 API,如 Direct3D。鑒于著色器程序設計揭示了 API所隱藏的事實真相,因而讀者需要進一步了解某些基礎理論,包括幾何、光照以及著色等內容,相信讀者會加深對此類問題的理解。同時,著色器程序設計還會幫助讀者剖析 API的工作原理,因而有必要對上述內容加以回顧。
本書采用 GLSL作為示例著色器,其原因在于, OpenGL跨平臺 API具有較為廣泛的應用范圍且兼具高效性。鑒于著色器理念之間的相似性,相關概念同樣適用于其他著色器 API,如 Cg和HLSL。本書首先通過著色器程序的基本角色和功能介紹固定功能圖形管線,隨后將在 glman和應用程序環境下編寫頂點著色器、片元著色器和幾何著色器。
盡管按照擴展圖形管線中的應用順序考察著色器更符合邏輯性,即頂點著色器 —幾何著色器 —片元著色器,但本書的處理方案則稍顯不同,即按照使用頻率這一順序考察著色器(片元著色器 —頂點著色器 —幾何著色器)。需要說明的是,該順序無法實現正確的工作流,其原因在于,片元著色器所接收的數據源自頂點著色器,因而頂點著色器位于初始位置,隨后依次為片元著色器、幾何著色器和細分著色器。
本書整體內容脈絡鮮明,第 1章涵蓋了后續章節所需要的背景知識,即基于固定功能的 OpenGL圖形管線。第 2章講述了 OpenGL的演化歷史。第 3章講解了頂點著色器、片元著色器和細分著色器的基本原理,以及基于 GLSL著色器語言的多個示例。第 4章以使用手冊方式引入了 glman軟件。第 5章討論了 GLSL著色器語言,并針對 C語言比較了兩者間的相似性和差異性。
第6~8章涉及頂點著色器和片元著色器等概念。其中,第 6章闡述著色器的視點光照,并引入了
ADS(環境光、漫反射光和鏡面光)光照函數,此類光照環境將在后續章節中多次提及。由于頂點著色器需要計算各頂點的光照,片元著色器負責計算各像素的光照,因而光照可視為頂點著色器和片元著色器的基礎內容。第 7章將重點探討頂點著色器,對應內容主要集中于輸入數據、輸出數據以及頂點幾何對象的調整方式。第 8章將討論片元著色器,包括輸入數據、輸出數據以及固定功能片元操作的替換方式。
第9~11章將分析片元著色器的特定功能項。第 9章將描述片元著色器與紋理貼圖之間的處理方式,包括凹凸貼圖、立方體貼圖以及場景的紋理渲染。第 10章將闡述噪聲函數及其在紋理和著色器中所飾演的角色。除此之外,第 10章還介紹了 noisegraph工具,以使讀者可對 1D和2D噪聲函數屬性進行調試。第 11章則根據片元著色器工具講述 2D圖像(紋理)的操控方式。
第12章講述了幾何著色器,包括幾何著色器與頂點著色器和片元著色器之間的關系,以及幾何著色器自身的功能項。本章通過多個示例強調幾何著色器針對幾何模型的擴展能力,以及細節級別的處理能力。第 13章介紹了細分著色器,著重說明該類型著色器與幾何著色器之間的相似性以及重大改進。
第14~16章集中討論應用程序中的圖形著色器。第 14章定義了 GLSL API,讀者可在應用程序中編譯、鏈接并使用著色器。另外,本章還分析了著色器程序的數據和圖形狀態信息的傳遞方式,并使用 C++類封裝著色器程序的整合操作。第 15章闡述了著色器在可視化應用程序中的應用方式,并演示了多個可視化操作示例。第 16章則考察了基于圖形著色器的多個有趣示例。
附錄部分顯示了 C++類的應用方案,以方便讀者編寫 OpenGL應用程序并處理某些 API棄用問題。
本書多數內容均較為直觀,部分內容則包含一定的技巧性,因而應引起讀者的足夠重視。本書中的數學知識源自 Nicholas Bourbaki所著教材,并采用符號加以標識,進而強調該問題的重要性。
由于著色器函數仍處于不斷發展中,因而新鮮事物以及對應處理方案層出不窮。相應地,本書采用符號加以標識,希望讀者對此有充分的認識。
通過本書的閱讀,讀者可進一步提升圖形編程能力,并盡享圖形編程的無限樂趣。 OpenGL前進的步伐從未停止,不久的將來,著色器或許是幾何對象以及渲染操作的唯一處理方式,我們有理由相信,讀者將會再次認識到本書的價值所在。
致謝
本書的出版得益于多方的支持。這里,首先對 Mike Bailey表達最真摯的謝意。另外,還要感謝俄勒岡州立大學同仁們的支持,他們是 Ron Adams、Bella Bose、Terri Fiez、Karti Mayaram、Ron Metoyer、Eric Mortensen、Cherri Pancake、Sinisa Todorovic以及 Eugene Zhang。
鳴謝 UCSD和OSU的同學們,他們才華橫溢并自始至終伴我左右,他們是 Tim Bauer、William Brendel、Guoning Chen、Matt Clothier、John Datuin、Will Dillon、Jonathan Dodge、Chuck Evans、 Nick Gebbie、Kyle Hatcher、Nick Hogle、Chris Janik、Ankit Khare、Vasu Lakshmanan、Adam Leibel、 Jessica McGregor、Daniel Mof.tt、Chris Moore、Patrick Neill、Jonathan Palacios、Nadia Payet、Randy Rauwendaal、Dwayne Robinson、Avneet Sandhu、Nick Schultz、Sudarshanram Shetty、Evon Silvia、 Ian South-Dickinson、Madhu Srinivasan、Michael Tichenor、Christophe Tome、Ben Tribelhorn、Ben Weiss以及 Alex Wiggins。
感謝我的同事 Ryan Bailey教授、 Mike Gannis教授、 Jenny Orr教授、 Todd Shechter教授以及 Justin
——
Spencer教授。同時,還要感謝 NVIDIA公司的鼎力支持,尤其是 Gary Brown、Greg Gritton、Jen-Hsun Huang、
David Kirk、Dave Luebke以及 David Zier。特別感謝來自 AMD/ATI公司的 Bill Licea-Kane。感謝 Randi Rost在3D Labs和Intel工作時給予的支持,感謝他所撰寫的 “橘皮書 ”,本書從中受益匪淺。感謝派拉蒙電影公司授權使用本書中的圖 2.2。同時,皮克斯動畫工作室提供了原始圖像,在此
一并表示感謝。感謝 xkcd.com授權使用前言首頁處的漫畫作品。最后,還要感謝 Alice Peters和Sarah Cutler為本書提供的建議以及所付出的努力;感謝本書的審稿
人員,他們的寶貴意見使得本書內容得到了進一步的完善。
Mike Bailey Corvallis,Oregon
Steve Cunningham Coralville,Iowa
第1章 固定功能管線
傳統的視見方案
頂點操作
管線的片元處理
圖形管線中的狀態
傳統視見機制的實現方案
頂點處理操作
渲染處理操作
固定管線中的齊次坐標
頂點數組
本章小結
本章練習
第2章 OpenGL著色器的發展
著色器發展史
OpenGL著色器發展史
OpenGL2.O/GLSLl.10
OpenGL3.x/GLSL3.30
OpenGL4.O/GLSL4.00
OpenGL4.x/GLSL4.x0
內部原因
OpenGLES
處理不同版本
本書方案
變量名命名規則
本章練習
第3章 著色器基本概念
圖形管線中的著色器
頂點著色器
片元著色器
細分著色器
幾何著色器
GLSL著色器語言
應用程序與著色器之間的數據傳遞
在應用程序中定義attribute變量
在應用程序中定義uniform變量
GLSL新版本之間的轉換方式
本章練習
第4章 glman的使用
使用glman
加載GLIB文件
編輯GLIB文件和著色器文件
生成GLIB場景
窗口和視見操作
轉換操作
定義幾何對象
定義紋理
定義著色器名
其他命令
定義uniform變量
GLIB文件示例
紋理和噪聲
使用紋理
使用噪聲紋理
glman界面窗口功能
生成并顯示場景的硬拷貝
全局場景轉換
眼睛轉換
對象拾取和轉換
紋理轉換
顯示幀速率
其他功能項
本章練習
第5章 GLSL著色器語言
著色器語言的成因
圖形卡功能項
通用GLSL語言
共享命名空間
函數擴展和操作符功能項
……
第6章 光照
第7章 頂點著色器
第8章 片元著色器和表面外觀
第9章 片元著色器中的表面紋理
第10章 噪聲
第11章 基于著色器的圖像處理
第12章 幾何著色器的概念和示例
第13章 細分著色器
第14章 GLSLAPI
第15章 基于著色器的科學可視化計算
第16章 著色器應用
參考文獻
附錄A 基于GLSL程序的C++類
附錄B Matrix4C++類
附錄C VecC++類
附錄D 頂點數組類