Unity学习笔记 Vol.65 Unity Shader Graph URP 中的三维映射(Triplanar)
摘要

我们将使用Unity通用渲染管线和ShaderGraph中部分功能制作根据位置和转向来调整外观的着色器,我们将使用《Boat Attack》demo。demo很好地展示出了通用渲染管线的可能性,及项目在支持多平台时能达到什么效果。demo项目下载及详细教程参考下面视频。

着色器详解

我们用ShaderGraph为岩块和峭壁制作了一个着色器,让网格的材质能自动适应,让对象在场景中不论位置,转向是多少都能使用正确的材质,着色器会让岩石底部一直是潮湿的,让植被仅在特定高度之上的岩块顶部出现。

来看看如何用ShaderGraph来制作这类着色器吧。首先,新建着色器,选择Shader> PBR Graph,让我们将它命名为RockShader,再创建一个新材质指定到岩块上,着色器主要通过计算获取对象在场景中当前 的位置和转向,再确定网格外观,为不同层级生成遮罩。


我们先在基础层级上添加岩石纹理,新建SampleTexture2D节点,连接上 一个新Texture节点,节点应转换为属性,命名为RockAlbedo,接着创建,连接法线贴图,在《Boat Attack》demo中,我们将法线贴图和环境光遮蔽贴图打包进了同一纹理中,将多个纹理打包进图像不同通道中可以 节省不少纹理内存,但也意味着贴图要解包后使用,指定通道时也不能出错。

新建一个SampleTexture2D节点,连接到涨到 AO或法线环境光遮蔽贴图上,然后抓取红色通道,把它连接到Preview节点就能看到,这是 岩块的环境光遮蔽贴图,那将输出连接到主节点的Occlusion上,再创建个Vector3节点,将绿色通道连接到y输入点,蓝色通道到z输入点,alpha通道到x输入点,随后重新映射输入纹理0到1数值范围到普通矢量的-1到1范围。为此,我们可将数值乘2再减1,新建Multiply节点,将数值都乘上2。

再连接到一个Substract节点将 数值都减去1 。在Preview中 ,能看到纹理重映射后已经能实际使用了,将输入连接到主节点作为法线贴图,同时连接上Albedo贴图。


岩块看起来挺好的,接下来看看如何在图表中添加些运算,在特定高度上添加植被。

回到ShaderGraph先整理下图表,我们能隐藏部分数值,在节点上右击,选择View>Collapse Ports。

菜单上还能选择隐藏节点的预览。

首先创建植被的纹理节点。接着,为 Normal和Albedo纹理添加Lerp节点,Lerp节点的Time输入决定了两种输入纹理之间着色器的过渡方式,输入应在0和1之间。但我们能使用灰阶纹理来设定,遮挡两个纹理的混合位置,给Time属性指定个SampleGradient节点就能显示出效果。

随着uv变化,颜色会 从黑变白,因为黑色 等0,白色等于1,Lerp节点2会根据输入从一个纹理逐渐过渡另一个纹理。不过岩块上看起来不对劲,这是因为网格uv展开方式不对。

我们需要用岩块纹理的数据来生成、修改植被的遮罩,让其只在顶部出现,将岩块纹理连接到 Lerp节点的A端口,植被纹理连接到B端口。

接着创建Position节点,取得对象的AbsoluteWorld世界绝对位置,

从中取得y轴位置,拆分输出,将绿色通道传入Smoothstep节点。

这时将输出连接到Lerp节点的Time端口,遮罩就会出现在岩块上了。

不过遮罩似乎只遮到了岩块的底层,这是因为我们使用了y轴位置来设定遮罩,任何大于1的 纹理都为白色植被纹理才会出现。

来看看如何将草地的分布向上挪一挪。在黑板中新建Vector1属性,称为GrassHeightBlend,将属性连接到Smoothstep节点的Edge2端点2,来控制植被出现的高度阈值。

可以注意到,当更改材质上的数值时,修改的是渐变效果,而不是遮罩间的交点,我们来添加个与Blend值相关的Smoothstep节点值,让边缘浓密度能保持一致。

新建Subtract节点,将数值减去1,让渐变效果从GrassHeightBlend减1单位的位置上开始。类似的,新建Add节点,将Smoothstep节点的第二个值,高为GrassHeightBlend加1单位的值。

这下边缘浓密度会保持一致,混合点则能在岩块上下移动。看起来很不错了。遮罩现在能正确混合了。最后一步是 让植被仅出在指向特定方向的网格上。我们能通过将法线贴图转换成方向矢量实现,抓取岩块法线贴图,用Transform节点将其从正切空间转换到场景空间,将Type类型设为Direction。

该纹理贴图就能显示出网格每部分的世界方向了。我们要让植被仅出现在向上的网格上,即纹理的绿色通道,那将输出拆分,将绿色通道接Multiply节点,将输出与此前的Smoothstep输出相乘,节点现在会根据网格法线向上的程度 来输出个0到1的值。

如果将输出用作Lerp节点的 遮罩,植被便只会出现在网格上最向上的部分出现。

在最后润色上,我们来为运算添加些控制,控制在岩块上并排的植被数量,在Multiply节点后新添Smoothstep节点。

在黑板上新建Vector1属性,称作Grass Threshold,设定为0到1的滑动条,将阈值连接到一 个One Minus节点,将输出输入到Smoothstep节点的 Edge2端点,将输出连接到Lerp节点的Time端点。现在,我们可以控制材质设定植被在岩块上的伸展程度了,经过短短几次更迭。我们就使用ShaderGraph为游戏制作了非常灵活的着色器 ,可以看到ShaderGraph是一个实用、强大的工具,可用来快速为游戏创建 、更迭着色器。