Unity ShaderGraph矩形节点:从SDF原理到高级遮罩与性能优化实战 📅 2026/7/24 15:50:10 1. 项目概述为什么矩形节点值得深挖在Unity的ShaderGraph世界里节点是构建视觉效果的基石。今天要聊的这个“矩形节点”Rectangle Node乍一看平平无奇不就是画个方框吗很多新手可能觉得用两个Step节点或者SmoothStep节点拼一下也能实现何必专门用一个节点。但在我实际开发材质和特效的这些年里这个看似简单的节点恰恰是构建UI遮罩、屏幕空间特效、风格化描边乃至复杂图案纹理的“瑞士军刀”。它的价值不在于功能有多复杂而在于其提供的数学纯粹性和性能优化潜力。当你需要高效、精确地生成一个轴对齐的矩形区域时手动拼接的节点网络在可读性和执行效率上往往不如一个原生的Rectangle节点。理解这个节点不仅仅是学会画一个矩形更是理解如何在Shader中高效地进行区域判断和遮罩处理。无论是制作一个简单的按钮高光还是构建一个复杂的网格背景矩形节点都能作为核心逻辑单元。接下来我会结合大量实战案例从原理、参数、到高级应用和避坑指南彻底拆解这个节点让你下次在ShaderGraph中遇到区域划分问题时能第一时间想到它并用得得心应手。2. 矩形节点的核心原理与参数拆解2.1 节点的数学本质符号距离场SDF要真正用好矩形节点不能停留在“输入宽高输出矩形”的层面必须理解其背后的数学原理符号距离场。简单来说SDF描述了一个点到某个形状边界的最短距离并在形状内部用负值表示外部用正值表示。矩形节点生成的正是一个轴对齐矩形的SDF。假设我们有一个中心在(0,0)宽度为Width高度为Height的矩形。对于空间中的任意一点UV通常我们使用UV坐标空间来讨论该节点内部的计算逻辑可以简化为以下核心步骤计算绝对偏移首先计算点UV到矩形中心默认为(0.5, 0.5)如果UV空间是[0,1]的话的偏移量并取绝对值。这步操作将第一象限的矩形扩展到了所有四个象限简化了判断逻辑。计算半宽高将输入的Width和Height乘以0.5得到半宽(halfWidth)和半高(halfHeight)。生成距离场矩形SDF的精髓在于取最大值操作。对于轴对齐矩形其SDF公式可以表示为distance max(abs(UV.x - centerX) - halfWidth, abs(UV.y - centerY) - halfHeight)这个公式计算的是点UV到矩形最近边的有符号距离。如果点在矩形内abs(UV.x - centerX) - halfWidth和abs(UV.y - centerY) - halfHeight这两个值至少有一个为负取最大值后结果即为负值点在内部。点在外部则为正值。注意ShaderGraph的矩形节点输出的是一个经过处理的“遮罩”值通常为0或1而不是原始的SDF距离值。它内部对上述SDF结果做了一个step(0, -distance)的操作。当distance 0点在内部时输出1否则输出0。理解这个底层SDF逻辑是进行高级混合和抗锯齿处理的关键。2.2 输入参数详解与实战意义矩形节点通常有四个输入端口每个都控制着矩形的关键属性UV这是最关键的输入决定了矩形在哪个坐标空间中被绘制。默认连接UV0意味着在模型自身的UV贴图空间绘制矩形。但它的威力在于灵活性连接Screen Position可以在屏幕空间画矩形用于制作全屏遮罩或扫描线效果。连接一个经过Tiling And Offset处理的UV可以生成重复的矩形网格图案。连接Position节点可以在世界空间或物体空间定义矩形区域用于实现基于位置的渐变或特效。Width宽度 Height高度定义了矩形的尺寸。这里有一个非常重要的细节这两个参数通常被解释为矩形的“整体宽度”和“整体高度”而不是半径。输入0.5意味着矩形将占据UV空间一半的范围。它们的值域理论上没有限制但通常与UV空间匹配如0到1。实战技巧如果你想绘制一个正方形不必同时调整两个参数。可以只连接Width然后将Height端口留空节点会自动使用Width的值作为Height非常方便。Position位置这个参数控制矩形的中心点。在默认的[0,1] UV空间中(0.5, 0.5)是中心。你可以通过动画或脚本来动态改变这个值让矩形移动。常见误区很多初学者会试图用Offset节点来移动矩形但其实直接修改Position参数才是正确且性能更优的方式。Position直接影响SDF计算的中心点。2.3 输出结果不仅仅是0和1矩形节点通常只有一个输出端口输出一个Float值。在绝大多数基础用法中你看到的是一个非0即1的二值化图像矩形内为1外为0。这个输出可以直接用作遮罩Mask与颜色或纹理相乘仅显示矩形内部部分。选择器Selector通过Lerp节点根据矩形内外选择两种不同的材质或颜色。然而正如前面原理部分提到的如果我们能访问其内部的SDF值将打开一扇新的大门。虽然ShaderGraph的默认节点不直接提供SDF但我们可以通过组合节点来“模拟”或利用其二值结果进行平滑处理。3. 核心应用场景与高阶技巧拆解3.1 场景一UI元素与屏幕空间特效制作这是矩形节点最直观的应用。假设我们要制作一个简单的按钮呼吸灯效果。基础实现创建一个Unlit Graph。添加Rectangle Node。UV连接Screen Position节点的XY输出需除以Screen节点的Width/Height进行归一化或直接使用Screen Position的Center模式。设置合适的Width,Height,Position来匹配屏幕上按钮的位置。矩形节点的输出连接至Color节点的Alpha或者与一个发光颜色相乘。高阶技巧动态边框与抗锯齿直接使用矩形节点输出的硬边在屏幕上会有锯齿。如何制作一个带平滑过渡的发光边框我们需要两个矩形节点一个(Rect_Inner)稍小一个(Rect_Outer)稍大。用Rect_Outer减去Rect_Inner得到一个环形的边框区域值为1。关键的一步抗锯齿。直接相减得到的边框依然是硬边。我们可以引入Smoothstep函数来软化边缘。// 假设borderWidth是想要的边框宽度UV空间值 float borderMask smoothstep(0, borderWidth, outerRect - innerRect);但更优雅的方式是利用SDF思想。虽然不能直接拿到SDF但我们可以通过比例计算来模拟将两个矩形的Width/Height设置成有微小差值其差值区域就是边框。通过计算当前UV点到两个矩形边缘的“相对距离”再用Smoothstep处理就能得到平滑的边框遮罩。这比单纯缩放UV再相减的效果要精确得多。3.2 场景二程序化纹理与图案生成矩形节点是构建复杂程序化纹理的完美积木。例如创建一个棋盘格纹理。传统做法使用Fraction和Step节点对UV进行取整和判断。矩形节点做法使用Tiling And Offset节点对UV进行平铺例如将Tiling设置为(8,8)。将平铺后的UV输入一个Fraction节点得到每个格子内独立的[0,1] UV。将这个UV输入矩形节点并设置Width和Height为0.5Position为(0.25, 0.25)。这样会在每个格子的左上角四分之一区域绘制一个矩形。复制上述流程但将Position改为(0.75, 0.75)绘制右下角的矩形。将两个矩形节点的输出相加就得到了一个散布的圆点棋盘格图案。通过调整矩形尺寸和位置可以轻松创造出千变万化的网格图案。优势分析这种方法比纯数学判断更直观易于调整单个“图元”矩形的形态。你可以轻易地将矩形替换成其他形状节点如圆形、多边形快速迭代不同的设计风格。3.3 场景三基于距离的复杂遮罩与混合这是体现矩形节点SDF本质优势的场景。假设我们要制作一个“窗体逐渐显现”的效果窗体边缘有平滑的淡入淡出。构建基础矩形用矩形节点定义窗体的基本形状。模拟SDF进行平滑我们无法直接拿到SDF但可以巧妙地利用Width和Height。我们可以将矩形的Width和Height通过一个Lerp节点从0动画到目标值。在动画过程中矩形区域是逐渐变大的。此时矩形节点边缘的过渡是生硬的。实现平滑边缘要实现平滑我们需要一个“软边界”。一个实用的技巧是先正常计算矩形遮罩硬边。然后计算当前UV点到矩形四边的距离。这需要一些计算dX abs(UV.x - centerX) - halfWidth;dY abs(UV.y - centerY) - halfHeight。这其实就是我们之前提到的SDF计算的一部分。取max(dX, dY)得到近似的“到矩形最近边的有符号距离”这是一个简化对于矩形角点不精确但用于边缘过渡足够。对这个距离值使用smoothstep(-feather, feather, -distance)其中feather是羽化范围。这样就能得到一个从内到外平滑过渡的遮罩。实操心得在性能允许的情况下这种基于距离的混合方式比使用Blur节点高效得多且效果更可控。它让矩形节点从一个简单的二值工具升级为一个可用于高级溶解、渐变映射和变形效果的基础构件。4. 性能优化与常见问题排查4.1 性能考量节点开销与替代方案矩形节点本身的ALU算术逻辑单元指令开销很低主要就是几次加减法、取绝对值和最大值比较。在绝大多数情况下它的性能不是瓶颈。真正的性能考量在于你如何使用它过度平铺与重复计算如果你为了生成一个密集的网格使用了极高的平铺倍数比如100x100然后每个格子都进行矩形判断这会导致像素着色器指令数暴增。在这种情况下考虑使用更高效的方法比如利用UV的Fraction和Step生成规律图案或者使用一张小的纹理进行平铺。屏幕空间使用的精度在Screen Position空间使用矩形节点时注意Width和Height的值是相对于屏幕比例0-1的。如果你需要像素精度的矩形比如精确匹配一个UI元素可能需要将像素尺寸转换为归一化的UV尺寸这涉及一次除法运算。对于移动平台如果每帧都需要计算可以考虑在CPU端算好传给Shader。与Blur节点的联用这是最常见的性能陷阱。为了软化矩形边缘很多人会直接将矩形节点的输出丢给一个Blur节点。Blur节点尤其是高斯模糊开销巨大因为它意味着每个像素需要采样周围多个像素。优先使用前面提到的基于Smoothstep的模拟SDF方法来实现边缘羽化这几乎零成本。4.2 常见问题与解决方案实录下面是我在项目中遇到的一些典型问题及解决方法整理成了速查表问题现象可能原因解决方案矩形显示不出来或位置不对1.UV输入错误。默认是模型UV如果模型UV拉伸或模型不在视野内矩形不可见。2.Position坐标空间误解。在屏幕空间使用时原点可能在左下角或中心。1. 检查模型和材质。尝试将UV端口连接到Position节点的Object或World输出看看矩形是否出现在物体上。2. 在屏幕空间使用时使用Screen Position节点的Default模式输出范围[0,1]原点左下角并据此计算Position。使用Center模式输出范围[-1,1]原点中心则需调整计算。矩形边缘有锯齿Aliasing这是二值遮罩在屏幕像素上的固有现象当矩形边界不与像素网格对齐时发生。1.抗锯齿主流方法不要直接使用矩形输出而是用Smoothstep创建平滑过渡。例如float softRect smoothstep(0, 0.02, rectOutput);这里的0.02是过渡宽度。2.超级采样SSAA在质量设置中开启性能开销大不推荐实时使用。3.确保像素对齐对于UI矩形计算其Position时确保其坐标是像素尺寸的整数倍可以减轻锯齿。矩形在物体表面拉伸变形UV输入使用了模型UV而该模型的UV被意外拉伸或扭曲。1. 检查3D模型的UV展开是否正确。2. 考虑切换坐标空间。如果不希望效果随UV变形改用Object或World空间的Position作为UV输入。注意这需要根据物体尺寸重新调整矩形的Width和Height。动画矩形时边缘闪烁或抖动1.Position或Width/Height动画变化步长过大。2. 在屏幕空间动画时没有考虑分辨率变化。1. 确保动画插值是平滑的如使用Lerp并保证足够高的帧率。2. 对于屏幕空间矩形将其尺寸和位置定义为基于屏幕分辨率Screen节点的计算结果而不是固定UV值这样在不同分辨率下表现一致。想要一个圆角矩形矩形节点本身只能生成直角矩形。需要组合节点实现1. 用矩形节点生成基础形状。2. 用四个圆形节点或一个Ellipse节点配合UV变换生成四个角部的遮罩。3. 通过Maximum操作合并矩形和圆形遮罩SDF的并集操作。更精确的方法是使用圆角矩形的SDF公式这需要在Custom Function Node中写少量代码但效果和性能最好。公式核心是计算到矩形直角区域的向量然后减去圆角半径最后取长度。4.3 调试技巧可视化中间数据当矩形效果不符合预期时学会调试至关重要颜色可视化法将矩形节点的输出直接连接到主颜色的RGB通道你会看到一个黑白图像。白色值1是矩形内部黑色值0是外部。这是最直接的查看方式。分离检查UV将连接到矩形节点UV端口的向量如Screen Position的R和G分量分别连接到颜色的R和G通道。这样你可以看到UV坐标在屏幕上的分布是否如你所想通常是一个从左到右、从下到上的红绿渐变。检查参数范围如果你用脚本动态传值给Width或Position在ShaderGraph中可以使用Divide节点除以一个较大的数或者用Clamp节点限制范围然后将结果可视化确保传入的值在合理的[0,1]区间内没有异常值。矩形节点是ShaderGraph中一个典型的功能单一但潜力巨大的节点。它教会我们一个道理在着色器编程中越是基础的数学构建块组合起来越能产生惊人的创造力。掌握它不仅仅是掌握一个画方框的工具更是掌握了一种在像素级别进行空间逻辑判断和区域划分的思维方式。下次当你需要在Shader中定义一块区域时不妨先想想“这里用矩形节点会不会更干净、更高效”