通过改变UV值来移动纹理

通过改变UV值来移动纹理 在当惊的游戏产业中,一个很常见的游戏纹理技术就是允许你对游戏物体表面的纹理进行滚动。这种技术可以让你创建很多效果,比如瀑布,河流,流动的沿江等等。同时这些技术也是制作动画精灵特效的基础,我们会在这一章节的一系列知识点中来讲解这些内容。 首先,让我们来看看在**表面着色器(Surface Shader)**如何创建一个简单的纹理滚动效果。 始前准备 在这个知识点开始之前,需要你创建一个新的着色器文件和材质。这么做的目的是为了有个干净的着色器,然后我们可以更加方便的学习和观看滚动效果。 操作步骤 闲话少说,我们打开刚才创建的的着色器[着色器的名字文章中没有说,就自己取一个启动的名字吧],然后输入下面每个步骤所展示的代码: 这个着色器需要两个控制纹理滚动的新属性。所以我们添加一个速度属性控制X方向的滚动,添加另一个速度属性控制Y方向的滚动,如下面的代码所示: Properties { _MainTint("Diffuse Tint",Color) = (1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _ScrollXSpeed("X Scroll Speed",Range(0,10)) = 2; _ScrollYSpeed("Y Scroll Speed",Range(0,10)) = 2; } 修改CGPROGRAM代码块中的Cg属性中的变量,创建新的变量[把原来的都删掉,用下面展示的代替],这样我们就能访问来自着色器属性的值了: fixed4 _MainTint; fixed _ScrollXSpeed; fixed _ScrollYSpeed; sampler2D _MainTex; 修改表面函数surface function从而修改传递给tex2D()函数的UV值。然后,使用内建的_Time变量来对UV进行循环播放的动画,这样的话当我们点击Unity中的运行按钮的时候,我们就能看到动画效果了: void surf (Input IN, inout SurfaceOutputStandard o) { // Create a separate variable to store our UVs // before we pass them to the tex2D() function fixed2 scrollUV = IN....

January 9, 2021 · 1 min · 191 words · Link

在LayaBox中使用Unity中的导航网格,实现AI自动寻路

在LayaBox中使用Unity的导航网格,实现AI自动寻路 使用这个这个库的好处在于,你不必了解AStar算法,一样可以使用AStar算法来进行AI导航。只需要调用接口即可。 下面我给出LayaBox的示例项目地址和Unity导出网格示例项目地址,各位按需克隆下来即可 Unity示例项目:https://github.com/linkliu/ExportNavMesh LayaBox示例项目:https://github.com/linkliu/LayaNavMesh 原始的教程在http://ask.layabox.com/question/47899这里,大家可以去看看这里也行 这次的实例会从下面三个方面来讲解: Laya要用到的导航组件库NavMesh.js Unity如何将Navmesh数据导出成json文件【Laya中用到】 Unity中用到的NavMeshComponents 开始之前,说一下相关软件的版本 LayaAir 2.9 ,Laya引擎库2.7.1,Unity 2018.4.11f1 1.Laya中用到的导航组件库NavMesh.js NavMesh.js可以直接从这里去拿https://github.com/lear315/NevMesh.Js/tree/main/build 名字可能跟我的不一样,但是里面内容完全一样,我这里是强迫症发作,把Nev改成了Nav。然后只要拿NavMesh.js和NavMesh.d.ts这两文件就行了。NavMesh.js请放在Laya项目的bin/libs目录下面。NavMesh.d.ts放在项目的libs文件夹中。并且在bin/index.js中增加loadLib(“libs/NevMesh.js”),注意需在loadLib(“js/bundle.js”);前面。完成上面这些步骤,就把导航组件库NavMesh.js放到我们的项目中了 2.Unity如何将Navmesh数据导出成json文件 将Unity的导航网格数据导出成LayaBox需要的json数据,需要用到两个关键文件,一个是把导航网格转换成.obj文件的NavMeshExport.cs。另一个是Python自动转换脚本convert_obj_three.py,这两个文件的获取方式,我贴在下面: NavMeshExport.cs:https://github.com/lear315/NevMesh.Js/tree/main/unity convert_obj_three.py: https://github.com/lear315/NevMesh.Js/tree/main/python NavMeshExport.cs是一个Unity中的一个C#脚本,只要放到Unity中即可,便会在Unity中生成一个导出菜单,合并在LayaBox的导出菜单中。如下图 点击Export按钮,就会把当前的导航网格导出到ExportNavMesh文件中,里面就是需要下一步需要的.obj文件。 convert_obj_three.py是一个python脚本,所以各位需要安装python,并且配置配置好python环境,并且把python添加到系统的环境变量中去。 这个脚本的使用方法是 python convert_obj_three.py -i xx.obj -o xx.json,这个命令是把上一步生成的.obj文件转换成.json文件,这样我们就能在LayaBox中使用这个.json文件来进行AI导航了。 我的示例项目中已经做好了一键obj转json的功能,具体的用法是:选中你要转换的obj文件,然后右键,菜单选择Convert Navmesh to Json,就回自动在当前目录下生成一个同名的.json文件。这个就是LayaBox需要的文件,把这个文件放在LayaBox中的一个目录中。 3.Unity中用到的NavMeshComponents Unity中的导航网格的生成需要用到NavMeshComponents组件,目前这个组件Unity没有集成到Unity编辑器中,至少Unity2018以及之前的版本没有。但是Unity官方把它们放在Github上,地址在这里:https://github.com/Unity-Technologies/NavMeshComponents 克隆下来后,你只需要把Assets/NavMeshComponents这个文件复制到自己的项目中就行了,其他的东西可以不用。 NavMeshComponents的用法我就不细讲了,各位可以到https://docs.unity3d.com/Manual/NavMesh-BuildingComponents.html查看,也可以看这个中文的的博客https://blog.csdn.net/wangjiangrong/article/details/88823523各位按需观看吧。 总结 完成上面的三个步骤后,准备工作都OK了,具体的使用,各位可以去看我的LayaBox示例项目吧,哪里有完整的代码。 感谢各位耐心看完。

January 7, 2021 · 1 min · 44 words · Link

向着色器添加纹理

向着色器添加纹理 通过纹理,可以很容易让着色器变得生动起来,获得非常真实的效果。为了更有效的使用纹理,我们需要了解一张2D图片是如何映射到3D模型中去的。 这个映射的过程称之为纹理贴图texture mapping,为了完成映射,我们在使用的模型和着色器上还有额外的工作。模型实际上是由很多的三角形拼接而成的;而三角形的每个顶点都保存有着色器可以访问的各种数据。 其中很重要的一个信息就是UV信息 (UV data)。 它包含两个坐标,U和V,其取值范围是0到1。这两者表示2D图片的像素点坐标的XY位置信息,而这些信息将会映射到顶点中去。 UV数据只为顶点表示[意思可能也等价于:UV数据只存在顶点中]; 当三角内的点需要被纹理贴图时,GPU会插值最接近的UV值,从而从相应的纹理中找到正确的像素点。下面的图片展示了一张2D纹理贴图到3D模型中的三角形中的情况: UV数据保存在3D模型中并且需要3D模型工具去编辑它们。有些模型缺少UV组件,因而它们不支持纹理贴图。比如3D模型软件中的默认的那个兔子模型,就没有提供这么一个组件。 始前准备 学习这个知识点的时候,你需要一个有UV数据和纹理的3D模型。然后把它们都导入到Unity中。也可以直接拖拽到Unity编辑器中,会自动导入。因为标准着色器支持默认的纹理贴图。我们会用到这一点,而后会详细的介绍它是如何工作的。 操作步骤 用标准着色器给你的模型添加一张纹理异常的简单,按照下面步骤: 创建一个叫TexturedShader标准着色器。 创建一个名为TexturedMaterial的材质球。 通过拖拽的方式,把着色器赋值给材质,把着色器拖到材质上即可。 选择刚才的材质,然后拖拽模型对应的纹理到一个叫**Albedo(RGB)的矩形区域中的空白部分。如果你正确的执行了上述步骤,你的材质检查器面板(Inspector )**会如下图所示: 原理介绍 当通过材质的检查器面板使用标准材质的时候,纹理贴图背后的处理过程对于开发者来说是透明的。如果我们想了解它是如何工作的,那我们需要更加详细的了解我们刚才创建的TexturedShader着色器。在着色器的属性Properties部分,我们可以看到**Albedo (RGB)**的纹理跟代码的关联如下代码所示: MainTex: _MainTex ("Albedo (RGB)", 2D) = "white" {} 在我们着色器代码中的CGPROGRAM代码块部分,纹理被定义为sampler2D类型,这是一种标准的2D纹理类型: sampler2D _MainTex; 紧接着下一行给我们展示了Input这个结构。这个结构就是surface 函数中得输入参数并且这个结构包含了一个叫做uv_MainTex的包组数组: struct Input { float2 uv_MainTex; }; 每一次调用**surf()函数的时候,对应3D模型中的包含_MainTex 这个UV的Input 结构都需要被渲染。标准着色器会知道uv_MainTex 跟_MainTex **是关联的,并且会自动初始化它。如果你真的很想了解到底UV是怎么从3D模型映射到2D纹理的话,你可以看看第三章, 理解光照模型。 终于,UV数据被用来在**surface **函数中展示成一张纹理: fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 注意 U和V的取值范围都是从0到1,**(0,0)和(1,1)**相当于两个相对的角[可以想象成一个是左下角,一个是右上角]。如果你的纹理出现了颠倒的情况,试着把V的值也颠倒就能解决了。 额外内容 当你把纹理导入到Unity的时候,你就会默认设置一些sampler2D类型将要使用的一些属性。 最重要的就是筛选模式Filter mode,它决定了一张纹理显示的时候颜色是如何插值的。跟UV数据会准确的指向像素的正中心非常不同;在一些其他的情况中,你也许想对最近的像素之间进行颜色插值从而获得更一致的颜色。下图是示例纹理在检查器面板Inspector tab的截屏: 当以一个很大的倾斜角去观看一张纹理时,纹理采样似乎会呈现一种看起来不舒服的人工制品。你可以通过设置更高的**Aniso Level **的值来减少这种感觉。这一点对地板纹理和天花板纹理特别有用,可以解决一些小瑕疵导致的纹理观感不连续性的问题。 相关补充 如果你想了解更多关于纹理时如何映射到3D模型表面的内部工作原理,你可以通过下面的网址了解相关信息[可能需要用梯子才能访问]:...

December 11, 2020 · 1 min · 73 words · Link

使用包组数组

使用包组[包装组织] 笼统的讲,显示器上每一个像素点都至少会执行一次。这也是为什么GPU要设计高度优化的并行架构的原因。同样的在Cg语言的标准变量类型和操作符中,这种设计哲学也很明显。理解它们,不仅仅是为了正确的使用着色器,同时也是为了能够写出更高效的着色器。 操作步骤 在Cg语言中有两种类型的变量:单精度值single和包组packed arrays。后者很容易辨别因为这种类型通常会以数字结尾,比如float4,int4等等。正如它们的名字所表示的一样,这些类型的变量跟我们编程语言中的结构体structs类似,这也意味着每一个这样的变量包含了多个单精度值。在Cg语言中我们称之为包组packed arrays,尽管它们并非真的是传统意义上的数组。 在包组中的元素能像常见的结构体那样访问。通常它们表示成x,y,z 和w 。然而Cg语言还有另一种表示,就是r,g,b,a。尽管你使用x或者r去表示都是可以的,但是对于代码阅读者来说它们之间的区别就非常的大了。事实上,在着色器编程中,经常涉及到的就是位置和颜色的计算。你可能对下面的标准着色器代码中的代码片段还有印象吧: o.Alpha = _Color.a; 在这里,o是一个结构体而**_Color就是一个包组。这也是为什么Cg要禁止上面提到的两种表示进行混用的原因:你不能使用_Color.xgz**。 这里还有一个很重要的包组的特性,这种特性在C#中没有:swizzling[这个不知道怎么翻译]。Cg允许仅通过简单的一行代码就对包组内的元素进行寻址和重新排序。又是下面在标准着色器中熟悉的代码片段: o.Albedo = _Color.rgb; Albedo 是一个 fixed3类型,也就是说它里面包含了三个fixed类型的值。 然而**_Color** 是一个fixed4类型的定义。由于**_Color**定义包含的元素比 Albedo定义包含的元素要多,直接赋值的话,由于不匹配,肯定会产生一个编译错误。如果用C#代码来进行同样的操作,代码如下所示: o.Albedo.r = _Color.r; o.Albedo.g = _Color.g; o.Albedo.b = _Color.b; 相比于C#代码,在Cg语言中,我们可以用如下代码简写: o.Albedo = _Color.rgb; Cg语言也允许对元素进行重新排序。比如,通过**_Color.bgr**这个代码去交换红色和蓝色通道的颜色。 最后要讲一点,当一个单精度值赋值给包组时,这个值会被复制到包组的所有元素中去: o.Albedo = 0; // Black =(0,0,0) o.Albedo = 1; // White =(1,1,1) 这个就是Cg语言中的smearing特性。 Swizzling还可以被用作表达式的左值,不过仅当包组的具体元素能被这样使用: o.Albedo.rg = _Color.rg; 上面这种特性,叫做masking. 压缩矩阵 真正发挥swizzling特性潜力的是在它应用于压缩矩阵的时候。Cg语言允许像float4x4这种类型,这是一个四行四列的矩阵。你可以使用***_mRC标记访问矩阵中的单个元素,R表示元素所在的行而C*表示元素所在的列: float4x4 matrix; // ... float first = matrix._m00; float last = matrix._m33; _mRC标记还可以接连使用:...

December 9, 2020 · 1 min · 90 words · Link

表面着色器和纹理贴图

第二章 表面着色器和纹理贴图 在这一章节,我们将会探索表面着色器的使用。我们会用一个非常简单的磨砂材质开始讲起,然后会在后面讲解全息投影和高级的地形混合。 我们将能够使用纹理制作动画效果,混合等,或者用着色器去驱动我们想要的属性。在这一章你将会学习下面一些表面着色器的使用方法: 漫反射的着色处理 使用包组 向着色器添加纹理 通过改变UV值来移动纹理 法线贴图 创建一个带透明度的材质 创建一个有全息效果的着色器 纹理的压缩和混合 在地形的表面绘制一个圆 介绍 我们在第一章,创建你的第一个着色器 已经介绍了表面着色器,这是Unity引擎中的主要着色器类型。在这一章我们将更详细的向你展示它到底是什么以及它具体是如何工作的。通常来说,每个表面着色器都有两个重要的步骤。 首先,你需要在材质中描述你想指定的物理属性,比如漫反射的颜色,光滑度和透明度等。 这些属性将会在一个叫表面函数 surface function的函数中初始化并且保存在一个叫表面输出 surface output的结构体中。其次,表面输出 surface output结构体传入到一个光照模型 lighting model中。这是一个特殊的函数,这个函数会获取场景周围的光照信息。所有获得的这些信息将会被用于去计算你的模型最终在每一个像素点上最终呈现出来的颜色。这个光照函数就是着色器真正进行计算的地方,而正是这部分代码,决定了使用这个着色器材质的光照表现。下面的示意图简单的总结了表面着色器时如何工作的。在第三章,理解光照模型 将探索自定义光照模型,当学习到第五章,顶点函数 会着重讲解顶点修改器: 漫反射的着色处理 在我们开始学习纹理贴图之前,了解漫反射材质时如何工作的显得尤为重要。具体的一些物体也许会有统一的光照和光滑的表面,但是可以还是不够光滑来反射光线。磨砂材质是漫反射着色器使用的一个典型代表 。然而我们现实世界中,完全漫反射材质是不存在的;漫反射着色器是一种成本相对比较低的实现方式并且在低多边形风格中有着大量的应用。 始前准备 有好几种方式来创建你自己的漫反射着色器。最快的一个方式是在Unity5中创建一个表面着色器然后编辑它,移除所有的纹理,跟我们前面学习的第一章,创建你的第一个着色器 类似。 操作步骤 让我们开始创建我们的标准着色器,首先在Unity中新建一个标准着色器,然后按照下面的步骤进行修改: 首先在着色器的属性列表移除除**_Color**之外的所有属性: _Color ("Color", Color) = (1,1,1,1) 在SubShader{}代码块中,移除_MainTex,_Glossiness和**_Metallic这三个变量。但是你不能删除uv_MainTex** 这个变量,因为Cg着色器语言不允许输入结构体为空。这个值会被Unity简单的忽略。 删除**surf()**函数内代码内容并且把下面代码放在里面: o.Albedo = _Color.rgb; 最终,你的着色器代码应该如下所示: Shader "CookbookShaders/Diffuse" { Properties { Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3....

October 24, 2020 · 1 min · 196 words · Link

使用表面着色器的属性

使用表面着色器的属性 现在我们已经为着色器创建了一些属性,这里我们将要正式的把这些属性跟着色器关联起来,这些属性就像着色器的调节器一样,可以让材质拥有更好的交互性。 我们可以在材质的**检查器面板(Inspector tab)**使用着色器属性的值,因为我们为这个属性添加了一个变量名,但是如果你在着色器代码中想要通过这个变量名来获得这个值,我们仍然还有很多事情要做。 操作步骤 下面的步骤展示了如何在表面着色器中使用属性: 开始之前,我们先删除下面的行的代码,就好像我们在章节创建一个基本的标准着色器中删除属性的操作步骤一样,删除**_MainTex**属性: _MainTex ("Albedo (RGB)", 2D) = "white" {} sampler2D _MainTex; fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 下一步,添加下面这些行的代码到着色器代码中,添加到CGPROGRAM下面, add the following lines of code to the shader, below the CGPROGRAM line: float4 _AmbientColor; float _MySliderValue; 当第二部完成之后,我们就可以在着色器中使用属性的值了。我们把**_Color属性的值与_AmbientColor值相加,并且把两者的结果赋值给o.Albedo**。为了达成目的,我们需要在着色器代码中的**surf()**方法中添加如下代码: void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = pow((_Color + _AmbientColor), _MySliderValue); o.Albedo = c.rgb; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; } 最终你的代码将会是如下所示。如果你在你的VSCode中保存好然后返回Unity编辑器,你的着色器将会重新编译。 如果没有什么错误,那么现在你可以修改材质的环境光和自发光的颜色,当然也可以通过滑动条增加最终颜色的饱和度。听巧妙的噢。 Shader "CookbookShaders/StandardDiffuse3" { // We define Properties in the properties block Properties { _Color ("Color", Color) = (1,1,1,1) _AmbientColor("Ambient Color", Color) = (1,1,1,1) _MySliderValue("This is a Slider", Range(0,10)) = 2....

September 2, 2020 · 2 min · 234 words · Link

给着色器添加属性

给着色器添加属性 着色器的属性对于着色器管线来说时非常重要,因为艺术家或者用户想要添加纹理或者调整着色器的值都是通过著色器的属性来修改的。着色器的属性在材质的检查器面板(Inspector )中会提供GUI,提供图形界面让玩家去调整一个着色器,不用打开额外的编辑器。用Visual Studio Code打开你的着色器代码,从第2行到第7行的代码块就是着色器的属性(Properties )。当前的这个着色器,他会有一个叫**_MainTex的属性。如果你查看使用了这个着色器的材质,你能注意到着色器的检查器面板(Inspector )中有一个纹理(texture )**的GUI元素。着色器中的这行代码为我们创建了这个GUI元素。还有就是,Unity工作人员通过编码方式和努力的迭代,让你改变属性的这个过程非常快速高效。 始前准备 让我们来了解一下这个过程在标准漫反射(StandardDiffuse)着色器中是如何工作的,为此我们要创建自己的属性并且学习更多相关的着色器语法。比如我们会修改之前创建的着色器。在这个修改的着色器中,不适用纹理,而是仅仅使用能从检查器面板(Inspector)直接修改的颜色和其他的属性。开始之前,我们先复制一个标准漫反射(StandardDiffuse)着色器。你可以在项目(Project)面板中选中它,然后按Ctrl + D。这样就会复制一份新的StandardDiffuse 1的着色器。【书上的写法有问题,在Inspector面板根本不能选中复制,应该在项目面板中选中在复制】 注意 你最好给你复制的这个着色器在第一行代码处给它一个恰当的名字。比如,Shader “CookbookShaders/StandardDiffuse”可以告诉Unity这个着色器叫StandardDiffuse并且把它分组到CookbookShaders这个着色器组。如果你是通过Ctrl + D复制的着色器,你新复制的这个着色器跟被复制的着色器就会用相同的名字和分组。为了避免混淆,一定要记得复制着色器代码之后,在第一行那里修改着色器的名字,给一个不会重复的名字。 操作步骤 当StandardDiffuse2这个着色器准备好后,我们就可以开始修改它的属性了: 在着色器的**属性(Properties )**块中,删除着色器中下面的属性代码,整行删除: _MainTex ("Albedo (RGB)", 2D) = "white" {} 当我们移除这个必要的属性后,着色器不会被编译直到所有跟**_MainTex**的代码都被移除。然我们删除另外有引用的代码: sampler2D _MainTex; 原始的着色器使用**_MainTex给游戏模型上色。为了改变这个,我们替换掉surf()**方法的第一行代码,通过如下代码: fixed4 c = _Color; 当你修改完成之后,返回Unity,然后着色器会被重新编译, 之后我们的材质检查器面板中就没有纹理选择这一选项了。 为了完成这个着色器的调整,让我们添加一个额外的属性给着色器,看看会有什么效果。输入下面的代码: _AmbientColor ("Ambient Color", Color) = (1,1,1,1) 我们在材质的检查器面板中添加了另一个颜色选项。现在,让我们来额外添加另一种类型的属性来找找属性语法的感觉。添加下面的代码到属性代码块中: _MySliderValue ("This is a Slider", Range(0,10)) = 2.5 我们创建了其他两种不同类型的GUI元素,它们可以让我们与着色器进行可视化的交互。我们这次创建了一个叫做This is a Slider的滑动条,就如下图所示: 着色器的属性让你可以通过可视化的方式调整着色器,而不用在着色器自己的代码中调整。 下一个知识点将会为你介绍如何利用这些属性创建一些更有趣的着色器。 注意 尽管属性属于着色器,但是着色器上属性的值却是保存在材质上的。不同的材质可以很安全的共用相同的着色器。从另一方面说,修改材质上的属性的值,将会影响到所有使用了该材质的游戏对象的外观。 原理介绍 每一个Unity的着色器都有它想要的内建的代码结构。属性代码块就是Unity所期望的功能之一。属性代码块的目的是让着色器编程人员能快速的创建GUI交互元素,并且将GUI元素与着色器代码相关联起来。那些你在着色器属性面板中申明的属性,能让你在着色器代码中使用,从而修改着色器中的一些值,颜色和纹理。 定义一个属性的语法[也可以叫语义,也可以叫语法糖]如下: 让我们来解释一下这个示意图。 当你第一次开始写一个新的属性时,你需要给这个书信一个变量名(Variable Name)。这个变量名能让着色器使用并且能让着色器代码获得来自该变量名绑定的GUI元素的值。这给我们节约了大量的时间因为我们不用自己来创建这么一个系统。属性的下一个元素时检查器面板GUI名称( Inspector GUI Name )和属性的类型(Type),这两个元素放在一对括号中。当玩家想要交互和调整着色器时,**检查器面板GUI名称( Inspector GUI Name )将会在材质的检查器面板(Inspector tab)**中展示。**类型(Type)**就是这个属性想要控制的数据类型。在Unity着色器中,有很多属性可以使用的类型。下面这个表展示了我们在着色器中可以使用的变量类型:...

August 19, 2020 · 1 min · 81 words · Link

如何把Unity 4的旧着色器迁移至Unity 5

如何把Unity 4的旧着色器迁移至Unity 5 不可否认,在过去10年中图形学在电子游戏中获得了惊人的发展。每一个新游戏带来的尖端技术让我们的游戏画面更加接近现实。随着Unity引擎版本的不断迭代,它的着色器技术也自然而然的经历了相当大的变化。这也是为什第一次接触着色器的时候感到困惑的原因。在Unity5还没有推出之前,Unity自带了两种不同的着色器,分别是:漫反射(Diffuse)和高光反射(Specular)。正如其名字所描述,它们分别用来模拟表面粗糙和表面光滑的材料。如果你现在使用的Unity5,那么你其实可以跳过这个知识点。该知识点会讲解如何在Unity5中重现这些效果。 始前准备 要开始这个知识点,前提时你有个用Unity4版本作为开发引擎工作空间,并且你使用了这个版本内建的一些着色器。当你开发新游戏的时候,毫无疑问你应该改选择最新版本的Unity引擎。然而如果你的项目已经使用了旧版的Unity引擎开发,那么你在迁移着色器前应该三思。引擎背后可能又很多东西都不一样了,即使有时候内建的着色器表面看起来可以正常工作,但是你写的脚本可未必能。所以如果你要迁移整个项目空间,这个时候首先要做的事情就是备份。但是要注意噢,仅仅只是保存Assets资源和场景可不够,同时所有的.meta文件也要一并保存,因为大多数Unity的配置信息保存在元数据中。在迁移项目的过程中最稳妥的办法还是要把整个项目空间所在文件夹都复制一份。最好的是物理拷贝一份,如果是windows就在资源管理器物理复制,如果是Mac就在Finder中物理复制。【建议大家将这个项目目录用压缩工具【如winrar】打包一份】。 操作步骤 如果你想要迁移你的内建着色器,有两个主要选择:采用自动升级的方式或者切换至标准着色器 着色器版本的自动升级 这种选择是最操作起来最简单的。Unity5可以导入使用旧版内建着色器的项目并且自动升级。你需要主义的是一旦升级完成后,那么你在Unity4中就不能再使用它们了。尽管这个过程并没有直接改变你的Assets资源,但是Unity的元数据已经被转换过了。要进行这个过程,你需要打开Unity5引擎,然后点击文件(File)|打开项目(Open Project)来打开你就项目所在的文件夹。然后回有提示问你是否愿意转换;然后点击升级(Upgrade)执行改过程。Unity就会重新导入所有的Assets资源并且重新编译所有的游戏脚本。如果你的项目非常巨大,这个过程可能回持续几个小时。一旦转换完成,来自Unity4的内建的旧着色器会被相应的替换掉。 你可以通过检查器面板验证这个转换,材质实例中从原来的Bumped Diffuse变为了Legacy Shader/Bumped Diffuse。 注意 尽管Unity4版本的漫反射,高光反射和其他内建的着色器现在已经已弃用了,但是Unity5依然向后对它们保持兼容。它们在材质的Legacy Shaders路径下的下拉列表中依然可以看到。 使用标准着色器 相比于使用旧版本的着色器,你可能想使用Unity5新的内建标准着色器替代它们。但是这么做之前,请留意新旧两个版本的着色器是基于不同的光照模型的,你的材质很可能看起来不一样。Unity4总共有8个不同的内建着色器,它被划分进了6个大类(法线(Normal),透明(Transparent),透明剪切(Transparent Cutout),自发光(Self-Illuminated)和反射(Reflective))。但在Unity5中,它们都被上一个知识点所讲的那些标准着色器所替代了。不幸的是,没有什么很好的办法能够将旧着色器完美的迁移只新版本的着色器。但是你可以通过下面这个表格着重理解如何通过配置标准着色器去模拟unity4的旧着色器的效果: 你可以在旧材质的**检查器面板(Inspector)上通过着色器(Shader)下拉菜单改变它所使用的着色器。所有你需要做的就是简单的选择适当的标准材质。如果你的旧着色器使用了纹理,颜色和发现题图,那么在新版本的标准着色器上也会自动使用。当然为了更好的接近之前旧版本着色器的光照模型,你可能需要配置标准着色器的相关参数。 下图展示的是常见的斯坦福兔(Stanford bunny ),它们分别使用旧版本的漫反射着色器(右),被转换的标准着色器(左),和把平滑度(Smoothness)**设置成0的标准着色器(中): 迁移用户自定义的着色器 如果你以前在Unity4上有写自定义的着色器,很有可能在Unity5中能直接正常使用。即使如此,Unity也有可能在着色器的工作原理上做了细小的改动,这些改动是可能引发一些错误和不一致性。有个变化最明显的重要参数就是光的强度。 光在Unity5中是原来亮度的两倍。所有的旧版本着色器在重写的的时候都应该考虑到这一点;如果你升级了你的着色器或者切换到标准着色器,你不会发现有任何的不同。但是如果你是自己写的光照模型,那么你就要注意确认光的强度不能再乘以二了。我们就用下面的代码举例来确认这种变化: // Unity 4 c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2); // Unity 5 c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten); 如果你还没有写过着色器,大可不必惊慌:光照模型会在第三章,理解光照模型 中全面详细的讲解。 注意 Unity5对着色器的处理相比于Unity4来说还有一些其他的变化,你可以下面这个网址中查看所有着色器在Unity5中的处理方式的变化 http://docs.unity3d.com/Manual/UpgradeGuide5-Shaders.html。 原理介绍 着色器的编写需要权衡画面表现和效率;效果逼真的着色器需要极大的计算量,可能导致严重的延迟。所以,有一点很重要,就是只使用我们确切需要的效果:如果一个材质不需要高光反射,那么就不要在着色器中去计算它们。这也是在Unity4中把这些效果拆分成了很多不同着色器的主要原因。 新版本的标准着色器有潜力替换掉先前旧版本的着色器,因为它把法线贴图,透明度和反射都包括在内了。然而,这个标准着色器经过巧妙的优化,使它能够只去计算用到的效果,没用到的效果就不计算。尽管这样,标准着色器主要还是设计用于模拟现实的材质。相比较而言,漫反射和高光反射着色器并不是为模拟现实的材质设计的。 这就是为什么从旧版本的着色器切换到标准着色器时,游戏对象在渲染的时候通常回发生一些细小的变化的原因。 相关补充 第三章, 理解光照模型, 将会深入探索漫反射和高光反射着色器的作用原理。尽管在Unity5中,它们已经被弃用了,但是如果你想要设计新的光照那么理解它们还是有必要的。 第四章,Unity 5中基于物理原理的渲染 ,将会介绍如何在Unity5中展现标准着色器的潜力。

August 15, 2020 · 1 min · 70 words · Link

内容结构

内容结构 在本书中, 会经常出现一系列的小标题 (始前准备,操作步骤,原理介绍,额外内容 ,相关补充)。 主要功能是对每一个知识点进行说明,如何完成该知识点的掌握。下面说明具体的用法: 始前准备 这个部分会告诉你这个知识点会学习什么,怎么安装和设置对应的软件。 操作步骤 这个部分包含了学习该知识点包含那些步骤。 原理介绍 该部分通常是为了详细解释“操作步骤”这个部分的知识原理,上面的每一步到底做了什么。 额外内容 为了让读者了解更多与该知识点相关的额外知识,我们才准备了这个额外信息让读者阅读。 相关补充 如果想了解更多与该知识点相关的信息,这里还额外提供了一些相关链接。

August 13, 2020 · 1 min · 16 words · Link

勘误表

勘误表 尽管我们非常注意本书内容的准确性,但还是会有不小心出错的地方。如果您在我们出版的书中(不限本书)找到了错误,有可能是文字错误或者代码错误,我们非常欢迎您将这些错误报告给我们。如此善举,既解他人之惑,亦可助改善此书。如果您发现任何勘误,请通过链接https://www.packtpub.com/support/errata (原书写的链接失效了)向我们报告。当您的勘误确认后,您提交的勘误将会被接受并且勘误会上传至我们的网站和任何已存在的勘误名单中。 如果您想看看之前的勘误提交,可以访问https://www.packtpub.com/support/code-downloads(原书的网址失效了,现在是这个),然后输入书名搜索,你想要的信息会出现在下面的勘误部分。

August 13, 2020 · 1 min · 4 words · Link