Per-pixel shader?

Member
Posts: 469
Joined: 2002.10
Post: #1
Here's my GLSL fragment shader:
Code:
uniform vec2 force;
    void main() {
        gl_FragColor = gl_FragCoord + vec4(force.x - 400.0, force.y - 300.0,0.0,0.0);
    }
The uniform value takes the window mouse coordinates.
The shader gets rendered as a single quad over a 1024x1024 framebuffer.
The output lines are the values sampled across the grid.

Here's the result:
[Image: fragmentproblems.png]

I want each pixel within the field to have its color value calculated based on its coordinate. From this result it looks like the fragments are calculated as larger 128x128[?] patches. How do I calculate per pixel?

Edit: Resolved... mostly.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #2
Here's the project so far:
http://kelnishi.com/imageshare/RTSwarm2008030920.zip

Edit: This one works. Code could be cleaner...

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Apprentice
Posts: 5
Joined: 2008.02
Post: #3
kelvin Wrote:Here's my GLSL fragment shader:
Code:
uniform vec2 force;
    void main() {
        gl_FragColor = gl_FragCoord + vec4(force.x - 400.0, force.y - 300.0,0.0,0.0);
    }
The uniform value takes the window mouse coordinates.
The shader gets rendered as a single quad over a 1024x1024 framebuffer.
The output lines are the values sampled across the grid.

I think your main problem is that you are massively overflowing your output.

gl_FragColor takes values 0.0<=x<=1.0 if you are using 8-bit per component, and you're using numbers like 1024, 400 & 300.

That doesn't explain where the blocks are coming from, but overflows of that scale might cause funny things.

btw: posting a whole project and expecting people to understand it is expecting a bit much.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #4
The buffers are 32bit Float RGBA. It turns out there's not much wrong with my first shader. It's in how I get my data back to the CPU. Because of geometry quirks, I'm going to have to use another shader and a different upload path to ensure I get the correct data back.

In any case, I'll post an update when I fix everything.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #5
So, I've managed to get my project in a working state.
I've had to turn off PBO async reads for my data (using glGetTexImage for now).
...And I've run into a bug with GLSL. See my earlier edited post for the project so far.

The demo so far calculates the a force at every point on the vector field using the GPU (frag shader). I've tried doing this calculation on the CPU previously and, let me tell you, the results are dramatically faster on the GPU. What you see in this demo is the force evaluated at points across the grid. While the force is calculated at each point in the field, only 1 point is displayed per 32x32 square. The force is displayed as a line away from the point evaluated.

The current program just creates a force towards the mouse that gets weaker by half every 20px away. While the points evaluated are in a grid in this demo, the code supports arbitrary sampling of the field... So that means you can have particles flying around the field interacting with the forces you create in it! Eventually I hope to make a nice little game or screen saver or something with this.

[Image: MouseGravity.png]

The bug: So, I've got my 32bitFloat texture vector field loaded as a texture unit in my GLSL fragment shader. But, I can't resolve indices bigger than about 768px. So, if I want to poll a 1024x1024 texture at 800x200, I get garbage back from texture2D().

You can see this behavior for yourself by editing line18 of Renderer.mm, line 78 in CRenderer.cc, and line 9 of pollField.frag. (change 512 to 1024 for all instances).
I've looked at the data coming out and it seems that the problem is just that the precision goes all out of whack when you start dividing 1.0 by 1024.0 in the shader (to scale to the tex).

Anyone got any idea on how to fix this? Ideally I'd use rectangle textures, but I don't know how to with GLSL. Anyone? Anyone? Arrekusu?

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
For rectangle textures, check for ARB_texture_rectangle, use 'em as you would've EXT_texture_rectangle, use sampler2DRect and texture2DRect with pixel coords in your shader.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #7
We have driver bug.
Using GL_TEXTURE_RECTANGLE_ARB and sampler2DRect and texture2DRect works... just like GL_TEXTURE_2D. Using pixel coords, it still craps out above ~768px. Maddening.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Well, you don't have to divide by 1024... maybe your card is using 16- or 24-bit floats internally and that's not sufficient precision. Have you tested on other hardware yet?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #9
Please check your state in OpenGL Profiler before deciding anything is a driver bug.

For example, the contents of GL_VIEWPORT -- you might want to set that in the same places you set the projection matrix, so your drawing is scaled to the size of your rendertarget, and not the window.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #10
OneSadCookie Wrote:Well, you don't have to divide by 1024... maybe your card is using 16- or 24-bit floats internally and that's not sufficient precision. Have you tested on other hardware yet?

I'm not dividing. I'm supplying exact pixel coordinates (for the recttex).
Here's the frag shader:
Code:
uniform sampler2DRect sourceField;
uniform sampler2DRect vertexData;
void main() {
    //here we really should be using a texture matrix to change coords.
    vec2 vCoord = gl_FragCoord.xy;
    
    vec2 sCoord = texture2DRect(vertexData, vCoord).xy;

    gl_FragColor = texture2DRect(sourceField, sCoord);

}

vertexData is a 64x64 float pixel texture that contains coordinates for target pixels in sourceField (a 1024x1024 float pixel texture). For any coordinates above a certain height and width, I get the glClear color instead of the data in that portion of sourceField. Even in the case of 16bit floats, I still should have a 10bit mantissa (which would accommodate 1024 coordinates).

Edit: btw, setting the viewport doesn't change the result.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
The shader in the linked project was dividing, via texture2DProj.
But that's not the issue. The drawing was being scaled to 800x600 because you didn't reset the viewport.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #12
arekkusu Wrote:Please check your state in OpenGL Profiler before deciding anything is a driver bug.

For example, the contents of GL_VIEWPORT -- you might want to set that in the same places you set the projection matrix, so your drawing is scaled to the size of your rendertarget, and not the window.

Why would the viewport affect the results of a texture lookup? The frag program should give me the color at the correct pixel in the texture regardless of viewport, projection matrix or float size.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #13
Ah. Arrekusu hit it. The problem wasn't in the pollField shader. It was in the addUniformForce shader! That shader was being clipped by the viewport. I'll add some code to the bind/unbind to fix.

Thanks!

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
Minor correction, it wasn't being clipped by the viewport. The viewport doesn't clip, only the view frustum and scissor window clip. The viewport scales the results of the vertex transform.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #15
Since my quad's coverage effectively clips the shader's output based on the current transform... details aside, I'm glad you found the problem for me.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  ios/mac shader - shared glsl source OptimisticMonkey 2 5,237 Jun 17, 2011 08:59 AM
Last Post: OptimisticMonkey
  passing values from vertex to fragment shader Sumaleth 6 10,884 Feb 18, 2011 01:54 AM
Last Post: Holmes
  [CoreGraphics] Image manipulation - pixel by pixel g00se 5 9,835 Jul 28, 2010 08:27 AM
Last Post: ThemsAllTook
  Changing Uniform Variables for a Single Shader reapz 3 5,477 Jul 15, 2010 01:29 AM
Last Post: dazza
  Vertex shader particle billboarding question TomorrowPlusX 3 5,609 Sep 15, 2008 06:46 AM
Last Post: TomorrowPlusX