Shader編程學習筆記(四)—— Unity Shader的組織形式(ShaderLab)


Unity Shader的組織形式

 

Unity Shader的形態

  Unity官方手冊上講Unity Shader有三種不同的編寫方案,這三種編寫方案分別是surface shaders、vertex and fragment shaders和fixed function shaders。 從前面幾篇筆記中可以了解到,可編程圖形管線中能夠編寫shader的主要是兩個部分:vertex shader和fragment shader,但Unity還有surface shaders和fixed function shaders。

  對於fixed function shaders,從表面意思來理解就是固定管線着色器,在可編程管線硬件出現之前,很多的光照流水計算都會放在硬件里進行處理,我們把這樣的固定管線功能也看作是對應於固定管線硬件的操作,這種shader的功能是很保守的,比如說啟用簡單的光照,進行簡單的紋理采樣等等,對於現在絕大多數硬件都能得到很好的支持。

  surface shaders是Unity中被推薦和鼓勵使用的着色器,當你在Unity(Unity5之前)中創建一個shader時,默認的代碼就是使用surface shaders。那么為什么會有surface shaders這樣的着色器呢?它和vertex and fragment shaders又有什么關系呢?我們可以這樣理解,可編程圖形管線能夠識別就是兩種shader程序:vertex shader和fragment shader,至於surface shader是在vertex shader和fragment shader上面的一種包裝,Unity引擎最終會把surface shaders代碼編譯成能夠被硬件識別和調用的vertex and fragment shaders。

  Unity官方推薦在學習shader時先去閱讀ShaderLab syntax的基本概念,然后再去閱讀surface shaders或者vertex and fragment shaders的相關內容。fixed function shaders只能夠使用ShaderLab語法進行編寫,而surface shaders和vertex and fragment shaders不限於ShderLab語法,是可以使用Cg/HLSL,甚至可用GLSL去編寫,它是鑲嵌在ShaderLab中的一種代碼片段。

 

ShaderLab基本結構

  ShaderLab是Unity定制的專門編寫Shader的一種方案。使用ShaderLab可以把上文提到的三種shader用同一種格式來編寫,這樣就不會導致編寫不同的shader需要不同的語法。前文中對shader、材質和貼圖等它們之間的關系做了一個形象的比喻:材質是最終要使用的對象,shader是關於如何加工和處理的一種方案,是一種程序片段,至於貼圖、顏色等它們是屬於這個加工方案中的材料。那么當要建立一個Shader,要把它用於在材質上去使用的時候,既需要有算法,也需要添加一些原材料,首先來了解一下ShaderLab的主要結構,以下是ShaderLab的基本結構:

shader "name"{
    [Properties]
    SubShaders
    [FallBack]
}

  Properties的作用是能夠允許在Unity材質(material)檢視面板中為材質去定義一些需要的參數,如顏色、貼圖、參數等,這些都屬於原材料,被shader程序使用。

  SubShader的作用就是專門為GPU渲染所編寫的shader程序片段,在一個shader當中有並且至少需要一個SubShader,也可以有多個SubShader,但是在執行時只能選擇其中的一個SubShader。那為什么允許多個SubShader同時存在呢?原因是shader中的某一種算法或者某一種指令可能不支持當前的硬件,比如說一個shader程序有多個SubShader,當這個shader程序被執行的時候,首先會去檢測當前硬件能不能完好地支持第一個SubShader,如果第一個SubShader可以被當前硬件良好支持,那么就會使用當前SubShader,如果不能,那么就去檢測下一個SubShader。在編寫shader時,假如不能確定當前的SubShader在某些老舊的硬件上得到良好的支持,可以編寫第二個SubShader,用來適配這些老舊的、稍差的圖形硬件,當然也可以繼續編寫第三個、第四個、第五個等等,編寫的SubShader功能要依次簡化、運算指令依次簡單,用來滿足更多的硬件支持。如果編寫的SubShader都不能支持當前的硬件時,就需要用到ShaderLab的“FallBack”功能了。

  FallBack的意思就是回滾。如果當前硬件無法支持所有的SubShader時,Unity會將當前的着色回滾,回滾到FallBack所指定的shader,因此FallBack指令后跟隨的一般都是系統自帶比較簡單的,能夠被絕大多數硬件執行的shader。以下列舉了幾個Unity官方的內建的shader,更加具體的信息可以查閱Unity官方手冊。

 

Unity Build-In Shader

  • Unlit. This is just a texture,not affected by any lighting.(不發光。這只是一個紋理,不被任何光照影響

  這是Unity中最為簡單的shader,執行效率非常快,該shader經常被用於UI系統。

  • VertexLit.(頂點光照

  該shader擁有在頂點上渲染光照的能力。

  • Diffuse.(漫反射

  漫反射也是一種光照形態,不過它不僅僅在頂點上進行光照計算,在片段程序中也要進行光照計算。

  • Normal Mapped.This is a bit more expensive than Diffuse:it adds more texture(normal map),and a couple of shader instructions.(法線貼圖,比漫反射更昂貴:增加了一個或更多紋理(法線貼圖)和幾個着色器結構

  法線貼圖技術是一種比較傳統的圖形渲染技術,通過一張貼圖進行采樣計算,但這張貼圖不是一張普通的貼圖,而是一張存儲法向量的貼圖,把這張圖采樣出來的數據當做法向量,然后再進行光照計算,主要目的就是當幾個模型面片頂點數量不多,構成的面片細節不多的時候,為了表達豐富的細節,可以使用法線貼圖去彌補這樣的細節,以假亂真,因此法線貼圖shader的使用率很高。

  • Specular.This adds specular highlight calculation.(高光。增加了特殊的高光計算

  Specular指的是鏡面高光反射,主要用於模擬光滑物體,比如金屬、玻璃等。

  • Normal Mapped Specular.Again,this is a bit more expensive than Specular.(高光法線貼圖。比高光更昂貴一點

  該shader結合了以上兩點,既有法線貼圖,又有高光顯示。

  • Parallax Normal mapped.This adds parallax normal-mapping calculation.(視差法線貼圖。增加了視差法線貼圖計算
  • Parallax Normal Mapped Specular.This adds both poarallax normal-mapping and specluar highlight calculation.(視差高光法線貼圖。增加了視差法線貼圖和鏡面高光計算

  視差即視覺的差異,比較形象的解釋就是當人的左眼和右眼分別去看同一個物體時,兩只眼睛看到的結果是不一樣的,正是由於人的左眼和右眼有三厘米左右的距離,人看到的這個世界是三維的、立體的。
  那么視差法線貼圖的作用是什么呢?原因就是當法線貼圖進行貼圖映射的時候,是為了更好地表現物體的細節,法線數據存儲在紋理當中,但是該紋理是不可變的,當物體渲染出來后,會得到一個比較好的結果,表現了物體凹凸的細節,所以法線貼圖在有些教科書當中也叫作凹凸貼圖,但是當把有法線貼圖的物體進行旋轉,照理說有些地方由於視角的偏差是看不到它的凹凸的形態或者說看到凹凸感覺會更強烈,由於法線貼圖是一個固定的貼圖,就會達不到這樣的效果,而視差法線貼圖的作用就彌補這樣的缺陷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM