本节摘要:帧缓冲里的数字要变成真实的光,得靠显示设备完成最后一步。本节对比 CRT、LCD、OLED 三代技术的发光原理,讲扫描时序与帧率、色域与 HDR 的基本概念,并说明硬件特性如何反过来影响渲染策略(为什么 HDR 需要更高亮度峰值、为什么 OLED 上纯黑省电)。它是第 2 站的收尾:看完这节,像素的"家"就参观完了。
阅读完本节,你应当能够:
CRT(阴极射线管)用电子枪逐行轰击荧光粉,扫描回程的间隙正是 2.1 节双缓冲换帧的时机——"垂直回扫"这个词就是 CRT 时代留下的化石。LCD(液晶显示)自己不发光,背光板发白光,每个像素是三片液晶阀门加红绿蓝滤光片,靠扭转液晶分子控制透光量。OLED 每个像素是一颗自发光二极管,无需背光。
结构差异直接带来显示特性的差异:
| 特性 | LCD | OLED |
|---|---|---|
| 黑色表现 | 背光漏光,黑是深灰 | 像素可完全熄灭,纯黑 |
| 对比度 | 数千比一 | 理论无穷(逐像素控光) |
| 响应时间 | 毫秒级,快速运动有拖影 | 微秒级 |
| 寿命短板 | 背光衰减均匀 | 蓝色材料衰减快,长时间高亮可能留痕 |
| 高亮峰值 | 依赖分区背光 | 峰值亮度受限 |
这些差异影响渲染决策:OLED 上纯黑像素省电,移动端深色 UI 不只是审美偏好;OLED 的逐像素控光让暗场细节对比更锐利,但也让 8 位色带的颗粒感更显眼,好在其面板常支持 10 位输出,HDR 素材收益更大。
显示器每秒完整刷新的次数是刷新率(60/120/144 Hz),GPU 渲染出帧的速率是帧率,两者独立又互相牵制。扫描是逐行下移的过程,从顶行到末行需要约十几毫秒,然后回到起点(垂直回扫)。若新帧在扫描中途被换入,就出现 2.1 节讲的撕裂;若开了垂直同步而渲染超时,帧率按整数倍跳水。
60 Hz 屏幕的帧预算:1000 / 60 ≈ 16.67 毫秒 渲染 + 提交 + 后处理 全流程必须塞进这个预算 144 Hz:约 6.94 毫秒,预算紧了一倍多 帧生成时间波动比均值更影响体验——偶发一帧 30 毫秒,比稳定 12 毫秒更卡
第 6 章讲管线优化时会反复回到这笔账:减 Draw Call、合并 Pass、降低过绘制,目标都是让最慢的那一帧也进预算。
色域是设备能显示的颜色范围在色度图上圈出的区域。sRGB 覆盖日常内容,DCI-P3 更宽(红更红、绿更绿,影视常用),Rec.2020 面向超高清,范围最大。同一份 RGB 数值在不同色域下的实际颜色不同——这叫色域未标记问题:一张按 sRGB 制作的图在广色域屏上若不转换,会显得过饱和。
def chroma_approximation(): # 用一个直观比例感受色域覆盖(近似值,仅作量级参考) domains = {"sRGB": 100, "DCI-P3": 135, "Rec.2020": 200} # 以 sRGB 为基准 for name, area in domains.items(): print(f"{name:9s} 相对覆盖 {area}%") # 输出: # sRGB 相对覆盖 100% # DCI-P3 相对覆盖 135% # Rec.2020 相对覆盖 200%
渲染侧的应对是"宽色域管线":中间计算在更大的线性空间(如 scRGB 或 AP1)进行,输出时按目标显示器的色域做映射。游戏引擎近年的"色彩分级"流程,就是在线性 HDR 空间调色、最后一步映射到目标色域与亮度。
传统 SDR 输出把亮度封顶在约 100 尼特,HDR 显示器能到几百上千尼特。但 HDR 不只是"更亮的屏幕",它是一整条链路:内容以更高位深(10/12 位)记录、以更宽色域标记、映射到更高峰值亮度。渲染端的对应做法是全流程线性 HDR:光强用浮点表示,太阳可以是 10000,蜡烛是 10,最后由色调映射压到显示范围。
def reinhard_tonemap(hdr): # Reinhard 色调映射:把任意高亮压回 0~1,简单但高亮会整体变灰 return [c / (1.0 + c) for c in hdr] print(reinhard_tonemap([0.2, 1.0, 5.0, 100.0])) # 输出: [0.1667, 0.5, 0.8333, 0.9901] # 亮度层次保留,但 5.0 与 100.0 都被压向 1,超亮细节挤在一起
更精细的映射(如 ACES 曲线)会在高亮段做柔和滚降并保持色相稳定,是现代游戏与影视后处理的标配,细节放在 6.4 节后处理里展开。
同一个 8 位 sRGB 帧,送到普通办公 LCD、广色域手机 OLED、HDR 电视上,观感差异可以大到像三张图。用本节概念可以精确归因:办公屏色域窄(约 sRGB),画面"安全"但平淡;手机 OLED 若未做色彩管理,sRGB 内容被拉伸到 DCI-P3 色域,红绿全部过饱和——艳得扎眼;HDR 电视若收到未映射的 SDR 信号又开了增强模式,暗部被强行提亮、高光被压缩,层次反而丢失。同一份数字,三个物理世界的三种翻译。工程上的对策是给内容打元数据标记(色域、亮度范围),显示端按标记做映射,而不是默认"数字相同即颜色相同"。
def gamut_map_srgb_to_p3(rgb): # 简化示意:广色域映射按色域比例缩放色度(真实实现查 3D LUT) return tuple(min(1.0, c * 1.15) for c in rgb) print(gamut_map_srgb_to_p3((0.8, 0.3, 0.1))) # 输出: (0.92, 0.345, 0.115) 饱和色被推向色域边界,观感更浓艳
第 2 站到站。户口本有了、颜色语言有了、发光的家也有了,第 3 章进入本教程最核心的一幕:像素正式出生——光栅化。