功能示例
Shader Graph 功能示例样本内容是一组 Shader Graph 资源,展示了如何在 Shader Graph 中实现常见技术和效果。该样本包旨在帮助用户了解实现特定效果所需的内容,并提供示例以便用户更轻松地学习。
此样本内容分为以下几类:
- 混合遮罩(Blending Masks) - 这些示例根据表面特性,如高度、朝向角度或与相机的距离,生成遮罩。
- 自定义插值器(Custom Interpolator) - 演示如何在 Shader Graph 中使用自定义插值器功能,将计算从片段阶段转移到顶点阶段,以提高性能。
- 细节贴图(Detail Mapping) - 添加不包含在基础纹理贴图中的表面细节的技术。
- 程序化噪声和形状(Procedural Noise and Shapes) - 使用数学而非纹理样本创建形状或图案的方法。
- Shader Graph 功能示例(Shader Graph Feature Examples) - 示例如何使用特定的 Shader Graph 功能,例如自定义代码节点或自定义插值器。
- UV 投影(UV Projection) - 创建纹理坐标以实现特定效果的方法,如视差遮蔽映射或三平面投影。
- 顶点动画(Vertex Animation) - 调整顶点位置以创建波浪、动态旗帜或面向相机的广告牌等效果的技术。
- 粒子(Particles) - 展示如何仅使用 Shader Graph 构建全功能的粒子系统。
- 条件(Conditions) - 展示如何根据图形质量设置和渲染管线分支。
- 自定义光照(Custom Lighting) - 演示如何使用 Shader Graph 构建自定义光照模型,包括 PBR、简单光照和卡通渲染。
混合遮罩
创建着色器的一个重要部分是确定特定效果应应用的区域。这可以通过创建遮罩并使用遮罩来区分应应用效果的区域和不应应用的区域来完成。此样本集提供了创建这些遮罩的多种方法的示例。
海拔遮罩
海拔遮罩(Altitude Mask) 在最小海拔以下为黑色,在最小和最大海拔之间从黑色渐变为白色,在最大海拔以上保持白色。您可以使用 AltitudeMask 子图在着色器中创建此效果。
海拔遮罩示例展示了如何使用 Altitude Mask 子图在着色器中实现两种材质之间的混合。在最小海拔以下使用鹅卵石材质,在最小和最大海拔之间材质从鹅卵石渐变为金色,在最大海拔以上使用金色材质。
您可以在 Altitude 子图节点的“Falloff Type”下拉菜单中选择渐变的类型。“Linear”选项使遮罩从最小到最大海拔呈直线渐变,而“Smoothstep”选项则使用 S 形曲线实现平滑过渡。
角度遮罩
角度遮罩(Angle Mask) 利用表面的朝向来确定遮罩应为黑色还是白色。如果表面朝向给定输入向量的方向,则遮罩为白色;如果背离该向量,则遮罩为黑色。
角度遮罩示例使用 AngleMask 子图生成遮罩,然后使用遮罩在鹅卵石材质和白色的雪状材质之间进行混合。
在该示例中,AngleMask 子图节点的 MaskVector 输入被设为 (0,1,0),这是一个指向上方的向量(正 Y 轴)。当物体表面朝向该方向时,遮罩为白色;当表面背离该方向时,遮罩为黑色。
AngleMask 子图的 Max 和 Min 输入值用于控制遮罩的渐变。两个值应使用零到一之间的数值。当 Max 和 Min 值靠近(例如 0.5 和 0.48),渐变将更锐利。当它们相距较远(例如 0.8 和 0.3),渐变将更加平滑和模糊。当 Max 和 Min 值接近 1 时,表面方向必须更接近 MaskVector 才能使遮罩变白;当它们接近 0 时,即使表面方向与 MaskVector 存在较大差异,遮罩也会变白。
相机距离遮罩
相机距离遮罩(Camera Distance Mask) 使用相机位置与物体表面的距离来确定遮罩应为黑色还是白色。当相机靠近表面时,遮罩为黑色;当距离增加时,遮罩为白色。
在此示例中,当相机靠近物体时使用鹅卵石材质,并随着相机远离物体逐渐过渡到金色材质。
CameraDistanceMask 子图的 Start Distance 和 Length 值控制遮罩的功能。Start Distance 值控制遮罩开始从黑色过渡为白色的位置。例如,在此处设置为 2 米,这意味着在 0 到 2 米之间遮罩为黑色。Length 值控制黑白之间的过渡距离,在此示例中同样设置为 2 米,所以在 2 米到 4 米之间遮罩从黑色过渡为白色。超过 4 米的距离时遮罩将保持白色。
高度遮罩
高度遮罩(Height Mask) 利用两个材质的高度数据将它们混合在一起,从而实现更逼真的交界效果。我们可以将一种材质应用到另一种材质的裂缝和凹槽中,而非简单地淡化过渡。
在此示例中,我们使用 U 纹理坐标作为平滑渐变遮罩,然后根据两种材质的高度来调整遮罩。最终效果是首先在鹅卵石的低洼区域应用金色材质,逐渐上升,直到鹅卵石的顶部显示出来,然后完全被金色材质替代。
要使此效果正确工作,至少其中一种材质需要具备良好的高度数据。此类过渡在高度变化明显的材质(如鹅卵石)上效果最好。对于大部分平坦的材质,使用此技术不会产生有趣的效果。
自定义插值器
Shader Graph 中的自定义插值器功能允许您在顶点阶段进行任何类型的计算,然后将结果插值传递到片段阶段。在顶点阶段进行计算可以显著提高性能,因为数学运算只需在每个顶点上执行一次,而不必对每个像素进行运算。
但是,顶点级计算可能会产生伪影,这在“伪影示例”中有展示。为避免这些伪影,请注意仅在低频变化的情况下使用顶点级计算。
插值伪影
此示例展示了在顶点阶段执行数学运算时可能出现的伪影。为了获得平滑的效果,光照需要在每个像素上进行计算 - 但是在这里,我们在顶点级别进行计算,然后将结果插值到像素上。插值是线性的,因此精度不足,导致结果看起来呈角状和不平滑,尤其是在高光区域。
插值节省
此示例展示了自定义插值器的高效应用场景。在创建着色器时,经常需要多次平铺和偏移 UV 贴图。这种操作在大型物体的 UV 滚动时可能会相当耗费资源。以水面着色器为例,其中水面覆盖了大部分地形。在片段阶段对 UV 进行平铺意味着要对水面覆盖的每个像素执行计算。优化的方法是首先在顶点阶段计算 UV,并将数据传递给片段阶段。因为屏幕上的顶点比像素少,计算开销也会更低。在这个例子中,与自定义插值器的 NdotL
示例不同,我们在采样之后进行操作,因此渲染结果几乎没有可见差异。
当 InFragStage
设置为 true
时,使用在片段阶段计算的 UV;当 InFragStage
设置为 false
时,在顶点阶段滚动 UV。在这个例子中,无论在顶点还是片段阶段滚动 UV,渲染结果几乎没有区别。然而,在顶点阶段进行计算并通过自定义插值器传递数据更具成本效益。
细节映射
细节映射(Detail Mapping) 是一组在模型表面上添加额外细节的技术,这些细节通常不包含在模型的基础纹理集中。使用这些技术的场景包括相机需要比纹理分辨率更接近模型,或者对象尺寸过大,基础纹理的分辨率不足以表现细节。
在三个细节映射示例中,我们使用了一种称为 NOS 的纹理打包格式作为细节纹理。NOS 代表法线 (Normal)、遮蔽 (Occlusion)、平滑度 (Smoothness),其中法线存储在纹理的红色和绿色通道,环境遮蔽存储在蓝色通道,平滑度存储在 alpha 通道。将数据这样打包可最大限度地利用单一的细节纹理,我们可以使用一次纹理采样来为颜色、法线、平滑度和 AO 添加细节。为简化流程,我们使用 UnpackDetailNOS
子图来采样 NOS 细节纹理并解包数据。
细节映射颜色
在颜色细节映射示例中,我们只是将 UnpackDetailNOS
子图的 Albedo
输出与基础颜色纹理相乘。NOS 纹理格式将环境遮蔽数据存储在细节纹理的蓝色通道中,UnpackDetailNOS
子图将遮蔽数据传递到 Albedo
输出端口。因此,对于颜色细节,我们只是将基础颜色乘以细节 AO。
请注意效果非常微妙。在过去,细节映射是一种新技术时,大多数表面仅使用颜色纹理,因此颜色细节映射是主要技术。如今,材料使用法线、平滑度、遮蔽等多个图层,将细节映射用于所有图层比仅用于颜色效果更好。
细节映射法线
在法线细节映射示例中,我们将 UnpackDetailNOS
子图的 Normal
输出与基础法线贴图结合使用。我们使用了 Normal Blend
节点将两种法线结合在一起,并选择了重新定向 (Reoriented) 模式以获得最佳质量。
注意法线细节映射示例比颜色细节映射示例更具影响力。细节法线改变了表面的感知形状,对光照效果有很强的影响,而颜色细节示例仅改变颜色,效果较弱。这表明如果只能为材质的一个纹理添加细节,那么法线是最有效的选择。
如果您想使渲染效果稍微便宜,可以将 Normal Blend
节点设置为默认模式(即使用 Whiteout 法线混合技术)。另一种优化方法是将 UnpackDetailNOS
子图的 Quality
下拉菜单设置为快速模式而不是准确模式。两者结合会减少渲染效果所需的指令数量。尽管效果会稍微不准确,但可能并不明显。您可以在自己的着色器中试试看。如果差异不明显,请使用更便宜的技术来获得更好的性能!
全细节映射
全细节映射示例为材质的颜色、法线、环境遮蔽和平滑度组件添加了细节——几乎为材质的所有组件增加了额外的细节。这是为表面添加细节的最有效方式,但也比颜色或法线示例稍微昂贵。
特别注意我们如何将 UnpackDetailNOS
子图的每个输出与主材质中的对应组件混合。对于颜色,我们使用乘法,因此细节颜色数据使基础颜色变暗。对于法线,我们使用 Normal Blend
节点。对于环境遮蔽,我们使用 Minimum
节点,结果是较暗的结果。我们使用 Minimum
而不是乘法来防止环境遮蔽过暗。最后,对于平滑度,我们使用加法,因为平滑度数据在 -0.5 到 0.5 范围内,将此范围加到基础平滑度上相当于覆盖效果,其中暗色使暗色变暗,亮色使亮色变亮。
程序化噪声与形状
在着色器中,“程序化”(procedural) 指的是使用一系列数学公式实时生成形状和图案的技术,而不是采样纹理贴图。程序化噪声图案和形状相比于纹理贴图有一些优势,例如不占用纹理内存、覆盖无限表面积且不会重复或平铺、并且与纹理分辨率无关。
六边形网格
六边形网格(Hexagon grid) 在各种项目中都很有用,因此我们在示例中包含了它。在示例中,HexGrid
子图的 Grid
输出端口简单地连接到主栈的 Base Color
。HexGrid
子图还具有 EdgeDistance
和 TileID
输出端口。EdgeDistance
输出提供一个表示到最近的六边形边缘距离的符号距离字段值。因此,六边形中心的像素是白色的,越靠近六边形边缘,像素变得越暗。TileID
输出端口为每个网格块提供不同的随机值。
HexGrid
子图节点还包含一些有用的输入端口。UV
输入允许控制用于生成图案的 UV 坐标。Scale
输入使您可以控制 X 和 Y 轴上效果的尺寸。最后,Line Width
输入控制网格轮廓的厚度。Line Width
仅适用于 Grid
输出,不会改变 Edge Distance
或 TileID
的输出。
程序化砖块
程序化砖块(Procedural Brick) 示例展示了如何使用纯数学生成砖块图案,而无需纹理采样。如果您在一个平台上进行开发,数学运算快而纹理采样慢,那么通过程序化生成砖块图案比采样纹理可能更高效。另一个优点是砖块图案的变化不会重复,因此如果您需要一个覆盖大面积而没有重复的图案,程序化生成可能是最佳选择。
SDF 形状
Shader Graph 提供了一组节点用于程序化生成形状(椭圆、多边形、矩形、圆角矩形、圆角多边形),但开发人员通常发现形状的符号距离字段比形状本身更有用。SDF 可以以有趣的方式结合在一起,并为生成结果提供更多的灵活性和控制。因此,我们在示例中包括了这些 SDF 形状。
Shader Graph 功能示例
Shader Graph 工具提供了多种高级功能,例如端口默认值和自定义插值器,但设置这些功能可能会较为复杂。本节包含这些高级功能的示例,帮助用户了解设置和使用这些功能的要求。
子图下拉菜单
在创建子图节点时,可以添加下拉控制,以允许用户进行选择。这在多种方法能实现类似效果时尤其有用,用户可以在子图中选择所需的方法。本示例展示如何在子图中添加一个下拉框。
创建子图资产后,将其在编辑器中打开,并打开黑板面板。点击顶部的加号,然后在参数类型列表底部选择“Dropdown”(下拉菜单)。为该下拉菜单命名。命名后,选择该下拉菜单并打开图形检查器,在此可以控制下拉菜单选项的数量和名称。使用底部的加号和减号来添加或删除选项,并点击选项以更改其名称。设置好所需的选项后,回到黑板面板,将黑板参数拖入图形中。下拉节点将作为一个开关,根据选择的下拉选项切换输入。
当子图添加到图形中后,用户可以从下拉菜单中选择一个选项,图形将使用已选择的分支。由于分支是静态的,只有被选中的分支会在运行时包含在着色器中,因此不会产生额外的着色器变体,也不会带来性能损失。
子图端口默认值
可以使用输入连接分支节点来为子图端口设置默认值,甚至可以创建大型图形树以在特定输入端口未连接时使用。子图端口默认值示例展示了如何实现这一功能。
创建子图资产后,将其在编辑器中打开,并打开黑板面板。点击顶部的加号并选择数据类型。在本示例中,我们选择了 Vector 2 类型用于UV坐标输入端口。选择类型后,给参数命名(如UV)。在将参数添加到图形前,选择该参数并打开图形检查器。在检查器中,勾选 “Use Custom Binding” 复选框并为参数设置标签。拖动黑板中的参数至图形中,然后添加一个 “Branch on Input Connection” 节点。将输入参数的输出端口连接到该节点的 “Input” 和 “Connected” 输入端口。接着,可将一个节点或节点树连接至 “NotConnected” 输入端口,作为未连接时的默认值。
UV投影
UV坐标用于将模型的3D表面区域映射到2D空间,以应用纹理贴图。本节包含一些创建、操作和应用UV坐标的示例,以实现多种效果。
逐帧播放
逐帧播放(Flipbook) 效果是按序列播放的一系列帧,帧以网格方式排列在纹理贴图上。Shader Graph 内置了生成跳转帧所需UV的节点。
在示例中,我们展示了如何使用 Shader Graph 的内置逐帧播放节点来创建动画效果,并展示了如何使用一对逐帧播放节点设置从一帧平滑过渡到下一帧的效果。
请注意,在 Blackboard 中,我们暴露了一个 Texture 参数,用于选择翻页纹理;行和列参数用于描述翻页纹理的布局;Speed 参数控制帧的播放速率;以及一个 Flip Mode 下拉菜单。
通过翻转模式下拉菜单,您可以选择从一帧翻转到下一帧,或者在帧之间混合(Blend)。请注意,如果选择混合选项,即使帧速率保持不变,播放效果也会显得更加流畅。使用这种混合模式是改善效果外观的好方法,即使在帧速率较低的情况下,也能让效果感觉不那么突兀。
流动贴图
流动贴图(Flow Mapping) 是一种通过在纹理上产生流动效果的技术。它通过沿着特定的流动方向随着时间变化来扭曲纹理坐标,以模拟流动的假象。这个过程分为两个阶段:当第一个阶段的扭曲效果达到一定程度时,便将其与未扭曲的第二阶段进行混合,然后对第二阶段进行扭曲,同时消除第一个阶段的扭曲效果。我们可以在两个阶段之间不断进行交替混合,从而营造出流动的错觉。
在示例中,我们使用了 UVFlowMap 子图来实现这一效果。我们提供一个流动贴图 (Flow Map) 来指示流动的方向。在此示例中,我们使用了类似于法线贴图的纹理来指定方向。然后我们给定一个强度值 (Strength),用以控制 UV 坐标被扭曲的距离。流动时间 (Flow Time) 可以简单地使用时间节点 (Time node),也可以连接到一个 Flow Map Time 子图,以在不同区域中变化时间,从而减少闪烁效果。UV 输入控制纹理的应用方式。这里我们使用 Tiling And Offset 节点将纹理平铺 8 次。最后,偏移值 (Offset) 控制拉伸效果的中点,默认值为 0.5,这意味着每个阶段从负方向拉伸一半开始,接着变为不拉伸,然后拉伸到正方向的一半。在大多数情况下,这样的设置能带来最佳效果。
在我们的示例中,我们添加了一个“时间模式” (Temporal Mode) 下拉菜单,以展示 Flow Map Time 子图的效果。当时间模式设置为仅时间 (Time Only) 时,仅使用时间作为流动时间输入,此时整个模型会呈现规律性的闪烁效果,这是因为阶段 1 和阶段 2 的混合在整个表面上是均匀的。当时间模式设置为流动贴图时间 (Flow Map Time) 时,使用 Flow Map Time 子图作为流动时间输入,子图会将阶段的混合效果分布成平滑的渐变,从而打破了均匀的闪烁效果。
室内立方体映射
室内立方体映射(Interior Cube Mapping) 是一种通过窗户创建建筑内部幻觉的技术,即便没有任何内部模型。这种效果可以让非常简单的建筑外部模型看起来拥有复杂的内部,同时比实际建模内部空间更节省资源。
在我们的示例中,UVInteriorCubemap
子图生成了用于采样立方体贴图的方向向量。立方体贴图创造了内部效果的错觉,图的其他部分则创建了外部建筑和窗户。
UVInteriorCubemap
子图提供了用于指定窗口数量的输入,以及控制是否对立方体贴图墙壁进行随机化的功能。随机化功能可旋转立方体贴图的墙壁,从而让每个内部空间拥有不同的侧墙和背墙。此外,还提供了一个下拉菜单,用于控制投影是否在物体空间或 UV 空间中进行。
纬经度投影
纬经度投影(Lat Long Projection) 示例展示了使用以纬经度格式存储的纹理图所需的数学运算。许多高动态范围环境图像都采用这种格式,因此了解如何使用这种图像非常有用。纬经度格式图像的特征是2:1的纵横比,通常中间带有地平线。
在我们的示例中,我们使用了 UVLatLong
子图。此节点生成了采样纬经度格式纹理所需的 UV 坐标。默认情况下,UVLatLong
子图使用反射向量作为输入,因此结果会像是在模型表面上的反射效果。如果希望结果贴合在表面上,可以使用法线向量。
选择 Sample Texture 2D
节点并打开图形检查器,注意到 Mip Sampling Mode
设置为 Gradient
。该设置使 Sample Texture 2D
节点具有 DDX
和 DDY
输入端口,这些端口已连接到 DDX
和 DDY
节点。这是因为用于纬经度投影的纹理坐标在投影的左右两侧拼接处有一个硬边缝。如果设置 Mip Sampling Mode
为 Standard
,纹理采样器在该硬缝处将因纹理坐标的 mips 值不连续而出现明显的硬缝。Gradient Mip Sampling Mode
允许我们通过 DDX
和 DDY
节点手动计算 mip 级别,而不是让采样器自动处理。
材质捕获(球面映射)
材质捕获(Mat Cap) 示例展示了将球面贴图投影到表面上所需的数学运算。该效果通常被称为材质捕获,因为它可以在纹理创建方式上表现材料的特性,如反射或次表面散射效果。某些3D雕刻软件使用 MatCap 投影来渲染对象。球面贴图的特征通常类似于一张铬球的图片。球面贴图是最便宜的反射形式——既节省纹理内存,数学运算成本也低,但准确性不足,因为它总是面向摄像机。
在我们的示例中,我们使用了 UVSphereMap
子图来生成采样球面贴图的纹理坐标。该子图有一个输入用于表面法线,并提供下拉菜单以选择法线所在的空间。默认使用的是顶点法线,但如果想给表面添加更多细节,可以连接一个法线贴图。
视差映射
有多种技术试图在实际几何体之外增加表面形状的细节。视差映射(Parallax Mapping) 示例展示了其中的三种技术,您可以使用材质中的 Bump Type
下拉框选择要显示的示例。
仅法线
这是最常见且最廉价的一种技术。它使用法线贴图来改变表面表观形状,每个贴图中的像素表示该点处表面的朝向。因为没有表面的偏移,这种技术相比其他两种看起来也较为平坦。
视差
视差映射会采样高度图,并使用该值根据高度相对于视角方向偏移 UV 坐标。这样会在表面上产生视差运动效果,使表面感觉像是具有真实的深度。然而,在陡峭的角度观察时,这种效果通常会出现瑕疵。在高度图上陡峭的地方,会有明显的拉伸瑕疵。
视差遮挡
视差遮挡映射(Parallax Occlusion Mapping) 沿视角方向多次采样高度图(基于步骤数量),重构表面景深并使用该深度信息来生成纹理采样的 UV 坐标。此过程较昂贵——尤其是当步数较多时,但可以通过创建一个掩码来基于摄像机距离和表面角度减少步数,从而降低成本。我们的示例展示了该技术。
三向投影
三向投影(Triplanar projection) 将纹理从正面、侧面和顶部投影到模型表面上。此技术适用于希望应用纹理而模型没有良好 UV 坐标的情况,或当 UV 布局用于其他目的时。它还适用于在多个相邻物体上投影相同的纹理或材质,使投影在它们之间连续。
纹理投影有多种方法。我们的示例展示了四种方法,您可以使用材质中的 Projection Type
下拉框选择要查看的方法,按成本从高到低排列。
三向纹理投影
三向纹理技术使用了 Shader Graph 中的内置三向节点。此节点会分别为顶部、正面和侧面投影采样每个纹理,并在三个样本之间进行混合。此技术效果最好,因为它在样本之间进行了混合,但成本也最高。
双向纹理投影
这是三向投影的一种巧妙优化,使用两个纹理样本代替三个。该着色器确定投影中最重要的两个面,并仅采样这两个面而非全部三个。在大多数平台上,它会比三向纹理便宜,但比三向 UV 成本更高。根据所采样的纹理,您可能会在三个面交汇处注意到一个小的奇异点瑕疵。
三向 UV 投影
三向 UV 技术使用 UVTriplanar
子图从顶部、正面和侧面投影 UV 坐标,然后仅采样纹理一次。因为它仅采样每个纹理一次,此技术成本较低。UV 坐标无法像纹理一样混合——因此此技术在投影交汇处有硬边,而不像三向纹理技术那样进行混合。不过,这些硬边在某些材质上并不明显,因此如果您需要更廉价的三向投影,该方法可能是可接受的替代方案。
请注意,在使用此技术时,法线贴图需要连接到 UVTriplanarNormalTransform
节点,以便正确变换法线。
UV
此选项仅使用标准 UV 坐标应用纹理,以便于与其他两种技术进行比较。
顶点动画
通常,我们认为着色器是用来改变像素的颜色和外观的。但着色器也可以应用于顶点,以改变网格的点位置。着色器可以操纵模型的顶点,从而创建各种动画效果,如本节所示。
旗帜动画
此示例展示了一种简单的方法,用于创建随风飘动的旗帜。效果的核心是Sine节点,生成起伏的波纹。我们使用顶点的X坐标乘以一个值来控制波长,并将其乘以时间,然后传入Sine节点。最后,将正弦波的结果与从旗杆固定点(0)到旗帜末端(1)的渐变遮罩相乘,最终效果是一个简单的飘动旗帜。
如果添加不同速度和波长的多个正弦波,可以增加细节和随机性。如果旗帜距离较远,此示例的效果可能已足够。
弯曲变形 - 草
此示例展示了如何将矩形条状物体弯曲成弧形,同时保持其长度不变。该方法可用于模拟草叶的动画。BendDeformer 子图对顶点的位置和法线进行调整,以确保更新后的形状有正确的光照效果。
Billboard
Billboard 示例展示了使平面面向相机的数学过程。Billboard 子图提供了初始朝向的选择。选择正确的朝向可确保平面正确转向相机,而不是其他方向。
Gerstner波
在该示例中,我们使用多个 GerstnerWave 子图实例来为网格添加波浪动画。GerstnerWave 子图进行单个波浪的运动计算。每个实例具有不同的方向、波长和波高。将这些不同的波浪组合在一起后,形成了逼真的波浪效果。将偏移值叠加后添加到位置,使用 Normal Blend 节点合并法线并直接作为法线使用。
粒子
此示例展示了如何仅使用 Shader Graph 创建简单的粒子系统。这种方法相对便宜,因为100%在GPU上运行,几乎所有着色工作都在顶点着色器中完成。虽然此方法不能替代团结引擎中的其他粒子系统,但展示了仅使用 Shader Graph 可实现的效果。对于简单的粒子效果,此方法可能比其他方法更便宜。不过,功能性不如使用 VFX Graph 的方法。
我们从一堆具有不同顶点颜色的平面开始,每个平面的颜色值作为ID区分平面。示例提供了3种平面堆叠方式,分别为25、50和100层。
Note
大多数粒子系统根据需要动态生成粒子,但我们使用的是静态几何体,因此粒子数固定。若效果需要更多粒子,只能更换网格,这是此方法的主要缺点之一。
使用 Billboard 子图让所有平面面向相机,并使用 Flipbook 节点为粒子添加动画效果。我们还增加了重力和风力,以控制粒子移动。在像素着色器中,提供了控制透明度的参数,并在粒子与其他场景几何体相交处淡化边缘。
以下是控制粒子外观和行为的材质参数说明:
发射器尺寸 - 控制粒子发射器在X、Y和Z轴上的尺寸。粒子将在此体积内随机生成。
Color
这是一个颜色值,用于与 FlipbookTexture 的颜色相乘。StartColor 会在粒子的生命周期内逐渐过渡到 EndColor。颜色的 alpha 值会与 FlipbookTexture 的 alpha 值相乘,从而影响粒子的透明度。
- StartColor - 粒子生命周期开始时的颜色倍增值
- EndColor - 粒子生命周期结束时的颜色倍增值
Opacity
这些属性控制粒子的透明度行为。
- Opacity - 粒子的整体透明度倍增值。值可以超过 1,以使细微粒子更明显。
- FadeInPower - 控制粒子淡入的渐变曲线。
- FadeOutPower - 控制粒子淡出的渐变曲线。
- SoftEdges - 启用柔和边缘效果,使粒子在与场景几何体相交时逐渐淡出。
- AlphaClipThreshold - 控制透明度的截断值,低于该值的像素会被舍弃不再绘制。值越高,舍弃的像素越多,有助于减少粒子的重叠绘制。
Scale
控制粒子的大小。粒子在生命周期内从 ParticleStartSize 逐渐过渡到 ParticleEndSize。
- ParticleStartSize - 粒子诞生时的大小(以米为单位)。
- ParticleEndSize - 粒子消亡时的大小(以米为单位)。
Movement
这些属性控制粒子的移动行为。
- ConstantFlow - 控制粒子流动的平滑度。值为 1 时,粒子流动在时间上均匀分布;值为 0 时,所有粒子会在阶段开始时同时生成;介于两者之间的值会使粒子生成速率更随机和不规则。
- ParticleSpeed - 控制粒子的整体移动速度。
- ParticleDirection - 粒子移动的主要方向。
- ParticleSpread - 粒子喷射锥的宽度(以度为单位),值为 0 表示单一方向喷射,值为 360 表示向所有方向喷射(形成球体)。
- ParticleVelocityStart - 粒子诞生时的初始速度。
- ParticleVelocityEnd - 粒子消亡时的速度。
Rotation
控制粒子的旋转行为。
- Rotation - 每个粒子静态旋转的角度值。
- RotationRandomOffset - 勾选后,为每个粒子应用一个随机的旋转量。
- RotationSpeed - 每个粒子的旋转速度。
- RandomizeRotationDirection - 启用后,每个粒子随机选择顺时针或逆时针旋转方向。
Flipbook
控制应用于粒子的动画纹理行为。
- FlipbookTexture - 应用于粒子的翻页纹理。
- FlipbookDimensions - 选择的翻页纹理的行和列数。
- FlipbookSpeed - 翻页动画的播放帧率。
- MatchParticlePhase - 启用后,翻页动画的第一帧会在粒子生成时播放,最后一帧会在粒子消亡前播放,使翻页动画的长度与粒子生命周期匹配。
Forces
控制影响粒子运动的外部力量。
- Gravity - 影响粒子的重力拉力。通常为 (0, -9.8, 0),但对于像烟雾或薄雾等轻质材料,可能会出现向上移动的效果,而非受重力向下拉动。
- Wind - 风的方向和强度。
Debug
这些选项用于调试粒子系统的特定部分。
- DebugTime - 启用后,允许使用 ManualTime 滑块手动调整时间前后滚动。
- ManualTime - 当 DebugTime 启用时,可以使用此滑块前后滚动时间,以查看粒子在生命周期不同点的表现。
条件
本节展示了两种方式来分支着色器逻辑。
基于渲染管线分支
Shader Graph 允许创建兼容多种渲染管线的着色器——内建管线(Built-In)、URP 和 HDRP。可以在 Shader Graph 中打开着色器,在图形设置的 Active Targets 部分添加希望支持的所有管线目标。
支持多种渲染管线时,有时需要根据所用的管线来调整图形逻辑。为此,可以在着色器中基于活动渲染管线进行分支。虽然 Shader Graph 中没有专门的分支节点,但可以通过创建包含 Custom Function 节点的子图来实现。
在此示例中,我们使用"基于渲染管线分支"来根据激活的渲染管线生成不同的结果。在示例中,我们仅改变立方体的颜色:URP 为绿色,HDRP 为蓝色,内建管线为黄色。不过,也可以使用此技术为每种渲染管线创建更复杂的特定操作。
基于材质质量分支
使用 Shader Graph,可以根据 GPU 处理能力创建多种方式来实现相同效果。此示例展示了将两张法线贴图相结合的三种不同方法。第一个方法(在图的顶部)使用 Normal Blend 节点的重新定向模式,是最精确的方法,效果最佳,但计算量最大。第二个方法(在中间)效果接近,但计算量稍低。第三个方法(在底部)计算量最低,效果也最差。
在图的右侧,三种不同方法连接到材质质量节点。可以在 Blackboard 中选择 Keyword->Material Quality 添加该节点,然后将 Material Quality 参数从 Blackboard 拖入图中。节点会根据选定的质量级别选择顶部、中间或底部部分的图形。
在 HDRP 中,质量设置由 HD Render Pipeline Asset 的材质部分中的 Default Material Quality Level 定义。为每个质量级别定义一个管线资产,并通过该资产控制着色器的质量级别。
在URP项目中,可以在用户界面选项选择时运行的脚本中使用 SetGlobalShaderKeywords 命令。例如,以下命令将材质质量设置为高:
MaterialQualityUtilities.SetGlobalShaderKeywords( MaterialQuality.High );
在 Shader Graph 中使用材质质量节点,使用户能够在应用程序中自定义体验。他们可以选择高质量视觉效果并牺牲帧率,或选择低质量视觉效果提高帧率,且具体效果控制在着色器中。