1. 程式人生 > >ShaderLab教程系列(二)

ShaderLab教程系列(二)

文章來自http://www.manew.com/thread-43291-1-1.html 

上一篇最後引出了shader存在的意義是為了讓二維螢幕繪製出栩栩如生的三維場景。此處進一步補充說明該觀點。
      首先,我們先來思考我們現實中是如何讓外部景物在我們的腦子中成像的。作為軟體開發的我們,務必永遠記住一點,這個世界是最合理最嚴謹的存在,如果你遇到你的業務邏輯無法理清,那麼,就去看看現實世界是如何運作的,忘記那些所謂高深的數學之類的東西,軟體程式設計,沒有高深的技巧,永遠別被那些所謂的演算法工程師嚇到,其實,就是忽悠,包括shader這邊,後續要撕逼的各種光照模型,其數學物理知識可謂簡單到高中生都理解基本無難度。
      我們看到一個物體 
      1)  第一個要點是要有光。
      2)  第二個要點是我們要有眼睛
      3)  第三個要點是確實存在物件。
      4)  第四個要點是我們要有腦子,進行後續各種經驗性糾正處理。
      通俗點說,我們看到紛雜豐富的世界是因為這些各式各樣的物體反射太陽光或者自己發射光進入我們的眼睛投影到視網膜上,然後這些視覺訊號傳輸到大腦,大腦進行後續各種經驗型糾正,然後最後在腦海中形成一幅影象。
      那麼,軟體是怎麼模擬這個事情的。軟體的模擬永遠是模擬,即儘量去模擬,但絕不是妄圖完全重現,軟體只是軟體,我們需要考慮我們當前的資源,然後抓取這個事務中重要的部分,按照重要程度進行依次模擬。
      1)  光:從自然界中我們抽取了點光源(模擬燈泡)、聚光燈(模擬手電筒)、平行光(模擬太陽光)以及環境光(各向無差異)。
 

點光源

 

聚光燈

平行光

      2)  眼睛:攝像機。攝像機所看到的就是相當於我們眼睛看到的,此時我們都是獨眼龍。此處提供了兩種相機,正交(遠景與近景一樣大小)與透視(存在透視點,所有地平線最後相交於透視點)。
      3)  物件:gameobject = mesh+material
      4)  腦子:渲染機制各種處理,保證渲染出來的效果符合預期。

      現在整個解決方案域的模型已經建好了,下面就是具體

問題解決的流水線了。即三維資訊到底如何從CPU到達GPU最後在螢幕上展示出來。

      如圖所示,應用程式將資料資訊準備好,通過3D API將資料送交GPU,GPU將資料進行各種變換處理後進行渲染輸出。

 

      GPU與CPU存在架構上的區別。如下圖:

      從圖中可以看出GPU為高併發性結構,存在多個處理器同時工作,GPU的控制單元以及暫存器明顯少於CPU,但這貨具有大量的邏輯運算單元,數說明GPU的強處在於數值處理,而非快取記憶體與流控制。通俗點說,CPU在一個時刻只能處理一個數據(單核CPU),而GPU可以同時處理多個數據。

      GPU採用的是流式平行計算,對每個資料獨立計算。通俗點說就是計算一個頂點的世界位置座標,不依賴於其他頂點的位置,多個數據可以同時被使用,多個數據並行運算的時間和1 個數據單獨執行的時間是一樣的。其編碼與CPU存在明顯的差異。見下圖

      那麼為何GPU需要如此設定。我們思考下對於1920*1080畫素尺寸的螢幕進行幀重新整理處理,如果場景中存在4kw個頂點,每個頂點需要進行100次運算,最後重新整理到畫素,每個畫素點需要進行5次運算,那麼我們需要運算的次數就是100*4kw+5*1920*1080,哪怕採取雙緩衝機制,一個水桶的容量取決於最短的那塊木板,最後為了滿足人的體驗,每秒重新整理幀數在60次,那麼需要進行的計算高達一億,每兩個脈衝可以完成一次獨立的計算,那麼需要我們的主頻必須十億赫茲,也就是1Ghz,這個代價太大。於是先賢整出了GPU。

 

     模型到底如何渲染出來。無外乎顏色的渲染,而渲染效果的好壞在於這些顏色的計算。對於如何模擬這些顏色,讓其效果更逼近現實,我們此處無非依然是參照現實世界。我們之所以看到一個物體,是因為該物體發射或者反射光線進入我們的眼鏡,現實世界如此,那麼,軟體模擬世界也比不過如此。我們採取的解決方案是計算光線、自發光等等各種因素影響下的頂點的顏色,然後頂點之間插值計算,從而得到每一個面的顏色分佈,最終展示出真實的效果。所以,shader你又可以理解為光照,他處理的無非就是各種光線問題,如漫反射、高光、自發光、半透明等等。

      數學模型建好之後,下一步就是具體的實施,此處有一個名字如雷貫耳,渲染管。資料如何從CPU流轉到GPU,GPU如何一步步計算最終在螢幕上展示,這個工作流水線是預定的,參見下圖。而shader只是開放出來的一個指令碼,用於將具體的渲染的一些效果控制交給開發者進行二次開發。      

      那麼shader存在的意義到底如何?其出現的更多的原因個人覺得是硬體的發展使然,以前硬體渣的時候,那麼,CPU只能呼叫GPU提供的API,進行簡單的引數調整渲染出其實還算可以的效果。隨著硬體的發展,大家越來越不滿足受制於人的感覺,於是,開始了可程式設計圖形元件,即提供了shader這個指令碼,而這個指令碼由兩個部分組成,頂點與片段,分別對應渲染管線中兩個片段,這樣你就可以做出各種你希望的效果,如顯示外圍輪廓等等。

 

       實際上,我們shader主要用於更逼真的顯示效果,所以,shader你又可以理解為基於物體本身屬性和光照條件,計算每個畫素的顏色值。當然,如果你用於各種非常規效果的話,那麼,就另當別論了。