TextMeshPro 文本和 UGUI 的视觉表现差异(Hack solution)

见图片,上部为在 Unity 编辑器内的样子,左侧为从 FairlyGUI 导出的控件,右侧是 TextMeshProUGUI 呈现的效果。行间距以外的文本设置相同(黑体,大小22,基础颜色 #333333)
 
编辑器版本 2022.3.13,渲染管线使用 URP,Stage Camera 关闭了后处理效果,颜色空间使用 Gamma。
 
富文本在 FairyGUI 编辑器内的呈现效果和 Unity 内一致,但视觉效果(边缘锐利程度、整体颜色、颜色随距离场渐变等)上富文本和 TextMeshProUGUI  差异很大。FairyGUI-TMP.shader 内的实现和 TMP_SDF.shader 几乎一致,差异仅仅是适应 FairyGUI 自身的剪裁方式。
 
FairyGUI 的富文本和 TextMeshProUGUI 的这种呈现效果差异让我认为 FairyGUI 还没有准备好在生产环境使用 TextMeshPro。到底是什么导致了这种显示差异?从哪里着手可以让它们的最终效果看起来一致?

0204-TextMeshPro对比.png

========
 
事情变得诡异起来了:在场景视图里近距离观察,FairyGUI 的富文本框呈现的文字总是具有锐利的边缘,但是稍稍拉开距离,边缘就会模糊。
 
我使用了一个脏的办法修复:修改 StageCamera::DefaultCameraSize 为 3(原先是5),现在 FairyGUI 的呈现效果和 UGUI(TextMeshPro) 大体一致了。
 
尽管我还是不知道背后到底发生了什么。
 
========
 
设置 StageCamera::DefaultCameraSize 的值(配合 StageCamera::constantSize 为真)会引发另一个问题:屏幕高度变化时应用了 TextMeshPro 的文本框采样清晰度会发生变化,这不是我想要的。
 
在配置了 TextMeshPro 的情形,将 StageCamera::constantSize 置为假,并修改 StageCamera::DefaultUnitsPerPixel 为 0.11,获得了较好的视觉效果(和 UGUI 接近)。
 
FairyGUI 编辑器也有类似的问题:窗口化编辑器,改变窗口高度,编辑器内使用 SDFAA 采样的字体的呈现效果会发生变化。 
 
=========
 
StageCamera::DefaultUnitsPerPixel 越小,SDF字体看起来越锐利(更好的经验值是 0.005)。我还是不知道引擎盖的背后发生了什么。
 
对需要在运行期更改分辨率的应用,StageCamera::constantSize 为假时调整窗体尺寸可能使文字的采样情况发生变化(可能因为 stage camera 重计算位置之类),具体来说是屏幕尺寸不同时文字的某个笔画可能恰好在显示器的像素点上(看起来较亮),或者在两个像素之间(看起来较暗)。
 
这种现象和是否使用 TextMeshPro 的 SDFAA_HINTED 采样无关。
 
基于 MeshRenderer 的呈现方式好像没有很好的方法实现像素级别的校正?

20240206-TextMeshPro对比.png

(留意上下两张图左侧部分文字的亮度差异)
 
========
 
更新的解决方式,也不用调 StageCamera::constantSize 了,倒不如说让这个值一直是真就可以。
 
比对了一下 FGUI 的 UIPanel 和 UGUI 的画布,在屏幕调整分辨率时它们的缩放比都会跟着变,但唯独 FGUI 的使用距离场材质的文本会有视觉效果变化的问题。
 
所以干脆去调整着色器。
 
找到 FairyGUI/TextMeshPro/Distance Field,编辑它。

VertShader 函数里声明 float2 pixelSize 的地方,既然视觉效果的变异和屏幕高度有关:
float2 pixelSize = vPosition.w;
pixelSize /= float2(_ScaleX, _ScaleY) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
pixelSize *= _ScreenParams.y / 1200;

原理上的事情查不动了,再有问题再说……
已邀请:

谷主

赞同来自:

我在之前的测试都没有发现这种差异。你提供的信息确实很多,我需要在新版本unity下重新测试一下demo看是否有问题再行答复。

要回复问题请先登录注册