Unity TMP_SDF 分析(九)UNITY_UI_CLIP_RECT 与 UNITY_UI_ALPHACLIP Unity TMP_SDF 分析九UNITY_UI_CLIP_RECT与UNITY_UI_ALPHACLIP适用版本Unity2021.3.23f1c1TextMeshPro3.0.9UGUI1.0.0分析范围项目中的标准Assets/TextMesh Pro/Shaders/TMP_SDF.shader及其关联源码Mobile、SSD、Surface 等变体不直接套用。系列导航第 9/9 篇前置BEVEL_ON法线、光照与反射下一篇无本文讨论 UGUI 裁剪路径SpriteMask 属于 SpriteRenderer 体系。标准 TMP SDF Shader 编译了两组独立的 UI 变体#pragma multi_compile __ UNITY_UI_CLIP_RECT #pragma multi_compile __ UNITY_UI_ALPHACLIPUNITY_UI_CLIP_RECT根据矩形和 Softness 乘低最终颜色主要服务于RectMask2D。UNITY_UI_ALPHACLIP对当前faceColor.a执行一个很低阈值的clip()主要用于需要按 Alpha 写入模板的 Mask 材质。RectMask2D、Mask 和 SpriteMask 分别使用矩形裁剪、模板缓冲与 SpriteRenderer 遮罩路径。一、UNITY_UI_CLIP_RECT如何启用RectMask2D会把裁剪矩形和 Softness 分发给所有IClippable/MaskableGraphic目标。UGUI 1.0.0 中可看到publicvirtualvoidSetClipRect(RectclipRect,boolvalidRect){if(validRect)canvasRenderer.EnableRectClipping(clipRect);elsecanvasRenderer.DisableRectClipping();}publicvirtualvoidSetClipSoftness(Vector2clipSoftness){canvasRenderer.clippingSoftnessclipSoftness;}CanvasRenderer 的 Rect Clipping 路径负责向 Shader 提供_ClipRect、_MaskSoftnessX/Y并选择矩形裁剪变体。常见场景包括 Scroll View、聊天窗口和任何矩形可视区域。RectMask2D 通过 Shader 数学公式完成每像素矩形判断。二、UNITY_UI_ALPHACLIP与 Mask 的准确关系UGUIStencilMaterial.Add()创建模板材质时使用useAlphaClipoperation!StencilOp.KeepwriteMask0;if(useAlphaClip)customMat.EnableKeyword(UNITY_UI_ALPHACLIP);elsecustomMat.DisableKeyword(UNITY_UI_ALPHACLIP);这意味着 Alpha Clip 主要在“向模板缓冲写入形状”的 Mask 材质上启用Mask 图形本身通常使用StencilOp.Replace或清除操作并具有写入掩码因此需要依据图形 Alpha 决定哪些片元真正写入模板。被 Mask 裁剪的普通子 Graphic 通常使用StencilOp.Keep进行模板测试其 Alpha Clip 关键字保持关闭。被 Mask 裁剪的普通子 Graphic 通常只执行模板测试Alpha Clip 主要作用于写入模板的 Mask Graphic 材质。如果 TextMeshProUGUI 自身作为 Mask 的图形或代码显式为其材质启用该关键字TMP Shader 中的 Alpha Clip 变体才会直接作用于该文本片元。标准TMP_SDF.shader通过材质关键字选择 Alpha Clip 变体Shader Properties 中未声明可见的_UseUIAlphaClip开关。三、两套机制对照项目UNITY_UI_CLIP_RECTUNITY_UI_ALPHACLIP典型来源RectMask2D/ CanvasRenderer Rect Clipping模板写入材质或代码显式启用关键字输入_ClipRect、_MaskSoftnessX/Y、input.mask当前faceColor.a操作计算 X/Y 可见度并乘 RGBAclip(faceColor.a - 0.001)是否支持 Softness是否仅有固定极低阈值是否依赖 StencilRect Clipping 本身不依赖常用于 UGUI Mask 的模板写入材质是否把幸存片元变为不透明否否四、顶点着色器准备output.maskfloat2 pixelSize vPosition.w; pixelSize / float2(_ScaleX, _ScaleY) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy)); float4 clampedRect clamp(_ClipRect, -2e10, 2e10); float2 maskUV (vert.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.mask half4( vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_MaskSoftnessX, _MaskSoftnessY) pixelSize.xy));当前 Shader 中maskUV变量后续没有被使用编译器通常会把它删除。真正传入片元阶段的是output.mask。五、_ClipRect的坐标与来源Shader Property 默认值为_ClipRect (Clip Rect, vector) (-32767, -32767, 32767, 32767)RectMask2D 生效时CanvasRenderer 会提供实际裁剪矩形_ClipRect (minX, minY, maxX, maxY)vert.xy是应用_VertexOffsetX/Y后、投影之前的文本顶点坐标。CanvasRenderer 会在兼容坐标空间中提供_ClipRect。普通 UGUIMask主要传递模板参数不负责为子对象生成_ClipRect_ClipRect的典型来源是 RectMask2D 的 Rect Clipping。六、为什么 Clamp_ClipRectfloat4 clampedRect clamp(_ClipRect, -2e10, 2e10);它把每个有限分量限制在很大的安全区间内避免默认“无限矩形”或外部传入的极端有限值在后续加减法中造成更严重的溢出和低精度问题。数值行为如下clamp()可以限制正负极大的有限值。NaN在许多 GPU 上经过 min/max 后仍可能继续传播。因此该表达式主要提供有限范围保护。七、output.mask.xy的数学含义mask.xy vert.xy * 2 - clampedRect.xy - clampedRect.zw;设rectMin (left, bottom) rectMax (right, top) center (rectMin rectMax) / 2则mask.xy 2 × (vert.xy - center)所以矩形中心为(0,0)。左下边界为(-width, -height)。右上边界为(width, height)。它的幅度携带矩形宽高尺度左右边界分别为-width/width上下边界分别为-height/height。片元着色器会对顶点输出做线性插值因此每个片元得到对应位置相对于矩形中心的坐标。八、output.mask.zw软裁剪斜率mask.zw 0.25 / (0.25 * softness pixelSize.xy);其中softness (_MaskSoftnessX, _MaskSoftnessY)通常来自 RectMask2D 的 Softness。pixelSize.xy是第三篇推导的“一个屏幕像素对应的局部尺度估计”。Softness 增大时分母增大mask.zw变小片元阶段的可见度斜率变缓屏幕像素在局部空间中变大时也会相应放宽抗锯齿过渡。pixelSize项还避免 Softness 为零时直接除以零并提供与屏幕采样尺度相关的基础过渡最终宽度还包含片元阶段双倍中心坐标带来的系数。九、片元阶段的矩形可见度#if UNITY_UI_CLIP_RECT half2 m saturate( (_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * input.mask.zw); faceColor * m.x * m.y; #endif设矩形尺寸size _ClipRect.zw - _ClipRect.xy因为input.mask.xy 2 × (position - center)所以在矩形内部size - abs(mask.xy) 2 × 当前点到对应轴最近边界的有符号距离边界处结果为0。内部为正。外部为负。乘mask.zw后再saturate()每个轴得到01的可见度。X/Y 为什么相乘faceColor * m.x * m.y;只有同时位于 X 和 Y 有效区间时结果才可见任一轴完全在外乘积为0。矩形内部远离边缘乘积接近1。靠近边缘时单轴渐变。靠近角落时两个小于1的值相乘形成二维柔化。该操作乘的是整个 RGBA不只是 Alpha因此能保持预乘 Alpha 颜色关系。十、Softness 与 Pixel Size 的等价过渡宽度以单轴为例令点到最近矩形边界的内部距离为dEdge则size - abs(mask) 2 × dEdge代入公式m saturate( 2 × dEdge × 0.25 / (0.25 × softness pixelSize)) saturate( dEdge / (0.5 × softness 2 × pixelSize))这个推导说明过渡宽度同时包含约0.5 × Softness的局部尺度项。约2 × pixelSize的基础屏幕采样项。实际视觉宽度还会受插值精度、Canvas 缩放、投影和平台 half 精度影响该公式给出的是等价尺度关系。十一、UNITY_UI_ALPHACLIP的真实行为#if UNITY_UI_ALPHACLIP clip(faceColor.a - 0.001); #endifclip(x)仅在x 0时丢弃因此faceColor.a 0.001 → 丢弃 faceColor.a 0.001 → 保留恰好等于0.001时传入clip()的值为0不会因该指令被丢弃。幸存片元保留原 Alpha若faceColor.a 0.2片元会被保留Alpha 仍然是0.2。因此幸存片元保持原有的半透明 Alpha。0.001是非常低的阈值绝大多数正常抗锯齿半透明像素都会保留。主要作用是丢弃几乎完全透明的片元使模板写入或后续缓冲写入更准确。执行时机在标准TMP_SDF.shader中它发生在Face/Outline 已生成之后。Bevel、Underlay、Glow 已处理之后。UNITY_UI_CLIP_RECT已乘入之后。最终input.color.a尚未乘入之前。Alpha Clip 检查faceColor.a顶点 Alpha 在后续return faceColor * input.color.a时应用。Glow 只增加faceColor.rgb不增加faceColor.a所以开启 Alpha Clip 时纯 Glow 外围可能因基础 Alpha 低于阈值而被丢弃。十二、Mask、RectMask2D 与 SpriteMask组件/机制适用渲染体系TMP UGUI 中的主要路径RectMask2DUGUICanvasRenderer Rect Clipping UNITY_UI_CLIP_RECTMaskUGUIStencil 写入/测试写入材质可能启用UNITY_UI_ALPHACLIPSpriteMaskSpriteRendererSprite Masking 路径Mask 的不规则形状来自 Mask Graphic 向模板缓冲写入的覆盖区域被裁剪的 TMP 子对象随后进行模板测试。SpriteMask 则服务于 SpriteRenderer。十三、最终数据流RectMask2D ├─ SetClipRect() → CanvasRenderer.EnableRectClipping() └─ SetClipSoftness() → CanvasRenderer.clippingSoftness │ ▼ _ClipRect _MaskSoftnessX/Y │ ▼ VertShaderoutput.mask │ ▼ PixShaderm.x × m.y × faceColor UGUI Mask 的模板写入材质 └─ StencilMaterialoperation ! Keep 且 writeMask 0 │ ▼ EnableKeyword(UNITY_UI_ALPHACLIP) │ ▼ clip(faceColor.a - 0.001)十四、源码索引Assets/TextMesh Pro/Shaders/TMP_SDF.shaderoutput.mask、矩形裁剪和 Alpha Clip。Library/PackageCache/com.unity.ugui1.0.0/Runtime/UI/Core/RectMask2D.cs裁剪矩形与 Softness 分发。Library/PackageCache/com.unity.ugui1.0.0/Runtime/UI/Core/MaskableGraphic.csEnableRectClipping()与clippingSoftness。Library/PackageCache/com.unity.ugui1.0.0/Runtime/UI/Core/Mask.cs模板写入材质。Library/PackageCache/com.unity.ugui1.0.0/Runtime/UI/Core/StencilMaterial.csUNITY_UI_ALPHACLIP启用条件。

相关新闻

最新新闻

BiliTools快速上手指南:3分钟搞定B站视频一键下载的跨平台免费工具箱

BiliTools快速上手指南:3分钟搞定B站视频一键下载的跨平台免费工具箱

BiliTools快速上手指南:3分钟搞定B站视频一键下载的跨平台免费工具箱 【免费下载链接】BiliTools 本项目已停止维护。 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools 上个月整理素材时,我想把一套B站公开课保存到本地慢慢啃。试…

2026/8/15 19:43:16
git-sync配置文件详解:从backup_dir到concurrency,打造个性化备份方案

git-sync配置文件详解:从backup_dir到concurrency,打造个性化备份方案

git-sync配置文件详解:从backup_dir到concurrency,打造个性化备份方案 【免费下载链接】git-sync 🔄 A simple tool to backup and sync your git repositories 项目地址: https://gitcode.com/gh_mirrors/gitsync1/git-sync git-sync…

2026/8/15 19:43:16
免费AI视频增强工具实测:我把十年前的模糊录像修复成了4K

免费AI视频增强工具实测:我把十年前的模糊录像修复成了4K

免费AI视频增强工具实测:我把十年前的模糊录像修复成了4K 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/vi…

2026/8/15 19:43:16
Bug处理流程

Bug处理流程

文章目录一. 简介二. 角色与职责分工三. Bug 处理流程1. 提交缺陷2. 指派缺陷3. 确认缺陷4. 推迟处理5. 处理缺陷6. 回归缺陷7. 关闭缺陷四. Bug 处理意见五. Bug 报告1. Bug 报告模版2. Bug 报告要素一. 简介 Bug 处理流程包含了从测试人员提交 Bug 到最终解决问题的一系列步骤…

2026/8/15 19:43:16
5 步玩转 Honey Select 2 终极汉化去码补丁:HS2-HF_Patch 完整上手指南

5 步玩转 Honey Select 2 终极汉化去码补丁:HS2-HF_Patch 完整上手指南

5 步玩转 Honey Select 2 终极汉化去码补丁:HS2-HF_Patch 完整上手指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 玩 Honey Select 2 的你&…

2026/8/15 19:43:16
还在为游戏服务器难上手发愁?10分钟跑通Skynet游戏框架从安装到首行日志

还在为游戏服务器难上手发愁?10分钟跑通Skynet游戏框架从安装到首行日志

还在为游戏服务器难上手发愁?10分钟跑通Skynet游戏框架从安装到首行日志 【免费下载链接】skynet A lightweight online game framework 项目地址: https://gitcode.com/GitHub_Trending/sk/skynet 你是不是也遇到过这样的场景:想搭一个游戏服务器…

2026/8/15 19:38:16