本系列主要參考《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++头文件来得出啦~