SpriteOutline
Outline是让物体在游戏中“脱颖而出”的一种非常流行的方法。
本次分享,我们将使用SpriteRenderer并使用Shader Graph为Sprite添加外轮廓。
原理
以不同的UV坐标对纹理进行多次采样,并根据这些采样的alpha值确定应该绘制轮廓还是正常纹理。
准备工作
导入我们希望应用Outline Shader的Sprite,Sprite周围需要有透明的边框。导入后在Inspector窗口中设置Texture Type为Sprite(2D和UI),设置Mesh Type为Full Rect。
![]()
使用Full Rect的原因是Unity默认会尝试缩小精Sprite Mesh的大小以优化项目。我们想要额外的空间,绘制轮廓的地方。
实现步骤
创建一个Sprite着色器
- 通过菜单Create | Shader | Universal Render Pipeline | Sprite Lit Shader Graph创建一个新的Shader Graph命名为 SpriteOutlineGraph。
![]()
通过菜单Create | Material 创建一个新材质 SpriteOutlineMat,并将材质的Shader设置为 Shader Graphs/SpriteOutlineGraph。
将我们之前导入的Sprite拖入场景,并将上一步创建的材质SpriteOutlineMat拖拽到Sprite对象上。
Sprite会显示为灰色,别着急我们马上让它恢复原样。
![]()
- 首先,我们把我们的纹理添加回Sprite。为此,我们将对主纹理进行采样。从Blackboard上,单击+按钮并选择Texture 2D,为其命名为Main Texture。打开Graph Inspector并将引用值更改为_MainTex。右键单击Main Preview并选择Quad,以便更轻松地查看着色器将如何工作。
![]()
- 将属性Main Texture拖放到Graph上。右键单击主纹理节点右侧,选择创建节点,选择Input | Texture | Sample Texture 2D。将 Main Texture (T2) 输出连接到Sample Texture 2D节点的Texture (T2)输入。
- 此时,我们可以将RGBA连接到Base Color,将A连接到Fragment节点上的Alpha通道,我们将拥有一个与普通着色器完全相同的Sprite着色器。
![]()
创建Outline着色器
我们需要一些额外的步骤来实现Outline,首先先断开之前Base Color和Alpha通道的链接。
我们希望原始纹理保持不变,为此我们将创建Main Texture和Sample Texture 2D节点的副本。我们可以通过鼠标拖动框选两个节点。选中后,按Ctrl+C,然后按Ctrl+V。将复制的节点移动到已创建的节点下方。
![]()
- 在新创建的Sample Texture 2D节点上,单击并从 UV (2)输入拖动到左侧,然后创建一个Tiling and Offset节点,并将Offset的X值设置为0.1。
- 在两Sample Texture 2D节点的右侧,创建一个Subtract 节点,将设置了Offset的 Sample Texture 2D的A连接到减法节点的A输入,将原始Sample Texture 2D的A连接到B输入。
![]()
- 为了把X和Y属性设置为我们想要使用的偏移量,在Tiling and Offset节点的偏移量输入的左侧,创建一个Vector 2节点,并将两个值为½ 的divide 节点作为Vector 2节点的输入。可以看到在X和Y方向上精灵移动了50%。
![]()
- 在Divide节点的左侧添加一个Texel Size节点,并将Main Texture变量连接到Texel Size节点的Texture输入。将Texel Size节点的Width输出连入X offset Divide节点的B输入中,将Texel Size节点的Height连入Y Offset节点的B输入中。 这样就可以按照像素对X,Y方向做偏移了。
![]()
- 单击并拖动Subtract 节点的输出并创建一个Multiply 节点。在Multiply 节点的左侧,通过空格创建一种颜色,然后选择 Input | Basic | Color。为了易于查看的使用了红色,确保Alpha设置为255。
![]()
- 我们希望在四个方向中的每一个方向都重复这种效果。为了使这更容易,我们需要创建一个Sub-graph。一次选择到目前为止已经创建的所有节点,然后右键单击并选择Convert To | Sub-graph。命名为GetEdgeGraph。
GetEdgeGraph Sub-Graph
- 双击打开GetEdgeGraph节点。我们将看到一个名为Output的节点。选择它,然后在Graph Inspector中的Inputs部分下,单击+图标并将新参数重命名为Edge并设置Vector4的类型。将Multiply 节点输出连接到刚刚创建的Edge输入。
![]()
- 接下来我使用参数来调整方向和厚度。为此,在Blackboard并单击+按钮并创建一个名为Direction的Vector2属性和一个名为Thickness的Float属性。在Graph Inspector窗口中,为Direction设置默认值(1,0)并将Thickness的默认值设置为5。
- 将Direction拖到Divide 节点的左侧。在它的右侧,创建一个Multiply 节点,然后将Direction和Thickness作为输入连接。拖拽Multiply 节点的输出,创建一个Split 节点。将R连接到X除法的A,将G连接到Y除法的A。
![]()
- 最后,右键单击Color 节点并选择Convert To | Property。重命名属性为Outline Color。
- 单击Save Asset按钮,然后返回SpriteOutlineGraph。
![]()
完成Outline着色器
现在GetEdgeGraph可以像其他节点一样工作,我们可以通过复制和粘贴轻松多次调用它。
在Blackboard窗口,点击+按钮,创建一个名为Outline Thickness的Float属性和一个名为Outline Color的Color属性。将Outline Thickness的默认值设置为5,将Outline Color设置为完全不透明的红色。
- 将这两个属性拖到Graph中,然后将它们连入GetEdgeGraph的输入。
![]()
- 我们现在将节点选中复制三次,并分别将Direction 设置为(-1,0)、(0,-1)和(0,1)。然后,创建一个Add节点将前两条边连接在一起,然后为第三条和第四条边创建一个Add节点。
- 然后添加一个Add节点,将两个Add节点连接在一起。
![]()
- 在组合的Add节点的末尾,创建一个Saturate 节点,并将Add节点的Out连接到Saturate 节点的In。
- 现在我们有了四个边,但是我们需要将效果添加到原始Sprite中。为此,为此我们还需创建另一个具有Main Texture的Sample Texture 2D节点。
![]()
- 从Saturate 节点的输出拖拽创建一个Add:(B) 节点,并将Main Texture的Sapmle RGBA连入A。
![]()
- 我们现在可以将Out结果连接到Fragment节点的Base Color属性,但alpha无法连接。为此,在Add节点的Out右侧,创建一个Split节点。将Split节点的A连接到Fragment节点上的Alpha。
![]()
- 点击Save Asset按钮,点击Play就可以看到最终效果。