经纬志
首页 / luma.gl / 使用示例

深度测试

三块重叠的四边形按「近 → 中 → 远」的顺序绘制。深度测试打开时近的压住远的; 关掉之后,遮挡关系立刻退化成绘制顺序。

luma.gl 9.4 · 更新 2026-10-28
源码与运行效果
运行效果

说明

十八个顶点一次画完,三块四边形在同一个绘制调用里。顶点顺序是蓝、绿、红, 但 z 值分别是 -0.7、0、0.6;裁剪空间里 z 越小离相机越近,蓝在最前。 深度测试打开时,后面画的绿与红在重叠处被蓝挡住; 关闭后,红作为最后一个画的三角形覆盖一切。

「关闭深度测试」把 depthCompare 从 less-equal 换成 always。这不是删掉深度缓冲,而是让每次比较都通过, 效果等同于不测深度。

项目取值说明
顶点数量18三块四边形各六个
图元triangle-list一次绘制画完
z 值-0.7 / 0 / 0.6裁剪空间里越小越靠近相机
深度比较less-equal关闭时改为 always
深度写入true两种状态都保持写入
绘制顺序蓝 → 绿 → 红固定不变

参数写在模型上

const model = new Model(device, {
  topology: 'triangle-list',
  vertexCount: 18,
  parameters: {
    depthCompare: 'less-equal',
    depthWriteEnabled: true
  },
  attributes: { positions: posBuffer, colors: colBuffer },
  bufferLayout: [
    { name: 'positions', stepMode: 'vertex', format: 'float32x3' },
    { name: 'colors', stepMode: 'vertex', format: 'float32x3' }
  ],
  vs: vsSource,
  fs: fsSource
});

深度状态属于管线。运行期调用 model.setParameters({...}) 会标记管线需要重建,下一帧自动换上新管线,不需要手工销毁旧对象。

深度值从哪来

顶点着色器输出的 gl_Position.z 是裁剪空间坐标, 除以 w 得到归一化设备坐标,再线性映射到 0–1 的窗口深度。 本示例的 w 恒为 1,所以 z 直接决定远近:-0.7 映射到 0.15, 0.6 映射到 0.8,前者离相机更近。

透视投影下这个映射是非线性的,靠近相机的区间精度高、远处精度低。 这也是远处两个面贴得很近时会出现闪烁的原因。

深度测试与混合的区别

深度测试混合
解决的问题哪个片元离相机更近同一像素上多层颜色如何叠加
结果保留或丢弃整个片元按权重合成颜色
透明物体需要先画不透明再画透明透明层靠它合成

GIS 里的对应场景

建筑体块、地形与标注重叠时,深度测试决定谁被遮住。 半透明面罩、云层、热力面则要在深度测试之外补上混合与绘制顺序, 否则边缘会出现硬切。

默认画布带深度缓冲,离屏目标要自己加。 自己建的帧缓冲如果没有 depthStencilAttachment, 深度参数不会报错,但所有片元都通过比较,画面按绘制顺序叠在一起。