0

我正在使用附加到帧缓冲区的纹理作为自定义深度缓冲区。在第一个渲染过程中,我渲染到纹理以便它存储深度值。在第二个渲染过程中,我从这个纹理中查找以确定是渲染还是丢弃片段。

这很好用,除了在设备 (iPad 3) 上,有一些令人讨厌的伪影,这些伪影似乎来自某种舍入误差,当深度值写入纹理时会发生这种误差。我试着写一些像0.5纹理这样的固定值,但是当它从纹理中读回时,它0.03高于或低于0.5.

我将深度值“编码”为三个 RGB 值(忽略第四个分量 alpha 或w):

const highp vec4 packFactors = vec4(1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0);
const highp vec4 cutoffMask  = vec4(1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 0.0);

void main() {
    highp float depth = ...
    ...
    highp vec4 packedVal = fract(packFactors * depth);
    packedVal.x = depth;      // undo effect of fract() on x component
    gl_FragColor = packedVal - packedVal.yzww * cutoffMask;
}

这样,我得到 3x8 位精度来存储深度(灵感来自http://www.rojtberg.net/348/powervr-sgx-530-does-not-support-depth-textures

在另一个片段着色器(第二个渲染通道)中,我从纹理中读取如下:

    highp vec4 depthBufferLookup = texture2D(depthTexture, vDepthTex);
    highp float depthFromDepthBuffer = dot(depthBufferLookup, vec4(1.0) / packFactors);

packFactors使用与第一个着色器中相同的值。

我希望这个过程能够提供一个不错的精度,但是超过0.03值的错误0.5使它非常不可用。

有什么提示吗?

顺便说一句,我正在使用以下纹理类型:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
4

0 回答 0