核心名词解释大全

58个渲染核心名词,每个都有:定义、一句话本质、类比解释、技术细节、常见误区

参考:月影《跟月影学可视化》图形基础篇、数学篇、视觉基础篇核心概念


阅读指南(初学者必看)

为什么你需要这份名词解释?

学习图形学时,你会遇到大量专业术语:VBO、MVP、NDC、光栅化、Early-Z……每个词看起来都很陌生。如果不理解这些术语,你会发现:

  • 看技术文档时每个字都认识,连起来就不懂了
  • 听技术分享时演讲者蹦出一堆缩写,完全跟不上
  • 写代码时IDE的API提示里全是看不懂的参数名
  • 面试官说"说说你对MVP矩阵的理解",你只会背定义

这份文档的目标:让每个术语从"天书"变成"人话"。

如何使用本文档

场景1:遇到不认识的词

  • 直接按Ctrl+F搜索关键词
  • 每个词都有"一句话本质",先看这个建立直觉
  • 再看"类比解释"加深理解
  • 最后看"技术细节"掌握精确含义

场景2:系统学习

  • 按分类顺序阅读(渲染管线 → GPU架构 → WebGL/API → 性能指标 → Cocos引擎 → 高级渲染)
  • 每个术语的"常见误区"一定要看,这是踩坑经验
  • 看完一个分类后,尝试用自己的话复述给 imaginary friend 听

场景3:面试准备

  • 重点看"一句话本质"和"技术细节"
  • 准备1-2个"类比解释",面试时用类比说明你的理解深度
  • 记住"常见误区",展示你对坑点的了解

文档结构

一、渲染管线术语(19个)- 最基础,必学
二、GPU架构术语(8个)- 了解性能瓶颈
三、WebGL/API术语(5个)- H5开发必备
四、性能指标术语(6个)- 优化必备
五、Cocos引擎术语(10个)- Cocos开发者重点
六、高级渲染术语(8个)- 进阶内容

如果读完还是不懂怎么办?

  • 正常现象:58个术语不可能一次全记住
  • 建议策略:先记住"一句话本质",建立基本认知框架
  • 实践策略:在写代码时遇到不懂的词再回来查,带着问题查效率更高
  • 关联学习:配合《GPU渲染管线详解.md》一起阅读,两个文档互相补充

一、渲染管线术语

1. 渲染管线 (Rendering Pipeline)

为什么需要这个概念? 渲染管线是图形学的"骨架"。不懂渲染管线,你看任何图形API文档都会迷失在函数调用中,无法理解"数据从哪来、到哪去、经历了什么变换"。

维度 内容
定义 将3D场景数据转换为2D屏幕像素的完整处理流程
一句话本质 图形数据的"生产线", raw data → 像素
类比解释 汽车工厂流水线:原材料(顶点) → 冲压(顶点着色器) → 喷漆(片元着色器) → 质检(测试) → 成品(画面)
技术细节 现代GPU管线分为:应用阶段(CPU) → 几何阶段(GPU) → 光栅化阶段(GPU) → 像素处理阶段(GPU)。其中顶点着色器和片元着色器是可编程的,其他阶段由硬件固定实现
常见误区 ❌ 以为所有阶段都能编程(实际只有顶点/片元着色器可编程)
❌ 以为管线顺序可以跳过(每个阶段依赖上一阶段的输出)

自问自答

  • Q:为什么叫"管线"而不是"流程"? A:因为数据像水流一样单向流动,不能回头,也不能跳过某个阶段。
  • Q:如果不懂渲染管线会怎样? A:写Shader时不知道自己的代码在哪个阶段执行,调试时完全抓瞎。

2. 顶点 (Vertex)

维度 内容
定义 构成几何图形的基本点,包含位置、颜色、UV等属性
一句话本质 3D世界的"原子",所有模型由顶点构成
类比解释 乐高积木的单个凸点。无数凸点组合成各种形状
技术细节 一个顶点通常包含:position(vec3)、normal(vec3)、uv(vec2)、color(vec4)。在GPU中存储为连续的Float32Array。一个Sprite需要4个顶点,一个立方体需要8个顶点
常见误区 ❌ 以为顶点就是像素(顶点是几何概念,像素是屏幕概念)
❌ 以为顶点越多越好(顶点增加会增加顶点着色器负担)

3. 图元 (Primitive)

为什么需要这个概念? GPU的硬件电路只支持几种固定的图元类型。理解图元类型,才能知道"怎么用最少的顶点画出想要的形状"。

维度 内容
定义 顶点组合成的基本几何形状
一句话本质 GPU能直接绘制的"最小单元"
类比解释 乐高积木的基本连接方式:可以拼成平面(三角形)、线条(线段)、点
技术细节 常见图元类型:POINTS(点)、LINES(线段)、LINE_STRIP(线带)、LINE_LOOP(线环)、TRIANGLES(三角形)、TRIANGLE_STRIP(三角带)、TRIANGLE_FAN(三角扇)。WebGL中三角形是最常用的,因为任何多边形都可以分解为三角形
常见误区 ❌ 以为GPU能直接画圆或曲线(GPU只认三角形,圆是用很多三角形近似)
❌ 用TRIANGLES画连续面(应该用TRIANGLE_STRIP减少顶点数)

代码示例

// TRIANGLES:每3个顶点一个三角形,不共享顶点
// 2个三角形需要6个顶点
const triangles = new Float32Array([
  // 三角形1
  -1, -1,   1, -1,   1, 1,
  // 三角形2
  -1, -1,   1,  1,  -1, 1,
]);
gl.drawArrays(gl.TRIANGLES, 0, 6);

// TRIANGLE_STRIP:相邻三角形共享一条边
// 2个三角形只需要4个顶点
const strip = new Float32Array([
  -1, -1,   // 顶点0
   1, -1,   // 顶点1
  -1,  1,   // 顶点2 → 三角形1: 0-1-2
   1,  1,   // 顶点3 → 三角形2: 1-2-3(共享边1-2)
]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

自问自答

  • Q:为什么GPU只支持这么几种图元? A:硬件电路需要固定功能,支持的图元类型越多电路越复杂。三角形是最通用的,任何多边形都能拆成三角形。
  • Q:如果不懂图元会怎样? A:你可能会用TRIANGLES画一个长条带,用了几百个顶点,而实际上用TRIANGLE_STRIP只需要几十个。

4. 顶点着色器 (Vertex Shader)

维度 内容
定义 对输入的每个顶点执行一次的可编程着色器,主要做坐标变换
一句话本质 "定位员":决定每个顶点在屏幕上的位置
类比解释 快递分拣员。拿到包裹(顶点),看地址(MVP矩阵),放到正确的货架(屏幕坐标)
技术细节 输入:attribute变量(顶点属性)、uniform变量(全局参数)。输出:gl_Position(齐次坐标,vec4)。执行次数 = 顶点数。一个Sprite执行4次,全屏画面可能只执行几百次
常见误区 ❌ 在顶点着色器里做复杂光照计算(应该放片元着色器)
❌ 修改gl_Position的w分量(除非你知道透视除法的影响)

5. 片元着色器 (Fragment Shader)

为什么需要这个概念? 顶点着色器只计算了3个顶点的颜色,但三角形内部有成千上万个像素。谁来决定每个像素的颜色?片元着色器就是干这个的。它是实现"特效"的核心 —— 溶解、发光、水波纹、灰度,全部在片元着色器里实现。

维度 内容
定义 对光栅化后的每个片元(潜在像素)执行一次的可编程着色器,决定最终颜色
一句话本质 "上色员":决定每个像素涂什么颜色
类比解释 十字绣的上色工人。拿到一个格子(片元),根据设计图(纹理+Shader逻辑)填色
技术细节 输入:varying变量(插值后的顶点属性)、uniform变量。输出:gl_FragColor(vec4,RGBA)。执行次数 = 覆盖像素数(1080P全屏约207万次!)。每多一行代码都被放大百万倍
常见误区 ❌ 在片元着色器里做分支判断(GPU并行执行,分支导致部分核心空转)
❌ 多次texture2D采样(每次采样都从显存读数据,是性能杀手)

代码示例

precision mediump float;

varying vec2 v_uv;              // 从顶点着色器接收的UV坐标(已插值)
uniform sampler2D u_texture;    // 纹理采样器
uniform float u_time;           // 时间变量(用于动画)

void main() {
  // 基础纹理采样
  vec4 texColor = texture2D(u_texture, v_uv);
  
  // 简单的脉冲效果:随时间变化透明度
  float pulse = sin(u_time * 3.0) * 0.3 + 0.7;
  texColor.a *= pulse;
  
  gl_FragColor = texColor;
}

自问自答

  • Q:为什么片元着色器执行次数比顶点着色器多这么多? A:因为一个Sprite可能覆盖几万个像素,但顶点只有4个。执行次数 = 像素数,不是顶点数。
  • Q:如果不懂片元着色器会怎样? A:你无法实现任何自定义视觉效果,而且容易写出性能极差的Shader(比如全屏模糊采样25次纹理)。

6. 光栅化 (Rasterization)

维度 内容
定义 将连续的几何图形(三角形)转换为离散的像素点(片元)的过程
一句话本质 "像素化":把矢量图形变成位图
类比解释 十字绣。图案是连续的线条,绣出来是一个个离散的格子。光栅化就是"把线条转成格子"
技术细节 核心步骤:(1)扫描转换:确定三角形覆盖哪些像素;(2)片元生成:每个覆盖的像素生成一个Fragment;(3)属性插值:用重心坐标在三角形内插值顶点属性(颜色/UV/深度)。GPU用专门的硬件电路并行完成
常见误区 ❌ 以为光栅化是软件算法(现代GPU有专门的光栅化硬件单元)
❌ 以为插值是线性插值所有属性(透视校正插值对UV和颜色不同)

7. 逐片元操作 (Per-Fragment Operations)

为什么需要这个概念? 片元着色器算出了一个颜色,但这个片元不一定能显示在屏幕上。它可能在裁剪区域外、被其他物体挡住、或者只是Mask外不应该显示的部分。逐片元操作就是一系列"安检",只有通过所有检查的片元才能最终显示。

维度 内容
定义 对每个片元执行的一系列测试和混合操作
一句话本质 "质检+打包":检查片元是否合格,合格就写入帧缓冲
类比解释 工厂质检流程:尺寸检查 → 重量检查 → 外观检查 → 合格品装箱
技术细节 5步测试(按顺序):裁剪测试 → Alpha测试 → 模板测试 → 深度测试 → 混合操作。任何一步失败,片元被丢弃。全部通过则写入帧缓冲。顺序是固定的,不能改变
常见误区 ❌ 以为深度测试在最前面(实际在模板测试之后)
❌ 以为混合操作对所有物体都开启(不透明物体应该关闭混合)

自问自答

  • Q:测试顺序可以改吗? A:不能。这是GPU硬件固定的顺序,目的是尽早丢弃不合格的片元,减少无效计算。
  • Q:如果不懂逐片元操作会怎样? A:你会遇到各种"莫名其妙"的渲染bug:Mask不生效、透明物体显示异常、z-fighting闪烁等。

8. 帧缓冲 (Frame Buffer)

维度 内容
定义 GPU用于存储最终渲染结果的内存区域
一句话本质 GPU的"画布",画完一帧就显示到屏幕
类比解释 画家的画布。画家在画布上画画(GPU写入),画完挂到墙上展示(屏幕显示)
技术细节 帧缓冲包含多个附件:(1)颜色缓冲(Color Buffer):存储RGB颜色;(2)深度缓冲(Depth Buffer/Z-Buffer):存储深度值;(3)模板缓冲(Stencil Buffer):存储模板值。通常使用双缓冲(前缓冲+后缓冲)避免画面撕裂
常见误区 ❌ 以为帧缓冲只有颜色(还有深度和模板)
❌ 以为帧缓冲就是屏幕(帧缓冲在显存,屏幕是物理设备)

9. 深度缓冲 / Z-Buffer (Depth Buffer)

为什么需要这个概念? 3D场景中物体会互相遮挡。没有深度缓冲,后画的物体会覆盖先画的,不管谁在前面。深度缓冲让GPU能自动判断"哪个物体更近",正确显示遮挡关系。

维度 内容
定义 存储每个像素深度值的二维数组,用于解决遮挡关系
一句话本质 "距离记录本":记录每个像素离相机多远
类比解释 画家画画时,先画远处的山,再画近处的树。深度缓冲就是"画家记住每个位置已经画了什么,新的笔画只有更近才覆盖"
技术细节 存储格式:16位整数(~1/65536精度)、24位整数(~1/16777216精度)、32位浮点(非均匀分布)。值范围[0,1],0=近平面,1=远平面。精度问题:远处z-fighting(两个面深度值相同导致闪烁)
常见误区 ❌ 以为深度值线性分布(透视投影后深度非线性,近处精度高远处低)
❌ 透明物体也开深度写入(透明物体应该关闭depthWrite,从后往前渲染)

逐步推导:深度测试

假设画两个重叠的Sprite:

Sprite A(在后面):深度 = 0.5
Sprite B(在前面):深度 = 0.3

画A时:
- 深度缓冲初始值 = 1.0
- 比较:0.5 < 1.0?通过!
- 写入A的颜色,更新深度缓冲 = 0.5

画B时:
- 深度缓冲当前值 = 0.5
- 比较:0.3 < 0.5?通过!(B更近)
- 写入B的颜色,更新深度缓冲 = 0.3

最终显示B的颜色(正确!)

自问自答

  • Q:为什么深度值范围是[0,1]? A:这是标准化范围,便于硬件存储和比较。0表示最近(近平面),1表示最远(远平面)。
  • Q:如果不懂深度缓冲会怎样? A:3D场景中物体会随机互相覆盖,出现"穿透""闪烁"等奇怪现象。透明物体也会显示异常。

10. 模板缓冲 (Stencil Buffer)

维度 内容
定义 存储每个像素模板值的二维数组,用于实现遮罩效果
一句话本质 "遮罩层":控制哪些区域可以绘制
类比解释 喷漆用的镂空模板。把模板放在纸上,喷漆只喷到镂空的部分
技术细节 通常8位整数(0-255)。操作:keep(保持)、zero(清零)、replace(替换)、increment(加1)、decrement(减1)、invert(取反)。Mask组件用2-Pass实现:Pass1写模板形状,Pass2只绘制模板内区域
常见误区 ❌ 以为模板缓冲和深度缓冲是一回事(功能完全不同)
❌ 忘记清除模板缓冲(每帧开始要gl.clear(gl.STENCIL_BUFFER_BIT))

11. 混合 / Alpha Blending

维度 内容
定义 将新绘制的颜色与帧缓冲中已有颜色按公式混合的技术
一句话本质 "颜色叠加":半透明效果的核心
类比解释 两层彩色玻璃叠加。你看到的效果是两层玻璃的混合色
技术细节 标准公式:结果 = 源色 × 源Alpha + 目标色 × (1 - 源Alpha)。其他模式:加法混合(发光)、乘法混合(变暗)、屏幕混合(提亮)。混合在深度测试之后执行
常见误区 ❌ 不透明物体也开混合(浪费性能,且可能产生错误颜色)
❌ 透明物体从前往后渲染(必须从后往前,否则混合结果错误)

12. VBO (Vertex Buffer Object)

维度 内容
定义 存储在GPU显存中的顶点数据缓冲区
一句话本质 GPU的"顶点仓库"
类比解释 餐厅的食材仓库。所有食材(顶点数据)提前放到仓库,厨师(GPU)直接从仓库取,不需要每次从市场(CPU内存)买
技术细节 创建流程:gl.createBuffer() → gl.bindBuffer() → gl.bufferData()。数据存储为类型化数组(Float32Array/Uint16Array)。使用STATIC_DRAW(数据不变)、DYNAMIC_DRAW(数据偶尔变)、STREAM_DRAW(数据每帧变)提示GPU优化
常见误区 ❌ 每帧都重新创建VBO(应该创建一次,更新用bufferSubData)
❌ 用普通Array而不是Float32Array(普通Array是JS对象,转换有开销)

13. IBO / EBO (Index Buffer Object)

为什么需要这个概念? 一个矩形有4个顶点,但画2个三角形需要6个顶点(有2个重复)。IBO通过"索引复用顶点",让4个顶点就能画2个三角形,节省显存和带宽。

维度 内容
定义 存储顶点索引的缓冲区,告诉GPU哪些顶点组成三角形
一句话本质 "连接表":顶点的接线图
类比解释 串珠子的说明书。珠子(顶点)已经摆好,说明书(IBO)告诉你哪几颗珠子串在一起
技术细节 索引类型:UNSIGNED_BYTE(0-255,最多256个顶点)、UNSIGNED_SHORT(0-65535,最常用)、UNSIGNED_INT(0-4294967295,WebGL2支持)。使用IBO可以减少顶点重复:4个顶点+6个索引就能画2个三角形,不用IBO需要6个顶点
常见误区 ❌ 顶点数少就不用IBO(即使只有4个顶点,用IBO也更规范)
❌ 索引类型选错(超过65535个顶点必须用UNSIGNED_INT)

代码示例

// 4个顶点
const vertices = new Float32Array([
  -1, -1,  // 0: 左下
   1, -1,  // 1: 右下
   1,  1,  // 2: 右上
  -1,  1,  // 3: 左上
]);

// 6个索引,组成2个三角形
const indices = new Uint16Array([
  0, 1, 2,  // 三角形1:左下→右下→右上
  0, 2, 3,  // 三角形2:左下→右上→左上
]);

// 创建VBO和IBO
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const ibo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

// 用IBO绘制(注意是drawElements不是drawArrays)
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

自问自答

  • Q:IBO和VBO有什么区别? A:VBO存的是顶点数据(位置、颜色等),IBO存的是索引(告诉GPU用哪几个顶点组成三角形)。
  • Q:如果不懂IBO会怎样? A:3D模型的顶点数据会膨胀几倍,占用大量显存,低端手机可能因此闪退。

14. MVP矩阵 (Model-View-Projection Matrix)

维度 内容
定义 将顶点从模型空间变换到裁剪空间的三个矩阵的乘积
一句话本质 "坐标变换三部曲":局部 → 世界 → 相机 → 屏幕
类比解释 快递配送:(1)从卖家仓库取货(Model) → (2)运到城市中转站(View) → (3)按地址分配到具体楼栋(Projection)
技术细节 M = 模型矩阵(节点的位移/旋转/缩放);V = 视图矩阵(相机的位置和朝向);P = 投影矩阵(透视或正交)。计算顺序:gl_Position = P × V × M × position。在Cocos中,MVP由引擎自动计算,通过uniform传给Shader
常见误区 ❌ 矩阵乘法顺序搞错(矩阵乘法不满足交换律,顺序必须是P×V×M)
❌ 在CPU端每顶点计算MVP(应该在CPU算一次MVP矩阵,GPU每个顶点做矩阵×向量)

15. NDC (Normalized Device Coordinates)

维度 内容
定义 归一化设备坐标,范围[-1,1]的标准化坐标系
一句话本质 "通用坐标语言":不同分辨率的屏幕都能理解的坐标
类比解释 百分比布局。不管屏幕多大,0%到100%都能对应。NDC就是-100%到+100%
技术细节 顶点着色器输出gl_Position(齐次坐标),GPU自动做透视除法:NDC = gl_Position.xyz / gl_Position.w。NDC的xy范围[-1,1]对应屏幕的宽高,z范围[-1,1]对应深度缓冲的[0,1]
常见误区 ❌ 以为NDC就是屏幕像素(NDC需要经过视口变换才是像素坐标)
❌ 手动设置gl_Position时忘记w分量(w=0会导致透视除法出错)

16. 视口变换 (Viewport Transform)

为什么需要这个概念? NDC是标准化的[-1,1],但屏幕像素是具体的[0,宽度]。视口变换就是这两者之间的"换算公式"。

维度 内容
定义 将NDC坐标转换为屏幕像素坐标的过程
一句话本质 "坐标翻译":把[-1,1]翻译成[0,屏幕宽度]
类比解释 汇率换算。NDC是美元(标准化),屏幕像素是人民币(实际尺寸),视口变换就是按汇率换算
技术细节 公式:screenX = (NDC.x + 1) × width / 2 + viewportX
screenY = (NDC.y + 1) × height / 2 + viewportY。在Cocos中,视口通常等于Canvas大小,由引擎自动设置
常见误区 ❌ 手动计算视口变换(引擎已经做了,不需要手动算)
❌ 改变Canvas大小后忘记更新视口(会导致画面拉伸)

逐步推导

已知:NDC范围[-1, 1],屏幕宽度width
求:NDC.x对应的屏幕像素screenX

Step 1:NDC[-1,1] → [0,1]
  t = (NDC.x + 1) / 2

Step 2:[0,1] → [0, width]
  screenX = t × width = (NDC.x + 1) × width / 2

验证:
- NDC.x = -1 → screenX = 0(最左边)✓
- NDC.x = 0  → screenX = width/2(中间)✓
- NDC.x = 1  → screenX = width(最右边)✓

自问自答

  • Q:视口变换是谁做的? A:GPU自动做的,不需要你写代码。你只需要告诉GPU视口大小(gl.viewport)。
  • Q:如果不懂视口变换会怎样? A:改变Canvas大小后画面拉伸,因为你没有更新视口设置。

17. DrawCall

维度 内容
定义 CPU向GPU发送的一次绘制命令
一句话本质 "画图指令":CPU告诉GPU画什么、怎么画
类比解释 打电话叫出租车。10个DrawCall = 打10次电话叫10辆车。1个DrawCall = 打1次电话叫1辆大巴载10人
技术细节 每次DrawCall,CPU需要设置:Shader程序、VBO/IBO、纹理、Uniform变量、混合模式、深度/模板状态。这些设置在CPU端执行,是CPU瓶颈。GPU反而可能在等CPU。目标:用最少的DrawCall画出相同的画面
常见误区 ❌ 以为DrawCall少就一定性能好(DrawCall少但片元着色器复杂,GPU还是瓶颈)
❌ 以为DrawCall只影响CPU(DrawCall切换也会打断GPU的流水线)

18. 合批 (Batching)

维度 内容
定义 将多个满足相同条件的渲染对象合并到一个DrawCall中绘制
一句话本质 "拼车":相同目的地(纹理相同)、相同车型(材质相同)就拼到一辆车
类比解释 快递分拣。同一小区的包裹(相同纹理)用同一辆车(同一个DrawCall)送,而不是每包裹一辆车
技术细节 合批条件(4个必须全部满足):(1)相同纹理/图集;(2)相同材质/Shader;(3)相同混合模式;(4)相同深度/模板状态。Cocos的Batcher2D自动合批:把多个Sprite的顶点合并到一个大VBO,一次DrawCall绘制
常见误区 ❌ 以为所有相同纹理的Sprite都能合批(中间有Mask/不同材质会打断)
❌ 以为合批只减少DrawCall(也减少CPU遍历开销和状态切换开销)

19. 着色器程序 (Shader Program)

维度 内容
定义 顶点着色器和片元着色器链接后的可执行程序
一句话本质 GPU的" executable":告诉GPU怎么画
类比解释 菜谱。顶点着色器是"备菜步骤",片元着色器是"烹饪步骤",链接后就是完整的菜谱
技术细节 创建流程:createShader → shaderSource → compileShader(顶点+片元分别编译)→ createProgram → attachShader → linkProgram → useProgram。编译后的Shader存储在GPU中,useProgram切换时有开销
常见误区 ❌ 编译失败不检查(必须用getShaderParameter检查COMPILE_STATUS)
❌ 每帧都useProgram(应该尽量减少Shader切换)

20. GLSL (OpenGL Shading Language)

为什么需要这个概念? GPU不认识JavaScript,它有自己的编程语言。GLSL就是写Shader用的语言,类似于C语言的语法。

维度 内容
定义 OpenGL的着色器编程语言,WebGL使用GLSL ES版本
一句话本质 GPU的"编程语言":用代码控制GPU怎么画
类比解释 厨师的专业术语。GLSL就是GPU能听懂的语言,用它可以精确控制每个像素的颜色
技术细节 WebGL1用GLSL ES 1.0,WebGL2用GLSL ES 3.0。主要数据类型:float、vec2/3/4、mat2/3/4、sampler2D。修饰符:attribute(顶点属性)、uniform(全局常量)、varying(顶点→片元传递)。精度修饰符:highp、mediump、lowp
常见误区 ❌ 把JavaScript语法用到GLSL中(GLSL是C-like语法,有严格类型)
❌ 忽略精度修饰符(移动端必须用lowp节省性能)

代码示例

// GLSL和JavaScript的关键区别

// 1. 必须声明类型(JS不需要)
float x = 1.0;      // 正确
var x = 1.0;        // 错误!GLSL没有var

// 2. 向量类型
vec2 pos = vec2(1.0, 2.0);  // 二维向量
vec3 color = vec3(1.0, 0.0, 0.0);  // 三维向量(RGB)
vec4 rgba = vec4(color, 1.0);  // 四维向量,前3个来自color

// 3. 精度修饰符(移动端重要)
precision mediump float;  // 声明默认精度
highp vec3 position;      // 高精度(位置)
lowp vec4 color;          // 低精度(颜色)

自问自答

  • Q:GLSL和JavaScript最大的区别是什么? A:GLSL是强类型的(必须声明变量类型),且没有动态内存分配。它更像C语言。
  • Q:如果不懂GLSL会怎样? A:写Shader时把JS语法套进去,导致编译失败。或者忽略精度修饰符,在移动端出现颜色断层或性能问题。

二、GPU架构术语

21. 显存 (Video Memory / VRAM)

维度 内容
定义 GPU专用的内存,用于存储纹理、顶点数据、帧缓冲等
一句话本质 GPU的"硬盘":存数据的地方
类比解释 画家的颜料柜。所有颜料(纹理)、画布(帧缓冲)都放在柜子里,画家(GPU)随时取用
技术细节 显存类型:GDDR6/GDDR6X/HBM2。带宽比CPU内存高得多(几百GB/s vs 几十GB/s)。显存容量限制:低端机可能只有1-2GB,高端显卡24GB+。纹理是显存占用大户:2048×2048 RGBA8888 = 16MB
常见误区 ❌ 以为显存越大越好(对2D游戏来说,2GB足够,关键是带宽)
❌ 不压缩纹理(未压缩纹理占用大量显存,导致低端机闪退)

22. 纹理 (Texture)

为什么需要这个概念? 3D模型本身是"白模"(没有颜色)。纹理就是给模型"贴皮肤"的图片,让模型看起来有细节、有颜色。

维度 内容
定义 存储在GPU显存中的二维图像数据,用于给模型贴图
一句话本质 "贴纸":给3D模型贴上的图片
类比解释 给石膏像上色。先做好一张彩图(纹理),然后贴到石膏像表面(UV映射)
技术细节 纹理参数:wrapS/wrapT(边缘重复/镜像/拉伸)、minFilter/magFilter(缩小/放大过滤:NEAREST/LINEAR/MIPMAP)。纹理格式:RGBA8888(32位)、RGB565(16位)、RGBA4444(16位)。Mipmap:预生成缩小版本,提升远处纹理的采样质量和性能
常见误区 ❌ 纹理尺寸不是2的幂次(WebGL1要求2的幂次才能重复,WebGL2无此限制)
❌ 忘记生成Mipmap(远处纹理闪烁/锯齿)

代码示例

// 加载纹理
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);

// 设置纹理参数
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);  // 水平边缘拉伸
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);  // 垂直边缘拉伸
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);     // 缩小时线性插值
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);     // 放大时线性插值

// 上传图片数据到GPU
const image = new Image();
image.onload = () => {
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
};
image.src = 'sprite.png';

自问自答

  • Q:纹理存在哪里? A:在GPU显存中。texImage2D()就是把图片数据从CPU内存上传到GPU显存。
  • Q:如果不懂纹理会怎样? A:Sprite显示黑屏或花屏,因为你没有正确加载或绑定纹理。

23. UV坐标 / 纹理坐标 (Texture Coordinates)

维度 内容
定义 定义顶点在纹理上的对应位置的二维坐标
一句话本质 "地图坐标":告诉GPU模型的每个点对应纹理的哪个位置
类比解释 地图的经纬度。UV就是纹理上的"经纬度",(0,0)是左下角,(1,1)是右上角
技术细节 范围[0,1],U是水平方向,V是垂直方向。每个顶点一个UV坐标,光栅化时自动插值。UV可以超出[0,1]范围,配合wrap模式实现重复/镜像效果。Sprite的4个顶点UV:(0,0)、(1,0)、(1,1)、(0,1)
常见误区 ❌ UV坐标用像素值(必须用归一化的0-1范围)
❌ V坐标方向搞反(OpenGL/WebGL的V=0是底部,DirectX的V=0是顶部)

24. Mipmap

为什么需要这个概念? 当一个纹理在远处显示时,它在屏幕上只占几个像素。如果直接用原始纹理采样,GPU需要从几千像素的纹理中"跳过"大部分像素,导致摩尔纹和闪烁。Mipmap预先生成缩小版本,让GPU可以直接用合适的尺寸采样。

维度 内容
定义 预生成的纹理缩小版本序列,每个级别尺寸减半
一句话本质 "纹理的缩略图":远处用小的,近处用大的
类比解释 地图的不同缩放级别。看全貌用小地图,看细节用大地图。Mipmap就是预先准备好所有缩放级别
技术细节 级别0是原始纹理,级别1是1/2尺寸,级别2是1/4...直到1×1。总内存增加约33%。采样时GPU根据像素覆盖的纹理区域大小自动选择合适级别。过滤模式:NEAREST_MIPMAP_NEAREST(快但跳变)、LINEAR_MIPMAP_LINEAR(慢但平滑,三线性过滤)
常见误区 ❌ 以为Mipmap只是优化性能(也解决远处纹理的摩尔纹和闪烁)
❌ 所有纹理都生成Mipmap(UI/2D精灵通常不需要,反而模糊)

自问自答

  • Q:Mipmap会增加多少内存? A:总内存增加约33%。因为 1 + 1/4 + 1/16 + ... ≈ 1.33。
  • Q:如果不懂Mipmap会怎样? A:3D场景中远处的纹理会闪烁、出现摩尔纹,画面质量很差。

25. 纹理过滤 (Texture Filtering)

维度 内容
定义 纹理采样时计算像素颜色的插值方法
一句话本质 "放大缩小算法":纹理和屏幕像素不匹配时怎么采样
类比解释 照片放大。NEAREST是简单复制像素(马赛克),LINEAR是双线性插值(平滑模糊)
技术细节 放大过滤(magFilter):NEAREST(快、像素风)、LINEAR(默认、平滑)。缩小过滤(minFilter):NEAREST(闪烁)、LINEAR(摩尔纹)、NEAREST_MIPMAP_NEAREST、LINEAR_MIPMAP_NEAREST、NEAREST_MIPMAP_LINEAR、LINEAR_MIPMAP_LINEAR(最佳)。2D游戏通常LINEAR/LINEAR
常见误区 ❌ 缩小用LINEAR(远处会摩尔纹,应该用Mipmap)
❌ 像素风游戏用LINEAR(应该用NEAREST保持锐利像素边缘)

26. 纹理图集 (Texture Atlas / Sprite Sheet)

维度 内容
定义 将多张图片合并到一张大纹理中的技术
一句话本质 "相册":把多张照片合到一页,翻一次看所有
类比解释 快递的集装箱。原来10个小包裹发10次(10个DrawCall),现在装到一个集装箱发1次(1个DrawCall)
技术细节 优势:(1)减少DrawCall(相同图集自动合批);(2)减少纹理切换开销;(3)更好的Mipmap支持。注意:图集大小不能超过GPU最大纹理尺寸(低端机2048×2048)。图集之间要留padding(1-2像素)防止纹理渗透
常见误区 ❌ 图集越大越好(超过2048低端机不支持,加载慢)
❌ 图集不留间隙(相邻图片的像素会互相渗透,出现杂边)

27. 动态图集 (Dynamic Atlas)

维度 内容
定义 运行时自动将小纹理合并到大图集的技术
一句话本质 "自动拼车":运行时把小包裹自动装进集装箱
类比解释 快递公司的智能分拣系统。包裹来了自动分类、装箱,不需要人工预先打包
技术细节 Cocos的Dynamic Atlas Manager自动将小于256×256的散图合并到2048×2048大图集。优点:无需手动打包,运行时自动合批。缺点:额外内存开销(每张图集16MB)、频繁换图导致碎片化、大图(>256)不参与。小游戏平台慎用(内存限制严格)
常见误区 ❌ 开启动态图集就不管了(需要监控图集数量和内存)
❌ 所有纹理都依赖动态图集(大图、频繁变化的图应该手动打包)

28. 统一缓冲区 / UBO (Uniform Buffer Object)

维度 内容
定义 存储在GPU显存中的Uniform数据缓冲区,多个Shader共享
一句话本质 "Uniform的仓库":一次上传,多处使用
类比解释 公司的公告栏。贴一次公告(上传Uniform),所有员工(Shader)都能看到
技术细节 WebGL2原生支持,WebGL1需要扩展。优势:减少Uniform上传开销(一次绑定vs逐个设置)、多个Shader共享同一组Uniform(如相机参数)。Cocos 3.8.x在WebGL2下自动使用UBO优化
常见误区 ❌ WebGL1环境用UBO(需要检查扩展支持)
❌ UBO数据不更新(UBO内容变化需要重新上传,不是自动同步的)

三、WebGL/API术语

29. WebGL上下文 (WebGL Context)

维度 内容
定义 JavaScript访问GPU渲染能力的接口对象
一句话本质 "GPU的遥控器":JS控制GPU的入口
类比解释 电视遥控器。遥控器(WebGL上下文)本身不播放画面,但它可以控制电视(GPU)播放什么
技术细节 创建:canvas.getContext('webgl')'webgl2'。WebGL上下文是状态机:所有操作都修改当前上下文的状态(当前Shader、当前纹理、当前缓冲区等)。Cocos中通过cc.director.root.device.gl可以访问底层WebGL上下文
常见误区 ❌ 创建多个WebGL上下文(每个上下文占用大量资源,一个页面通常只有一个)
❌ 上下文丢失不处理(浏览器可能回收GPU资源,需要监听webglcontextlost事件)

30. WebGL扩展 (WebGL Extension)

维度 内容
定义 WebGL标准之外的额外功能,通过扩展机制启用
一句话本质 "插件":给WebGL增加额外能力
类比解释 浏览器的插件。基本浏览器能上网,安装插件后能播视频、去广告
技术细节 常用扩展:OES_texture_float(浮点纹理)、WEBGL_compressed_texture_s3tc(DXT压缩)、EXT_shader_texture_lod(Shader中手动选Mipmap级别)、OES_vertex_array_object(VAO)。WebGL2很多功能原生支持,不需要扩展。Cocos GFX层自动处理扩展检测和启用
常见误区 ❌ 假设扩展一定存在(必须检查返回值,不存在时要有fallback)
❌ 扩展名拼写错误(区分大小写,如OES不是oes)

31. VAO (Vertex Array Object)

维度 内容
定义 存储顶点属性配置状态的对象,可以一次性绑定所有顶点属性
一句话本质 "顶点配置的快照":保存一次,重复使用
类比解释 预设的电台频道。调好后保存,下次一键切换,不需要重新调频
技术细节 没有VAO时:每次绘制都要重新设置vertexAttribPointer和enableVertexAttribArray。有VAO时:创建时设置一次,绘制时只需bindVertexArrayOject。WebGL1需要OES_vertex_array_object扩展,WebGL2原生支持。Cocos底层自动使用VAO优化
常见误区 ❌ VAO存储顶点数据(VAO只存储配置,不存储数据,数据仍在VBO中)
❌ 一个VAO绑定多个VBO(一个VAO可以引用多个VBO,但通常一个模型一个VAO)

32. FBO (Frame Buffer Object)

维度 内容
定义 离屏渲染的目标,可以将渲染结果输出到纹理而不是屏幕
一句话本质 "离屏画布":画到纹理上,而不是屏幕上
类比解释 草稿纸。先在草稿纸上画(FBO),满意后再贴到正式画布上(屏幕)
技术细节 FBO可以附加:颜色附件(纹理或renderbuffer)、深度附件、模板附件。用途:RenderTexture(Cocos中相机渲染到纹理)、后处理效果(模糊、发光)、反射/阴影贴图。注意:FBO的纹理尺寸影响性能和内存
常见误区 ❌ FBO和默认帧缓冲混用(切换有开销,尽量减少切换次数)
❌ FBO尺寸和屏幕不一致(会导致画面拉伸或模糊)

33. 精度修饰符 (Precision Qualifier)

维度 内容
定义 GLSL中指定变量计算精度的关键字
一句话本质 "计算精度档位":高精度慢,低精度快
类比解释 计算器的小数位数。highp是10位小数(精确但慢),lowp是2位小数(快但不精确)
技术细节 highp(高精度,32位浮点,范围大)、mediump(中精度,16位浮点,范围±2^14)、lowp(低精度,8-10位,范围±2^8)。默认精度:precision mediump float;。移动端建议:颜色用lowp,UV用mediump,位置用highp。WebGL1中片元着色器默认没有高精度浮点
常见误区 ❌ 所有变量都用highp(浪费性能,移动端可能不支持)
❌ 在片元着色器里用highp(WebGL1片元着色器可能不支持highp)

四、性能指标术语

34. FPS (Frames Per Second)

为什么需要这个概念? FPS是衡量游戏流畅度的最直观指标。玩家能直接感受到卡顿,而FPS就是量化这种感受的数字。

维度 内容
定义 每秒渲染的帧数
一句话本质 "流畅度指标":每秒换多少张画
类比解释 翻书动画。FPS=60就像每秒翻60页,看起来是流畅的动画。FPS=10就像每秒翻10页,明显卡顿
技术细节 60fps = 每帧16.67ms;30fps = 每帧33.33ms。人眼舒适下限:30fps。游戏目标:60fps。VR需要90fps+。Cocos中cc.debug.setDisplayStats(true)显示FPS。注意:FPS高不代表性能好(可能是场景简单)
常见误区 ❌ 只看FPS不看帧时间(FPS波动大时,看平均帧时间更稳定)
❌ 追求120fps不考虑耗电(移动端高帧率=高耗电+发热)

自问自答

  • Q:FPS和帧时间有什么关系? A:FPS = 1000 / 帧时间(ms)。60fps = 16.67ms/帧。帧时间比FPS更稳定,优化时应该看帧时间。
  • Q:如果不懂FPS会怎样? A:你无法判断游戏是否流畅,也不知道优化目标是什么。

35. DrawCall数

维度 内容
定义 一帧中CPU向GPU发送的绘制命令次数
一句话本质 "CPU喊话次数":喊一次GPU画一次
类比解释 老师点名。点10个同学(10个DrawCall)vs 点一次"全班起立"(1个DrawCall)
技术细节 2D游戏目标:<50个DrawCall。3D游戏目标:<200个DrawCall。每个DrawCall的CPU开销约0.1-1ms(取决于CPU性能和设置复杂度)。DrawCall是2D游戏的第一优化指标。Cocos中cc.debug.setDisplayStats(true)显示DrawCall数
常见误区 ❌ 只看DrawCall不看Overdraw(DrawCall少但同一个像素画10次,GPU还是卡)
❌ 以为DrawCall=0最好(什么都不画当然0,但没有意义)

36. Overdraw

维度 内容
定义 同一个像素被多次绘制的现象
一句话本质 "重复劳动":同一个位置画了又画
类比解释 刷墙。先刷红色,再刷蓝色盖住,再刷绿色盖住。Overdraw=3,但只看到绿色
技术细节 计算方式:总片元数 / 屏幕像素数。理想值=1(每个像素只画一次)。UI游戏Overdraw通常2-4x。减少方法:从前到后绘制不透明物体(Early-Z剔除)、避免大面积半透明叠加、使用遮挡剔除
常见误区 ❌ 只关注DrawCall忽略Overdraw(Overdraw高时GPU在无效计算)
❌ 全屏半透明背景(这是Overdraw杀手,每个像素至少画2次)

37. 帧时间 (Frame Time)

维度 内容
定义 渲染一帧所需的时间(毫秒)
一句话本质 "画一帧要多久":时间越短越流畅
类比解释 画一幅画的时间。画得越快,每秒能画的画越多
技术细节 目标:16.67ms(60fps)。>16.67ms → 掉帧。<33.33ms → 至少30fps。测量方法:Chrome DevTools Performance面板、Cocos DisplayStats。帧时间比FPS更稳定(FPS是帧时间的倒数,波动大)
常见误区 ❌ 只看平均帧时间(要看最大帧时间,卡顿往往由几帧的尖峰引起)
❌ 启动时帧时间高就优化(启动加载资源帧时间高是正常的)

38. GPU时间 / GPU Frame Time

维度 内容
定义 GPU处理一帧渲染所需的时间
一句话本质 "GPU干活时间":GPU有多忙
类比解释 工厂生产线的运转时间。GPU时间高 = 生产线满负荷运转
技术细节 测量工具:SpectorJS、Chrome GPU Timeline、RenderDoc。细分:顶点着色器时间、片元着色器时间、纹理采样时间、带宽瓶颈。如果GPU时间 < CPU时间 → CPU瓶颈(DrawCall太多)。如果GPU时间 > CPU时间 → GPU瓶颈(Shader太复杂/Overdraw高)
常见误区 ❌ 分不清CPU瓶颈和GPU瓶颈(优化方向完全不同)
❌ 只优化CPU忽略GPU(2D游戏常见CPU瓶颈,但复杂Shader会导致GPU瓶颈)

39. 带宽 (Bandwidth)

维度 内容
定义 GPU与显存之间的数据传输速率
一句话本质 "数据传输速度":路有多宽、车有多快
类比解释 高速公路的车流量。带宽高 = 高速公路宽,同时能跑很多车(传输大量数据)
技术细节 单位:GB/s。高端显卡900+GB/s,集成显卡几十GB/s。带宽瓶颈表现:纹理采样慢、大量顶点数据传输卡顿。优化:压缩纹理(减少数据量)、Mipmap(减少采样数据)、合并纹理(减少切换)
常见误区 ❌ 只优化计算忽略带宽(Shader计算很快,但等数据从显存来会卡住)
❌ 大量小纹理(每个纹理切换都导致带宽开销,应该合并)

五、Cocos引擎术语

40. Batcher2D

为什么需要这个概念? Cocos场景中可能有几百个Sprite。如果每个Sprite都发一个DrawCall,性能会极差。Batcher2D就是Cocos内置的"自动合批系统",帮你把能合并的Sprite自动合并。

维度 内容
定义 Cocos 2D渲染系统的核心类,负责收集、合并、提交2D渲染数据
一句话本质 "2D渲染管家":收集所有2D元素,合并后发给GPU
类比解释 餐厅的点菜系统。顾客(Sprite)点菜,系统(Batcher2D)按菜品(纹理)分类,同一类的菜一起下单(合批),减少厨房(GPU)的工作量
技术细节 核心方法:walk()遍历场景树 → commitComp()判断合批条件 → flush()提交DrawCall。合批条件:相同纹理哈希、相同材质、相同深度/模板状态。每帧执行:遍历所有可见节点,收集渲染数据,自动合批,提交GPU
常见误区 ❌ 以为Batcher2D对所有节点都合批(Mask、自定义材质、Graphics会打断合批)
❌ 节点顺序不影响合批(Batcher2D按遍历顺序合批,节点顺序直接影响能否合批)

自问自答

  • Q:Batcher2D什么时候会打断合批? A:纹理不同、材质不同、混合模式不同、有Mask、使用了Graphics组件等都会打断合批。
  • Q:如果不懂Batcher2D会怎样? A:你的游戏DrawCall很高但不知道为什么。实际上可能是节点顺序不对,或者中间插了Mask导致无法合批。

41. RenderPipeline

维度 内容
定义 Cocos的渲染管线管理器,控制整个渲染流程
一句话本质 "渲染总指挥":安排谁先画、谁后画
类比解释 电影导演。决定拍摄顺序(渲染顺序)、调用哪些演员(Shader)、用什么道具(纹理)
技术细节 Cocos 3.8.x使用可定制的RenderPipeline。默认流程:更新相机 → 收集可见物体 → 排序(按优先级/深度) → 执行RenderPass(阴影/主场景/后处理) → 提交CommandBuffer。支持自定义RenderPipeline实现特殊效果
常见误区 ❌ 2D游戏不需要关心RenderPipeline(2D也走RenderPipeline,只是流程简单)
❌ 多相机渲染顺序随意(相机priority决定渲染顺序,影响最终画面)

42. GFX (Graphics API Layer)

维度 内容
定义 Cocos的图形API抽象层,封装WebGL/WebGL2/Metal/Vulkan
一句话本质 "翻译官":把Cocos的渲染指令翻译成不同平台的API
类比解释 联合国翻译。各国代表(WebGL/Metal/Vulkan)说不同语言,GFX是同声传译,让Cocos代码一套跑所有平台
技术细节 GFX抽象了:Device(设备)、Buffer(缓冲区)、Texture(纹理)、Shader(着色器)、CommandBuffer(命令缓冲)、Framebuffer(帧缓冲)。H5平台使用WebGLDevice,原生iOS使用MetalDevice。Cocos代码调用GFX API,GFX底层转换为对应平台的原生API
常见误区 ❌ 直接调用GFX API(应该使用Cocos高层API,GFX是内部实现)
❌ 以为GFX有性能损耗(GFX是薄封装,几乎没有额外开销)

43. Material / 材质

维度 内容
定义 定义物体外观的属性集合,包括Shader、纹理、渲染状态
一句话本质 "物体的皮肤":决定物体长什么样
类比解释 人的衣服。同一个人(模型),穿不同衣服(材质)看起来完全不同
技术细节 Material包含:effectAsset(引用哪个Effect)、technique(使用哪个technique)、passes(Pass数组,每个Pass包含一个Shader程序)、properties(运行时参数,如颜色、透明度)。两个Sprite使用不同Material → 不能合批。修改Material的Uniform → 所有使用该Material的物体都受影响
常见误区 ❌ 直接修改sharedMaterials(会影响所有使用同材质的Sprite,应该用getMaterial(0)获取实例)
❌ 每个Sprite创建独立Material(材质实例化会打断合批)

44. Effect / 效果文件

维度 内容
定义 Cocos的Shader定义文件,包含着色器代码和渲染状态配置
一句话本质 "Shader配方书":定义怎么画、用什么参数
类比解释 菜谱。Effect是菜谱,Material是按菜谱做的菜,Shader是具体的烹饪步骤
技术细节 Effect文件(.effect)包含:CCEffect块(定义techniques、passes、properties)、CCProgram块(顶点/片元着色器代码GLSL)。一个Effect可以有多个technique(如opaque/transparent),每个technique可以有多个pass(多Pass渲染)。Cocos内置Effect:sprite、label、graphics等
常见误区 ❌ Effect和Material混淆(Effect是定义,Material是实例)
❌ 修改内置Effect(应该创建自定义Effect,避免引擎升级覆盖)

45. RenderQueue / 渲染队列

维度 内容
定义 控制渲染对象绘制顺序的队列机制
一句话本质 "排队系统":决定谁先画、谁后画
类比解释 医院叫号系统。急诊优先(不透明物体先画),普通号后叫(透明物体后画)
技术细节 Cocos中渲染队列值越小越早绘制。不透明物体:RenderQueue < 2500(从前往后,利于Early-Z)。透明物体:RenderQueue >= 2500(从后往前,利于Alpha混合)。同一队列内按其他规则排序。自定义队列:可以创建自己的RenderQueue控制特殊物体的绘制顺序
常见误区 ❌ 透明物体放不透明队列(会导致混合错误)
❌ 以为RenderQueue是唯一排序依据(同队列内还有深度排序、材质排序等)

46. 脏标记 (Dirty Flag)

维度 内容
定义 标记对象属性是否发生变化,只有变化时才更新
一句话本质 "变化检测器":没变就不重算
类比解释 黑板擦。黑板上10行字,只有1行写错了,只擦那1行重写,不用全擦
技术细节 Cocos中的脏标记:TransformBit(位置/旋转/缩放变化)、markForUpdateRenderData(渲染数据需要更新)。原理:属性变化时设置标记 → 渲染阶段检查标记 → 只有标记为脏才重新计算。效果:100个Sprite每帧更新 → 只更新变化的 → CPU降低50-80%
常见误区 ❌ 每帧都设置position(即使值没变也标记脏,应该判断后再设置)
❌ 手动调用markForUpdateRenderData(引擎自动管理,除非你知道在做什么)

47. 静态合批 (Static Batching)

维度 内容
定义 对不移动、不变化的节点标记为静态,跳过每帧的遍历和更新
一句话本质 "固定展品":摆好就不动,不用每天重新摆
类比解释 博物馆的展品。不会动的展品(静态节点),只需要摆一次,不用每天重新摆
技术细节 Cocos中设置node._static = true(3.8.x内部属性)。效果:跳过Transform更新遍历、跳过渲染数据重建。适用:背景UI、固定装饰、不交互的元素。注意:静态节点不能有动态子节点,设置后子节点的变换更新会被跳过
常见误区 ❌ 所有节点都设_static(动态节点设静态会导致不更新)
❌ _static是公开API(这是内部属性,官方不推荐直接使用)

48. 动态合批 (Dynamic Batching)

维度 内容
定义 引擎在运行时自动将满足条件的渲染对象合并到一个DrawCall
一句话本质 "自动拼车":满足条件就自动合并
类比解释 拼车软件。只要目的地相同(纹理相同)、车型相同(材质相同),就自动拼到一辆车
技术细节 Batcher2D每帧自动执行。条件:相同纹理、相同材质、相同混合模式、相同深度/模板状态、顶点数不超过65535。优点:自动,无需手动操作。缺点:每帧遍历判断有CPU开销、条件不满足时不合批。小游戏平台:动态合批正常可用,但要注意CPU开销
常见误区 ❌ 以为动态合批是万能的(条件不满足时不会合批)
❌ 动态合批和静态合批混淆(静态合批跳过遍历,动态合批每帧遍历)

49. Label组件

维度 内容
定义 Cocos中显示文字的组件
一句话本质 "文字渲染器":把文字变成图片显示
类比解释 打印机。把文字(字符串)打印(渲染)到纸上(屏幕)
技术细节 三种类型:TTF(TrueType字体,动态生成纹理,支持任意文字但每变一次要重建)、SystemFont(系统字体,性能最好但不同平台效果不同)、BMFont(位图字体,预生成纹理,性能好但只支持固定字符集)。TTF Label的合批:相同字体、相同大小、相同颜色的Label可以合批
常见误区 ❌ TTF Label频繁修改文字(每次修改都重建纹理,非常耗CPU)
❌ 用TTF显示大量静态文字(应该用BMFont或SystemFont)

50. Mask组件

维度 内容
定义 实现遮罩效果的组件,只显示特定区域内的内容
一句话本质 "镂空模板":只让特定形状的内容显示
类比解释 剪纸。把纸剪成形状(Mask),贴在照片上,只露出剪出的部分
技术细节 实现方式:模板测试(Stencil Test)。Mask节点绘制时写入模板缓冲,子节点绘制时检查模板值。性能影响:Mask打断合批(模板状态变化)、增加2个DrawCall(写模板+用模板)。建议:尽量少用Mask,能用矩形裁剪(ScrollView的裁剪)就不用Mask
常见误区 ❌ Mask嵌套太多层(每层Mask增加2个DrawCall和模板操作开销)
❌ 以为Mask只是视觉裁剪(Mask是渲染层面的,不影响节点的事件响应区域)

六、高级渲染术语

51. LOD (Level of Detail)

维度 内容
定义 根据物体距离相机的远近,使用不同精度的模型
一句话本质 "远近有别":远处模糊,近处清晰
类比解释 看风景。远处的山只看轮廓(低模),近处的花要看细节(高模)
技术细节 通常设置3-4个级别:LOD0(最近,最高精度)、LOD1(中等距离)、LOD2(远距离,最低精度)。切换方式:按距离切换、按屏幕占比切换。注意:LOD切换要平滑过渡,否则会出现"弹出"(Pop)现象
常见误区 ❌ 2D游戏也用LOD(2D游戏通常不需要,Sprite本身就是平面)
❌ LOD切换距离设置不合理(太近切换会看到模型变化,太远切换浪费性能)

52. Occlusion Culling / 遮挡剔除

维度 内容
定义 不渲染被其他物体完全遮挡的物体
一句话本质 "看不见的就不画"
类比解释 站在墙后的人。既然被墙挡住了,就不用画这个人
技术细节 实现方式:软件遮挡查询(CPU计算遮挡关系)、硬件遮挡查询(GPU的OCCLUSION_QUERY)、预计算遮挡(烘焙遮挡数据)。Cocos 3.8.x对2D游戏自动做简单的屏幕裁剪(超出屏幕的不渲染),但3D遮挡剔除需要额外实现
常见误区 ❌ 遮挡剔除没有开销(计算遮挡本身有CPU/GPU开销,需要权衡)
❌ 所有游戏都需要遮挡剔除(2D游戏通常不需要,3D大场景才需要)

53. GPU Instancing

维度 内容
定义 一次DrawCall绘制多个相同几何的实例,每个实例可以有不同的变换和颜色
一句话本质 "批量复制":画100个相同的树,只要1个DrawCall
类比解释 印章。刻一个章(模型),盖100次(100个实例),每次盖在不同位置
技术细节 WebGL2原生支持,WebGL1需要ANGLE_instanced_arrays扩展。实例数据通过attribute传递(每个实例一个值,不是每个顶点)。Cocos 3.8.x在3D渲染中支持GPU Instancing。限制:所有实例必须共享相同几何和材质,只有变换/颜色等可以不同
常见误区 ❌ Instancing和动态合批混淆(Instancing是GPU特性,动态合批是CPU合并顶点)
❌ 以为Instancing对所有物体都适用(只有大量相同几何的物体才适合,如草、树、粒子)

54. SRGB vs Linear

维度 内容
定义 两种不同的颜色空间,SRGB是非线性的,Linear是线性的
一句话本质 "颜色存储格式":SRGB省空间,Linear适合计算
类比解释 音量的分贝刻度。人耳对低音更敏感,所以分贝是非线性的。类似地,人眼对暗部更敏感,SRGB在暗部存储更多细节
技术细节 SRGB:存储时gamma编码(约0.45次方),显示时gamma解码(约2.2次方)。Linear:线性存储,直接参与光照计算。问题:如果在SRGB空间做光照计算,结果会偏暗/偏亮。正确流程:SRGB纹理 → 解码为Linear → 光照计算 → 编码为SRGB → 显示。Cocos自动处理颜色空间转换
常见误区 ❌ 在线性空间存储纹理(暗部精度不足,出现色带)
❌ 在SRGB空间做Shader计算(光照结果错误)

55. MRT (Multiple Render Targets)

维度 内容
定义 一次渲染同时输出到多个颜色缓冲
一句话本质 "一鱼多吃":画一次,得到多张图
类比解释 拍照时同时拍彩色和黑白。按一次快门,得到两种照片
技术细节 WebGL2原生支持,WebGL1不支持。用途:延迟渲染(同时输出颜色/法线/深度)、后处理(输出原图+模糊图)。限制:所有目标尺寸必须相同。Cocos 3.8.x的RenderPipeline支持MRT
常见误区 ❌ MRT目标尺寸不同(GPU要求所有目标尺寸一致)
❌ 滥用MRT(增加带宽压力,只在需要时用)

56. Compute Shader

维度 内容
定义 在GPU上执行通用计算任务的着色器,不直接参与渲染
一句话本质 "GPU计算器":用GPU做非图形计算
类比解释 用显卡挖矿。显卡本来是用来画画的,但也可以用来做数学计算(挖矿就是解数学题)
技术细节 WebGL不支持Compute Shader(需要WebGPU)。用途:粒子系统、物理模拟、图像处理、AI推理。优势:利用GPU并行计算能力,比CPU快几十到几百倍。Cocos目前主要通过原生插件支持Compute Shader
常见误区 ❌ WebGL环境用Compute Shader(WebGL不支持,必须用WebGPU或原生)
❌ 所有计算都用GPU(数据在CPU和GPU之间传输有开销,小计算在CPU更快)

57. 后处理 (Post-Processing)

维度 内容
定义 在场景渲染完成后,对最终画面进行额外处理的效果
一句话本质 "照片滤镜":画完后再加特效
类比解释 拍照后用PS加滤镜。先拍一张照片(场景渲染),然后调色、加模糊、加光晕(后处理)
技术细节 实现方式:渲染场景到FBO纹理 → 用全屏Quad绘制该纹理 → 片元着色器处理每个像素。常见效果:Bloom(泛光)、Blur(模糊)、Tone Mapping(色调映射)、Color Grading(调色)。性能影响:至少增加1个全屏DrawCall + 片元着色器处理所有像素
常见误区 ❌ 后处理不影响性能(全屏后处理每帧处理所有像素,是性能杀手)
❌ 所有效果都堆上去(后处理效果叠加,性能和画质都要权衡)

58. 延迟渲染 (Deferred Rendering)

为什么需要这个概念? 传统渲染(Forward Rendering)中,每个物体都要计算光照。如果场景有100个光源,每个物体都要算100次光照,性能爆炸。延迟渲染把光照计算推迟到最后,只算屏幕上可见的像素,光源数量不再影响性能。

维度 内容
定义 将光照计算推迟到几何信息收集完成后进行的渲染技术
一句话本质 "先存信息,后算光照":不是画一个物体算一次光照,而是全部存下来统一算
类比解释 装修房子。传统方式:每刷一面墙就上一次色(Forward Rendering)。延迟渲染:先刷完所有墙(存几何信息),最后统一上色(光照计算)
技术细节 G-Buffer:存储位置/法线/颜色/材质属性的多目标渲染纹理。优点:光源数量不影响性能(适合多光源场景)、光照计算在屏幕空间(只计算可见像素)。缺点:需要MRT支持、内存开销大(G-Buffer占显存)、半透明物体需要单独处理(Forward Rendering)。Cocos 3.8.x支持延迟渲染管线
常见误区 ❌ 2D游戏用延迟渲染(2D游戏通常只有1-2个光源,Forward Rendering更快)
❌ 延迟渲染一定比Forward好(简单场景Forward更快,延迟渲染有额外开销)

自问自答

  • Q:延迟渲染为什么不适合2D游戏? A:2D游戏通常只有1-2个光源,Forward Rendering已经足够快。延迟渲染需要额外的G-Buffer内存和MRT支持,对2D来说是"杀鸡用牛刀"。
  • Q:如果不懂延迟渲染会怎样? A:在3D项目中盲目使用延迟渲染,导致内存占用过高、半透明物体处理困难。

学习建议

如何高效使用本文档

第1阶段:建立框架(1-2天)

  • 通读所有术语的"一句话本质"和"类比解释"
  • 不需要记住技术细节,先建立直觉认知
  • 目标:看到术语能知道它大概是干嘛的

第2阶段:深入理解(1周)

  • 按分类逐个学习,重点看"技术细节"
  • 配合《GPU渲染管线详解.md》一起阅读
  • 目标:能用自己的话解释每个术语

第3阶段:实践验证(持续)

  • 写代码时遇到不懂的词,回来查文档
  • 重点关注"常见误区",避免踩坑
  • 目标:将知识转化为实际编码能力

第4阶段:面试准备(按需)

  • 重点记忆"一句话本质"和"类比解释"
  • 准备2-3个"常见误区"的应对策略
  • 目标:能流畅地回答技术面试问题

如果读完还是记不住怎么办?

  • 正常现象:58个术语不可能一次全记住
  • 建议策略:先记住你最常用的10-15个(如VBO、Shader、DrawCall、合批等)
  • 记忆技巧:把术语和实际项目中的问题联系起来("上次卡顿就是因为DrawCall太多")
  • 重复策略:每隔一段时间回来复习,每次都会有新收获

速查表

按分类速查

分类 名词
渲染管线 渲染管线、顶点、图元、顶点着色器、片元着色器、光栅化、逐片元操作、帧缓冲、深度缓冲、模板缓冲、混合、VBO、IBO、MVP矩阵、NDC、视口变换、DrawCall、合批、着色器程序、GLSL
GPU架构 显存、纹理、UV坐标、Mipmap、纹理过滤、纹理图集、动态图集、UBO
WebGL/API WebGL上下文、WebGL扩展、VAO、FBO、精度修饰符
性能指标 FPS、DrawCall数、Overdraw、帧时间、GPU时间、带宽
Cocos引擎 Batcher2D、RenderPipeline、GFX、Material、Effect、RenderQueue、脏标记、静态合批、动态合批、Label、Mask
高级渲染 LOD、遮挡剔除、GPU Instancing、SRGB vs Linear、MRT、Compute Shader、后处理、延迟渲染

关键数字记忆

数字 含义
4 Sprite顶点数、顶点着色器输出gl_Position(vec4)
6 Sprite索引数(2个三角形)、IBO索引数
16.67ms 60fps的目标帧时间
65535 单个DrawCall最大顶点数(uint16限制)
50 2D游戏DrawCall目标上限
207万 1080P屏幕像素数
128 WebGL1最小支持Uniform数量(vec4)
2048 低端机最大纹理尺寸
0-1 UV坐标范围、深度缓冲值范围
-1~1 NDC坐标范围
65535 单个DrawCall最大顶点数(uint16限制)
50 2D游戏DrawCall目标上限
207万 1080P屏幕像素数
128 WebGL1最小支持Uniform数量(vec4)
2048 低端机最大纹理尺寸
0-1 UV坐标范围、深度缓冲值范围
-1~1 NDC坐标范围
------ ------
渲染管线 渲染管线、顶点、图元、顶点着色器、片元着色器、光栅化、逐片元操作、帧缓冲、深度缓冲、模板缓冲、混合、VBO、IBO、MVP矩阵、NDC、视口变换、DrawCall、合批、着色器程序、GLSL
GPU架构 显存、纹理、UV坐标、Mipmap、纹理过滤、纹理图集、动态图集、UBO
WebGL/API WebGL上下文、WebGL扩展、VAO、FBO、精度修饰符
性能指标 FPS、DrawCall数、Overdraw、帧时间、GPU时间、带宽
Cocos引擎 Batcher2D、RenderPipeline、GFX、Material、Effect、RenderQueue、脏标记、静态合批、动态合批、Label、Mask
高级渲染 LOD、遮挡剔除、GPU Instancing、SRGB vs Linear、MRT、Compute Shader、后处理、延迟渲染

关键数字记忆

数字 含义
4 Sprite顶点数、顶点着色器输出gl_Position(vec4)
6 Sprite索引数(2个三角形)、IBO索引数
16.67ms 60fps的目标帧时间
65535 单个DrawCall最大顶点数(uint16限制)
50 2D游戏DrawCall目标上限
207万 1080P屏幕像素数
128 WebGL1最小支持Uniform数量(vec4)
2048 低端机最大纹理尺寸
0-1 UV坐标范围、深度缓冲值范围
-1~1 NDC坐标范围