2

I am trying to do a 2D fluid simulation by OpenGL ES 2.0. After reading some books and searching on internet for while. I have some basic ideas, but I am not sure if it's correct. Maybe you can help me on it.

Firstly, I read some book says we can use the Texture as a 2D array, we can get/set the data in fragment shader. Is this what the FBO doing? We can set and get the data by gl_FragData[n]? However, if we store a integer in a texture, how can we set/get data by float?

Secondly, how can we get the right 2D index by gl_FragCoord? As we know, we use the (s,t) to represent the texture coord, but it between [0,1]. If I just want to draw a rectangle, which is (0,0) (0,1) (1,0) (1,0) and the texture is 512*512. How can we get the right 2d index in the fragment shader?

After question is coming from shader Toy http://www.iquilezles.org/apps/shadertoy/

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

I don't quite understand what this line means. I know this is about the position, I think. However, I don't understand why.

Sorry for my poor english.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Yongwei Xing
  • 12,983
  • 24
  • 70
  • 90

2 Answers2

2

You can't write into gl_FragData, you can only read from it.

Something you could do is:

  • Create 2 Rendertargets ( 2D textures )
  • Bind rt0 as the texture you read from and rt1 as the texture you render the "scene" into
  • Bind rt1 to a second shader which is used to display the current texture onto the screen
  • Swap rt0 ( write ) and rt1 ( read ) and start from beginning

If you want to improve this technique you could also use deferred shading to write multiple textures at the same time.

Felix K.
  • 6,201
  • 2
  • 38
  • 71
1

Using a framebuffer object you can render on a texture, by attaching it on a color attachments point. Don't bind the texture object on a texture unit (used by the shader) while the former is attached on the framebuffer.

I doubt that gl_FragData can read the textel of the texture attached to the framebuffer: gl_FragData should be undefined until it is written. Indeed you can only read gl_FragData only once it is written, otherwrite you will get an undefined bahvior.

Texture samples values are usually normalized in the [0.0,1.0] range. Since gl_FragData is declared as vec4, writing a value in the range [0.0,1.0] determine a texel value of [0,MAX_VALUE], where MAX_VALUE is the maximum value of the base type determined by the texture internal format. You can get those integer values by calling glGetTexImage. Not sure what happens if you set a value outside the [0.0,1.0] range.

Texture internal formats can be also defined as floating-point.

Destination fragments are determined by the texture, since the texture is the destination buffer. Each fragment shader determine the color of the fragment at position gl_FragCoord.xy (in texture/buffer/screen coordinates): this variable is offered by the shader executor, and it is read-only. Essentially one fragment shader instance for each texture texel.

Knowing the "screen" dimensions (a.k.a. the texture dimensions), you can write texture coord (x/y) in the range [0.0,1.0] using the shader instance having gl_FragCoord equals to (gl_FragCoord.x/texSizeX,gl_FragCoord.y/texSizeY).

Luca
  • 11,646
  • 11
  • 70
  • 125
  • I have question about the vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy; From the sample I read, it can use the texure2D(texture,p) to set the color. From other sample, there is a varying variable passing from vertex shader, such as textCoord, then use this one in texture2D. From my understanding, every pixel would be calculated in fragment shader, it's reasonable to use gl_FragCoord.xy / resolution.xy, but why textCoord passing from vertex shader also work, since it only runs sizeof(vertex) times. – Yongwei Xing Nov 25 '11 at 01:36
  • The fragment shader is executed for each fragment resulted from a rasterization of any triangle. – Luca Nov 25 '11 at 06:32