1

着色器相当新,所以如果我在这里做一些愚蠢的事情,请多多包涵。:)

我正在尝试在 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 中),并且我需要非常高的精度以供以后处理,否则我会得到明显的伪影。

我可以通过增加多边形数量来实现相当高的精度,但这会使我的帧率下降很多,那么,有没有更好的方法?

4

2 回答 2

2

您需要将 z 除以 w 分量。

于 2011-12-21T14:04:00.547 回答
0

这很简单,深度不是线性的,所以你不能对 z 使用线性插值......如果你插值 1/z 而不是 z,你会很容易地解决它。您还可以按照 rasmus 的建议执行一些 w 数学运算。您可以在http://www.luki.webzdarma.cz/eng_05_en.htm阅读更多关于坐标插值的信息(关于实现简单软件渲染器的页面)

于 2012-01-11T20:58:43.877 回答