欢迎光临散文网 会员登陆 & 注册

从零开始独立游戏开发学习笔记(三十八)--Unity学习笔记18-- Creative Core 2(上)

2022-05-19 01:12 作者:oyishyi  | 我要投稿

名字起的很怪,但是这一章实在太长。我不想文章总是超过 1 万字,既不方便看,也不方便自己之后查阅。
但直接分成 (二)和(三)又有一种内容独立的感觉,但这两个地方的内容其实是连在一起的。 所以就这么分了,(上)里主讲 materials,(下)里主讲 shaders。

5/18 更新:我感觉这一系列学完,再加几个 demo,我要还是学生的话可以直接入职了,东西也太多了。不愧是官方教程。

1. Shaders 和 Materials

Shaders 和 Materials 可以让你定义一个 3D 物体的样子:颜色,反射,物理纹理。

下载教程项目后,打开其中一个 scene,我们要做的就是做一些看起来逼真的 object,放在下图右边的工作台上:

画面中有很多指示图标,可以在 gizmos 里调整 3D icons 的大小,但注意最好不要直接关掉。如果看到很多黄线,则可以关掉 lightProbeGroup。

1.1 探索 meshes 和渲染

shaders 和 materials 定义了如何渲染一个 mesh。因此这一节我们好好讲解一下 mesh 和渲染的关系。

1.1.1 mesh 是啥?


mesh 这个词确实很难从名字看出是个啥,中文翻译叫网格体,但依旧不明所以。
不过其含义其实相当简单,在 Unity 中,所有被渲染出来的 object 都有一个几何形状,而这个形状就叫做 mesh。

我们可以在 Unity Editor 中比较直接地看到 mesh 的存在:

  1. 选择工具栏左边的这个拉框(叫 draw mode 拉框),可以看到其中 shading mode 部分被设置成为 shaded。

  2. 我们将其切换成 wireframe。

现在你看到的就是,没有 shaders 和 materials 的时候,这些物体的样子。(所以之前那个模式才叫做 shaded)

1.1.2 mesh 到底是啥?


好,上面是一个比较浅显的解释。我们再往深一点探索:

  • mesh 是 GameObject 的 3D 骨架。Unity 中所有的 GameObject 都有一个 mesh,是这个物体的几何元素。

而 shaders 和 materials 则告诉 unity 要怎样去渲染这个 mesh(换言之,怎样让这个 mesh 从 3d 物体变成 2D 图片)。

然后我们仔细观察 mesh(用 wireframe view)。

  • 现在我们可以说, 1 个 mesh 就是一系列的由节点构成的 2D 多边形。这些节点位于 3 维空间,具有 xyz 坐标值。

1.1.2.1 法线

但是,如果 mesh 只包含这些信息,会让所有的 3D objects 显得像是钻石,我们需要有个办法让其看起来光滑或弯曲。
所以 mesh 还包含一个数据,叫做法线,法线储存着顶点方向的信息。

  • 如果所有法线都是垂直于边缘,那么多边形就会看起来就会像是这样,像钻石:

  • 法线中包含多边形弯曲的信息,甚至是弯曲的多少。shaders 会根据 mesh 上的法线信息来渲染多边形的弯曲度,而不是改变 mesh 本身。一个球体实际上是多个多边形构成,但是法线让其弯曲以显得平滑。

读取节点信息,以及法线信息,将 mesh 表面渲染出来,是 shader 的工作。

1.1.3 创建 mesh


unity 里有提供一些简单的 primitive shape(就是右键新建就能创建的 cube,sphere 那些)。不过复杂的还是要去专门的建模软件里弄。

1.1.4 mesh filter 组件和 mesh renderer 组件


选中一个非空 object,可以看到都含有 mesh filter 和 mesh renderer 这两个组件。

mesh filter

mesh filter 组件记录了 mesh 相关的数据信息。可以在这里切换 mesh。很多时候切换物体可以只切换 mesh 而不用创建新物体。

mesh renderer

mesh renderer 则是用于定义 mesh 如何被渲染。里面有很多设置,其中比较重要的是 materials,本教程之后会经常来这里切换 materials。

1.1.5 给 mesh 添加 material


material 是一种 asset,和 shaders 一起工作,用于定义 mesh 如何被渲染。一个 material 可用于多个 meshes。

  1. 先返回 shaded view,毕竟现在我们不看 mesh 了。

  2. 选中场景中的一个白色苹果,选中其子物体 AppleBody。

  3. 观察其 Materials 属性,是一个列表,目前 element 0 有一个 plain white 的材质。一个 mesh 可以有多个 materials,不过本项目不讲这个。

  4. 将那个 material 切换成 AppleRed。

  5. 可以在 mesh 的 inspector 里下方看到 material 的信息,可以在这里修改 material 的信息。这样就不用专门点到 material 的 inspector 里去了。

1.2 探索 shaders

shader 是一个脚本,用于将包含在 materials 里的信息应用到渲染上。每一个 shader 都是为了某个特定的 render pipeline 写的。

因此,使用什么 shader,取决于你用的什么 render pipeline。在 unity 中,每一个模板都包含着专门为这个模板相关的 render pipeline 设计的 shader。

不同 shaders 之间差异很大,提供各种各样不同的视觉效果。

1.2.1 shaders 的类型


总体来讲,一个 shader 上的行为可以被分为两种:fragment shading 和 vertex shading。

Fragment Shading 又称 Pixel Shading,用于展现 mesh 表面在 2D 画面中呈现的颜色。本项目之后会讲到其将如何在光照下起作用。

Vertex Shading 则作用在 vertices 上,改变其位置用于使 mesh 表面移动或变形。

注意,shader 被分为这两种类型,仅仅是因为其起到的作用,是一种马后炮的分类方式。实际上所有的 shader 都能够做任何事。这只是一种根据其使用目的来分类的方式。

1.2.2 基于物理的 shaders 和渲染


随着电脑运算能力的增强,和图形技术的发展,PBR(Phsically Based Rendering) 越来越成为趋势。PBR 模拟现实世界的物理法则,光照来生成各种光效,阴影等等各种效果。

在 PBR 中,光照效果和物体分离。光只包含光照的属性,物体包含物体的属性,包含 materials,颜色,一起一些其他真实世界属性。当光照在物体上时,shaders 会计算光效会产生的效果,显示出来。

相比之下,非 PBR 则一般显得不会很真实,红色就是单纯的红色,加上一丁点阴影或者反射等效果。

  • 但也不是说非 PBR 就不好,有些风格化渲染就会故意用到非 PBR,比如某些 3 渲 2 的场景。

1.2.3 URP 中的 shaders


在上一篇文章中已经提到了,我们要使用 URP,因此我们注重 URP 相关的 shaders。
本教程中(指整个 Creative Core)会讲述大部分的 shaders,只有一些特殊作用以及高级效果的 shaders 不会被涉及到。

许多 shaders 里的命名包含 lit 或者 unit。lit 表示这个 shaders 会对光照产生反应。unlit 则表示不会随着光照而变化。后者一般用于特殊的艺术效果,或者优化。

在 materials 组件里可以看到 shader,切换不同的 shader 看看效果,注意选择在 URP 名下的:

  1. 2D -> Sprite Default Lit。专为 2D 设计的,如果用在 3D 物体上,会将其渲染成 2D 效果。因为是 lit,会根据场景中的光照改变渲染效果。

  2. Particles -> Lit, Simple Lit, Unlit。为视觉特效使用的 shaders。之后的特效的文章中会用到。

  3. Terrain -> Lit。专为 Terrrain 工具设计的。之后关于原型的文章中会用到。

  4. Baked Lit。会自动添加到 lightmap 上。之后关于光照的文章中会用到。

  5. Complex Lit,Lit,Simple Lit。一般情况下使用的 3 个 shaders。属于 PBS(Phsically Based Shaders)。

  6. Unlit。不应用光照效果。

本节中使用 URP/Lit,因为这个 shader 是基于物理的,materials 将会基于真实世界的属性而变化。

1.3 管理 materials

尽管 shaders 很重要,大部分时间会花在创建 materials 上。

而管理 materials 则是其中相当重要的一部分。

1.3.1 shaders 和 materials 的区别


Shader 可以很特指,也可以很广泛。shaders 可以控制物体的颜色,或者让 materials 来控制颜色。实际上,shaders 可以让场景上所有的物体看起来不一样,但却仍有统一的特质。

在我们的例子中,虽然我妈们所有物体都使用同一个 shader。但是那些由 material 提供给 shaders 的属性(颜色和光滑度),让每个物体看起来不一样。

正如一开始就提到的,shaders 和 materials 一起工作。shaders 决定了一个物体能够长得咋样,而 materials 则决定了一个物体实际长得咋样。

在 unity 中更换一个 material 的 shader 的时候可以看到,下面的设置会跟着变化,这就是上面这句话的解释。

5/23 修正:

经过评论提醒,material 并不是真的和 shader 一起工作。而是 material 会被翻译成 shader 代码。类似于一种封装 shader 的高级语言。

1.3.2 修复品红色物体错误


在我们的例子中,有一个柠檬看起来有问题,呈现这种品红色:

每一个 material 是为了某个 shader 而写的。很多时候,我们会遇到将某个项目的素材导入到另一个项目中的情况。但是很多时候,不同项目使用的 render pipeline 不一样,因此就会产生这样的错误。
查看这个物体的 shader,可以发现叫做 standard,而这并不是 URP 的 shader。因此就会出现这样的品红色,来警告使用者。

解决方式很简单,standard 是属于 built-in 的 render pipeline,将其换成 URP/Lit 即可。

批量修改

这里只是一个物体,但遇到多个物体的时候就不能这样子了。教程里给的方式其实已经比较老了,新的解决方式在之前的文章中也提到过。

1.3.3 默认材质


新建一个 shpere,注意此时场景上已经有很多物体了,因此右键新建物体反而有些麻烦。此时可以使用 hierarchy 左上方的 + 按钮,之前觉得这种设计多余,现在不觉得了。

查看这个物体的材质,这就是默认材质,可以发现叫做 lit,使用的 shader 是 URP/Lit,但是所有的地方都是灰色,因为你不能编辑默认材质(除了使用代码)。

1.3.4 找到你想使用的 material


实际使用过程中,materials 的存在可能很复杂,除了你自己的 materials 文件夹。可能还会有些 materials 存在从其他项目或者 asset store 中导入的 materials。

在 project window 中,其实 unity 提供了一些方便的选项,如:

再仔细观察上图,可以发现搜索框里有一个 "t:Material" 字样,其中 t 代表 type,因此照葫芦画瓢也可以大概知道,如果想搜索所有的脚本就应该使用 "t:Script"。

然后我们再看下面,可以看到有 "In Packages", "In Assets" 字样,这样可以缩小搜索范围。后者指的就是在你的 Assets 文件夹下搜索。

搜索还可以再次缩小,在搜索框后面加上 red。也就是 "t:Material red",还可以继续缩小到名字里带有 red 的 assets 文件夹里的 Material 类型的素材。

1.3.5 赋予 material


当然,这很简单,但是有四种方式你知道吗?

  1. 直接拖到物体上(scene 或者 hierarchy)。

  2. 拖到 mesh renderer 的 Materials 属性里。

  3. 在 Materials 属性中使用 object selector(那个圆圈)。

  4. 找到一个已经有某个材质的物体中,将其材质组件拖到其他物体上。

一个材质多个物体

同一个材质可以给予多个物体,并且因为材质是个 asset(多次提到,很重要)。因此在改变材质的时候,会同时改变所有带有这个材质的物体的外观。不只是当前 scene,所有 scene 都会受到改变,因此改变的时候要好好想想。

也因此,管理 materials 是很重要的课题。

1.3.6 更改材质


  1. 选中刚刚我们创建的球体。

  2. 找到 base map 属性,更改颜色,可以看到其他使用该材质的球体的颜色也跟着一起更改。

1.3.7 找到材质 asset


现在,我们换了颜色,这个 material 的名字还叫 Applered,这已经不合适了,我们想改名。

之前我们都是在 inspector 里使用 material。但是 material 毕竟是 asset,我们其实可以在 project window 里找到。

  1. 在 Material Renderer 里的 Material 属性,点一下可以定位到 folder 里的 material。

  2. 直接改名即可,不会失去引用。

1.2.8 创建新 material


  1. 复制一个刚创建的球体。

  2. 在 materials 文件夹里创建一个新的 material。

  3. 选个颜色,给到新的球体上。

1.2.9 复制 material


除了新建一个新的 material,另一个方便的办法就是直接复制现有的 material,然后稍加修改。

  1. 复制新的球体。

  2. 复制 material。

  3. 赋到球体上,修改颜色。

这样就比较轻松了,比起创建一个新的,步骤少很多。

1.3 模拟纯色表面

为了创建类似于显示物体表面的 material,最好还是要了解一些光线的基本原理,以及它如何在物体上起作用的。

1.3.1 光线的行为


当光与物体接触的时候,会可能发生以下三件事:

  1. 反射。

  2. 穿透。(如果物体有透明度)

  3. 被吸收。

人类眼睛观察物体的时候,取决于物体是如何与光线这 3 个作用交互的。我们将会用上一步创建的球体(苹果)来描述这 3 种现象,以及 unity 是如何模拟这 3 种现象的。

1.3.2 镜面反射和漫反射(specular reflections & diffuse reflections)


先讲反射。光线在物体上的反射可以分为两种:镜面反射和漫反射。

镜面反射是闪亮物体上最明显的直接反射,在下图中,白色的箭头就是镜面反射,表示光线本身也是白色:

但不是所有的光都是直接照到表面,然后直接反射回来。有的光线会穿透表面,或者在表面凹凸处反射好几次,然后被吸收或者反弹回去。这些往外逸出的光就是漫反射。

一个物体的漫反射,决定了它的可见色。苹果的红色光以外的光被吸收,只反射红色光。(镜面反射呈现白色,因为它反射所有的光)

镜面反射和漫反射构成了物体表面的所有反射,反射只能是镜面反射或者漫反射。

1.3.3 漫反射:base map


现在,我们知道了,物体的颜色其实就是其漫反射的光的颜色。

在 URP/Lit shader 中,base map 表示的就是这个漫反射的颜色。不过在很多其他的 shader 中,这个叫做 Albedo 或者 Diffuse Map。(尽管从技术上来说,这些属性还是有区别的)

Albedo

上面出现了一个奇怪的单词,Albedo。Albedo(反照率) 是一个天文属于,是用于衡量漫反射的物理值。通常是一个指定颜色,由 RGB 构成(也可转换为 HSL 模式)。Albedo 颜色的亮度(L)取决于漫反射的数量,色调(H)和饱和度(S)则表示从物体表面逃逸出的光的质量。

为什么叫 base map

base 还能理解,尤其是这个 map 不是很懂。

之后我们会仔细讲解 mApping。不过 Maps 可以是纯色,也可以是 2D 图片用于增加表面的变化。但 base map 里使用 color picker 选择的颜色,仅仅只是纯色。

1.3.4 Specular Workflow 中的金属


讲完了漫反射,现在来讲镜面反射。

对于金属而言,比起漫反射,镜面反射更多。

假如上面的苹果变成镜面反射的话,苹果将不会有任何红色,而只会有反射的光源的颜色,你也可以在镜面表面上直接看到光源。

这个让表面看起来像金属的属性叫做 Specularity。(或者说能看到反射的光源的程度)

如果你可以从物体上看到其反射的光源,那就可以称其为镜面。一些无色的金属,如银,钢铁,我们看到的颜色其实就是光源的颜色。

Specularity 和 Smoothness 的区别(后面光滑度部分有更详细的讲解)

从属性上来说没有任何关系。你可以让一个苹果变得极其光滑,但是完全可以没有任何反射效果。
不过,从实际上来说,一个光滑的物体,最好还是有点镜面反射,看起来才不违和。

以下是一堆苹果,smoothness 都一样,但是 specularity 逐渐增大:

和漫反射表面一样,金属表面一样会吸收光。比如说你把一块金属放在太阳底下,它就会变热。

不过在一些有色金属上,如黄金,铜。其颜色并非来自漫反射光,而是着色后的镜面反射光。这个颜色来源于金属吸收了可见光谱上的部分光,只反射剩余的部分的光。

Specular workflow

Specularity 是一种表示物体表面看起来有多像金属的属性。Unity 中有两个 workflow 来表示物体如何像金属。

其中一种是 Specular workflow:

在这个工作流中:

  • 一个闪亮的金属,有着高 specularity,高光滑度。

  • 一个闪亮的非金属,有着低 specularity,高光滑度。

  • 光滑度控制着镜面反射的焦点。而 Specular Map 则控制着镜面反射的数量和颜色。

  • Specular Map 可以使用 RGB(乍一看比较奇怪为什么要在专门提这个,这主要是和后面的 metallic workflow 进行比较)。

然后我们在 unity 里使用这个 workflow:

  1. 调整 workflow mode 为 specular。

  2. 调整 smoothness 从 0 到 1.

  3. 将 specular map 颜色调整为白色,此时物体和镜子一样,没有自己的颜色,只显示反射的颜色。(调整颜色,实际上就是调整物体会吸收哪些颜色的光)(即是说,颜色越接近白色,specularity 越高)(此外,随着颜色逐渐变白,你会发现漫反射颜色,也就是 base map 的颜色逐渐被忽略)

  4. 多多调整 specular map 的颜色,会发现颜色特别的神奇。这是因为要时刻想到,现在的颜色是 base map 和 specular map 同时起作用的结果。(但是仔细想想,这也并不是非现实的。试想一下在蓝色光源下的红色汽车,实际上这些颜色是非常正常的)

1.3.5 metalic workflow 中的金属


另一种 workflow 是 metalic。这种方式比较简单方便,但是并不完全符合物理世界的规则。

在这个工作流中:

  • 一个闪亮的金属,有着高 metallic map 值和高光滑度。

  • 一个闪亮的非金属,有着低 metallic map 值和高光滑度

  • 光滑度控制着镜面反射的焦点。

  • metallic map 仅仅只能控制灰度。(对比 specular map 可以控制 RGB 3 通道)

两个工作流的对比

可以很明显看出,specular 工作流能够控制的东西更多,更加复杂。

  • 在 metallic workflow 中,base map 并不严格等于漫反射颜色。无论怎么调节 metallic map 值,颜色依旧保持。对比之下,在 specular worklflow 中,金属度最低的时候(specular map 白色),base map 的颜色就消失了。

  • metallic map 只有一个滑块,控制着灰度值。对比之下,specular map 可以有 RGB 3 个通道。

两种选择各有优缺点。metallic 工作流比较简单,但不太符合物理现实。specular 的颜色控制比较复杂,但是符合现实物理效果。

1.3.6 光滑度(smoothness)


观察一下真实世界的纯色物体:纸张,塑料等。看看它们的高光,是聚焦的还是模糊的?能够从反射中看到光源吗?你能从中得到光滑度和粗糙度吗?

如果反射是模糊的高光,说明其比较粗糙。如果能够很清楚地看到反射的光源,说明其比较光滑。

但注意,光滑度会增加镜面反射率。不过并不一定像金属。

Smoothness 和 Specularity 的对比

对比一下不同设置,以方便理解:

从人眼来看:

  • (左图)一个高 Smoothness ,低 Specularity 的东西。看起来非常光滑,有高光。但就是看不出来反射了个啥。像个陶瓷。

  • (右图)一个低 Smoothness,高 Specularity 的东西。你能模糊地看到反射的东西,也许你看不到细节,但你大概知道轮廓。而且可以肯定这是个金属。

结合理论来看:

  • 左图意味着,所有的反射都是镜面反射,但是反射的数量极少,大部分光线都被吸收了。

  • 右图意味着,不怎么吸收光线,如实地反射光源的信息,但是漫反射居多,不清晰。

也就是说:

  • Smoothness 决定了是镜面反射,还是漫反射。

  • Specularity 决定了镜面反射光线的颜色(哪部分)和亮度(多少)。

1.4 给 material 添加 texture

前面讲的内容基于一个事实--物体为纯色。但实际上,大多数情况下,物体并不会是纯色,而是有各种花纹,或者痕迹啥的。

对于大多数物体来说,光滑度和反射度并不是平均分布的。这就是 Maps(贴图) 的用武之地了,Maps 是包裹住 GameObject 的 2D 图像,就像一张纸一样。Maps 可用于设置颜色,镜面,金属度,物体材质,等各种属性。包含 maps 的 2D 图像文件就叫做 texture(纹理)。

1.4.1 texture 是啥?


如果经常接触 3D 作品,即使只是看看评论区和弹幕,想必也经常听到类似纹理材质建模各种概念术语。那么 texture 到底是个啥呢?

首先我们要知道,texture 本身就只是一个普普通通的图片文件,像是 jpg,png,tif,BMP 等格式。并不是像是 material 等有专门的的后缀区分。

如果有一些基础的图像知识,应该也会知道图像或者是单通道(greyscale),或者三通道(RGB,HSL 等),部分图像可能会再多一个 Alpha 通道。以 texture 的作用来讲,这些信息就已经足够了,无需再为其创建一个新的格式了。本来,texture 的定义就是一个图片。

(如果你还记得的话,前面用到的 base map 和 specular map,其实就是一个 color picker,这便是一个 3 通道的图片。或者类似于 metallic map 这种单通道的 greyscale)

materials 会使用这些通道的数据,来计算出一些属性,像是光滑度,镜面度等等。

texture 文件的来源

虽然 texture 文件本身只是图片,任何能产出图片的地方都可以成为来源。但是一般来说为了达到想要的纹理效果,还是会有专门的生产软件。艺术家往往会在 3D DCC 中随着模型一起导出来。当 texture 和 mesh 被导入进 unity 之后,就会使用 texture 来生成 materials。

在 unity 的 texture 文件,可以在 project window 里直接双击,会用默认图片查看器打开。

1.4.2 更换 base map texture


注意 base map texture 不是 base map,是 base map 左边的那个框框(见下面的 gif 图)。

base map texture(或者说 diffuse texture,Albedo texture)是一个普通的 2D 图片,使用其 RGB(A) 信息来定义物体的漫反射,或者说就是颜色。

赋予 base map texture 后还可以调整 base map 来改变颜色。不过一般来说都是白色,来表示 texture 本身的颜色。

1.4.3 平铺纹理(tiled texture)


有些纹理设计成用于平铺在任何 mesh 上。在很多时候还能看到无缝纹理,这种纹理在不同 tile 之间不会有缝隙偏差。

在 unity 中有两个设置可以调整平铺,tiling 和 offset:

  • tiling 表示密度。越高,纹理就越密集。

  • offset 就是纹理的偏移,0.5 表示一半的纹理长度(或宽度)。

1.4.4 UV 贴图纹理(UV MApped Texture)


对于球体,方块这种,比较简单的物体,纹理的位置其实并不重要。边缘和表面纹理是一样的,纹理的移动不会有什么观感上的影响。

但是对于像是人体这种复杂的物体,衣服上的纹理,就很重要了。比如说示例项目,点进去看会发现整个衣服都是同一个 texture 文件。

可是它怎么知道的每个位置对应在哪里呢?

texture 是怎么包裹 mesh 的

当你在 3D DCC 里创建模型的时候,软件会使用一个叫做 UV 映射的技术来生成 texture。

由 DCC 创建的 mesh,会生成一套 UV 坐标数据。UV 是一个 2D 坐标系的坐标。之所以叫做 UV,是为了和 XYZ 坐标系区分开来。UV 的坐标和 3D 空间无关,是相对于 mesh 的坐标。

UV 映射

UV 映射过程,是首先将 3D 模型展开成一个 2D 表面,然后再映射成 2D 纹理贴图。模型软件会生成 UV 坐标,等到使用的时候,会从模型的顶点信息中读取 UV 坐标,然后去纹理贴图上去找,以此就能够复现模型的外观。

submesh

查看一下我们的人物模型,可以看到有很多个 materials。但是 mesh 只有一个。这就很奇怪,我们整个人物明明只使用一个 texture,却有多个 material,而且看起来每一个 material 都对应不同的部位。

那这就要引出 submesh 的概念了,每一个 submesh 对应初始 mesh 的一部分。而 unity 会根据 materials 来区分 submesh。有几个 material 就有几个 submesh,且 submesh 的部分就是这个 material 对应的顶点构成的部分。

回到 UV 映射,由于映射的存在,我们就可以避免生成多个 meshes。不然就要给领结做一个 mesh,衣服做一个 mesh,头发做一个 mesh,balabala

1.4.5 使用 texture 改变反射特性


现在我们来看下一个 texture,metallic map 左边的 texture。

目前我们可以看到是一个黑白色的图片,不过在这之前我们可以先试着调整一下 smoothness,我们会发现,只有外衣的部分会随着调整。衬衣的光滑度并不会有任何变化,其他地方甚至会有光滑度差异,有些改变比较大,有些比较小。这是怎么做到的?

首先黑白的理解很简单,因为这个用的是 metallic workflow,因此 metallic map 就是 greyscale 图。当然,图片本身是有 RGB 通道的,不过 metallic map 属性只读取 R 通道。

至于 smoothness 则是读取这个 texture 中的 A 通道。

注:刚才说的调整 smoothness 调整会影响光滑度变化,但不会影响像不像金属,那个是由 metallic map 来决定的。简而言之,对于 metallic workflow 而言,金属度只由这个 texture 的 R 通道来决定。光滑度则由这个 texture 的 A 通道,以及滑块共同决定。(举一反三,如果是 specular workflow,那金属度就是由 RGB 控制,光滑度依旧是 A 来控制)

这也是为什么刚才光滑度滑块拖动,会造成不同地方发生有差异的变化。因为不同地方的 texture 的 A 通道值不同。衬衣部分的 Alpha 值太低了,因此滑块的影响不大。

1.5 创建半透明和透明效果

1.5.1 创建透明的玻璃瓶


  1. 选取示例项目中的一个玻璃瓶样的 mesh。

  2. 赋予一个新的 material,然后将 Surface Type 改成 transparent。

  3. 此时已经可以看到有一点效果了,现在看起来的样子,就像是前半部分被削掉一样。这是因为我们设置了 Render Face 为 front。这会导致面向玩家的部分不被渲染,以便玩家看到里面的部分。

  4. 这个设置是为了游玩体验,而且主要用在不透明的物体中。这里我们毕竟创造的是一个透明物体,因此这里直接设置成 both 即可,这样就可以看到整个物体表面。

  5. 不过,设置完之后,还是很违和。并不像是透明,而是我们有了透视眼一样。物体表面不是透明的,但我们可以看到里面的东西。

  6. 因此我们去 base map 里,调整 alpha 通道值即可。

  7. 调整 smoothness 为 1,metallic 为 0,这个时候效果就已经很好了。但是我们其实可以稍微提高一点 metallic 值,因为我们需要玻璃有一点点反射效果。(正如现实中,可以从玻璃中看到反射的自己一样)

1.5.2 使用 alpha-cliping 创建物体细节


像是叶子这种物体,也许你会想让艺术家创建一个叶子形状的建模。但问题是,场景中可能会有几万个叶子,如果都是用这种建模,将会花费超多的性能。因此实际上我们会用简单的模型加上 alpha-cliping 来代替。
看一下示例项目中的叶子,一开始长啥样?

都是些纸片,然后我们将其剪切成叶子的形状。使用 alpha 通道让部分形状不可见。可以节省相当多的性能消耗。

  1. 和之前一样,新建一个 material,赋给所有的叶子。

  2. 发现一个奇怪的现象,当摄像头从下往上看的时候,叶子都不见了。仔细想想这是为什么?之前讲过的。

  3. 实际上,就是刚刚提到的 render face。我们将其改成 both 即可,叶子只有一面,因此从下面看就相当于消失了。(有没有发现,只要改其中一个的 render face,所有叶子都变化了?这是当然的,render face 是属于 material 的属性,而这些叶子共用同一个 material)

  4. 将准备好的 texture 赋到叶子上,可以看到一部分被上色了,现在就像是叶子图案被打印在纸上一样,如下图。

  5. 打开 alpha clipping,调整滑块到适当的值。这个值代表着当值低于多少的时候会被裁剪掉。

1.6 凹凸贴图(bump maps)

unity 中对凹凸贴图的定义和其他地方用的有点不一样。
unity 把凹凸贴图分为法线贴图(normal maps)和高度贴图(height maps)。
但实际上,在其他地方,高度图和凹凸贴图是一个意思。法线贴图就是法线贴图,并不属于凹凸贴图的一类。

1.6.1 什么是凹凸贴图和法线贴图


这里还是不用 unity 自己的命名法则,用大家所接受的命名来比较好。

之前我们使用 base map ,specular map 和 smoothness map 来给物体添加颜色,金属度和光滑度。
但是,假使物体表面有很多小石子,或者一些刀痕啊,之类的细节。首先如果我们只是在 base map 上添加小石子及其阴影,确实看起来有点像,但很容易穿帮,这也是很多低成本游戏的样子。
我们不可能专门为这些东西建模,不然性能影响太大了。(当然,虚幻 5 解决的就是这个问题,让我们可以建高模直接导入,无需法线。不过,我们用的是 unity,我也不太清楚虚幻 5 到底是咋样的)

此时,凹凸贴图和(或)法线贴图起作用的地方就到了:

  • 之前我们提到过法线,那时指的是 mesh 中顶点的法线,那时已经可以让表面弯曲了,但是想要表示细节是不够的。而法线贴图则是在整个表面上赋予法线,这样就会造成表面上凹凸细节的假象。

  • 而高度贴图就比较简单,是一个灰度图,表示表面每一点的高度,低于 50% 灰度就是凹下去,高于就是凸起来。通过这种方式来表示凹凸细节。

这两个贴图都可以增加表面细节,而不会消耗过多的性能。但一般来说,都是仅使用法线贴图。

1.6.2 添加法线贴图


和别的贴图一样,法线贴图也是在 3D DCC 里制作的。

还是和别的贴图一样,法线贴图也是个图片。具有 RGB 通道。RGB 分别代表不同的方向。这也是为什么法线贴图一般都是青紫色,因为 B 通道方向的法线大多数情况下都是最多的。

在示例项目中,对比一下有无法线贴图的衣服:

  • 无法线贴图:

  • 有法线贴图:

可以看到,无法线贴图,手肘处即使有褶皱的贴图,但看起来完全不如有法线贴图的样子。
至于衬衣的痕迹就更明显了。

1.6.3 高度贴图


高度贴图是一个灰度图,如果使用 RGB 通道,只会读取 green 通道。灰度代表高度,低于 50% 灰度就是凹下去,高于就是凸起来。

相较法线贴图而言,高度贴图用的不多。一般用于一些特殊效果。不过由于高度贴图会拉伸 base map,如果 base map 不是纯色,最好小心点用。

1.7 其他 texture 类型

除了刚刚讲的,还有许多其他 texture 类型同样会起到重要作用。

1.7.1 occulsion maps(遮挡贴图)


遮挡,指的是物体对于光线的遮挡。

即使是在 PBR 中,环境光在阴影上的表现依旧非常奇怪,因此我们需要使用遮挡贴图的帮助来使得这部分阴影展现更好的效果。遮挡贴图的效果不能说是非常明显,但会提高细节的真实度。

occlusion maps 也是灰度图。

1.7.2 更细节的表面


如果还想要更加细节的表面,例如指纹,人脸的毛孔。则可以使用 detail input 里的属性:

这里的 normal map 和 surface input 里的 normal map 一起创建出复杂的细节。
此外,还有两个属性:

  • base map 可以添加细节的颜色,例如毛衣的线。

  • mask 则是一个 alpha 通道的图像,则用于指定部分区域不使用 base map 和 normal map 的效果(专指 detail inputs 里得)

1.7.3 emission maps(自发光贴图)


有一些 emissive material 会自己发光。而 emission maps 就是用于定义表面的哪些地方会发光。

我们再来看一下示例项目中主角的 emission map:

整个图像是一片黑色,只有 3 个青色光点。

然后我们再看人物,身上有这么 3 个光源:

当然,很明显,就是这 3 个光源。

  • 我们可以关闭 emission 属性。可以很明显看到颜色变得非常暗淡。

  • 贴图上的颜色会影响光的颜色,此外 HDR 选项会让这些被影响的部分(也就是非黑色的部分)发额外的光。

  • HDR 也就是高动态范围,会让这部分发出超出一般范围的亮度,造成强烈的发光效果。HDR 的 color picker 下边有一个调整亮度的地方(见下图右边)


从零开始独立游戏开发学习笔记(三十八)--Unity学习笔记18-- Creative Core 2(上)的评论 (共 条)

分享到微博请遵守国家法律