caccolona
caccolona

Reputation: 33

Multiple gradient drawing in DirectX

How can I draw a gradient rect (a color hue spectrum actually) like this: enter image description here

I thought of drawing it pixel by pixel but it takes a lot of time (memory). I thought of drawing 4 different gradient rects with vertex buffers, and it should be good, but is there another way to do that?

Upvotes: 1

Views: 2336

Answers (2)

Drop
Drop

Reputation: 13003

Such color effects is very easy to implement in pixel shader procedurally.

  • Add texture coordinates to your vertex declaration (if it's not have it yet) and assign them to your rectangle: for example, left top corner (0.0f, 0.0f), right bottom (1.0f, 1.0f), right top (1.0f, 0.0f) and left bottom (0.0f, 1.0f)
  • As usual, pass texture coordinates unchanged from vertex shader
  • In pixel shader, you will receive smoothly interpolated texture coordinates
  • Set any color you want depend on texcoord value: in your example you want horizontal rainbow effect, so change hue component of color in HSL system along horizontal component (x) of texture coordinates. Then convert hue to RGB color.

Here is a code from my GLSL shader, adopted for HLSL (renamed vec3 to float3 and clamp to saturate etc.). Note, that it has not been tested as HLSL.

struct PSInput
{
    float2 texcoord;
};


float3 HueToRGB(in float h)
{
    float3 rgb = 0.0f;
    rgb.r = abs(h * 6.0f - 3.0f) - 1.0f;
    rgb.g = 2.0f - abs(h * 6.0f - 2.0f);
    rgb.b = 2.0f - abs(h * 6.0f - 4.0f);
    rgb = saturate(rgb);
    return rgb;
}

void main() : SV_Target
{
    float3 colorRGB = HueToRGB(in.texcoord.x);
    return float4(colorRGB, 1.0f);
}

For more control over colors, you can:

  • write more sophisticated pixel shader
  • add more vertices with different color components (like Ylisar adviced).
  • just apply a texture

Happy coding!

Upvotes: 0

Ylisar
Ylisar

Reputation: 4291

For every distinct color add a a vertex pair containing the color as vertex data. In the vertex shader, forward that color to the pixel shader, and let the pixel shader simply output it. As the attribute will be interpolated from the vertex shader -> pixel shader you'll get the gradient for free.

Upvotes: 1

Related Questions