UE4 Material 101学习笔记——30-37 植物叶片(透光/mask/面片隐藏/法线调整/AO/渐隐/世界空间色彩/随风舞动)
Posted 清清!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 Material 101学习笔记——30-37 植物叶片(透光/mask/面片隐藏/法线调整/AO/渐隐/世界空间色彩/随风舞动)相关的知识,希望对你有一定的参考价值。
UE4 Material 101学习笔记——30-37 植物叶片(透光/mask/面片隐藏/法线调整/AO/渐隐/世界空间色彩/随风舞动)
- Lec30 叶子透光 Foliage Translucency
- Lec31 叶子贴图打包 Foliage Texture Packing
- Lec32 隐藏叶子面片 Foliage Hiding Planes
- Lec33 叶子法线 Foliage Normals
- Lec34 叶片AO Foliage Ambient Occlusion
- Lec35 叶片渐隐 Foliage Camera Fade
- Lec36 叶片的色彩变化 Foliage Color Variation
- Lec37 叶片随风飘舞 Foliage Wind Sway
本系列学习资料来源,Ben Cloward大佬的频道,B站的搬运翻译
接下来的章节将会讨论一些提升树叶表现的技术
Lec30 叶子透光 Foliage Translucency
在这一节,我们会讨论叶子的半透明
首先来看看现实中太阳照射叶子的情况
太阳光穿过树叶,我们在树叶背面也能够看到其颜色变化,这就是我们希望得到的目标
首先我们在初学者包里拿到这个SM_Bush,作为我们的实验对象
使用其自带的材质,拷贝一份作为实验对象
我们在12课做过一个叶子的shader,我们把它放进来
这是我们的基础效果
当我们到背光面,可以看到现在是黑黑的,我们希望能够得到透光的效果
在根节点的着色模型选择双面植物
创建给次表面颜色的蒙版,应用UV偏移(该蒙版是把叶子选出来,去掉其他不应该透射的部分)
Lec31 叶子贴图打包 Foliage Texture Packing
上节我们用了三种纹理,但其实可以有更好的处理方法
首先我们忘记处理一个问题,我们启用了双面照明,但是法线贴图只是一面的
所以为了修正这点,使用TwoSideSign节点,它会输出±1来标识正面
见仁见智,开起来反面会死黑?感觉不连TwoSideSign也没事
1 合并粗糙度/透明度/次表面mask
这一节要教的是,如何打包 粗糙度 和 次表面散射的透明度 到一个通道中
另外资产我们也进行了替换,使用Luis Garcia制作的树的资产,可以从这里免费获得
我们来看看怎么打包这些图
- 第一个红绿蓝的图,是我们自己画出来的mask
第二个图,是原本的树叶的不透明度的mask
二到三,我们把树干擦掉 - 三到四,我们取得原本diffuse图的灰度版本
与之前的遮罩进行叠加
提亮一点
- 四到五,把第二张图灰阶调低
然后五到六,叠加上第四张图
得到这个结果,其直方图是这样的
2 一图多用
我们把它塞入A通道
——————
为了获取不透明度的模板,我们获取它的值,乘一个较大的数,所有非0的都会超过1
这样在UE中会自动clamp到1
——————
再者,我们来设置次表面颜色
我们如果想通过这个alpha图获取叶子的部分,用来做叶子次表面颜色的系数的话
那么我们只需要整个纹理减去一个灰度值,相当于做一个灰度的截断即可
之后需要补上个乘法提亮,然后saturate限制到0和1
这样不用做更多的纹理采样,对性能有所帮助
——————
接下来,用它设置粗糙度,使用1-x节点,让叶子变黑,其他变白,稍微加一点,就可以做粗糙度
切换到粗糙度视图
然而现在看这些树,似乎分叉非常的明显,呈现Y状,这样不好,我们之后要改进它
Lec32 隐藏叶子面片 Foliage Hiding Planes
在本节,我们要学习如何隐藏植物的那些面片
一棵树,不加shader原本是这样的
树由许多面片组成,叶子是在面片上添加着色器形成的
在一个面片上呈现几十片叶子,而不是用好多多边形去组成一个叶子
我们需要去隐藏面片的效果
1 修正
在此之前,做一些小修正
- 我们看到叶子会这样长出了树干
这显然是不合理的,原因是因为 我们shader的UV 和 叶子在面片的UV 不一样
做如下改正
- 上一节在透明模板部分乘了个4,有些太高,可以改成1.5
2 “计算”法线——DDX&DDY
如何让人看不出叶子在一个平面上呢?
我们需要在角度较偏的时候,隐藏叶子
做法采用,相机和法线的点乘,因为双面,所以再附上绝对值,反转自乘反转,限制一下角度
也就是以下节点,把它们乘上不透明模板
想一想这样的做法,确实可行
但是我们看看模型的法线,发现有些诡异
- 法线实际上并不在这个面片指向的方向
- 模型的法线实际上已经被调整过,不是沿着面片的朝向,而是指着离开树木中心的方向,为了让树木的照明正确(这些是下节要讨论的内容)
- 但是为了达到我们需要的目的,我们要做一些tricky的东西,去克服表面法线不对劲这个事情
于是我们要去计算多边形的表面法线,这在UE中有两个节点,一个叫做DDX一个叫做DDY,可以给我们提供帮助
- DDX和DDY,是片段着色器指令,可以用于计算任何值相对于屏幕空间坐标的变化率
- 我们知道在光栅化的时刻,GPUs会在同一时刻并行运行很多Fragment Shader,但是并不是一个pixel一个pixel去执行的,而是将其组织在2x2的一组pixels分块中,去并行执行。
- 而偏导数就正好是计算的这一块像素中的变化率。
从下图可以看出来ddx 就是右边的像素块的值减去左边像素块的值,而ddy就是下面像素块的值减去上面像素块的值。其中的x,y代表的是屏幕坐标。
我们使用DDX获取X方向的斜率,DDY获取Y方向的斜率,相当于获取了两个向量
那么这两个向量的叉积,就是法线
(这里最后反正要点积再取绝对值,所以DDY和DDX谁叉乘谁都影响不大,不过下节就会有影响了)
连出来到不透明模板这里
Ben提到,我们目前做的事情,都是为了让效果看起来尽可能好,可能对于手游来说要更加简便为好
Lec33 叶子法线 Foliage Normals
1 引入
叶片的法线需要特殊处理,为什么呢?
我们知道,叶片是由面片构成的,但是面片实际上代表了好多好多叶子,我们并不想让一整个片上的叶子都是同样的光照情况
之前我们制作了叶子的抖动动画,平面的渐隐渐出,这节我们来调整面片的法线。
为了尽可能直观,我们把SkyLight关掉,把材质里的次表面颜色断开,方便直白的观察法线的影响
2 四种法线
有以下几种方法构建面片的叶子法线
2.1 Face Normals
FaceNormal就是叶子所在这个面片的VertexNormal,也就是面片的朝向
虽然面片方向确实是这样,但是照的不好看
我们之前用过法线计算遮挡,在红框处做的调整我们就能得到FaceNormal,连到节点上
(为什么这里要乘以-1呢?因为这里是DDY叉乘DDX,右手定则是朝-Z的法线,所以乘个-1翻回去
(如果改成DDX叉乘DDY也行,就不要乘以-1了
切换到法线视图,可以看到法线都是平面化的,这样不太适合“叶子”,显得很笨拙
这是我们要避免的FaceNormal
2.2 Bent Normals
对于特定的树,我们有第二种法线,BentNormal
这也是之前我们自带的normal做法,我们点开模型,点开法线
在树梢的末端,这些绿色的法线,以一种指向外部的方式背对中心,这就是BentNormal
我们在生成树的模型的3D软件中,可以从一个球来烘焙法线,烘焙到树的几何体上
有一些具体的实际制作教程,如以下链接
对比一下植物的法线和球的法线,是很接近的
2.3 Object Pivot Normals
如果我们因为一些原因,无法去改变几何体的法线,或者想要某种类型的法线
那么,我们可以从几个不同的位置生成法线
我们知道,向量是一个位置减去另一个位置
我们可以用像素的物体的世界中心的位置与对象中心的位置,两者相减,得到从物体向外朝着像素的向量,把这个当法线,输出球状照明
效果是这样,和之前BentNormal很像,并且是真的平滑过渡,我们也没有使用顶点法线
但是我们现在还没用法线贴图呢,所以我们要把这个平滑过渡加到之前的法线贴图上(注意,下方应该是world space到Tangent space)
非常平滑又有法线
2.4 Camera Normals
第四种方法其实是用CameraVector作为表面的法线
这种方法制作的法线,通常用做那些一直要朝向我们的面片
3 方法混合 Bonus Hybrid Method
对于树,我们想这么混合
树枝,使用CameraVector,叶子,使用Object Pivot Normals,插值的参数用之前的mask(注意,下方应该是world space到Tangent space)
可以看到叶子和枝干是区分开的,这是我们的节点
对比一下,这是我们做法线调整之前的树
这是之后
动图对比
这是之前
这是之后,法线的过渡更加平滑
然而这样做会有死黑的问题,因为Object Pivot Normals可能和插片的方向一样,导致法线和插片的面法线垂直了,直接黑掉了
Ben后来的做法,该用面法线,vert normal
Lec34 叶片AO Foliage Ambient Occlusion
本节将会为叶片制作AO,做法有些和一般的AO不一样,因为我们的叶子是存在于面片上的
我们想一想,树上有大量的树叶,其由一堆不同方向的随机面片组成,我们需要一个均匀平滑的好AO——也就是,树的中心变暗,朝着树的方向变亮
为什么呢?思考一棵树在阳光下是什么样的情况,我们往树的中心走,透过叶子的阳光就越少,就越暗了
上一节我们用过Object Pivot Normals
如果我们用像素位置减去树模型这个对象的位置,得到这个向量并测量长度,那么我们就可能知道我们离中心有多远,以此来设置黑白的值
连到高光度,去看看高光度缓冲的效果(此处法线连的要是add那个地方,不过只是看缓冲区,没关系,后面改回来了)(注意,法线应该是world space到Tangent space)
再加一个power,加大对比度看看
我们将其运用到次表面颜色和镜面值(注意,法线应该是world space到Tangent space)
中间暗,周围亮很明显
我们如果把它也真的连到AO上,整个数黑了很多
我们整理一下节点,总览(注意,法线应该是world space到Tangent space)
分布
(感觉连了AO太黑的,可以不连)
Lec35 叶片渐隐 Foliage Camera Fade
我们会让相机进入叶子时,叶子渐隐
真实的世界不会这样,但是为了游戏性考虑,进入丛林时,会让丛林变得暗淡
我们建立一个CameraDistanceMask的材质函数
随着相机的前后移动,会呈现0-1的变化,Near和Far设置的是200到600厘米,将预览值作为默认值
我们把它乘上不透明模板
确实,裁减了,但是很生硬
我们接着用dither temporal aa
效果还不错
我们注意到,我们的shader很复杂,不过实际用的时候,可以按需选择想要的部分
Lec36 叶片的色彩变化 Foliage Color Variation
这节,我们为树制作颜色变化的shader
如果我们只有一棵树,那很不错,但是如果我们有一座森林呢?
每个树的shader都一样,颜色都一样
实际生活中并不会这样
所以我们想要制作一个材质函数,让每个树的颜色略有不同
我们需要将这个纹理,从上到下投影到世界空间,每棵树,对这个纹理做稍微不同的采样,将树的纹理和这个噪声纹理混合起来
(我做不到一样,就用其他噪声纹理替代了)
以下是这个材质函数,绝对位置作为梯度,物体位置作为基准决定颜色
1000是基于位置的比例,0.5是混合程度
同时我们发现以前的叶子有些黑边,在此做一些修改
创造了几棵树,使用同一个shader,他们随着位置的不同,采样了纹理的不同位置
Lec37 叶片随风飘舞 Foliage Wind Sway
这节,我们要加入风的做法
之前的动图,我们看得到树干在摇摇晃晃的,但是我们的叶子整体保持不动
确实之前我们做过叶片动画,但是那是像素的UV移动
这次我们让顶点动起来
我们的风,既能wiggle(小幅度、快速的扭动)也能sway(节奏比较缓慢的摇摆,摇曳)
1 Wiggle——小幅扭动
也就是我们要专注于世界位置偏移了
我们会用到这个节点
wiggle非常好做,这就是它所要用的
它最后连出来的是
2 Sway——缓慢摇摆
Sway略显复杂,我们需要用到一个节点,RotateAboutAxis
Position使用世界位置
PivotPoint,我们不会使用ObjectPosition而会是原点
NormalizedRotationAxis,需要风向和向上向量的叉积
RotationAngle,需要两组正弦波叠加
同时在Sway最后,让上面叶子动的多,下面动得少,最后的最后和之前的Wiggle进行叠加,连到偏移上
以上是关于UE4 Material 101学习笔记——30-37 植物叶片(透光/mask/面片隐藏/法线调整/AO/渐隐/世界空间色彩/随风舞动)的主要内容,如果未能解决你的问题,请参考以下文章
UE4 Material 101学习笔记——19-22 程序化噪声的使用(Noise节点)
UE4 Material 101学习笔记——23-29 水涟漪/水深/折射反射/Gerstner海浪/波光焦散/泡沫/FlowMap