Unity着色器和屏幕特效开发秘笈(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-25 20:39:35

点击下载

作者:(美)Kenny Lammers

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Unity着色器和屏幕特效开发秘笈

Unity着色器和屏幕特效开发秘笈试读:

前言

本书将指引你逐步熟悉如何在Unity3D中创建着色器和后期特效。我们将从创建最基本的着色器和学习着色器代码的结构开启学习之旅。通过循序渐进地学习每一章的基础知识,将使你们逐渐地掌握着色器语言,而且还会学到模拟人体皮肤的着色器,处理动态反射的着色器,以及如何开发后期特效(如,夜视)等知识。

在每章的最后,你还将学习新的技术,包括提高着色器质量,甚至如何使着色器编写过程更加高效。不管你是初学者或者专家,这些章节都是为你量身定制的,你可以跳过任意部分去学习特定的技术。对于那些在Unity中学习着色器的新手而言,你可以循序渐进地学习每一章以便逐步建立自己的着色器知识库。无论通过哪种方式,你都将学习到现代游戏的制作方式和方法。

读完本书,你将获得一组能够在Unity3D游戏中使用的着色器,同时掌握如何添加相应的着色器来实现新的特效并满足性能要求。本书的主要内容

第1章通过在Unity3D中构建一个着色器解释了着色器编写的基础知识。然后,利用所学的知识创建默认的漫反射光照,并从游戏的角度提供了创建自定义漫反射光照的技巧。

第2章介绍了如何利用纹理来创建不同的特效。你将学习如何利用着色器在精灵表单(Sprite sheet)上实现动画纹理,以及如何利用纹理的不同通道,让着色器更有效率。在该章的最后,你将掌握利用纹理来创建自定义特效的技能。

第3章教给你在创建应用最广泛的高光类型——Blinn和Phong时所需的所有知识。你将学习如何应用这些着色器效果来创建蒙版镜面、金属镜面,并学习创建各向异性镜面的技术。在该章的最后,你将有足够的信心为自定义着色器创建属于自己的镜面效果。

第4章带你了解现代游戏最受欢迎的效果之一,即把反射技术写入着色器中。该章将教你关于反射的一切知识,从Unity3D着色器中反射的基础知识到如何使用C#创建简单的自定义动态反射系统。

第5章开始创建更复杂的着色器。你将学习如何创建自定义光照模型来实现自定义类型的表面。每个方法展示了不同的技术来完成不同的任务,都是为了提高着色器编写能力。在该章的最后,你将创建自己的皮肤着色器、发光球体着色器以及车辆喷漆着色器。

第6章介绍透明度。有数据表明,在游戏制作的过程中,透明度已经成为一项必要的技术。在一定程度上,几乎所有游戏都需要使用透明度,如图形用户界面(GUI)、树叶、贴花等。在该章中,你将学习如何使用Unity3D中的透明度,以及使用透明度时如何处理可能发生的任何问题。

第7章包括如何访问存储在3D网格中的每个顶点信息。你将学习如何得到顶点信息,并且在着色器中使用这些信息实现诸如纹理混合和动画的效果。

第8章主要介绍了利用Unity的内置标记和内置值来减少着色器内存开销的方法。这对于我们处理移动平台上的着色器特别重要。

第9章展示了学习重用代码的必要性,重用代码可以让着色器的编写更有效率。该章也展示了如何创建自定义CgInclude文件来存储需要重用的重复代码。

第10章从现代游戏如何利用屏幕特效(有时也称为后期特效)开始,到如何改变一个游戏的最终渲染效果。你将学习如何创建自己的屏幕特效,并了解如何添加颜色调整以及纹理叠加背后的秘密,从而为你的游戏制造出不一样的视觉外观。

第11章将进一步介绍屏幕特效,并为你展示在游戏当中是如何增强游戏氛围的。你将学习如何创建一种老电影的屏幕特效以及夜视的屏幕特效。阅读前的准备工作

以下是我们完成本书内容所需的软件和可选的软件列表:

·Unity3D(第10章和第11章需要使用Unity3D专业版)

·3D建模软件,如Maya、Max或Blender(可选)

·2D图像编辑软件,如Photoshop或Gimp(可选)本书的读者对象

本书是为所有的Unity3D开发者而编写的,读者范围从初学者到高级开发人员。如果你在编写C#或JavaScript脚本方面具有丰富的经验,你会感觉在Unity3D编辑器中创建一些简单的资源是非常轻松的。我们建议你阅读一下Packt出版社的另一本书籍《Unity 3.x Game Development by Example Beginner’s Guide》,该书能为你使用Unity3D打下坚实基础。下载本书的彩色图片

我们为你提供了一个PDF文件,它包含了一些书中使用的截图或者图表。这些彩色图片能够帮助你理解相关章节的内容,你可以通过网址http://www.packtpub.com/sites/default/files/downloads/5084OT_Images.pdf来下载这些图片。第1章 漫反射着色

本章将介绍一些现代游戏中开发渲染管线时常见的漫反射技术。1.1 引言

任何优秀的着色器开始总是会依赖于一个基础的漫反射组件或者光照模型。因此从漫反射部分开始着色器的编写是非常有意义的。

在过去的计算机图形学中,漫反射的着色过程(diffuse shading)是通过所谓的固定功能光照模型来完成的,它只允许图形程序员通过一些参数或纹理来对单一的光照模型进行调整。而现在,我们可以通过Cg语言更加灵活地控制渲染细节,特别是使用Unity中的表面着色器。

漫反射着色器主要描述了各个方向上的光线在一个表面上的反射方式。这听起来跟反光镜的工作原理很相似,但事实上它们是不相同的。反光镜实际上反射的是周围环境的图像,而漫反射光照是将所有的光源,如太阳的光线,反射到观众的眼睛中。反射将在后面的章节中介绍,但现在我们的目的是利用这些知识帮助我们区分两者之间的区别。

为了实现一个基本的漫反射光照模式,我们必须创建一个着色器,它包含了自发光颜色(emissive)、环境反射光的颜色以及所有光源叠加的光照。接下来的教程将告诉你如何建立一个完整的漫反射光照模型,同时也将展示一些不同行业的技巧,对于只使用纹理创建更复杂的漫反射模型来说总会派上用场。

在本章的最后你将学会如何创建基本的着色器,使之能执行基本的操作。有了这些知识,你将能够创建几乎任何表面着色器。1.2 创建基本的表面着色器

随着我们进一步学习本书,你已经知道如何在Unity当中设置工作区,从而提高你的工作效率,而且这很容易实现。如果你已经熟悉了在Unity 4中创建着色器和设置材质,可以跳过这个教程。这里,我们只是为了确保新的Unity 4开发者能够顺利学习有关表面着色器的其他教程。1.2.1 准备工作

开始学习本教程之前,你需要先打开Unity 4,并且创建新的项目。在本书中有一个Unity项目,所以当你学习到相应的教程时,你可以使用这个项目并添加自定义的着色器。当你完成了这些,现在就准备进入实时阴影的奇妙世界吧!1.2.2 如何操作

在开始我们第一个着色器之前,我们需要创建一个小的场景(scene)供我们使用。这可以通过Unity编辑器中的GameObject|Create Other菜单来完成。然后可以创建一个平面作为地面,创建两个球体作为着色器的应用对象,以及一个定向光作为场景的灯光。场景建立完毕,我们就可以开始编写着色器了:

1.在Unity编辑器的Project面板上,右击Assets文件,选择Create|Folder。如果你使用的是本书提供的Unity项目文件,你可以直接跳到步骤4。

2.重命名创建的着色器文件夹,可以选中文件夹然后右击选择“Rename”,也可以使用键盘上的“F2”键。

3.创建另一个文件夹,将其重命名为“Materials”。

4.选中着色器文件夹单击右键,选择Create|Shader。然后在“Materials”文件夹上单击右键,选择Create|Materials。

5.将刚才创建的Shader和Material都重命名为BasicDiffuse。

6.双击BasicDiffuse着色器,打开MonoDevelop(Unity的默认脚本编辑器),它将会自动启动编辑器并显示着色器代码。你会看到Unity已经为我们添加了一些基本的着色器代码,默认情况下,你将得到基本的漫反射着色器,它会接受一个纹理信息。我们会修改这些基本代码,这样我们就可以学习如何快速地开发自定义着色器。

7.现在我们需要给着色器一个自定义文件夹路径。着色器代码中的第一行是对着色器的自定义描述,这样我们就可以在Unity着色器下拉列表中找到它,并且将它赋给某个材料。我们已经将着色器路径重命名为Shader “CookbookShaders/BasicDiffuse”,但是你可以在你需要的任何时刻对它进行重命名。所以你无须担心它此刻的依赖关系。保存MonoDevelop的shader代码,回到Unity编辑器。当它确认文件已更新时,Unity将自动编译着色器。这样可以使着色器实时地显示它的效果:

8.选择我们在步骤4中创建的名为BasicDiffuse的材质,并在Inspector面板中进行查看。从Shader下拉列表中选择CookbookShaders|BasicDiffuse(如果你选择使用不同的路径名,你的着色器路径可能是不同的)。将你的着色器赋给材质,以便你可以将其赋给某个物体。要将材质赋给某个物体,可以从Project面板上通过简单选中拖曳至视图中的物体。也可以在Unity编辑器中拖曳一种材质至物体的Inspector面板中。

此时它看起来没什么效果,但着色器的开发环境已经设置好了,现在我们可以开始修改着色器代码,以满足我们的需求。1.2.3 实现原理

Unity已经帮你完成了着色器和运行环境的建立,你只需要简单地点击几下鼠标便可以开始后面的工作了。对于表面着色器本身而言,很多元素都是在后台工作的。Unity采用Cg作为着色语言,Cg语言使你的代码编写更加高效。表面着色器语言大多基于组件的方式写入着色器。如纹理坐标和转置矩阵之类的功能Unity已经帮你实现了,因此你不必从头开始了。以前,为了编写一个新的着色器,你必须重复重写很多代码。在你已经熟悉表面着色器之后,你自然想探索更多关于Cg语言的基本功能,以及Unity是如何在底层的图形处理单元(GPU)上执行低级图形运算的。

因此,通过简单地更改着色器路径名,我们已经拥有了一个可以在Unity下运行的基础漫反射着色器,包含的灯光和阴影也能正常工作。而这一切的实现只需改变一行代码而已!1.2.4 参考

为了了解更多关于Unity内置的大量Cg功能,可以访问Unity安装目录下的Unity4\Editor\Data\CGIncludes,有三个文件需要特别注意的,UnityCG.cginc、Lighting.cginc和UnityShaderVariables.cginc.。目前我们的着色器使用的正是这三个文件里的功能。

我们会在第9章更加深入地学习Cglncludes文件。1.3 为表面着色器添加属性

着色器的属性在渲染管道过程里是很重要的,因为它们是一个接口可以让使用着色器的美工或用户指定纹理和调整着色器的值。属性可以作为GUI元素暴露在材质的Inspector面板上,而不需要单独的编辑器,它提供了可视化的方法供你调整着色器。

使用MonoDevelop打开你的着色器,查看第3行到第6行的代码。这些就是着色器的Properties块,目前,它只有一个名为_MainTex的属性。如果你查看对应的材质,你会注意到Inspector面板上有个对应的纹理GUI元素,这就是使用我们的代码自动生成的。

需要再次说明的是,Unity采用高效的编码方式实现这一过程,它花费一定的时间量通过遍历来改变属性值。1.3.1 如何操作

让我们通过创建自己的着色器属性,来了解BasicDiffuse着色器的语法以及它是如何工作的。

1.在着色器的Properties块中,删除下面的代码来移除当前属性:

2.输入下面的代码,并保存着色器,然后再次打开Unity编辑器。

3.当你返回Unity时,着色器将完成编译,并且你在材质Inspector面板上可以看到一个名为Emisslve Color的颜色样本,它替换掉了之前的纹理样本。接下来我们再添加一个看看会发生什么。输入如下代码:

4.我们已经在材质Inspector面板上添加了另一个颜色样本,现在让我们再次添加并且看看其他类型的属性,在Properties块中输入如下代码:

5.现在我们已经创建了另一种GUI元素,在Inspector面板上我们可以很直观地进行交互。这次我们创建的是一个滑动条(Slider),如下图所示。

属性可以让你创建一个可视化面板来调整着色器,而不需要更改着色器代码。1.3.2 如何操作

每个Unity着色器都拥有一个内置结构(在它的代码中我们可以看到),这些Properties块也是Unity所希望带给你的功能之一。这样做的原因是希望给用户提供一种快捷方式来创建GUI元素并和着色器代码绑定。在Properties块中声明的属性可以在接下来的代码里用于调整值、颜色或者纹理。

让我们来看看Unity着色器在背后都做了哪些工作,当你第一次添加一个新属性时,你需要赋予它一个变量名,这个名字可以让你的着色器代码从GUI元素中获取相应的属性值,这为我们节省了大量的时间,因为我们不需要亲自建立这个系统。

属性的下一个元素就是GUI Inspector面板的名字和属性类型,它们包含在圆括号当中。GUI Inspector面板的名字就是出现在材质Inspector面板里的属性名字,它是用于与着色器交互和调整着色器的。属性的数据类型是由我们控制的。Unity提供了很多类型让我们在着色器里使用,下表描述了这些类型:

最后,这些属性都有各自的默认值,代码里的属性会被快速赋予默认值。因此,在示例里,由于_AmbientColor的类型是Color,所以默认值被设为1,1,1,1。这四个值代表RGBA 或者float4,或者r,g,b,a=x,y,z,w,当它在第一次创建后,就被设置为白色。1.3.3 参考

这些属性都记录在Unity手册里,网址是http://docs.unity3d.com/Documentation/Components/SL-Properties.html。1.4 在表面着色器中使用属性

现在我们已经创建了一些属性,我们可以将它们与着色器关联起来,以便使用属性来调整着色器并让材质处理获得更多的交互性。

我们可以在材质Inspector面板上调整属性,因为已经为属性赋予了一个变量名,如果你想在着色器代码里通过变量名来获得它的属性值,则必须创建与之对应的另一个变量。1.4.1 如何操作

接下来将演示如何在表面着色器中使用属性:

1.首先,要删除以下代码,因为在1.2节删除了MainTex属性。

2.然后,在CGPROGRAM行下面添加以下几行代码:

3.当你完成步骤2之后,你就可以在着色器里使用属性值了。让我们将_EmissiveColor的属性值加到AmbientColor属性值上,然后把计算结果赋值给o.Albedo。将以下代码加入到surf函数。

4.最后,着色器的代码应该和下面一样,在MonoDevelop中保存着色器代码并返回Unity窗口后,如果没有错误,着色器将会自动编译,你现在可以在材质里修改ambient和emissive属性的颜色值了,让我们通过滑动条来增加这些属性的饱和度。

pow(arg1,arg2)是自带的函数,相当于数学公式中的power(求幂),参数1代表底数,参数2代表指数。如果你想了解关于pow()函数的更多信息,你可以查阅Cg教程,这是一份优秀的免费教程,你可以学到更多着色器的知识,也可以查阅各种着色器的Cg函数用法。

http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html

下面这个截图展示的是在材质Inspector面板中调整颜色和饱和度之后的样子。1.4.2 实现原理

当你在Properties块声明一个新属性之后,便为着色器提供了一种从材质Inspector面板上获得调整后属性值的方法,这些值保存在对应的变量名里。在上面创建的着色器里,_AmbientColor、_EmissiveColor和_MySliderValue这些变量保存着调整后的值。为了能在SubShader{}里使用这些值,你需要创建三个与属性同名的变量,Unity会自动将二者关联起来,它们拥有同样的数据。同样,这些变量的数据类型将会在后面的一个章节里用到。

当你在SubShader里创建好变量后,就可以在surf()函数里使用它们了。在本章的例子中,我们将把_EmissiveColor和_AmbientColor进行叠加,然后使用材质Inspector面板中获取的属性值_MySliderValue对叠加后的值进行乘方运算。

现在我们已经创建了任何着色器都需要使用的一个漫反射组件。1.5 创建自定义漫反射光照模型

Unity自带的光照函数已经很强大了,不过你需要的不仅仅是这些,你可能希望学到更多并且想要创建大量的自定义光照模型。从实际的经验来看,我们永远不会认为一个只使用自带光照模型的项目是个好项目。我们希望创建自定义光照模型来实现各种效果,比如实现边缘高亮的效果,或者实现更多基于立方贴图的光照,甚至你还想控制你的着色器对游戏过程进行反馈(它可以将所有它能控制的领域反馈给你)。

本节将着重介绍如何创建自定义光照模型,并使用它创建出各种各样的效果。1.5.1 如何操作

使用前面创建的basic diffuse Shader(基础漫反射着色器),我们通过下面的步骤再次修改它:

1.将#pragma标记修改为如下代码:

2.在subshader中加入如下代码:

3.在MonoDevelop中保存着色器代码并返回Unity窗口后,着色器会自动编译。如果没问题,你就可以看到材质已经发生了不是很明显的变化。我们刚才所做的工作都是为了删除Unity自带的漫反射光照,并且实现一个可以自定义的光照模型。1.5.2 实现原理

刚才的代码中有很多的元素参与了工作,现在让我们逐行解释它们是如何工作的:

·#pragma surface指令告诉着色器将使用哪个光照模型来计算。在我们创建的第一个着色器代码里,默认使用Lighting.cginc文件里包含的Lambert光照模型,所以可以使用这种光照模型来计算。现在我们告诉着色器将使用名叫BasicDiffuse的光照模型。

·通过声明一个新的光照模型函数我们就能创建一个新的光照模型了,当完成了这个步骤后,便可以将函数名替换成你想要的任何名字。函数名的格式是:Lighting<任何名字>。你可以使用三种格式的光照模型函数:

·half4 LightingName(SurfaceOutput s,half3 lightDir,half atten){}

·该函数用于不需要视角方向的前向着色。

·half4 LightingName(SurfaceOutput s,half3 lightDir,half3 viewDir,half atten){}

·该函数用于需要视角方向的前向着色。

·half4 LightingName_PrePass(SurfaceOutput s,half4 light){}

·该函数用于需要使用延迟着色的项目。

·点积函数(dot product function)是Cg语言的另一个内置数学函数,我们可以用它来比较两个向量在空间里的方向。点积函数会检查两个向量是互相平行还是互相垂直。任意两个向量都可以通过点积函数获得-1~1的夹角范围,-1表示平行向量并背离你的方向,1也表示平行向量,不过是朝向你的方向,0表示和你垂直的方向向量。矢量点积(或内积)的归一化向量N和L是测量两个向量之间夹角的方法。两个向量之间的夹角越小,点积越大,表面可以接受的入射光也越多。

参考如下链接:

http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter05.html

·为了完成漫反射计算,我们需要将Unity和SurfaceOutput结构体提供给我们的数据做乘法运算。为此我们需要乘上s.Albedo(来自于sur函数)和_LightColor0.rgb(来自Unity)然后再将结果与(difLight * atten)相乘,最后,返回这个值作为颜色值。如以下代码所示:

下图展示了上面的基础漫反射着色器的效果:1.5.3 更多内容

通过使用Cg标准库中的max函数,我们可以限制点积函数的计算结果。max函数采用两个参数max(arg1,arg2),我们在着色器里使用max函数来确保漫反射的计算结果永远介于0和点积最大值之间。这样你就永远不会得到小于0的值,更不会是-1,否则可能会在你的着色器区间生成极度黑色的区域,并且在之后的着色器运算过程中容易出问题。

在Cg标准函数库里还有一个类似的saturate函数,可以帮助我们将浮点值限制在0~1。saturate(和max)两者唯一的区别是saturate可以直接将浮点值转换成饱和度。max函数包含两个参数并返回二者之间的最大值。1.5.4 参考

·你可以访问网址http://docs.unity3d.com/Documentation/Components/SL SurfaceShader-Lighting.html了解更多关于表面着色器光照模型函数的参数信息。1.6 创建Half Lambert光照模型

Half Lambert(半兰伯特)是由Valve公司提出的技术,是一种用于在低光照区域照亮物体的技术。它基本上提高了材质和物体表面周围的漫反射光照。“Half Lambert”光照模型是一项最早应用于原版《半条命》游戏的技术(https://developer.valvesoftware.com/wiki/Half-Life)。它用来防止某个物体的背光面丢失形状并且显得太过平面化。这个技术是完全没有基于任何物理原理的,而仅仅是一种感性的视觉增强。它是广义光照模型的一个例子。参考如下链接:https://developer.valvesoftware.com/wiki/Half_Lambert1.6.1 如何操作

首先使用我们在上一节创建的基础着色器,让我们通过如下步骤来更新漫反射计算:

·将漫反射计算结果乘以0.5,然后,将下面的代码加入至光照函数里:

下图展示了在着色器的光照模型中加入Half Lambert技术之后的效果:

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载