預定義shader預處理宏:
Target platform:
Surface shader pass indicators:
内置全局狀态變量:
内置的矩陣:
内置的向量:
光照相關的:
變量:
内置光照參數:
對于不同的Rendering Path和Pass Tag,可以使用的光照參數是不一樣的。(當然所有參數你都可以在shader中使用,但并不能保證其一定會存儲有效的值)。
Forward rendering(ForwardBase和PorwardAdd标記的pass)支援的變量:
說明:
(1)_LightColor0在ForwardBass裡面表示:主光,一定是Pixel(Important)、Directional光源,沒有的話則改值不可用;
(2)_LightColor0在ForwardAdd裡面表示:目前執行的ForwardAdd的pixel光;
_WorldSpaceLightPos0的意義和_LightColor類似,也是在Base裡表示主光,Add裡表示像素光。
(3)unity_LightColor是距離物體最近的4個point光,也就是說同一個場景中每個物體的這4個光不一樣,注意這4個point光的選擇非常有意思;
(a)當shader中沒有ForwardAdd Pass的時候,unity_LightColor記錄了4盞vertex point光源,無視pixel光;
(b)當shader中包含ForwardAdd Pass的時候,unity_LightColor記錄了4盞point光源,pixel比vertex優先。
(4)如果場景中有多個pixel光,則對每一個物體,所有的非主光的pixel光都會執行一遍ForwardAdd Pass,按照強度大小、平行光優先的順序來執行;
(5)不要在ForwardAdd Pass裡面使用unity4LightPosX/Y/Z等資料,因為它們就是給ForwardBase Pass使用的,而且如果其中有pixel光,它們本身就會對ForwardAdd執行一遍;
(6)可以使用Shade4PointLights函數在ForwardBase中計算Vertex光源的照明。
Deferred shading:
Vertex-lit rendering(Vertex标記的pass):
頂點光照可以使用最多8盞光源,這些光源按照亮度排序,按順序存儲在一下這些資料結構中,如果光源數量少于8,那麼多出來的都将黑色:
(1)_LightColor0表示unity_LightColor[0]
(2)unity_LightPosition是MV空間中的位置
(3)逐頂點光照函數float4 ShadeVertexLights(float4 vertex, float3 normal)
注意:
(1)_LightColor0變量不代表某個具體含義,它在不同的Render Path和Pass裡面是有不同的意義的
(2)ShaderLab裡面的内置變量是不會及時清理的,這是Unity處于性能方面的考慮,因為在CPU和GPU之間頻繁傳遞資料是很耗資源的
Fog和Ambient環境光資訊:
使用multi_compile編譯Shader的多個版本:
有時候我們希望保留一個shader的大多數實作,而隻是做一些細節的修改,此時我們就可以通過該方式來生成shader的多個版本,然後在代碼中控制使用哪個版本。
指令:
#pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
控制:
Material.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
Shader.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
在shader中根據定義好的關鍵字處理具體顯示方案:
注意不要在shader中大量使用此指令,因為關鍵字的個數是有上限的,而多條multi_complie會交叉比對産生很多種結果。
GLSL shader程式設計
在Shader中,除了Cg/HLSL以外,GLSL(OpenGL Shading Languate)也可以直接使用。
一般不建議使用GLSL,除非你确定你的目标平台隻有Max OS X或相容OpenGL ES 2.0的移動裝置。
Unity預設都會将Cg/HLSL交叉編譯出優化過得GLSL,以此來支援多平台。在desktop平台下可以通過打開#pragma glsl選項來支援。
平台特性相關的渲染差異:
Unity封裝了大多數的平台問題,但有些時候還是需要自己處理一下的。
紋理坐标:
Direct3D裡面是左上角為原點;
OpenGL和OpenGL ES是左下角為原點。
多數時候都ok,除了在Render To Texture時。但是在RTT時,Unity對于D3D平台會自動将渲染的貼圖上下翻轉一下,以此隐藏了各平台的差異。
D3D平台下,有一種情況不需要Unity自動翻轉渲染貼圖,那就是使用Image Effects和Anti-Aliasing時,因為直接渲染到Screen了,
需要手動處理的情況:但同時使用screen texture和RenderTexture時,有可能會得到不一緻的坐标朝向,此時就需要在shader裡面通過代碼處理了:
AlphaTest:
在OpenGL ES 2.0和Direct3D 11中,沒有alpha testing的固定函數。是以在編寫programmable shader時,建議在pixel shader中使用CG/HLSL clip()函數來替代。
D3D 11 shader編譯器比較挑剔:
D3D 9和OpenGL使用NVIDIA的Cg來編譯shader,但D3D 11使用微軟的HLSL來編譯,此時就會産生一些差異化。
OpenGL ES 2.0隻支援部分GLSL原生的東西,是以Unity實作了一些内置的參數,讓其以OpenGL的方式工作,但是也有一些參數是沒有的。
CSDN部落格:http://blog.csdn.net/candycat1992/article/details/47284289