本書(shū)中從著色器技術(shù)必須掌握的向量、矩陣與空間等數(shù)學(xué)知識(shí)開(kāi)始介紹, 通過(guò)大量的實(shí)例, 圖文并茂地講解了渲染流水線的原理, 著色器相關(guān)的語(yǔ)言、數(shù)據(jù)結(jié)構(gòu)、基本語(yǔ)法, 著色器的分類(lèi)等相關(guān)內(nèi)容, 讓讀者在實(shí)戰(zhàn)中逐步掌握Unity Shader的相關(guān)技術(shù), 并應(yīng)用到實(shí)際工作中。
1.面向零基礎(chǔ)人群寫(xiě)作,內(nèi)容由淺入深,基礎(chǔ)知識(shí)全面,注重原理講解,讓讀者知其然更知其所以然。
2.語(yǔ)言通俗易懂,插圖豐富,用大量生動(dòng)與圖形化的描述講解Shader及其原理知識(shí),學(xué)習(xí)門(mén)檻低,上手快。
3.內(nèi)容貼近實(shí)戰(zhàn),幫助讀者舉一反三,拓展知識(shí),不局限于書(shū)中介紹的內(nèi)容。
4.配套資源齊全。課后習(xí)題,幫助讀者鞏固知識(shí)。
前言
當(dāng)我還是一個(gè)剛高考完的愣頭青時(shí),抱著滿(mǎn)腔熱血打開(kāi)Unity,滿(mǎn)腦子都是光怪陸離的游戲畫(huà)面,以為下一個(gè)非同尋常的獨(dú)立游戲就要出現(xiàn)在我的手里,結(jié)果在第一步就卡住了——想象的畫(huà)面很美好,但Unity只給了我一個(gè)平平無(wú)奇的Standard材質(zhì),這可如何是好?于是我創(chuàng)業(yè)未半而中道找教程,才知道有個(gè)東西叫“Shader”,要想真正隨心所欲地“畫(huà)”出理想的游戲畫(huà)面,我要先學(xué)會(huì)它。
彼時(shí),Shader還在社群里被認(rèn)為是一種“高端”的代碼,資料不多、教程很少,即便是當(dāng)時(shí)流行的入門(mén)資料也是有一定門(mén)檻的(這種情況到目前也依然存在),無(wú)論是對(duì)數(shù)學(xué)的要求,還是對(duì)編程的要求,以及對(duì)計(jì)算機(jī)圖形學(xué)知識(shí)的要求。畢竟Shader本身就是一項(xiàng)融合了多種學(xué)科知識(shí)的技術(shù),尤其是對(duì)于對(duì)Shader還一無(wú)所知的初學(xué)者來(lái)說(shuō),不了解線性代數(shù),不會(huì)編程,基本就告別大多數(shù)教程了。近幾年來(lái),獨(dú)立游戲越來(lái)越多,游戲開(kāi)發(fā)的門(mén)檻也一降再降,當(dāng)很多入門(mén)不久的用戶(hù)都能使用C#在Unity面前游刃有余時(shí),唯獨(dú)Shader保持著它那“高冷而不近人情”的高門(mén)檻。對(duì)于大多數(shù)剛剛?cè)腴T(mén)的Shader初學(xué)者,或者是那些只是想能看懂Shader以對(duì)它稍作修改的開(kāi)發(fā)者,掌握晦澀難懂的底層理論是否真的是必要的?
因此,本書(shū)嘗試用淺顯易懂的語(yǔ)言和大量的比喻、引導(dǎo),先力求讓讀者明白“寫(xiě)Shader到底是在寫(xiě)什么”,只有建立起對(duì)Shader的宏觀概念,才能談“怎么寫(xiě)Shader”,否則寫(xiě)起來(lái)就像盲人摸象,很容易陷入“只會(huì)改Shader而不會(huì)寫(xiě)Shader”的困境。另外一點(diǎn),比起用案例和代碼的堆砌來(lái)教讀者“怎么做”,本書(shū)將更多的筆墨集中在寫(xiě)“為什么這么做”,這個(gè)理念從第1章一直持續(xù)到了最后一章,也是筆者最希望讀者從本書(shū)中學(xué)到的。我們總是先遇到問(wèn)題,再去想解決問(wèn)題的方法,而只知道“怎么做”,只能解決一種問(wèn)題,我們也不可能指望網(wǎng)上的教程總能完完全全地貼合我們的需求,一五一十地照搬案例只會(huì)讓未來(lái)的開(kāi)發(fā)變成“對(duì)著墻磚找墻洞”——那我們豈不就成了案例的提線木偶了?本書(shū)的大部分案例都旨在告訴讀者一種新思想、一種新工具,并希望讀者能真正將它們?nèi)跁?huì)貫通,變成屬于自己的“武器”。
在視頻資料和電子文檔大行其道的當(dāng)下,閱讀一本紙質(zhì)書(shū)學(xué)計(jì)算機(jī)知識(shí)看起來(lái)多少是有一些“傳統(tǒng)”,但筆者認(rèn)為紙媒依然有著獨(dú)特的作用。它不依賴(lài)于電子設(shè)備和網(wǎng)絡(luò)環(huán)境,也方便反復(fù)查看,讀者可以更聚焦于代碼之外的行文思路,學(xué)習(xí)每一步之間的思路推理過(guò)程,所以本書(shū)在許多章節(jié)中并不著重突出“代碼與反饋”的內(nèi)容。這不是一本“沒(méi)有計(jì)算機(jī)在旁邊隨時(shí)操作就看不下去”的書(shū)(當(dāng)然,并不是認(rèn)為看本書(shū)的時(shí)候不需要實(shí)踐)。
在本書(shū)的編寫(xiě)過(guò)程中,參考了許多前輩撰寫(xiě)的入門(mén)教程,包括Catlike Coding的教程、馮樂(lè)樂(lè)的《Unity Shader入門(mén)精要》。在數(shù)學(xué)章節(jié)中,筆者受到3Blue1Borwn極大的影響,他對(duì)線性代數(shù)的集合本質(zhì)進(jìn)行了鞭辟入里的講解。這些教程都是很棒的學(xué)習(xí)資料,讀者在學(xué)習(xí)中遇到問(wèn)題時(shí)也可以進(jìn)行查閱。
在編寫(xiě)本書(shū)的過(guò)程中,我盡可能地檢查校對(duì)內(nèi)容的準(zhǔn)確性,但由于個(gè)人能力和知識(shí)儲(chǔ)備的限制,難免會(huì)存在一些錯(cuò)誤或者不足之處。因此,非常歡迎讀者朋友在閱讀本書(shū)的過(guò)程中積極提供反饋和建議,以幫助我更好地改善內(nèi)容。
非常感謝何睿驊、李恒、肖洪廣和胡致遠(yuǎn),他們對(duì)本書(shū)的校對(duì)、編排、內(nèi)容調(diào)整提供了巨大的幫助。同時(shí),對(duì)中國(guó)鐵道出版社有限公司的編輯于先軍先生的約稿表示感謝,是您的信任讓本書(shū)得以面世。
15年前,有個(gè)名叫66RPG的獨(dú)立游戲論壇用一句“夢(mèng)想世界,在你手中”的口號(hào)激勵(lì)了成千上萬(wàn)的游戲開(kāi)發(fā)者,而我正是其中之一。我們的游戲世界從來(lái)不缺乏奇景,只是我們還未能擁有足夠的魔法將它的綺麗展現(xiàn)出來(lái)。衷心期盼本書(shū)能成為每一位讀者在游戲世界中創(chuàng)世的魔法指南,祝各位早日開(kāi)發(fā)出自己夢(mèng)想中的游戲。
黃志翔(網(wǎng)名:Hking Auditore)
2023年10月
黃志翔,網(wǎng)名HkingAuditore,國(guó)內(nèi)某知名游戲大廠技術(shù)美術(shù)。曾參與項(xiàng)目:玩具帝國(guó)(第二屆CUSGA中國(guó)大學(xué)生游戲開(kāi)發(fā)創(chuàng)作大賽具潛力獎(jiǎng)提名,2023GWB騰訊獨(dú)立游戲大獎(jiǎng)賽決賽入圍);糖果災(zāi)難(第二屆中國(guó)原創(chuàng)藝術(shù)類(lèi)精品游戲大賽提名、2021indiePlay中國(guó)獨(dú)立游戲大賽最佳設(shè)計(jì)獎(jiǎng)提名)。
第1章 數(shù)學(xué)基礎(chǔ)
1.1 向量
1.1.1 向量的基本運(yùn)算
1.1.2 線性組合
1.1.3 線性相關(guān)與線性無(wú)關(guān)
1.1.4 基向量
1.2 矩陣與空間
1.2.1 矩陣概念與幾何意義
1.2.2 矩陣運(yùn)算及其幾何意義
1.2.3 使用矩陣進(jìn)行空間變換
1.3 習(xí)題
第2章 渲染流水線
2.1 教機(jī)器人畫(huà)速寫(xiě)
2.2 GPU的“思維方式”
2.3 應(yīng)用階段
2.4 幾何階段
2.4.1 頂點(diǎn)著色器
2.4.2 曲面細(xì)分著色器
2.4.3 幾何著色器
2.4.4 投影
2.4.5 裁剪
2.4.6 屏幕映射
2.5 光柵化階段
2.5.1 圖元組裝
2.5.2 三角形遍歷
2.5.3 片元著色器
2.5.4 逐片元操作
2.6 可編程渲染管線:Unity SRP
2.7 習(xí)題
第3章 Shader基礎(chǔ)
3.1 我的第一個(gè)Shadel
3.2 Properties
3.3 SubShader
3.4 Pass
3.4.1 Pragma
3.4.2 Include
3.5 Shader內(nèi)的結(jié)構(gòu)體
3.5.1 頂點(diǎn)著色器輸入
3.5.2 片元著色器輸入
3.6 頂點(diǎn)著色器
3.7 片元著色器
3.8 我該怎么寫(xiě)呢
3.8.1 基本語(yǔ)法
3.8.2 常用函數(shù)
3.9 習(xí)題
第4章 上個(gè)色吧:基礎(chǔ)Shader上手
4.1 紋理
4.1.1 平移、縮放、旋轉(zhuǎn)——UV的奇妙用途
4.1.2 更多的紋理、奇妙的遮罩
4.1.3 混合的藝術(shù)
4.1.4 示例代碼
4.2 不同空間的操作
4.2.1 世界空間與模型空間
4.2.2 觀察空間與裁剪空間
4.3 控制覆蓋的方式
4.3.1 渲染隊(duì)列
4.3.2 深度測(cè)試、深度寫(xiě)入、深度裁切與Early
4.3.3 溶解效果:Alpha Test與Clip操作
4.3.4 模板測(cè)試
4.4 完善材質(zhì)面板:Properties
4.5 你能獲得的其他信息
4.5.1 頂點(diǎn)上的其他信息
4.5.2 其他信息
4.6 習(xí)題
第5章 計(jì)算與串聯(lián):需要思考的Shader
5.1 邊緣光效果
5.1.1 如何“看到”外邊緣
5.1.2 讓效果不斷變換
5.1.3 使用遮罩美化
5.1.4 讓功能是“可選的”:Shader變體
5.1.5 最終代碼
5.2 簡(jiǎn)單光照
5.2.1 漫反射
5.2.2 環(huán)境光
5.2.3 高光反射
5.2.4 陰影
5.2.5 多光源渲染
5.2.6 球諧光照
5.2.7 障眼法:烘焙
5.2.8 完整代碼
5.3 法線貼圖
5.3.1 提高模型細(xì)節(jié)的“障眼法”
5.3.2 翻譯法線貼圖
5.3.3 Unity中的法線貼圖
5.3.4 完整代碼
5.4 類(lèi)玻璃物體的渲染
5.4.1 折射效果與Grabpass
5.4.2 模糊
5.4.3 反射
5.4.4 完整代碼
5.5 習(xí)題
第6章 在模型上雕塑:Shader與幾何
6.1 描邊
6.1.1 額外的Pass
6.1.2 平直著色物體描邊
6.1.3 完整代碼
6.2 無(wú)中生有的頂點(diǎn):曲面細(xì)分著色器
6.2.1 曲面細(xì)分的流程及數(shù)據(jù)傳遞
6.2.2 Gerstner波
6.2.3 計(jì)算法線
6.2.4 基于視距的曲面細(xì)分
6.2.5 完整代碼
6.3 改變網(wǎng)格:幾何著色器
6.3.1 幾何著色器的流程與數(shù)據(jù)傳遞
6.3.2 生成隨機(jī)草地
6.4 習(xí)題
第7章 中轉(zhuǎn)站:Render Texure
7.1 軌跡效果
7.1.1 渲染的中轉(zhuǎn)站Rerder Teture
7.1.2 在Render Tenure上作畫(huà)
7.2 后處理效果
7.2.1 Uhity Post Processing包
7.2.2 創(chuàng)建自己的后處理效果
7.2.3 后處理中的描邊效果
7.3 習(xí)題
第8章 非真實(shí)感渲染
8.1 色彩控制
8.2 風(fēng)格化描邊
8.3 邊緣光
8.4 筆觸感
8.5 我們想要什么樣的“非真實(shí)感”
8.6 習(xí)題
第9章 真的入門(mén)了嗎
9.1 是否是個(gè)好Shader
9.1.1 良好的代碼習(xí)慣
9.1.2 函數(shù)庫(kù)
9.1.3 互不耦合的屬性
9.1.4 小心容易忽略的風(fēng)險(xiǎn)
9.1.5 性能與效果的平衡
9.2 學(xué)習(xí)的路還很長(zhǎng)