Skip to content

渲染引擎

渲染引擎是根据高级语言的绘图指令和图形源数据计算生成屏幕显示所需要的像素颜色数据的核心组件。

现代 GUI 程序底层依赖于通用渲染引擎提供图形的绘制能力,以此向用户呈现 UI 界面。在高级渲染场景中,例如影视和游戏程序中,渲染引擎需要暴露更多的高级接口,使得用户可以实现高级渲染效果。

渲染引擎集成了计算机图形学的众多算法成果,以实现高效和美观的像素颜色计算,包括 2D 图形和 3D 场景的渲染计算;为了提高计算速度,渲染引擎往往会操作 GPU 完成加速计算;同时,为了实现跨平台的渲染能力,渲染引擎需要屏蔽不同操作系统平台上的视图系统的差异,参考:linux 视图系统

渲染管线

渲染管线是指由图形 API 所定义的完成从图形源数据生成最终像素数据的一个流水线化的固定过程。渲染引擎就是在各个图形 API 所提供的渲染管线上工作的,在此之上,渲染引擎封装管线,并向上层应用提供简单的图形渲染指令 API。

前后端架构

为了实现跨平台的渲染能力,现代渲染引擎普遍提出前后端分离的架构设计。这种架构将渲染引擎分为两个层次:前端和后端,各自承担不同的职责。但其实,它就是一个层次结构,前端(引擎层)是面向上层开发者的,并且封装各个平台的图形 API,也就是所谓的后端。

前端是渲染引擎对外暴露的 API 层,提供统一的高级绘图指令接口,屏蔽底层操作系统和图形 API 的差异。前端 API 通常设计为平台无关,开发者只需调用前端接口,无需关心底层是 Windows、macOS 还是 Linux。

前端负责将高级绘图指令转换为中间表示(Intermediate Representation),这种中间表示是平台无关的抽象描述,类似于一种通用的图形指令语言。例如,Skia 的前端提供统一的 2D 绘图 API,开发者调用 drawRect()drawPath() 等方法,前端将这些调用转换为 Skia 内部的中间表示。

后端负责将前端生成的中间表示转换为具体平台上的图形 API 调用。每个平台都有各自的后端实现,针对该平台的特性进行优化。

在 Windows 上,后端可能调用 Direct2D/Direct3D API;在 macOS/iOS 上,后端可能调用 Core Graphics/Metal API;在 Linux 上,后端可能调用 Cairo 或直接操作 OpenGL/Vulkan;在浏览器中,后端可能调用 WebGL/WebGPU API。

后端实现了平台相关的优化,比如利用硬件加速特性、处理平台特定的内存管理、适配不同的 GPU 驱动等。这种多后端架构使得上层应用可以用同一套代码运行在多个平台上,而无需关心底层差异。

典型示例

Skia 是前后端架构的典型代表。Skia 前端提供统一的 C++ 绘图 API,后端支持多种实现:GPU 后端(基于 OpenGL、Vulkan、Metal、Direct3D)、软件光栅化后端、PDF 生成后端等。Chrome 使用 Skia,在 Windows 上通过 Direct3D 后端渲染,在 macOS 上通过 Metal 后端渲染,在 Linux 上通过 OpenGL/Vulkan 后端渲染,但 Chrome 的渲染代码完全不需要修改。

这种架构设计的优势在于:上层应用开发者只需学习一套 API,代码可以跨平台复用;渲染引擎开发者可以针对每个平台进行深度优化,充分发挥硬件性能;平台特定的 API 变化只影响对应的后端实现,不会影响上层代码。

常见引擎

渲染引擎分为 2D 渲染引擎、3D 实时渲染引擎和 3D 非实时渲染引擎。

2D 图形和 3D 场景的渲染有着显著的差异,2D 图形的绘制可以直接基于一个有限大小的画布进行绘制,但是 3D 场景的渲染就要引入复杂计算机图形学理论,使用场景、灯光、相机等概念,将一个 3D 场景变成一张二维的图形。而且 2D 渲染一般使用简单的指令,3D 渲染往往需要使用 3D 模型作为输入,构建 3D 场景,其数据量陡然提升。

2D 渲染引擎

引擎名称主要用途代表作/应用备注
Skia通用 2D 图形Chrome, Flutter, Android,Qt多后端,性能优异,Google
PixiJS/CanvasAPIWeb 2D 图形所有现代浏览器Web 标准,JavaScript
Cairo跨平台 2D 图形GTK, Firefox, SVG 渲染Linux 生态重要组件
Cocos2d-x2D/轻量 3D 游戏捕鱼达人、开心消消乐、神庙逃亡中国流行,移动端友好
Unity 2D2D 游戏开发Monument Valley, Alto's Adventure3D 引擎的 2D 模式

3D 渲染引擎

在 3D 引擎中又分为实时渲染引擎和非实时渲染引擎,前者强调在短时间内完成快速连续的渲染,帧率要求 60 FPS,以适应游戏等交互式应用,为了达到这个目标,实时渲染必须舍弃部分画面质量以换取更快的渲染速度;后者强调高质量和高保真的图形渲染,不必追求实时性,以获得极高的视觉效果,适合电影和静态图片制作。

区分实时和非实时渲染的原因在于当前的图形渲染技术还不够高效,硬件条件尚未能完整覆盖常见的渲染质量需求,人们不得不做出妥协,将有限的资源进行特化。

光线追踪技术是一项典型的高质量渲染技术,需要消耗大量计算资源。实时渲染引擎支持有限的光线追踪功能,使用近似光照尽可能模拟真实效果;非实时渲染引擎力求获得更高级的渲染效果,通常支持更复杂和完善的光线追踪。

非实时渲染引擎

引擎名称主要用途代表作/应用备注
Arnold高质量渲染3ds Max, Maya, 好莱坞电影光线追踪,电影级
Cycles高质量渲染Blender, MayaBlender 内置,开源
V-Ray高质量渲染3ds Max, SketchUp, 建筑建筑可视化的行业标准
RenderMan高质量渲染皮克斯电影,迪士尼动画工业标准,影视级
Clarisse场景组装大型场景,影视特效高效处理复杂场景

实时渲染引擎

引擎名称主要用途代表作/应用备注
Unity URP/HDRP游戏/AR/VRUnity Editor、原神、王者荣耀、马里奥跑酷2D/3D 均支持,生态最丰富
Unreal 渲染组件高保真游戏/虚拟制作Unreal Editor、堡垒之夜、黑神话、虚幻演播厅Nanite, Lumen,高端渲染
Three.js/WebGLWeb 3D 渲染Web 3D 演示、数据可视化JavaScript,最流行的 Web 3D 库
Godot独立游戏Godot Editor、小型独立游戏开源免费,轻量级

大包大揽工作流

渲染引擎往往需要展示渲染效果的窗口,并且为了解决使用代码接口来布局的麻烦,这个窗口往往提供了图形化界面来进行布局的能力。这就是渲染引擎往往被打包成一个 GUI 编辑器的原因。

特别地,针对于美术设计师的而言,这些 GUI 编辑器包含了众多的场景构建工具和方便快捷的美术编辑体验。而对于客户端开发者,则提供了集成代码编辑能力的 coding IDE 能力。Unity 和 Unreal 都提供了一个大包大揽的游戏开发 IDE,不过,也可以不必下载其 IDE,直接使用其提供的 API 库。

引擎切换之痛

引擎屏蔽了底层的图形 API,但是又引入了新的割裂。

随着引擎数量的增加,各个引擎又形成了各自新的山头,导致出现了新的兼容性问题,那就是不同的引擎之间存在着差异;基于一个引擎构建的 3D 场景效果,编写的渲染逻辑代码,只能在该引擎上生效,如果想要切换生态,那么就意味着已有工作量的浪费。

还有一个比较麻烦的问题在于,美术设计师和客户端开发者使用的引擎是不一样的,美术设计师使用的非实时引擎和美术设计软件,而开发者使用的是实时引擎和游戏引擎 IDE,将美术资产从一个引擎搬到另一个引擎,那是不可名状之痛。