UniformBuffer
需要预先学习: 着色器 缓冲对象与顶点 glsl语法 UniformBuffer 回顾一下常规的 uniform 设置方式:glUniform* 逐个把值传进当前着色器程序。在 Phong模型与Blinn-Phong模型 里已经能看到问题的一角——光颜色、光位置、视角位置……每个变量一次调用。当场景里的着色器程序越来越多,每个程序又都要一份相同的 view、projection 矩阵时,这种方式的 CPU 开销会变得难以忽视。 UniformBuffer(uniform buffer object,UBO,统一变量缓冲对象)把一批 uniform 打包进一个缓冲对象:一次上传整块数据,绑定到绑定点(binding point)之后,任意多个着色器程序都可以直接读取同一份数据。 这篇文章先走完 UBO 的完整使用流程,再分析 std140 布局规则,最后从底层回答一个问题:它到底比 glUniform* 快在哪里。 常规方式的问题 先看常规方式的做法与它的两个问题。 每帧渲染时,你需要先激活程序,再逐个设置 uniform: glUsePro...
纹理压缩格式
需要预先学习: 纹理 伽马校正 为什么不用 PNG 和 JPG 纹理 里加载纹理用的是 png、jpg 这类常见图片格式,解码后上传给 glTexImage2D。这在学习阶段没问题,但看一下 GPU 视角就会发现两个问题: 解码成本。png 与 jpg 是为"存储与传输"设计的压缩:压缩率高,但必须整体解码成未压缩像素才能使用。GPU 无法直接采样一张 png——每帧渲染前都得把整张图解压,显存里实际存放的还是未压缩数据,压缩只在磁盘上省了空间。 随机访问。GPU 采样纹理是随机的:一次双线性插值(见 纹理)要读 4 个相邻纹素,三线性过滤还要跨 mip 层。jpg 的压缩依赖整张图的频域信息(DCT 变换块之间有关联),想取"坐标 (x,y)(x, y)(x,y) 的一个像素",必须把周围一大片都解出来——随机访问的代价是灾难性的。 显存带宽。未压缩的 RGBA8 纹理每像素 4 字节。一张 4096×4096 的纹理 64 MB,加上 mipmap 约 85 MB;采样时的带宽、显存的占用,都会成为...



