本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書做者),同一時候會加上一點我的理解或拓展。函數
這裏是本書所有的插圖。ui
這裏是本書所需的代碼和資源(固然你也可以從官網下載)。spa
========================================== 切割線 ==========================================操作系統
瞭解內置的CgInclude文件固然很是好,但是假設咱們想要建立本身的CgInclude文件來存儲光照模型和輔助函數又該怎麼辦呢?.net
好消息是咱們的確可以建立本身的CgInclude文件。壞消息是咱們需要再瞭解一點代碼語法。好啦,那就開始吧!code
好消息是此次的準備工做最終有點不一樣了。。orm
。壞消息是我不能再複製粘貼了。blog
。ip
。資源
固然,操做系統一般會給你一些警示信息。說這個文件將變得不可用,但相信我,咱們這個是可用的。
這些聲明和#pragma、#include類似,在這裏,咱們想要去定義一個新的代碼集合,僅僅要咱們的Surface Shader在它的編譯指令裏面包括了這個文件,這些代碼就可以運行了。在CgInclude文件的最開始鍵入例如如下代碼:
#ifndef MY_CG_INCLUDE #define MY_CG_INCLUDE
就和一個if語句需要兩個花括號同樣。
在#define指令如下鍵入例如如下代碼:
#endif
// Custom Build-in Variables fixed4 _MyColor; // Lighting models inline fixed4 LightingHalfLambert (SurfaceOutput s, fixed3 lightDir, fixed atten) { fixed diff = max (0, dot (s.Normal, lightDir)); diff = (diff + 0.5) * 0.5; fixed4 c; c.rgb = s.Albedo * _LightColor0.rgb * ((diff * _MyColor.rgb) * atten * 2); c.a = s.Alpha; return c; }
#ifndef MY_CG_INCLUDE #define MY_CG_INCLUDE // Custom Build-in Variables fixed4 _MyColor; // Lighting models inline fixed4 LightingHalfLambert (SurfaceOutput s, fixed3 lightDir, fixed atten) { fixed diff = max (0, dot (s.Normal, lightDir)); diff = (diff + 0.5) * 0.5; fixed4 c; c.rgb = s.Albedo * _LightColor0.rgb * ((diff * _MyColor.rgb) * atten * 2); c.a = s.Alpha; return c; } #endif
咱們需要告訴當前的Shader。咱們想要使用本身的文件和代碼。
咱們需要在塊中包括咱們本身的CgInclude文件,就像C++中需要在開頭加入頭文件引用同樣。
同一時候,以前咱們的Shader使用內置的Lambert光照模型,但現在咱們想要使用本身定義的Half Lambert光照模型。
因爲咱們已經包括了該CgInclude文件,咱們可以直接在#pragma指令中指明這一模型:
CGPROGRAM #include "../CgIncludes/MyCgInclude.cginc" #pragma surface surf HalfLambert
也就是說。假設它和Shader放在同一個目錄下,那麼直接寫名稱就能夠。
但在個人項目中,Shader放在了Shaders目錄下,而.cginc放在了CgIncludes目錄下。所以需要上述寫法。
Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _DesatValue ("Desaturate", Range(0, 1)) = 0.5 _MyColor ("My Color", Color) = (1, 1, 1, 1) }
也就是指。咱們使用#ifndef指令和#ifndef指令的地方。
當咱們聲明#ifndef指令時,咱們就是在告訴Unity,假設未定義這個名字,那麼就使用這個名字去定義一些東西!
在本節中。咱們是想要去#define MY_CG_INCLUDE。
所以,假設Unity沒有找到一個名爲MY_CG_INCLUDE的定義,它就會在編譯該CgInclude文件時建立它。而#endif就是告訴Unity,這是該定義在這裏結束啦。如下的不用再找啦。
其它優勢,像靈活性等。你可以聯想C++頭文件來得出啦~