Opengl es 渲染深度缓冲区到纹理

Opengl es 渲染深度缓冲区到纹理,opengl-es,textures,shader,depth-buffer,Opengl Es,Textures,Shader,Depth Buffer,在shaders还是个新手,所以如果我在这里做傻事,请容忍我。:) 我试图在iOS上使用opengl ES 2.0将场景的深度缓冲区渲染为纹理,但除非模型在显示器上显示相对较高密度的多边形,否则我似乎无法获得完全准确的结果 例如,如果我渲染一个只有四个顶点的大平面,我会得到非常不准确的结果,但是如果我细分这个平面,每个细分的结果都会更准确,最终我会得到一个正确渲染的深度缓冲区 这让我想起了很多关于仿射和透视投影纹理贴图的问题,我想我需要用“.w”组件来解决这个问题。但我认为“可变”变量应该已经考

在shaders还是个新手,所以如果我在这里做傻事,请容忍我。:)

我试图在iOS上使用opengl ES 2.0将场景的深度缓冲区渲染为纹理,但除非模型在显示器上显示相对较高密度的多边形,否则我似乎无法获得完全准确的结果

例如,如果我渲染一个只有四个顶点的大平面,我会得到非常不准确的结果,但是如果我细分这个平面,每个细分的结果都会更准确,最终我会得到一个正确渲染的深度缓冲区

这让我想起了很多关于仿射和透视投影纹理贴图的问题,我想我需要用“.w”组件来解决这个问题。但我认为“可变”变量应该已经考虑到这一点,所以我在这里有点不知所措

这是我的顶点和片段着色器:

[vert]
uniform mat4 uMVPMatrix;
attribute vec4 aPosition; 
varying float objectDepth;
void main()
{
    gl_Position=uMVPMatrix * aPosition;
    objectDepth=gl_Position.z;
}

[frag]
precision mediump float;
varying float objectDepth;
void main()
{
    //Divide by scene clip range, set to a constant 200 here
    float grayscale=objectDepth/200.0;
    gl_FragColor = vec4(grayscale,grayscale,grayscale,1.0);
}
请注意,这个着色器被简化了很多,只是为了突出显示我正在使用的方法。虽然对于肉眼来说,它似乎在大多数情况下都能很好地工作,但事实上,我正在渲染32位纹理(通过将浮点填充到ARGB中),并且我需要非常高的精度以便稍后处理,否则我会得到明显的瑕疵


我可以通过增加多边形计数来获得相当高的精度,但这会使我的帧率下降很多,所以,有没有更好的方法?

您需要将z除以w分量。

这非常简单,深度不是线性的,所以您不能对z使用线性插值。。。如果插值1/z而不是z,将很容易求解。你也可以按照rasmus的建议进行一些w运算。
您可以在(关于实现简单软件渲染器的页面)上阅读更多关于坐标插值的信息。

我对GL ES了解不多,但您启用了透视正确插值吗?或者ES是否具有属性的
smooth
限定符?另外,您说您正在将浮子打包到ARGB中;你确定这真的能正常工作吗?是的,我彻底检查了编码器和解码器,它工作得很好。我在使用常规8位灰度时也遇到同样的问题,只是不太明显,所以我肯定编码器不是罪魁祸首。我不知道opengl ES 2.0中有什么类似于透视校正插值开关的东西?如果我插值纹理坐标,它们会通过透视投影进行插值,我只是假设这对于插值的任何值都是正确的。顺便说一下,我使用了本页中的代码进行编码/解码: