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

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

这里是本书全部的插图。

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

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

写在前面

啦啦啦,又开了新的一章。。。为什么会讲CgInclude呢?什么又是Cg呢?呜,按我的理解就是Cg是Shader语言里面的跨平台语言。众所周知,GLSL语言是工作在OpenGL接口上的,而HLSL语言是工作在DirectX接口上的。而Cg语言能够使用这两种不同的API,而不须要考虑平台问题。当然,这里面还有非常多平台相关的性能问题。

Unity同意在Shader中嵌套Cg代码片段,然后会再编译成OpenGL、DirectX、Flash等。以便让我们的Shader工作在不同的平台上。而使用CgInclude能够让我们重用代码,实现Shader的模块化。

实际上,我们之前在不知不觉中就使用过一系列Unity内置的CgInclude来编写Surface Shader。

还记得Lambert、BlingPhony光照函数吗?这就是使用了Unity提前为我们编写好的Cg片段。

理解并编写我们自己的CgInclude文件。有助于我们更快、更方便地改动Shader。

而在编写自己的文件之前,我们先来学习下Unity为我们提供了哪些内置的光照模型、函数和状态变量。

Surface Shader是Unity的骄傲,它为我们节省了非常多代码量,当中非常重要的原因就是它在背后为我们做了非常多工作。我们能够在Editor/Data/CGIncludes(MAC下是Content/CGIncludes)下找到这些代码。这些文件有的负责阴影和光照。有的则是一些辅助函数,还有一些负责平台依赖。假设没有它们,我们的Shader编写起来会变得更加费劲。

你能够在这个链接里找到Unity提供的一些信息。

以下通过使用UnityCG.cginc文件中面的辅助函数,来正式開始理解内置的CgInclude文件。

准备工作

  1. 创建一个新的场景和一个球体,加入一个平行光。
  2. 创建一个新的Shader和Material,能够命名为HelperFunctionShader。
  3. 把Shader赋给Material,把Material赋给球体。
  4. 最后,打开UnityCG.cginc文件。以便我们能够查看这些辅助函数的具体实现。

实现

  1. 在Properties块中加入以下新属性。我们须要一张纹理以及一个控制去色滑动条:
    	Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _DesatValue ("Desaturate", Range(0, 1)) = 0.5
    }
  2. 在CGPROGRAM里面加入上述新属性的引用:
    		sampler2D _MainTex;
    fixed _DesatValue;

    注意:fixed类型的范围是-2.0到+2.0。精度是1/256,超过了就不行了哦!

  3. 最后,改动surf函数。它里面使用了一个我们之前没有见过的函数——lerp和Luminance。Luminance函数是在UnityCG.cginc里面定义的。而lerp是Cg的一个函数。
    		void surf (Input IN, inout SurfaceOutput o) {
    half4 c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = lerp(c.rgb, Luminance(c.rgb), _DesatValue);
    o.Alpha = c.a;
    }
最后,通过改变去色滑动条的大小。就能够得到以下的效果(从左到右去色值分别相应0.0,0.5,1.0):
【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件

解释

我们通过使用内置的辅助函数Luminance(),来高速得到一个去色效果,或者说是实现了Shader的灰度化。这些都是由于UnityCG.cginc文件自己主动为我们的Shader包括了相关代码。
假设你搜索UnityCG.cginc文件,你能够找到例如以下代码:
// Converts color to luminance (grayscale)
inline fixed Luminance( fixed3 c )
{
return dot( c, fixed3(0.22, 0.707, 0.071) );
}
由于Unity会自己主动编译这些代码,因此我们能够直接在Shader中使用这些函数。
而还有一个函数lerp(),是Cg的一个函数。官网里有具体的函数说明。
细心的话,你能够在CGInclude目录下找到还有一个文件——Lighting.cginc(代码不多)。这个文件中面包括了全部我们在相似#pragma surface surf Lambert这种声明里使用的光照模型。
上一篇:【java多线程】volatile 关键字


下一篇:flask-Datatables