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