iDevGames Forums
Per-pixel shader? - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Per-pixel shader? (/thread-2733.html)

Pages: 1 2


Per-pixel shader? - kelvin - Mar 7, 2008 02:37 PM

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.


Per-pixel shader? - kelvin - Mar 7, 2008 03:05 PM

Here's the project so far:
http://kelnishi.com/imageshare/RTSwarm2008030920.zip

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


Per-pixel shader? - Weebull - Mar 8, 2008 05:09 AM

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.


Per-pixel shader? - kelvin - Mar 8, 2008 02:16 PM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 02:56 AM

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?


Per-pixel shader? - OneSadCookie - Mar 9, 2008 03:11 AM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 09:47 AM

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.


Per-pixel shader? - OneSadCookie - Mar 9, 2008 12:33 PM

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?


Per-pixel shader? - arekkusu - Mar 9, 2008 12:34 PM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 02:31 PM

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.


Per-pixel shader? - arekkusu - Mar 9, 2008 02:36 PM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 02:52 PM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 02:57 PM

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!


Per-pixel shader? - arekkusu - Mar 9, 2008 05:06 PM

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.


Per-pixel shader? - kelvin - Mar 9, 2008 07:12 PM

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.