## Recommended Posts

mapa8489    100
I'm looking to fill an array of pixels (or use a Pixel Shader) so I can fill any 2D polygon with a linear gradient. I'd like to be able to specify an angle for the gradient, and the colors to use to make the gradient. Any help?

##### Share on other sites
dave    2187
Any help with what? The algorithm? The implementation with a shader? What have you tried?

##### Share on other sites
mapa8489    100
Sorry for the confusion. When I said "Pixel Shader", I was trying to say that if someone implemented a gradient filling using a pixel shader, I could use that. Or if someone had an idea of how to do it with a pixel shader, I could use that. I could do with either the pixel shader help, or the algorithm help. It was an open-ended question because either one will do.

In my shader code, I first sent in two colors, the min/max y, and the (x,y) position to the vertex shader. Then, I sent the two colors, the min/max y, and the y position to the pixel shader. I was able to achieve a simple a left-to-right and top-to-bottom gradient, but only with two colors, and not at any angle.

I then tried to implement a "disecting-line" technique in code (not using a Pixel Shader). So, find the mid-point of the polygon, and then extend a line outwards from the midpoint disecting it into two pieces. The angle of the line would be from the X-axis. However, I wasn't able to figure out where to go from there.

I was hoping there would be some kind of mapping function that I could call like "ColorAt(int x, int y)" that would take into account the angle, and the colors I wanted to use.

In short, I would like help with an algorithm I could use to fill an array of pixels, OR pixel shader code.

##### Share on other sites
Emergent    982
A linear gradient takes the form

f(x,y) = dot((u,v), (x,y)) + b

for some fixed vector (u,v) and scalar offset b. The gradient will change in the direction of the vector (u,v).

Now, suppose you are given a unit vector (u',v'). By iterating over the vertices of your polygon, you can determine which vertex (vx,vy) minimizes dot((u',v'),(vx,vy)), and which one maximizes it.

Now, (u,v)=k(u',v') for some scalar k. Given the information about maximizing and minimizing vertices, you need only solve for,
- k
- b
to set the maximum and minimum colors at the maximizing and minimizing vertices, respectively.

Just do this on paper; it's not hard. This will give you the function to use, which you can evaluate by hand at each pixel using the pixel-shader approach.

--------

Alternatively, compute the AABB for your polygon, rotated at the correct angle. Render the polygon to the stencil buffer; then draw the AABB with appropriate stencil test options set, and vertex colors as desired to achieve your gradient.

##### Share on other sites
eq    654
You could do this without any pixels shaders and no per pixel math ops at all.
A gradient is just a one dimensional texture IMO.

Just calculate the scalar value per vertex on the CPU and use as U coordinate for a 2x1 pixel sized texture, set clamping and bilinear interpolation and there you have it.

Making more complex gradients (with many colors etc) just requires you to create a slightly bigger texture, i.e 4 evenly spaced colors would need a 4x1 texture etc.

My 2c

##### Share on other sites
Emergent    982
Quote:
 Original post by eqJust calculate the scalar value per vertex on the CPU and use as U coordinate for a 2x1 pixel sized texture, set clamping and bilinear interpolation and there you have it.

I think we have a winner...

##### Share on other sites
mapa8489    100
Thank you! Thank you! Thank you! I love that I was given a function, AND a method to do it without a pixel shader. I will be implementing both over the next few days. I've been looking for help for weeks now and I couldn't wrap my mind around it myself. Thank you :).