# v4vendeta's homepage

Home | About | Contacts | Blogs| Others

# 关于z-buffer

### z_buffer为什么是非线性的

While W is linear in view space it’s not linear in screen space. Z, which is non-linear in view space, is on the other hand linear in screen space

### z_buffer精度问题

z fighting

• 将znear设置的尽可能小可以改善z’‘的分布，将更多的变化空间留给远平面

• 使用无限远平面

• 用精度更高的数据类型存储

• 使投影矩阵与其他矩阵分开，并将其应用于顶点着色器中的单独操作中，而不是将其组合到视图矩阵中-

P.S.

Differentiating depth between close objects is more important than differentiating depth between far objects

### reverse-z

(Nvidia官方的案例是DirectX为例的)

DirectX中z的投影变换（z>0，z映射到[0,1]） $z’’=\frac{z_{far}}{z_{far}-z_{near}}-\frac{z_{far}\ z_{near}}{z_{far}-z_{near}}\frac{1}{zp}$

DirectX

reverse-z的做法是，将近平面映射到z=1，将远平面映射到z=0，使得浮点的准对数分布在某种程度上取消了1/z非线性，使我们在近平面上的精度与整数深度缓冲区相似，并且极大地提高了其他地方的精度

$z’’=\frac{z_{near}}{z_{near}-z_{far}}-\frac{z_{near}\ z_{far}}{z_{near}-z_{far}}\frac{1}{zp}$

OpenGL

### multiple frusta

rtr4中另一种减少z fighting的做法，渲染多个frustum

Cozzi proposes to use multiple frusta, which can improve accuracy to effectively any desired rate. The view frustum is divided in the depth direction into several non-overlapping smaller sub-frusta whose union is exactly the frustum. The sub-frusta are rendered to in back-to-front order. First, both the color and depth buffers are cleared, and all objects to be rendered are sorted into each sub-frusta that they overlap. For each sub-frusta, its projection matrix is set up, the depth buffer is cleared, and then the objects that overlap the sub-frusta are rendered.

reference: