2012-02-19 162 views
1

我试图使用顶点着色器重新定位传递给碎片着色器并存储在单独纹理中的粒子(存储在纹理中)。将纹理数据解释为顶点着色器中的顶点数据

我试图完全在GPU上实现高效的空间装仓。这是用于SPH流体模拟。

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

+0

你用什么工具来做到这一点?尝试使用该工具的名称以及可能的其他一些紧密相关且相关的标签来标记您的问题。 – Irfy 2012-02-19 23:41:59

回答

1

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

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


鉴于“我存储的数据作为纹理因为粒子的位置是一个片段着色器的输出,”我可以告诉更多的有用的东西:buffer textures。这些是将数据存储在缓冲区对象中的一维纹理。它们仍然可以用作渲染目标(尽管显然你需要改变你如何栅格化数据,因为它们是一维渲染目标),但是它们渲染的内容存储在缓冲区对象中。

这样,您可以对缓冲区纹理进行渲染,然后将缓冲区作为数组和源进行绑定。

如果你绝对必须渲染2D纹理,你可以使用较慢的方法:read from the texture into a buffer object.公益组织主要用于异步像素的传输,所以我建议给GPU别的东西,你执行glGetTexImage的时间之间做进入缓冲区,您可以拨打glDrawArrays来渲染它。否则,你只会停止GPU。

+1

我将数据存储为纹理,因为粒子位置是片段着色器的输出。 – JohnD 2012-02-20 00:28:43

+0

@JohnD:那么你应该提到这一点。我只能根据你所说的提供建议,而不是你在想什么。看我的编辑。 – 2012-02-20 00:33:45

+0

将顶点存储在纹理中是完全可能的。这里是一个例子 http://jsfiddle.net/greggman/7t2Dj/ – gman 2014-02-26 07:09:07

3

如果硬件支持Vertex Texture Fetch,则可以将2D纹理传递到顶点着色器。您可以测试这个使用下面的代码:

int maxVertexTextureImageUnits; 
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); 

如果maxVertexTextureImageUnits是零,那么不支持此功能。

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

我从来没有亲自使用这个特性(我的平台不支持),但是我已经看到很酷的粒子/流体演示。我相信对它的支持很不明显。即使在支持它的硬件上,驱动程序也可能不会实现它。

1

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

相关问题