深度
正确处理对象的前后关系
WebGL能自动分析出三维对象的远近吗?
答: 不能。
WebGL不能正确处理遮挡关系,后绘制的图形总是覆盖先绘制的图形。
WebGL为了加速绘图操作,优先按照顶点在缓冲区的顺序进行处理(处理遮挡关系的话需要对顶点数据进行打乱重排吗?)。
打乱PerspectiveView的缓冲区顶点顺序绘制效果如何?
1 | let verticesColors = new Float32Array([ |
隐藏面消除
隐藏面消除(hidden surface removal)
具体功能: 消除被遮挡的表面,已经被内嵌在WebGL中。
开启方式
难道就不能给个Boolean属性直接表示开启或关闭吗?恼啊!
隐藏面消除前提
必须要先设置可视空间,无论是正射还是透视类型。
1.开启隐藏面消除功能
1 | gl.enable(gl.DEPTH_TEST); |
2.绘制前清除深度缓冲区
1 | gl.clear(gl.DEAPTH_BUFFER_BIT); |
enable和disable
enable用来开启WebGL汇总的多种功能,disable与之相反。
cap的取值不止这些
更多可参阅OpenGL Programming Guide一书。
为什么说深度缓冲区是个中间对象?
答: 想一想,如果要根据顶点的深度坐标对图形进行隐藏面消除,
那首先就要知道 每个几何图形的深度信息,深度缓冲区就是用来存储 深度信息 的。
为什么隐藏面消除功能要命名为DEAPTH_TEST?
答: 因为该功能的实现原理就是通过检测(Test)物体每个像素的深度(Depth)来决定是否绘制的。
深度缓冲区的清空时机
答: 在绘制任意一帧之前都要清除深度缓冲区。
同时清除两个缓冲区时,可以使用 按位或操作 进行简化。
1 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
DepthBuffer Code
1 | gl.enable(gl.DEPTH_TEST); |
深度冲突
深度冲突(Z fighting)
指的是物体两个表面极为接近时,绘制出来的表面斑驳不平滑。
原因是在表面过于接近时,深度缓冲区有限精度不足以区分前后。
这种问题最容易出现在场景中有多个运动着的物体时。
多边形偏移(polygon offset)
是WebGL用于解决深度冲突的方式。
实现原理: 自动在Z值上加一个偏移量,该值由 物体表面相对于观察者视线的角度 来确定。
多边形偏移机制的启用(2步)
1.启用多边形偏移
1 | gl.enable(gl.POLYGON_OFFSET_FILL); |
2.绘制之前指定计算偏移量的参数
1 | gl.polygonOffset(1.0,1.0); |
1 | gl.polygonOffset(factor,units) = m * factor + r * units; |
- m 表示顶点所在表面相对于观察者的视线的角度
- r 表示硬件能够区分两个z值之差的最小值
Zflighting
Zflighting Code
1 | pvMatrix.setPerspective( |
1 | pvMatrix.lookAt( |
1 | let verticesColors = new Float32Array([ |
多边形偏移前后对比
1 | gl.enable(gl.POLYGON_OFFSET_FILL); |
1 | gl.enable(gl.POLYGON_OFFSET_FILL); |