【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;

    注意:只有范围在0到1的浮点值才可以使用fixed类型哦~

  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这样的声明里使用的光照模型。

时间: 2024-10-20 04:01:35

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

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

本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码和资源(当然你也能够从官网下载). ========================================== 切割线 ========================================== 写在前面 了解内置的CgInclude文件当然非常好,可是假设我们想要创建自己的CgInclu

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

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 我们已经看到如何使用Unity内置的CgInclude文件,以及如何创建我们自己的CgIn

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

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 啦啦啦,终于毕业啦~上个月上任了游戏版版主,感觉在毕业前的一个月又给自己找了不少事.自己还

Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画

上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色.顶点坐标等. 这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画. 简单介绍原理: 在顶点函数中,获取到顶点坐标 vertex,然后,求float offsetY = sin(vertex.x) ,然后将 offsetY 加到 vertex.y 上,这样就把原来的平面 ,变成了 正弦 波浪. 然后再使用之前学过的 内置变量 _Time ,算式变为 float offset

【Unity Shaders】Shader中的光照

写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已.当然,我相信这是因为我们写得少...不过这也是由于官方文档对这方面介绍很少的缘故,导致我们无法自如地处理很多常见的光照变量.这篇我们就来讨论下Unity内置的一些光照变量和函数到底怎么用. 以下内容均建立在Forward Rendering Path的基础上. 自己总结的,如果有硬伤一定要告诉我啊!感激不尽~ 主要参考: http://en.wikibooks.org/wiki/Cg_P

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

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 之前学习的各种Shader时,我们从没有考虑在所有平台下的可用性.Unity是一个强大的跨

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

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 在上一篇里,我们学习了一些技巧来初步优化Shader.这次,我们学习更多的技术来实现一个更

【Unity Shaders】Vertex &amp; Fragment Shader入门

写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判断的,因此,对于那些平整的表面,它们的法线通常是一个常量或者会发生突变(例如立方体的每个面),这样就会导致最后的效果并非如我们所愿.如下图所示: 因此,我们有一个更好的方法来实现描边效果,也就是通过两个pass进行渲染--首先渲染对象的背面,用黑色略微向外扩展一点,就是我们的描边效果:然后正常渲染正

【Unity Shaders】初探Surface Shader背后的机制

转载请注明出处:http://blog.csdn.net/candycat1992/article/details/39994049 写在前面 一直以来,Unity Surface Shader背后的机制一直是刚開始学习的人为之困惑的地方. Unity Surface Shader在Unity 3.0的时候被开放给公众使用.其宣传手段也是号称让所有人都能够轻松地写shader.但因为资料缺乏,非常多人知其然不知其所以然,无法理解Unity Surface Shader在背后为我们做了哪些事情.