Search code examples
c++directxdirectx-9

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?


Solution

  • 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!