【问题标题】:Render depth buffer to texture将深度缓冲区渲染到纹理
【发布时间】:2011-12-10 21:22:55
【问题描述】:

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

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

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

【问题讨论】:

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

标签: opengl-es textures shader depth-buffer


【解决方案1】:

您需要将 z 除以 w 分量。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多