本系列主要參考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同一时候会加上一点个人理解或拓展。

 

 

这里是本书全部的插图。

这里是本书所需的代码和资源(当然你也能够从官网下载)。

========================================== 切割线 ==========================================

 

 

写在前面

 

我们已经看到怎样使用Unity内置的CgInclude文件。以及怎样创建我们自己的CgInclude去保存光照模型、变量和辅助函数。在这篇中,我们关注怎样更动态、有效地使用CgInclude文件,使得我们的Shader更加模块化,而且能够依据须要切换不同的状态。

 

因此,本篇中,我们将会改动上一节中创建的Half Lambert光照模型,为它加入一个定义(definition)。

这样,假设我们的Shader中定义了Half Lambert,那光照模型将会使用Half Lambert漫反射。否则就会使用标准的NdotL光照模型。

 

这节代码就3行,仅仅是个引子。

 

 

实现

 

我们首先再来看一下我们的CgInclude文件。

我们想要让该光照模型具有两个状态:

 

  1. 第一个状态。是正常的NdotL(Normal*LightDir)漫反射光照模型。而第二个状态,就是一个Half Lambert光照模型。改动我们的CgInclude文件去包括以下的两行代码:
    【Unity Shaders】使用CgInclude让你的Shader模块化——使用#define指令创建Shader_辅助函数

  2. 然后,在我们的Shader中,更新CGPROGRAM块中的指令:
    【Unity Shaders】使用CgInclude让你的Shader模块化——使用#define指令创建Shader_光照模型_02

  3. 保存你的Shader,返回Unity编译。这时你不会看到不论什么变化。这是由于我们告诉Unity,去定义一个名为HalfLambert的指令,假设它在不论什么已包括的文件里找到了这个定义。它就会使用第一步中的代码。

  4. 返回Shader。然后凝视掉我们刚才新加的指令。

     

    保存后返回Unity查看:
    【Unity Shaders】使用CgInclude让你的Shader模块化——使用#define指令创建Shader_光照模型_03

这时就会发现。Unity没有使用Half Lambert,而是使用了标准的NdotL光照模型。

 

这时由于我们未定义HalfLambert,因此Unity在编译时将会跳过那段代码。这使得我们的Shader更加灵活有效,我们能够不再编写或删除大量反复的代码。

 

 
 
 
解释
 
 
如你所见,尽管这节代码仅仅有3行。但我们能够利用这些简单的技术来使得光照模型更加多变。通过使用#ifdef指令,我们告诉Unity去查找这个名称的定义,这里这个名字指的是HalfLambert。
 
使用CgInclude来编写Shader。不仅能够帮助我们节省大量的代码,还能够存储大量的光照模型。

 

这使得我们更easy地去调用光照模型,或者使用多个状态去改动它。

 

 
这里讲到的这些技巧。事实上和C++里面的相关知识非常相似。而这些也是CG的知识内容。越学越感到。Unity尽管封装了非常多细节,但学习原始的Shader越显得重要啊。