1. 程式人生 > >Shade學習方法總結

Shade學習方法總結

 最近網友candycat1992的新書《Unity Shader入門精要》出版了,估計萬千的中國unity開發者又要掀起一波學Shader熱潮了。我也想把自己這幾年學習Shader的一些歷程和心得記錄下來。一來當給自己的學習做個記錄,二來是給更多的後來人留些參考。

  寫之前先宣告幾點:

  1. 本文標題中的Shader並不特指Unity Shader,本文也不涉及任何程式碼細節,僅是討論學習方法。

  2. 圖形技術的水很深,我還只是個小學生,只是單純的分享自己的學習歷程,大神看到了別見怪。

  3. 每個人的性格,思想都不一樣,所以學習方法這種東西向來不是照搬照抄的,所以我說的不一定適合你,還需要自己取捨。

個人歷程

  容我講講自己學習Shader的經歷,你會發現,入門並沒有那麼難,只要你肯下功夫。

  畢業後的第一份工作就是從事Unity客戶端開發,當然了作為新人也就是寫寫UI,作作邏輯。恰巧當時專案的一個同事W君有Shader的經驗,就每週都挑兩天下班後的時間給我們上課,從最開始的矩陣變換到他離職前最後一課輝光效果。因為大學裡的圖形學課基本上也沒怎麼太認真(現在很後悔呀)。也就是這大概十幾節課,讓我對圖形渲染有了最初的認識。就從這段時間開始,我斷斷續續的開始了學習Shader的路。那時候國內還沒有一本專門講UnityShader的書。而我對圖形渲染的認識也是很膚淺的,只能去網上找資料,看程式碼例子,問同事,恰巧我有一個同事Y君,是學圖形的研究生畢業,所以很多事情都可以向他請教,所以他也算是我在這方面的老師了。也是他推薦我看的
《GPU程式設計與CG語言之陽春白雪下里巴人》
,以及《Cg教程_可程式設計實時圖形權威指南》(後來第二本書我還想盡了辦法弄到一本正版實體書收藏了)。就是這兩本書,還有網上那些我已經忘卻名字的很多前輩的分享,我開始一點一點的去了解Shader,瞭解圖形渲染,漸漸的也就成了我的一個興趣點。

  到了第二年,工作上得心應手一些,我就花更多的業餘時間在Shader上,一個問題想不明白就不停的想,直到能說服自己為止,也差不多就是那段時間郭浩瑜的那本《Unity 3D ShaderLab開發實戰詳解》出版了,要知道當初我和Y君可是每天都在關注出版進度,託了大半年終於出了,趕緊買來看。這本書現在看來別的不說,至少佈局結構是極其不合理的,相當不適合新人,該詳不詳,該略不略。很多地方程式碼一扔,也不解釋。不過,話說回來,因為我這人學東西如果一個地方看不懂就得想辦法搞懂,所以這本書也讓我知道了很多。這時候我也開始在Blog上寫了
第一篇Shader教程
(2014年2月份,其實那時候自己也剛剛入門)。就這樣邊寫邊學,漸漸到隱藏在unityShader背後的圖形渲染世界,不斷的讀書,寫作,練習,我幾乎是沒有在專案裡實際寫Shader的,因為一般由Y君負責,但基本上所有的Shader我都會看,然後不理解的就要和Y君討論弄明白。這樣發現那段時間自己成長很快,尤其是寫Blog,因為你要寫給別人看,要講的通俗易懂,還要剖析原理,寫的每一句話都要負責,所以一定要搞懂。這期間還讀了劉鵬翻譯韓國人寫的《計算機圖形學-基於3D圖形開發技術》,這本書其實很早就讀過,那時候實在是水平不夠,看不懂還怨人家翻譯差,後來再看了解了不少東西。

  大概一年前,很巧合有一個機會來到了現在的公司進行了遊戲引擎的開發。換工作之前也是想了很多,自己的圖形渲染知識都是工作後自學的,之前兩年的工作基本都是做Unity的邏輯開發工作,而且寫引擎要用C++。當時還有很多機會,繼續做Unity的開發工作,但還是橫下心來做引擎,因為這是我這幾年一直的想法,不論怎麼樣,有這機會就抓住,即使發現自己不適合,也會是一段很好的鍛鍊經歷。筆試面試最後也過了。也算是對自己之前兩年默默努力的一個回饋吧。

  做引擎開發者一年以來,得以有機會近距離看到遊戲引擎的原理,對OGL也有了更好的瞭解。也知道了所有的遊戲引擎核心原理沒什麼大的不同。但這一年來,由於沒有再接觸Unity,所以blog裡的Shader教程長期沒有更新。最近又打算重新開寫了。因為渲染這東西重要的是原理和引擎是無關的。有時間我會繼續更新。

  好吧,囉嗦了這麼長(誰愛聽啊!)。下面進入正題:

正確的理解Shader

  很多人對Shader的理解都不同,特別是初學者,往往對Shader的認知是很膚淺的。大都認為Shader就是UnityShader,就是Unity引擎裡一個用來創造畫面效果的一種檔案格式。

  這也是我當初剛接觸Shader的時候的認知。這當然是一葉障目,不見泰山了。如果要學好Shader,用好Shader,就不能只停留在瞭解和使用UnityShaderLab的語法的層次。這是遠遠不夠的,因為當你深入學習的時候你就會發現,由於你不理解Unity為你提供的某一個ShaderLab引數的具體原理,導致你也不能正常使用,即使是可以使用也不能舉一反三。

  當然作為一個初學者,認知上的缺陷是難免的,但希望你在看到了這篇文章後,能看的更深遠一些。Shader不只是指Unity的ShaderLab,也並不代表圖形渲染的全部,它只是渲染流程上的一環,或者說是關鍵的一環。是很多很多步驟的結合作用才最終把畫面正確的呈現出來。如果你真的想吃透Shader,用好Shader,這些東西都是你要去掌握理解的。那些渲染管線流程圖什麼的我就不拿過來貼上了,本文只做學習方法總結,不討論具體技術。

  綜上,飯要一口一口吃,知識也肯定是一點一點學,循序漸進持之以恆,但如果一開始就能比較全面和整體的理解Shader的定位,那麼也會在學習過程中,也就不會太自以為是,學的太膚淺。

如何起步

  其實現在比幾年前好多了,有了不少資源,很多熱心網友寫的教程,也有幾本還能看的書。

  我還是談談我的建議,首先找個遊戲引擎(當然你也可以不用引擎直接自己寫OGL或DX),一本合適的書。unity當然是現在最容易上手的了,書的話用來入門瞭解的有幾本是我覺得可以看的,但適不適合要看你自己了:

  2. 《Cg Programming in Unity》,這是Wiki上的一系列UnityShader教程,不過現在可能需要FQ看了。

  3. 《Cg教程_可程式設計實時圖形權威指南》,因為Unity的Shader大部分還是用CG語言來寫的,這本書雖然年代有點早,但還是值得一看的,而且Nvidia的網站上有最最新的英文版。

  4. 《Unity Shader入門精要》candycat1992,小姑娘這本書絕對的值得一看的,雖然是面向入門級的,但是裡面涉及了很多底層的,原理的性的內容。國內Unity書總算有本值得買的了。

  別問我為啥不推薦那本《Unity 3D ShaderLab開發實戰詳解》,前面已經說了。

  有了書,開啟引擎開始學,你需要的就是耐心和恆心了,我想學其他的知識也是一樣吧。Shader的水很深,做好打持久戰的準備,不斷的練習,不斷的嘗試,不斷的總結。

  在學習過程中遇到問題是必然的,合理的使用搜索引擎,去論壇和站點和大家交流。保持一顆謙卑的心,別人總有比你強的地方,虛心的學習,慢慢的積累。如果你身邊有一個可以請教的人,那就太好。就像我遇到Y君一樣。

  當你覺得自己入了一點門以後,就可以嘗試著分析專案裡的Shader程式碼了,結合著遊戲中的實際效果,看看程式碼裡用到了哪些你不知道的技術,或者說有什麼你覺得不合理的地方。如果有機會,就嘗試著申請在專案裡實際寫Shader的工作。這樣的鍛鍊是難得的。可惜我當初做Unity時候沒有這樣的機會。

  起步的一開始一定會是有些無從下手的感覺,度過這段時間,找到適合自己的節奏,就會有個很快速的學習積累過程。要堅持。

如何提高

  剛接觸Shader時候會有個迷茫期,其實當你學了一段時間,感覺自己學到了很多東西以後,也會有個迷茫期,不知道怎麼進一步的提高自己,感覺自己該掌握的都已經掌握了,但是又寫不出什麼東西。

  正如我在前面說的,我們總覺得自己好像該學的都學了,又感覺哪裡好像沒吃透。這說明我們還是沒有觸碰到我們學習內容的全貌,才只看到整個知識體系的冰山一角。所以一定會經歷這個從覺得自己什麼都會了,到感覺自己什麼都不會了的轉變。這個轉變是必要的,它意味著你將瞭解到更深更廣的知識。

  廢話不說了,一般我們入了門以後還要去理解更多的知識,我總結一下,大概有幾方面:

  1. 首先要對渲染管線有個透徹的瞭解,至少要知道每一步發生了什麼。很多學Unity從業者說會Shader也就只停留在前面那個語法層次了。如果連渲染管線都不知道,就不要再往簡歷寫會Shader了。這方面的資料很多,candyCat1992那本書以及《計算機圖形學-基於3D圖形開發技術》都有,還有Trace大神搬運過來的一套教程。瞭解渲染管線,能讓你對Shader裡的很多用法都能有更深入的認識。

  2. 去學習OpenGL或者DirectX的知識(如果你經歷足夠可以雙管齊下),看好,不是說HLSL或者GLSL這些Shader語法,而是OGL和DX。瞭解了渲染管線之後,再去了解一下圖形API,試著動手寫寫,你才能真正的理解渲染管線的實際流程,以及那些被遊戲引擎所隱藏起來的渲染邏輯。你也就能瞭解到Unity中的FBX模型裡到底都放了什麼資料,場景模型上的MeshFilter元件和MeshRenderer元件都是起什麼作用的,等等。對這些圖形API有了一定的掌握,不僅可以對渲染流程有更深入的瞭解,甚至可以自己開發一個簡單的渲染引擎了。這方面的學習資料就太多了,學OGL就是紅寶書,DX的話自然就是龍書

  3. 再有很重要的一塊就是圖形演算法,想要在通過Shader做出各種驚豔或者特殊的渲染效果,可不是隻學會寫Shader語法就可以做到的,就像大學裡學程式設計後還要學習演算法是一樣的,圖形渲染中也有大量的演算法,從最基礎的光照演算法,到HDR,FXAA,Toon。再到最近次時代流行的PBR等等。有很多已經很成熟的演算法,但這些演算法不一定完全適合你的專案或者平臺,所以必須瞭解他們改進它們,甚至研究出新的演算法。這個過程估計是最痛苦的了,因為國內的資料不多,討論的人也不多,演算法中往往還涉及到大量的數學和物理知識。如果能持續不斷的堅持學習和實踐,那你也許就會是萬千遊戲開發大軍中的的佼佼者。這方面的書雖然不多,基礎類的我就不說了,很多書上都有,有一些大部頭的經典如:《GPU Gems》系列,《Real-Time Rendering》,《Physically Based Rendering》。國內能讀完這些書的人應該是是很少的。我自己還不到這個層次,不過也準備要開始塌下心來學習。還有一個論壇OpenGPU,也推薦給大家,不過這個不是入門向的,裡面的大神太多了,不要在裡面提太沒營養的問題,會被鄙視的。

  4. 補補數學再學點物理知識吧。線性代數的重要性就不用我說了,如果能力和精力允許的話,就多補一補,我這數學渣就不多說話了,不過我也有時間會學一學的。這方面也有一些好的資料。我手頭就有一本《Mathematics for 3D Game Programming and Computer Graphics》。這個我就不多說了,沒事多學學,省著用到了撓頭。

  ...

  其實還有很多,比如把C++好好學一學,不過已經不要緊了,路很長,要怎麼走還是要靠你自己。我也只是個一定意義上的入門者,不想誤導別人。大家一起提高,互相幫助吧。

最後幾句心裡話

  其實無論別人看別人多少文章,多少教程,多少書,學習的路上往往都是沒有捷徑的,總要經歷些坎坷和挫折。否則牛人怎麼才是牛人呢,自己這幾年的學習歷程也是經歷了很多,寫這篇文章並不是能給大家提供什麼捷徑和速成法,只是給大家些勇氣,希望大家少一些磕磕絆絆。像我這樣的都能入個門,大家也一定可以的。

  也希望大家,能樂於分享,讓大環境更成熟起來,也希望能湧現更多的牛人。

分類: Unity,遊戲之路