• 【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):



    解释


    我们通过使用内置的辅助函数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这样的声明里使用的光照模型。





  • 相关阅读:
    python--------------内置函数
    下载文件的一致性验证之MD5值校验
    MySQL最大连接数设置
    Jenkins构建次数设置
    Linux(CentOS7)安装zip、unzip命令
    如何在CentOS 7上安装Munin
    Intellij IDEA14 搜索框及控制台乱码解决
    IDEA测试结果查看
    IDEA运行TestNG报错rg.testng.TestNGException: org.xml.sax.SAXParseException;
    intellij idea 注释行如何自动缩进
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314678.html
Copyright © 2020-2023  润新知