GPU自动处理专题1-裁剪到底在裁什么(裁剪)

裁剪到底在裁什么

学 WebGL 3D 的时候,很多人都会反复看到一个词:

裁剪。

教程里经常会说:

  • 顶点先进入裁剪空间
  • GPU 会做裁剪
  • 裁剪之后再做透视除法

但很多人其实并没有真正搞明白:

裁剪到底在裁什么?

常见的困惑通常有这些:

  • 是不是把跑到屏幕外的点直接删掉
  • 是不是只裁顶点,不裁线和三角形
  • 为什么裁剪要发生在 clip space
  • 为什么不是到了 NDC 或屏幕坐标再裁
  • 如果一个三角形只有一半跑出去了,GPU 会怎么处理

如果这一步理解不透,前面学过的这些概念就会一直像断开的:

  • gl_Position
  • clip space
  • w
  • 透视除法
  • NDC
  • viewport

这篇文章就专门把"裁剪"这一步单独讲清楚。

学完这一篇,你应该能回答这些问题:

  1. 裁剪发生在哪个阶段
  2. 裁剪到底裁的是点、线、三角形,还是别的东西
  3. 为什么裁剪不是简单"删掉看不见的点"
  4. 为什么裁剪必须发生在透视除法之前
  5. 为什么裁剪空间会叫"裁剪空间"

一、先给最短答案

如果你只想先记住最核心的一句话,可以先记:

裁剪裁掉的不是"某个随便越界的像素",而是那些落在可见体之外的图元部分。GPU 会在裁剪空间里判断图元哪些部分还能进入后续流程,哪些部分必须被丢掉或切掉。

再压缩成一句更好记的话,就是:

text 复制代码
裁剪裁的是"图元中超出可见范围的部分"。

注意这里最关键的不是"顶点"两个字,而是:

text 复制代码
图元

也就是:

  • 线
  • 三角形

这些真正参与光栅化的几何单元。

二、先把裁剪放回完整管线里

前面的专题里你已经反复看过这条链:(这篇文章)

text 复制代码
相机坐标 -> 裁剪空间 -> 透视除法 -> NDC -> viewport -> 屏幕像素

现在把裁剪插进去,就会更完整一点:

text 复制代码
相机坐标
-> 投影矩阵
-> 裁剪空间
-> 裁剪
-> 透视除法
-> NDC
-> viewport
-> 屏幕像素

这说明:

  • 裁剪不是最后才发生的
  • 它也不是屏幕阶段的小修小补
  • 它发生在非常靠前的位置

而且这个位置不是随便选的,而是有严格原因。

三、为什么这一步叫"裁剪空间"

这个名字本身就已经在提示答案了。

clip space 之所以叫:

text 复制代码
裁剪空间

不是因为它"名字听起来专业",而是因为:

GPU 就是在这一层空间里判断图元哪些部分还应该被保留。

换句话说:

  • 顶点着色器输出 gl_Position
  • gl_Position 进入裁剪空间
  • 然后 GPU 开始做"可见性范围判断"

所以裁剪空间不是一个抽象中转站,它本身就是为裁剪这件事准备的标准空间。

四、裁剪到底在裁什么

这是整篇文章最核心的问题。

很多人会误以为:

"裁剪是不是就是把跑到屏幕外的顶点删掉?"

这个理解不完全对。

更准确地说:

裁剪裁的是图元中超出可见体的那部分几何。

什么叫图元

WebGL 最终不是直接拿"一个个孤立数字"画图,而是拿图元画图。

比如:

  • POINTS
  • LINES
  • TRIANGLES

这些才是 GPU 真正处理的绘制单位。

所以裁剪关注的不是"某个顶点单独死活",而是:

一个点、一道线、一个三角形,是否完全在可见范围内,或者只有一部分在可见范围内。

五、点、线、三角形在裁剪时有什么区别

这是很适合理解裁剪的一步。

1. 点

如果一个点完全在可见范围外,那它通常就直接被丢掉。

因为点这种图元非常简单,没有"被切开还剩下一半"的说法。

2. 线

如果一条线有一部分在可见范围内,一部分在外面,那 GPU 不会简单把整条线全删掉。

它通常会:

  • 保留在可见范围里的那一段
  • 把超出去的那部分切掉

也就是说,线是可以被"截断"的。

3. 三角形

如果一个三角形只有一部分在可见范围内,也不会直接整块消失。

GPU 会做更复杂的处理:

  • 把超出视锥体的部分裁掉
  • 保留仍在可见范围里的那部分区域

有时候一个原始三角形甚至会因为裁剪而变成新的多个三角形片段,再继续进入后面的光栅化流程。

所以:

裁剪不是只会"删东西",很多时候它也会"重建可见部分"。

六、为什么裁剪不是简单删除顶点

这点非常重要。

假设一个三角形有 3 个顶点:

  • 2 个在可见范围内
  • 1 个在可见范围外

如果 GPU 只是把那个外面的顶点简单删掉,会怎样?

答案是:

  • 这个三角形的几何结构会直接坏掉
  • 你没法正确得到剩余可见区域

所以 GPU 不能只是"删顶点",而必须:

按照几何边界重新求交,得到图元仍然可见的部分。

这就是为什么裁剪是一个几何过程,而不是一个简单的"数组过滤"。

七、可见范围到底是什么

说到这里,必须再把"裁剪到底以什么为边界"讲清楚。

在裁剪空间里,GPU 判断的不是:

  • DOM 像素边界
  • 浏览器窗口边界
  • CSS 布局边界

而是:

视锥体对应的裁剪边界。

用最简化的直觉理解,就是:

  • 能进入最终可见投影范围的部分保留
  • 超出这个范围的部分裁掉

你可以把它想成一个 3D 摄像机前方的"可见盒子/可见体"。

只有落在这个合理范围里的图元部分,才值得继续进入后面的透视除法和屏幕映射。

八、为什么裁剪必须发生在透视除法之前

这是理解裁剪的第二个核心点。

很多人会自然问:

"反正后面都会到 NDC,那为什么不等除完以后再裁?"

原因有两个层面。

第一层:裁剪空间就是为这一步设计的

裁剪空间里的 gl_Position 是齐次结果:

text 复制代码
(x_clip, y_clip, z_clip, w_clip)

GPU 可以在这一层用统一标准判断图元可见部分。

如果跳过这里,直接到 NDC 才处理,会把前面精心设计的裁剪语义绕掉。

第二层:透视除法会改变数值关系

透视除法会做:

text 复制代码
x / w
y / w
z / w

这一步本身已经引入了深度相关的缩放。

所以从图形管线设计上,更合理的顺序是:

  1. 先在齐次裁剪空间里判断和切割图元
  2. 再把结果送去做透视除法

这样流程更稳定,几何意义也更一致。

九、为什么如果一个三角形只露出一角,它不会整个消失

这个现象特别适合帮助你理解裁剪。

假设一个大三角形有大半都跑出可见范围了,只剩一个角还在镜头里。

如果 GPU 的逻辑是:

  • 只要有顶点越界就整块删掉

那这个三角形本来应该还能看见的一角,也会消失。

但真实情况不是这样。

GPU 会尽量保留:

仍然落在可见范围内的那部分几何。

于是你在屏幕上看到的,往往是:

  • 三角形被"切掉了一部分"
  • 而不是整个突然消失

这正是裁剪的意义所在。

十、为什么裁剪发生得这么早

你可以从效率角度再理解一次。

如果一个图元根本不可能出现在屏幕里,那 GPU 最理想的做法当然是:

  • 尽早丢掉它

而不是等它继续经过:

  • 透视除法
  • 视口映射
  • 光栅化
  • 片元着色

以后再发现"哦,原来根本看不见"。

所以:

裁剪本质上也是一次非常重要的早期过滤。

它既保证几何正确,又避免后面为不可见内容浪费太多处理资源。

十一、裁剪和 culling 是一回事吗

这也是特别容易混的一个点。

很多人会把:

  • 裁剪
  • 剔除

混成一回事。

其实它们不完全一样。

裁剪 clipping

更强调:

  • 超出可见体的图元部分被切掉
  • 保留仍然在范围内的部分

剔除 culling

更强调:

  • 某些图元直接整块不参与后续处理

比如:

  • 背面剔除
  • 视锥剔除

所以你可以简单理解为:

裁剪更像"切",剔除更像"整块不要"。

这两者相关,但不完全等价。

十二、把它放回 gl_Position 再理解一次

你现在再回头看:

glsl 复制代码
gl_Position = ...

就应该知道:

  • 这不是最终像素
  • 这不是 NDC
  • 这也不是"直接就拿来光栅化"的最终结果

它更像是:

一个等待被裁剪、等待被透视除法、等待继续进入后续管线的标准输入。

所以 gl_Position 之所以要先去裁剪空间,不只是为了名字完整,而是因为:

后面的裁剪逻辑正是围绕它展开的。

十三、一个特别适合理解的例子

假设你绘制一个非常大的三角形,它横跨整个相机可见范围,有一部分跑出去了。

这时候 GPU 不会做两件极端的事:

极端 1

直接整块删除。

这样会把本来应该看见的部分一起丢掉。

极端 2

直接完全不管,让它带着超范围部分进入后续所有流程。

这样会让后面处理变得不规范,也浪费资源。

它真正做的是:

正常做法

  • 判断图元和可见体的关系
  • 求出仍然在范围内的那一部分
  • 只把那一部分继续送往后续阶段

这就是裁剪的几何本质。

十四、从职责边界再压一遍重点

如果你想彻底不混,可以按职责来记:

投影矩阵负责什么

  • 把点送进裁剪空间
  • 给 GPU 提供可裁剪的齐次结果

裁剪负责什么

  • 判断图元哪些部分还能保留
  • 切掉超出可见体的部分

透视除法负责什么

  • 把裁剪空间结果变成 NDC

viewport 负责什么

  • 把 NDC 映射到真实屏幕像素区域

这样一来你就会发现:

裁剪正好卡在投影之后、透视除法之前。

这个位置一点都不随意。

后续讲 GPU自动处理专题2-NDC是什么(透视除法)

相关推荐
奔跑的蜗牛ing1 小时前
CentOS Nginx 安装与静态文件服务器配置指南
前端·面试·架构
子兮曰1 小时前
Bun 重写为 Rust:11天、64个Claude、16.5万美元,一次改变行业认知的激进实验
前端·后端·bun
子兮曰1 小时前
Node.js v26.5.0 深度解读:import Text、流式 ReadableStreamTee、以及隐藏的安全加固浪潮
前端·后端·node.js
子兮曰1 小时前
TypeScript 7.0 RC 深度解读:Go 重写完成,10 倍提速,编译器的「奇点时刻」
前端·后端·typescript
还有多久拿退休金1 小时前
让飞书知识库跟着 commit 自己长:一套自动化知识库的真实实现
前端·算法·架构
喝拿铁写前端2 小时前
AI 时代,ESLint 应该怎么做得更好
前端·人工智能·代码规范
妙码生花2 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(二十七):管理员登录验证码开关
前端·后端·ai编程
尼斯湖皮皮怪2 小时前
iceCoder 记忆系统深度分析
前端·javascript
用户25577655743002 小时前
Cloudflare Pages 部署 Vite 项目踩坑记
前端