前言

在笔者的上一篇文章中,有一条很有意思的评论:

macOS 的 HiDPI 模式是不是跟 SSAA 异曲同工?

顺着这个问题,结合多年的折腾经验以及一些图形学方面的专业基础,笔者在这篇文章中试图用清晰易懂的语言讲清楚 HiDPI 究竟是什么。

我派站内也有不少关于如何开启 HiDPI 的文章,若你有实践方面的需求,不妨参考下述文章:

从分辨率说起

你可能早已对「分辨率」这个名词习以为常。但实际上,分辨率远远不是那几个数值那么简单,HiDPI 原理的核心其实就是在分辨率上做文章。

物理分辨率

物理分辨率便是我们认知范围内经常出现的「分辨率」,它代表着一个显示器上有多少个物理像素点。

macOS 中「系统信息」展示了该显示器的分辨率

逻辑分辨率

如果你仔细看过 macOS 的「设置」中显示器分辨率的选项,你应该会感到有些奇怪:为什么我的 MacBook 显示器分辨率那么低,甚至连常见的 1080p 都没达到?

而上图「系统信息」中却显示了这块显示器的实际分辨率为 3024 × 1964,究竟哪个数值是准确的?

为了解决这个疑问,我们得回到 2012 年的 WWDC。

High Resolution In OS X

Retina

这一年,Apple 发布了配备 Retina(视网膜)显示屏的全新 MacBook Pro,这也是 MacBook 系列显示效果领跑行业的开端。

彼时的 Apple 官网

全新 MacBook Pro 的 Retina 显示屏是一款具有超高分辨率的笔记本电脑显示屏,像素数量达到惊人的 500 万,比 HD 高清电视还要多 300 万像素。每英寸 220 个像素的超高像素密度超过了人眼所能分辨的范围,在正常观看距离内,单个像素的颗粒感似乎已然消失。因此屏幕表现才会如此栩栩如生,呈现的文字和图形才会如此锐利和真实。

从直觉上来看,提高分辨率自然是好事:像素越多,画面越清晰。这对于图像、视频与游戏画面等的显示提升是显而易见的。

但对于操作系统来说,事情并没有那么简单。系统元素(如字体、矢量图标等)的渲染与图片不同。在传统显示器时代,应用程序 UI 设计往往直接使用 Pixel(像素)作为界面布局单位。一个按钮宽 100 像素,一个图标高 32 像素,字体也按照固定的像素数量进行绘制。

然而,当显示器的像素密度不断提升时,问题出现了。

假设同样尺寸的两块显示器,其中一块拥有另一块显示器成倍的像素数量,屏幕上的每一个像素都会变得更小。如果界面仍然按照原来的像素数量进行布局,那么原本宽度为 100 像素的按钮,其实际显示尺寸也会随之缩小。

下图可以清晰地说明这一概念。在高分辨率的显示器中,如果还按照原来的模式渲染输出画面,我们将难以看清其中的元素。

同一画面下 macOS设置不同逻辑分辨率的对比

在 Retina 显示屏出现前,大多数 macOS 开发者习惯了以 Pixel(像素)作为界面设计与布局的基本单位。窗口大小、按钮位置、图标尺寸与绘制图形时的坐标等,往往都直接使用像素进行描述。

「All coordinates are in points」

图源:Apple

在 WWDC 2012 的 Session 213 演讲中,Apple 提出了一套新的设计思路:Unified Coordinate System(统一坐标系统)。

图源:Apple

在这套体系下,应用程序不再直接与 Pixel(像素)打交道,而是使用一种名为 Point(点)1的逻辑单位。

Apple 采用了一个看似简单却影响深远的设计:在配备 Retina 显示屏的 MacBook 上,一个逻辑上的 Point,由原来的对应单个物理像素转换为了由四个物理像素共同表示。

对于开发者而言,一个按钮、一个窗口依然可以是固定数值的大小,只是表示的单位换了。至于这些 Point 最终应该如何映射到实际屏幕上的 Pixel,则完全交给系统处理。

图源:Apple

假设一个窗口的逻辑尺寸为 1920 × 1080 Points,在传统显示器上,系统需要绘制 1920 × 1080 Pixels。而在 Retina 显示器上,同样大小的窗口实际上会被渲染为:3840 × 2160。

经过处理后,应用程序的界面尺寸完全没有发生变化;但从用户的角度来看,由于系统拥有更多像素来描述同样的内容,因此文字边缘更加平滑,图标细节更加丰富,整体画面也更加锐利。

图源:Apple

而在 Apple 的设计中,Retina 显示屏增加的是 Pixel 的数量,而不是 Point 的数量。逻辑空间保持不变,显示精度则提升了四倍。这也是为什么配备 Retina 的 MacBook 的界面尺寸与旧款 MacBook 基本一致,但显示效果却有着肉眼可见的提升。

详解HiDPI

渲染分辨率与 FrameBuffer

前文中,我们提到了「逻辑分辨率」与「物理分辨率」两个概念。逻辑分辨率决定了桌面拥有多大的工作空间,而物理分辨率则代表显示器真实拥有多少个像素。但 macOS 并不只是简单地将逻辑分辨率映射到物理分辨率上。事实上,在逻辑分辨率与物理分辨率之间,还存在着一个经常被忽略,却至关重要的概念 —— 渲染分辨率。

顾名思义,「渲染分辨率」是系统实际绘制桌面时所使用的分辨率。应用程序绘制的窗口、文字、图标以及各种界面元素,都会首先被渲染到一块位于显存中的缓冲器上,即 FrameBuffer(帧缓冲区)。而图像在 FrameBuffer 中绘制的尺寸,便是渲染分辨率。

LoDPI 与 HiDPI

对于传统的 LoDPI 显示模式而言,渲染分辨率的大小通常与显示器的物理分辨率保持一致。系统渲染多少像素,显示器便显示多少像素,即逻辑分辨率、渲染分辨率与物理分辨率是以 1:1:1 对应的,无需进行多余的操作。

然而在 HiDPI 模式下,情况发生了变化。

为了让同样大小的界面拥有更高的显示精度,macOS 并不会直接按照逻辑分辨率进行绘制,而是会先按照一定的缩放倍率调整渲染分辨率,并在一个更大的 FrameBuffer 中完成渲染。

以 Retina 显示屏常见的 2× Scale Factor 为例,一个逻辑上的 Point 会对应 2 × 2 个 Pixel。因此,一个逻辑分辨率为 2560 × 1440 Points 的桌面,实际上的渲染分辨率为 5120 × 2880 Pixels。此时,「5120 × 2880」 便是系统实际使用的渲染分辨率。

这其实和游戏中使用 SSAA(Super Sampling Anti-Aliasing,即超采样抗锯齿) 来抗锯齿的方法是类似的。SSAA 的思路是在更高的分辨率下渲染画面,再把这张更大的画面缩小回当前屏幕分辨率。由于高分辨率渲染提供了更多采样信息,最终缩小后的图像边缘会更加平滑。

图源:GAMES101

同理,Apple 在 WWDC 2012 中提出的「1 Point = 2 × 2 Pixels」,本质上并不是简单地把一个像素拆成四份,而是在更高分辨率的 FrameBuffer 中重新绘制整个界面。

到了这里,我们应该大致理解了 macOS 中 HiDPI 画面的渲染流程:

  1. 用户在系统中选择一个逻辑分辨率;
  2. 系统根据缩放倍率,生成更高的渲染分辨率;
  3. 系统在 FrameBuffer 中绘制界面元素;
  4. 最终结果再被映射到显示器的像素上,以物理分辨率输出。

整数缩放

到这里,你是否发现了一个有趣的现象。以笔者搭载 M2 Pro 芯片的 14 英寸 MacBook Pro 为例,这台笔记本内置显示器的物理分辨率为 3024 × 1964,系统 UI 的逻辑分辨率为 1512 × 982。我们将逻辑分辨率的长、宽各自乘以 2,即总像素数变为原来的 4 倍,便会得到 3024 × 1964,这与显示器的物理分辨率相同。

是的,这就是 Apple 软硬件设计协同的最佳体现之一。

整个过程恰好构成了一个 Retina 体系中理想的 2× 映射关系,系统在渲染阶段绘制出的每一个像素,最终都能够与显示器的物理像素一一对应,没有任何缩放、插值或重新采样的过程。

系统渲染出的每一个细节,都能够原封不动地显示在屏幕上。这也是 Retina 显示屏观感如此出色的重要原因之一。这种逻辑分辨率、渲染分辨率与物理分辨率之间严密的对应关系,通常被称为 Integer Scaling(整数缩放)。

如果你仔细看 Apple 的产品线,会发现很多产品物理分辨率与默认逻辑分辨率的关系都满足前文所提到的「整数缩放」。

产品物理分辨率逻辑分辨率(默认)缩放关系
14 英寸 MacBook Pro3024 × 19641512 × 982
16 英寸 MacBook Pro3456 × 22341728 × 1117
Studio Display5120 × 28802560 × 1440
Pro Display XDR6016 × 33843008 × 1692
21.5 英寸 iMac4096 × 23042048 × 1152
24 英寸 iMac4480 × 25202240 × 1260

对于大多数厂商而言,产品往往先确定物理分辨率,再通过系统缩放去适配用户的使用需求。而在 Apple 对 Retina 的理想设计体系中,逻辑分辨率才是优先级更高的存在。最终显示器的物理分辨率往往会按照显示器尺寸与逻辑分辨率共同决定。

但事情不总是理想的。

分数缩放

如果你使用的是 Studio Display 等由 Apple 推出的显示器,体验应该是十分丝滑的。但当我们把 Mac 连接到一台第三方显示器时,事情开始变得复杂起来。此时显示器的物理分辨率与逻辑分辨率之间,大多已经不再是简单的整数倍关系。

以最常见的 27 英寸 4K 显示器为例,其物理分辨率为 3840 × 2160。而对于这一尺寸的显示器而言,2560 × 1440 左右的逻辑分辨率通常能够提供更舒适的视觉体验。然而问题在于,2560 × 1440 经过 Retina 所要求的 2× 映射后,对应的渲染分辨率应为 5120 × 2880,这已经超过了显示器本身所拥有的物理像素数量。

因此,macOS 采用了一种折中的方案。系统依然会先以 5120 × 2880 的分辨率完成整个桌面的渲染,再将这张画面缩放至显示器实际拥有的 3840 × 2160 像素进行输出。

当你在系统设置中选择「2560 × 1440」,即「系统信息」里显示的「UI 看起来类似:2560 × 1440」时,macOS 实际经历的过程是:

  1. 逻辑分辨率:2560 × 1440
  2. 渲染分辨率:5120 × 2880
  3. 物理分辨率:3840 × 2160

这种先以高分辨率渲染,再缩放到目标分辨率输出的机制,被称为 Fractional Scaling(分数缩放)。

从结果来看,这种方案依然能够获得远优于传统 LoDPI 的显示效果。因为系统仍然是以 5K 的渲染分辨率完成界面绘制,文字、图标与曲线边缘依旧拥有充足的像素用于描述细节。虽然最终会经过一次非整数倍缩放,画面偶尔会在极细的线条上出现微小的模糊或像素对齐问题,但绝大多数用户几乎无法察觉其中带来的损失。

但 Apple 也不总是默认选择 2×

虽然 Apple 在 WWDC 中明确提出了 macOS 中 HiDPI 渲染画面的理想情况是 2× 整数缩放,也在 UI 设计文档中提出了这一点。

在设计文档中可以看到 macOS 建议的缩放系数为 1× 或 2×

但在有些产品中,Apple 并没有完全践行「2× 整数缩放」的设计理念。

如果你使用过 2016 到 2019 年前后的 MacBook Pro,可能会发现一个有些微妙的变化:这些机型的屏幕物理分辨率与前代相同,系统设置中也仍然保留了 2× 对应的逻辑分辨率选项,但 Apple 却默认启用了分数缩放。

为什么 Apple 要这么做?或许 Apple 发现,更大一部分用户群体对桌面空间的敏感度,要高于对分数缩放带来的画质下降的敏感度。因此,在权衡了市场需求和设计规范后,Apple 做了一个「违背祖宗」的决定,在部分机型上默认使用分数缩放以换取更大的逻辑分辨率。

以当时 15 英寸 MacBook Pro 为例,该机型的物理分辨率是 2880 × 1800。如果严格采用 2× 整数缩放,它对应的逻辑分辨率就是 1440 × 900。这个分辨率固然清晰,但对于很多用户来说,桌面空间会显得偏小。打开一个代码编辑器和一个浏览器,桌面看起来就已经十分拥挤。

MacBook Pro(15 英寸,2016)技术规格界面。 图源:Apple 官网

因此,Apple 在部分机型上默认启用了更大的逻辑分辨率,例如「1680 × 1050」。这意味着系统会先以 3360 × 2100 的渲染分辨率绘制桌面,再缩小到 2880 × 1800 的物理屏幕上输出。此时用户获得了更大的桌面空间,但缩放系数不再是 2×,画面会经过一次非整数缩放,对于较小元素的细节可能会有所损失。但对于大多数用户来说,更大的桌面空间是立刻可感知的,而非整数缩放带来画质的轻微损失往往并不明显。

直到 2021 年,Apple 推出了新一代 14 英寸与 16 英寸的 MacBook Pro,情况才发生变化。新款 14 英寸 MacBook Pro 的物理分辨率提升到 3024 × 1964,默认逻辑空间为 1512 × 982;16 英寸 MacBook Pro 的物理分辨率提升到 3456 × 2234,默认逻辑空间为 1728 × 1117。彼时,Apple 终于通过更高规格的面板,让「桌面空间」和「2× 整数缩放」不再是一道选择题。

最新 MacBook Pro 技术规格界面。 图源:Apple 官网

而提到 MacBook Air,情况又有所不同。实际上,Apple 从未在配备 Retina 显示屏的 MacBook Air 默认启用过整数缩放。

以今天的 MacBook Air 产品线为例,13 英寸机型的物理分辨率为 2560 × 1664,如果严格采用 2× 整数缩放,对应的逻辑分辨率应为 1280 × 832。但在默认设置下,13 英寸 Air 的逻辑分辨率为 1470 × 956,并不是 2× 整数缩放。

MacBook Air 技术规格界面。 图源:Apple 官网

当然,这背后主要与 Air 的产品定位有关。相比 MacBook Pro,Air 更强调轻薄、续航和性价比,Apple 并没有为它配备像 Pro 那样更高像素密度的面板。因此,在有限的成本下,Air 选择默认启用分数缩放,来拥有较为合理的默认 UI 空间。这样的设计对于 Air 用户群体来说或许更实用,也能让不同 MacBook 产品之间的 UI 尺度保持相对统一。类似的思路,也出现在了定位更入门的 MacBook neo 身上。

为什么低 PPI 显示器在 macOS 上字体的字体显示反而更糟糕?

缺席的「子像素抗锯齿」

如果你曾经把 Mac 连接到一台 24 英寸 1080p 或 27 英寸 1440p 显示器,大概率会发现一件奇怪的事情:高分屏上 macOS 的字体表现非常精致,但在低分屏下看起来反而没有 Windows 清晰锐利?

在传统 LCD 显示器上,一个像素实际上由红、绿、蓝三个子像素组成。早期操作系统会利用这些子像素进一步提高字体边缘的显示精度,通过控制不同颜色子像素的亮度,让文字边缘呈现出比物理分辨率更细腻的过渡效果。Windows 至今仍在使用的 ClearType,便是这一思路的代表。

然而,Apple 在 Retina 时代逐渐放弃了这条路线。对于拥有足够高像素密度的显示器而言,单个物理像素本身已经非常细小,系统无需再依赖子像素结构进行额外优化。因此从 macOS Mojave 开始,Apple 正式移除了子像素抗锯齿技术,将显示质量完全建立在高 PPI 与 HiDPI 渲染之上。

这一决策在 Retina 显示屏上几乎没有任何问题。以 MacBook Pro 或 Studio Display 为例,它们本身就拥有远高于传统显示器的像素密度,即使仅依靠普通的灰阶抗锯齿,文字边缘也已经足够平滑。但当 macOS 被连接到低 PPI 显示器时,由于缺少了子像素渲染带来的额外精度补偿,字体边缘只能依赖有限的物理像素进行描述,此时便容易出现 macOS 用户们经常提到的「字体边缘发虚」现象。

「LCD 平滑」又是什么?

在讨论 macOS 的字体显示时,还有一个经常与「子像素抗锯齿」一同被提及的功能 —— LCD 平滑。

前文提到,Apple 从 Mojave 开始移除了传统意义上的子像素抗锯齿,但在 Big Sur 之前的「系统偏好设置 - 通用」中,macOS 还提供了「LCD 平滑字体」的选项。这个选项主要面向传统 LCD 显示器,用来调整字体边缘的平滑程度。对于非 Retina、低 PPI 的显示器而言,它可以在一定程度上影响文字边缘的观感,让字体看起来更平滑。

到了 Big Sur 前后,这个图形界面中的开关逐渐从系统设置里消失,但用户仍然可以通过命令行修改 「AppleFontSmoothing」 参数。不过,如今修改「AppleFontSmoothing」并不会带回类似 Windows ClearType 的子像素字体平滑,它只是改变传统灰阶抗锯齿的强度。调整不同数值带来的效果主要是让字体看起来更细或更粗。

0 是最细,1 是中等,2 是恢复原始的粗细,3 则为最粗。

defaults -currentHost write -g AppleFontSmoothing -int 0
defaults -currentHost write -g AppleFontSmoothing -int 1
defaults -currentHost write -g AppleFontSmoothing -int 2
defaults -currentHost write -g AppleFontSmoothing -int 3
defaults -currentHost delete -g AppleFontSmoothing

相关的操作在我派文章《在 macOS Big Sur 上关闭「LCD 平滑字体」》也有提及。

强制开启 HiDPI,到底有什么作用?

有了上述原理之后,我们再回头看 RDM 等工具提供的「强制开启 HiDPI」功能,事情就容易理解得多了。

默认情况下,当你连接一台 27 英寸的 1440p 或 24 英寸的 1080p 显示器时,macOS 会认为它的像素密度不够,从而拒绝开放 Retina 缩放选项。此时系统采用的是最原始的 LoDPI 模式,即物理分辨率与渲染分辨率 1:1 对应,屏幕上的文字边缘会呈现出明显的锯齿感和像素颗粒。

而强制开启 HiDPI,本质上就是强制 macOS 动用分数缩放的机制,其中原理正与前文中提到的 SSAA 操作相同。通过在 FrameBuffer 中渲染高分辨率的画面,再缩放回低分辨率输出,原本生硬的锯齿就被较为平滑的灰阶过渡所取代。尽管受限于物理像素的数量,它永远达不到真正原生高分辨率显示器配合整数缩放的锐利感,但相较于不加处理的 LoDPI 输出,其字体平滑度与整体观感会得到提升。

不过,正如前文所说,这种「超采样」是以成倍增加的渲染像素为代价的。对于 GPU 而言,强制开启 HiDPI 意味着它需要时刻以远超屏幕物理分辨率的规格进行渲染。随之而来的,便是显著增加的能耗与显存带宽占用,有时还会导致严重的掉帧或发热。

关联阅读

  • Apple Inc. Supporting High Resolution Screens In OS X [EB/OL]. Apple Developer Documentation, 2012.
  • Apple Inc. Human Interface Guidelines: Displays [EB/OL]. Apple Developer Documentation.
  • Waydabber. Add an option to change font smoothing level in macOS #3474 [EB/OL]. GitHub, 2024.
  • Waydabber. MacOS Scaling, HiDPI, LoDPI Explanation [EB/OL]. GitHub Wiki, 2023.

文中配图若无特殊注明,均为作者本人制作。

若你对本文提到的「SSAA」等技术感兴趣,不妨查看笔者的上一篇文章,那篇文章详细解释了抗锯齿技术与渲染方面的知识。

 

> 关注 少数派小红书,感受精彩数字生活 🍃

> 实用、好用的 正版软件,少数派为你呈现 🚀

24
9