【问题标题】:Interpret Texture data as Vertex data in Vertex Shader在顶点着色器中将纹理数据解释为顶点数据
【发布时间】:2012-03-10 09:35:08
【问题描述】:

我正在尝试使用顶点着色器来重新定位粒子(存储在纹理中),这些粒子被传递到 Frag 着色器并存储在单独的纹理中。

我正在尝试完全在 GPU 上实现高效的空间分箱。这是用于 SPH 流体模拟的。

是否可以将 2D 纹理的所有像素(文本)传递给顶点着色器?每个文本 (RGBA) 将被重新解释为传入的顶点 (XYZW)。

【问题讨论】:

  • 您使用什么工具来执行此操作?尝试使用该工具的名称标记您的问题,并可能使用其他一些紧密相关且相关的标签。

标签: c++ opengl graphics glsl gpu


【解决方案1】:

如果硬件支持Vertex Texture Fetch,则可以将二维纹理传递给顶点着色器。您可以使用以下代码对此进行测试:

int maxVertexTextureImageUnits;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits);

如果maxVertexTextureImageUnits 为零,则不支持此功能。

您不直接将纹理作为顶点数据传递,而是创建一个顶点网格,其坐标对应于纹理中每个像素的纹理坐标。然后在顶点着色器中,您使用这些顶点来读取在片段着色器中生成的实际顶点坐标(纹素值)。然后将这些用于计算gl_Position

我从未亲自使用过此功能(在我的平台上不支持),但我看过很酷的粒子/流体演示。我相信对它的支持相当参差不齐。即使在支持它的硬件上,驱动程序也可能无法实现它。

【讨论】:

    【解决方案2】:

    不可能假装 2D 纹理实际上是顶点数据。但是,我想知道您为什么要这样做。

    最有效的方法是不要将粒子数据存储为纹理,而是存储在buffer objects 中。您可以直接使用缓冲区对象作为顶点数组的源数据。


    鉴于“我将数据存储为纹理,因为粒子位置是片段着色器的输出”,我可以提出更有用的建议:buffer textures。这些是 1D 纹理,将其数据存储在缓冲区对象中。它们仍然可以用作渲染目标(尽管显然您需要更改栅格化数据的方式,因为它们是 1D 渲染目标),但它们渲染的内容存储在缓冲区对象中。

    这样,您可以对缓冲区纹理进行渲染,然后将缓冲区绑定为数组并从中获取源。

    如果您绝对必须渲染到 2D 纹理,您可以使用较慢的方法:read from the texture into a buffer object. PBO 主要用于异步像素传输,所以我建议让 GPU 在您在缓冲区中执行glGetTexImage 的时间以及调用glDrawArrays 以从中渲染的时间。否则,您只会停止 GPU。

    【讨论】:

    • 我将数据存储为纹理,因为粒子位置是片段着色器的输出。
    • @JohnD:那么你应该提到这一点。我只能根据你所说的给出建议,而不是你的想法。查看我的编辑。
    • 在纹理中存储顶点是完全可能的。这是一个例子jsfiddle.net/greggman/7t2Dj
    【解决方案3】:

    是的,这很简单:只需渲染与像素一样多的顶点,但不要绑定顶点缓冲区。相反,通过获取顶点 ID (gl_VertexID) 计算与当前顶点对应的像素(您应该渲染为点。)从顶点 ID,您可以对纹理发出 fetch 并获取数据(确保使用texelFetch.)

    【讨论】:

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