Shader 的中文意思是着色器,是給模型上色的一個工具
在 Unity 中往往需要配合使用材質和 Unity Shader 才能達到理想的效果
常見的流程:
創建一個新的材質
創建一個 Unity Shader,並把它賦所創建的材質
把這個關聯了 Shader 的材質賦給需要渲染的游戲對象
在材質面板中調整 Unity Shader 的屬性,以得到滿意的效果
Shader 是什么
Shader 其實就是專門用來渲染圖形的一種技術
通過 Shader,我們可以自定義顯卡渲染畫面的算法
小到每一個像素點,大到整個屏幕,從而讓畫面達到我們想要的效果
比如下面這兩個游戲中比較常見的效果:
Shader 分為兩類:
-
頂點 Shader:3D圖形都是由一個個三角面片組成的,頂點 Shader 就是計算每個三角面片上的頂點,並為最終像素渲染做准備
-
像素 Shader:顧名思義,就是以像素為單位,計算光照、顏色的一系列算法
幾個不同的圖形 API 都有各自的 Shader 語言:
-
在 DirectX 中,頂點 Shader 叫做 Vertex Shader,像素 Shader 叫做 Pixel Shader
-
在 OpenGL 中,頂點 Shader 也叫做 Vertex Shader,但像素 Shader 叫做 Fragment Shader
所以說,Shader 其實就是一段代碼
而這段代碼的作用就是告訴 GPU 具體怎樣去繪制模型的每一個頂點的顏色以及最終每一個像素點的顏色
Shader 編程語言
既然 Shader 是一段代碼,那必然要使用一種語言來書寫它
目前主流的有三種語言:
-
基於 OpenGL 的 OpenGL Shading Language,簡稱 GLSL
-
基於 DirectX 的 High Level Shading Language,簡稱 HLSL
-
還有 NVIDIA 公司的 C for Graphic,簡稱 Cg 語言
GLSL 與 HLSL 分別是基於 OpenGL 和 Direct3D 的接口,兩者不能混用
而 Cg 語言是用於圖形的 C 語言,初衷就是讓基於圖形硬件的編程變得和 C 語言變成一樣方便、自由
Cg 語言是 Microsoft 和 NVIDIA 相互協作,在標准光照語言的語法和語義上達成一致,所以,HLSL 和 Cg 其實是同一種語言
Unity Shader
在 Unity 中,Shader 的編程反而會變得簡單起來
我們不需要在眾多顯卡、圖形 API 以及 Shader 編程語言中進行選擇
我們只需關心如何去實現我們想要的效果就可以了,其余的事情 Unity 會自動進行處理
這是因為我們在 Unity 中編寫的 Shader 最終會根據不同的平台來編譯成不同的着色器語言
Unity Shader 嚴格來說並不是傳統意義上的 Shader,而是 Unity 自身封裝后的一種便於書寫的 Shader,又稱為 ShaderLab
在 Unity 中有三種 Shader(三種不同的寫法):
-
Surface Shaders:表面着色器
-
Vertex/Fragment Shaders:頂點/片斷着色器
-
Fixed Function Shaders:固定管線着色器
其中 Fixed Function Shaders 已經被淘汰,完全沒有學習的必要了
Surface Shaders 其實就是 Unity 對 Vertex/Fragment Shaders 的又一層包裝
以使 Shader 的制作方式更符合人類的思維模式,同時可以以極少的代碼來完成不同的光照模型與不同平台下需要考慮的事情
但是 Surface Shaders 也有它的局限性
就是 Vertex/Fragment Shaders 能實現的效果,Surface Shaders 不一定能實現
反過來則成立,Surface Shaders 能實現的 Vertex/Fragment Shaders 則一定可以實現
並且在 Unity 2018 后的版本中推出了 Unity 官方自己的可視化 Shader 工具:Shader Graph
Unity Shader 模板
在 Unity Project 面板中點擊創建 Shader,你會發現這幾個選項:
其中:
Standard Surface Shader
標准表面着色器,是一種基於物理的着色系統(使用了 Physically Based Rendering(簡稱PBR)技術,即基於物理的渲染技術),
以模擬現實真實的方式來模擬材質與燈光之間的關系,可以很輕易的表現出各種金屬反光效果,同時此種 Shader 的書寫邏輯也更符合人類的思維模式
Unlit Shader
Vertex/Fragment Shader,也就是最基本的頂點片斷着色器,不受光照影響的 Shader,多用於特效、UI 上的效果制作
Image Effect Shader
也是頂點片斷着色器,只不過是針對后處理而定制的模版
Compute Effect Shader
Compute Shader 是運行在圖形顯卡上的一段程序,獨立於常規渲染管線之外的,
它可以直接將 GPU 作為並行處理器加以利用,從而使 GPU 不僅具有 3D 渲染能力,還具有其他的運算能力
Shader Variant Collection
Shader 變體收集器,在創建的時候,你會發現 Shader Variant Collection 與以上四個是被隔開的
就是因為這個與它們不一樣,它不是制作 Shader 的模版,而只是對 Shader 變體進行打包用的容器
Unity Shader 框架
打開創建的 Shader 后,刪除其余代碼只留框架:
剩下的框架結構可以拆分成以下幾個大部分:
-
Shader "name"
-
Properties
-
SubShaders
-
FallBack
-
CustomEditor
Shader 名稱路徑
第一行的內容是 Shader "Unlit/NewUnlitShader"
這一行中的 Shader 字眼是一個關鍵字,后面 "" 雙引號中的內容就是具體的路徑與名稱,其中雙引號中的 / 表示的是創建子層級
如果我們把路徑名稱放在 Hidden 下面的話
則表示在材質面板中隱藏此 Shader,你將無法通過材質下拉列表中找到它
這在做一些不需暴露的 Shader 時很有用處,可以使 Shader 下拉列表更精簡整潔
Properties 屬性
材質球面板中顯示的貼圖和一些參數什么的都是在這個 Properties 中進行定義設置的
當然,如果你確定不需要屬性的話也可以將整個 Properties 以及它的 {} 全部刪除,因為 Properties 是可選項
SubShaders
我們都知道不同的硬件性能是不一樣的,游戲內通常把機器配置分為高、中、低三種
假如我們做了一個效果很好的 Shader,但是卻只能在高配機上才有較好的性能表現,中低端就會顯的太費性能
這時 SubShader 就可以派上用場了:我們可以在這個 Shader 內做三個 SubShader,分別對應於高、中、低不同的配置
FallBack 備用
有的時候我們寫的 Shader 難免在一些機器上會出現不支持的問題(最終呈現的就是顯示成粉紅色)
而這個時候我們只要添加了 FallBack,並且在后面的雙引號內寫上了其它 Shader 的有效路徑名稱
那么在碰到不支持的硬件時這個 Shader 就會自動切換成 FallBack 內的 Shader
如果 FallBack 內的 Shader 也不支持呢,那就繼續從 FallBack 內的 Shader 中再找 FallBack ... ...
CustomEditor 自定義界面
我們可以通過這個功能來自由定義材質面板的顯示結果,它可以改寫 Properties 中定義的顯示方式
Unity Shader Properties 語法格式
屬性的寫法有個通用的格式:
[Attribute]_Name ("Display Name",Type) = Default Value
其中:
Attribute
屬性標記,也就是 Unity 內置的幾個屬性標記關鍵字,用於對當前這條屬性進行一些特殊的處理
_Name
屬性的名稱,也就是變量名,在 Shader 的 CG 代碼中就是通過這個名稱來調用此屬性內容的,在外部利用腳本調用時也是這個名稱
Display Name
顯示在材質面板上的名稱,主要起到說明解釋的作用
Type
屬性的類型,常用的有以下幾種:
-
Color(類型:顏色)
-
Int(類型:整型)
-
Float(類型:浮點數)
-
Vector(類型:四維向量)
-
2D(類型:2D紋理)
-
3D(類型:3D紋理)
-
Cube(類型:立方體紋理)
Default Value
默認值,當第一次指定此 Shader 時,或者在材質面板上執行 Reset 時,屬性的值會自動恢復到默認值
通用屬性標記
-
[Header]
在材質面板上進行標注,通常用作分類組別用,注意只支持英文、數字、空格以及下划線
-
[HideInInspector]
在材質面板中隱藏此條屬性,在不希望暴露某條屬性時可以快速將其隱藏
👉 | 以上內容僅為學習參考、學習筆記使用 | 👈