Sign in to follow this  

Summing Data with a Pixel Shader

Recommended Posts

Recently I have been fooling around with pixel shaders and I am currently trying to make one which will add up numbers. So here is what I do: -Start with texture (512x512) with numbers to be added in the blue component (its 24bit 8 for each color) other components are zero. -Render a quad half of the size of the current texture (512x512 texture means 256x256 quad, quad texture coordinates for 255,255 would be (.5f,.5f)) -Each pixel for the quad is rendered through a pixel shader. The pixel shader adds up the color values for four points. It is adding up itself (in the upper left hand corner), then the 3 other points in the other quadrants. if point has coordinates x,y add up: x,y 1-x,y x,1-y 1-x,1-y Then check for overflow. The blue component is the least significant number, g is middle, and red is most significant. (ex. a Color.r*256^2 + Color.g*256+Color.b = number) output.b = frac(sum.b); output.g = frac(sum.g) + floor(sum.b)/256; output.r = frac(sum.r) + floor(sum.g)/256; -The output from the render is not send to the screen, it is saved to a texture. This texture is then fed back in for another loop. Each loop cuts the width and height of the values in the texture left to add in half. After some number of loops one pixel remains and its value can be calculated. At this point the program is adding numbers, but there is a significant amount of error. It seems to me like texture lookups were not meant to be as exact as I need them to be (I need them to be distinct from their neighbors where with a normal texture it does not matter if you blur it a little). Any ideas on if I am on the right track or not? Thanks for the help :D.

Share this post

Link to post
Share on other sites
For this sort of operation you probably want to disable texture filtering - set your MIN, MAG and MIP filter to be POINT rather than LINEAR or ANISOTROPIC.

You can use linear filtering to great effect - there's an ATI slide deck that demonstrates how you can cleverly position sample locations to get the texture samplers to do a free 4px summation for you. However, if you get the sampling locations slightly wrong then you will end up getting unexpected values (e.g. 75% of the target pixel, 25% of the neighbour). Using point filtering should elminate most of this - you either get what you want or you get the wrong pixel, never some hybrid mix of the correct and incorrect results...


Share this post

Link to post
Share on other sites
Your long summation you posted is wrong. For example (and I'm multiplying everything by 256 for convenience), if you add RGB(0, 255, 255) with RGB(0, 0, 1), you'd get:

sum.b = 256;
sum.g = 255;
sum.r = 0;

output.b = 0;
output.g = 256;
output.r = 0;

The answer should have been (1,0,0).

Note also that a 512x512 texture can result in values larger than can fit into three bytes. You'd have to add the alpha channel if you need this accuracy.

For simplicity, or at least for comparison I'd suggest using floating point textures and calculations. They'd also limit accuracy, but the likelihood of an error in the shader code will be lower, and they should work faster, since the shader will be simpler.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this