从FBO设置并获取数据

时间:2011-11-24 16:35:20

标签: opengl-es glsl

我正在尝试通过OpenGL ES 2.0进行2D流体模拟。在阅读了一些书籍并在网上搜索了一会儿。我有一些基本的想法,但我不确定它是否正确。也许你可以帮助我。

首先,我读了一些书说我们可以使用Texture作为2D数组,我们可以在片段着色器中获取/设置数据。这是FBO做的吗?我们可以通过gl_FragData [n]设置和获取数据?但是,如果我们在纹理中存储一个整数,我们如何通过float设置/获取数据?

其次,我们如何通过gl_FragCoord获得正确的2D索引?我们知道,我们使用(s,t)来表示纹理坐标,但它在[0,1]之间。如果我只想绘制一个矩形,即(0,0)(0,1)(1,0)(1,0),纹理为512 * 512。我们如何在片段着色器中获得正确的2d索引?

问题来自着色器玩具http://www.iquilezles.org/apps/shadertoy/

vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;

我不太明白这条线的含义。我想,我知道这是关于这个职位的。但是,我不明白为什么。

抱歉我的英语很差。

2 个答案:

答案 0 :(得分:2)

你不能写入gl_FragData,你只能从中读取。

你可以做的事情是:

  • 创建2个Rendertargets(2D纹理)
  • 将rt0作为您读取的纹理绑定,将rt1绑定为将“场景”呈现为
  • 的纹理
  • 将rt1绑定到第二个着色器,用于在屏幕上显示当前纹理
  • 交换rt0(写入)和rt1(读取)并从头开始

如果你想改进这种技术,你也可以使用延迟着色来同时写多个纹理。

答案 1 :(得分:1)

使用framebuffer对象,您可以在纹理上渲染,方法是将其附加到颜色附件点上。不要在纹理单元(由着色器使用)上绑定纹理对象,而前者附加在帧缓冲区上。

我怀疑gl_FragData是否可以读取附加到帧缓冲区的纹理的textel:gl_FragData应该是未定义的,直到它被写入。实际上,只有在写完gl_FragData之后才能阅读,否则你将得到一个未定义的行为。

纹理样本值通常在[0.0,1.0]范围内归一化。由于gl_FragData被声明为vec4,因此写入[0.0,1.0]范围内的值可确定纹素值[0,MAX_VALUE],其中MAX_VALUE是纹理内部格式确定的基本类型的最大值。您可以通过调用glGetTexImage来获取这些整数值。如果设置的值超出[0.0,1.0]范围,则​​不确定会发生什么。

纹理内部格式也可以定义为floating-point

目标片段由纹理决定,因为纹理是目标缓冲区。每个片段着色器确定位置gl_FragCoord.xy处的片段的颜色(在纹理/缓冲区/屏幕坐标中):此变量由着色器执行器提供,并且它是只读的。基本上每个纹理纹理元素的一个片段着色器实例。

了解"屏幕"尺寸(例如纹理尺寸),您可以使用(x/y)等于gl_FragCoord的着色器实例在[0.0,1.0]范围内编写纹理坐标(gl_FragCoord.x/texSizeX,gl_FragCoord.y/texSizeY)