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

这里是本书全部的插图。

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

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

写在前面

了解内置的CgInclude文件当然非常好,可是假设我们想要创建自己的CgInclude文件来存储光照模型和辅助函数又该怎么办呢?

好消息是我们的确能够创建自己的CgInclude文件。坏消息是我们须要再了解一点代码语法。好啦,那就開始吧!

准备工作

好消息是这次的准备工作最终有点不同了。。

。坏消息是我不能再复制粘贴了。

  1. 首先,创建一个新的文本文件,比如MyCgInclude.txt。
  2. 然后。把文件后缀改为.cginc。

    当然,操作系统通常会给你一些警示信息。说这个文件将变得不可用,但相信我,我们这个是可用的。

  3. 将新的.cginc文件导入到我们的Unity项目中(注意,在我的项目里,它的位置在一个新的名为CgIncludes的目录下)。等编译完毕后,我们能够看到Unity把该文件当成一个CgInclude文件编译好了。像以下这样:
如今,我们已经做好准备能够创建自己定义的CgInclude代码啦。双击CgInclude文件。在MonoDevelop中打开它吧~

实现

打开CgInclude文件后。開始键入例如以下代码。
  1. 首先,使用以下的预处理指令開始我们的CgInclude文件。

    这些声明和#pragma、#include相似,在这里,我们想要去定义一个新的代码集合,仅仅要我们的Surface Shader在它的编译指令里面包括了这个文件,这些代码就能够运行了。在CgInclude文件的最開始键入例如以下代码:

    #ifndef MY_CG_INCLUDE
    #define MY_CG_INCLUDE
  2. 然后。我们必须确保#ifndef或者#ifdef要有一个#endif来结束定义检查。

    就和一个if语句须要两个花括号一样。

    在#define指令以下键入例如以下代码:

    #endif
  3. 接下来,我们就能够填充剩余部分了。键入例如以下代码:
    // 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;
    }
  4. 以下是完整的MyCgInlcude.cginc文件:
    #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。我们想要使用自己的文件和代码。

  5. 返回上一节所用的Shader。

    我们须要在块中包括我们自己的CgInclude文件,就像C++中须要在开头加入头文件引用一样。

    同一时候,之前我们的Shader使用内置的Lambert光照模型,但如今我们想要使用自己定义的Half Lambert光照模型。

    由于我们已经包括了该CgInclude文件,我们能够直接在#pragma指令中指明这一模型:

    		CGPROGRAM
    #include "../CgIncludes/MyCgInclude.cginc"
    #pragma surface surf HalfLambert

    解释:这里须要指明.cginc文件的相对与该Shader的路径。

    也就是说。假设它和Shader放在同一个目录下,那么直接写名称就可以。

    但在我的项目中,Shader放在了Shaders目录下,而.cginc放在了CgIncludes目录下。因此须要上述写法。

  6. 最后,还记得我们在CgInclude文件里声明了一个_MyColor变量吗?我们还须要在Shader的Properties中加入该属性:
    	Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _DesatValue ("Desaturate", Range(0, 1)) = 0.5
    _MyColor ("My Color", Color) = (1, 1, 1, 1)
    }
最后,返回Unity。假设出现编译错误。说找不到.cginc文件。那么就是你的位置写的有问题。又一次看上面的解释更改一下就能够喽。
最后的结果例如以下所看到的。注意到。这里Unity已经使用了我们新的Half Lambert光照模型(和原来相比。就是提亮了背光面的亮度),而且加入了一个新的样色样本。左側为上一篇结果,右側为本篇结果。
 

解释

当编写Shader的时候,我们能够像使用C++中的头文件一样,使用#include预处理指令来包括其它代码集合。这告诉Unity我们想要当前的Shader使用包括的这些文件里的代码。我们这样做实际上是在对应位置包括了Cg代码片段。
一旦我们声明了#include指令,Unity就能够在项目中找到该文件,然后Unity会在文件里查找定义的代码片段。

也就是指。我们使用#ifndef指令和#ifndef指令的地方。

当我们声明#ifndef指令时,我们就是在告诉Unity,假设未定义这个名字,那么就使用这个名字去定义一些东西!

在本节中。我们是想要去#define MY_CG_INCLUDE。

因此,假设Unity没有找到一个名为MY_CG_INCLUDE的定义,它就会在编译该CgInclude文件时创建它。而#endif就是告诉Unity,这是该定义在这里结束啦。以下的不用再找啦。

如今,你看到了自己定义的CgInclude文件是多么强大(和C++中的头文件相似),我们能够使用它们来存储全部的自己定义光照模型。以降低代码的反复。

其它优点,像灵活性等。你能够联想C++头文件来得出啦~

【Unity Shaders】使用CgInclude让你的Shader模块化——创建CgInclude文件存储光照模型的更多相关文章

  1. 【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  2. 【Unity Shaders】使用CgInclude让你的Shader模块化——使用#define指令创建Shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  3. 【Unity Shaders】Transparency —— 透明的cutoff shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  4. 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  5. 【Unity Shaders】Diffuse Shading——向Surface Shader添加properties

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  6. 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建一个简单的动态Cubemap系统

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  7. 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建Cubemaps

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  8. 【Unity Shaders】Mobile Shader Adjustment —— 为手机定制Shader

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图.这里是本书所需的代码和 ...

  9. 【Unity Shaders】Mobile Shader Adjustment—— 什么是高效的Shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

随机推荐

  1. StreamCQL

    StreamCQLhttps://github.com/HuaweiBigData/StreamCQL http://blog.csdn.net/viewcode/article/details/90 ...

  2. SNMP中文

    SNMP4J 处理中文信息时的问题 http://qsjiangs.iteye.com/blog/1966899

  3. MongoDB实战指南(三):MongoDB的锁机制

    与关系数据库一样,MongoDB也是通过锁机制来保证数据的完整性和一致性,MongoDB利用读写锁来支持并发操作,读锁可以共享写锁具有排他性.当一个读锁存在时,其他读操作也可以用这个读锁:但当一个写锁 ...

  4. [状压dp]HDOJ4539 郑厂长系列故事——排兵布阵

    中文题,题意不再赘述 对于“?”这一格,它所能攻击到的(曼哈顿距离为2的) 前方的 即“√”的四个位置 那么与此格有关的即它前方两行(即状压这两行) 首先预处理每行能满足的: i 和(i<< ...

  5. udelay、mdelay、ndelay、msleep使用比较说明

    时间单位:    毫秒(ms).微秒 (μs).纳秒(ns).皮秒(ps).飞秒(fs).阿秒.渺秒    1 s = 10^3 ms = 10^6 us = 10^9 ns = 10^12 ps = ...

  6. App运营者必须知道的30款数据分析工具

    如今的移动应用早已不再是某种结构单一.功能简单的工具了.当我们的移动应用变得越来越庞杂,我们便会需要借用分析工具,来跟踪和分析App内的每一个部分.幸运的是,目前市面上有许多数据分析工具可供App开发 ...

  7. 6个可以隐藏运行bat,浏览器等程序的方法

    在电脑启动时或者设置时间时运行指定的程序很容易实现.但是有时候还需要运行时不显示主界面,隐藏到后台运行.比如:开机时一段Bat批处理执行删除默认共享; 开机自动运行浏览器隐藏到后代打开指定网页等,希望 ...

  8. NameValueCollection类

    最近在研究HttpRequest类,发现里面的很多属性都返回一个NameValueCollection对象,今天再来了解一下这个神秘的对象. 随便写了个例子,发现跟HashTable类似.但是这个东西 ...

  9. Visual Studio 2012 Professional 密钥

    Visual Studio 2012 Professional 密钥 4D974-9QX42-9Y43G-YJ7JG-JDYBP

  10. CodeForces - 445A - DZY Loves Chessboard解题报告

    对于这题本人刚开始的时候觉得应该用DFS来解决实现这个问题,但由于本人对于DFS并不是太熟,所以就放弃了这个想法: 但又想了想要按照这个要求实现问题则必须是黑白相间,然后把是字符是'B'或'W'改为' ...