Jump to content
  • Advertisement
Sign in to follow this  
enigmagame

Linear gradient shader ( Photoshop-like)

This topic is 954 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm searching a way to implement a linear gradient shader that behaves as the linear gradient in Photoshop (only the vertical case is necessary). It will be applied to 2D sprites.

Currently I'm passing to the pixel shader these parameters:

  • StartColor.
  • EndColor.
  • Offset: the gradient starting point.
  • Length: the gradient length (the range inside where the colors will be interpolated).
  • isFixed: a boolean parameter that indicates if the gradient must be influenced by the camera position or not.

Here a first attempt of the vertex shader and the pixel shader that I've implemented:

struct VsInput
{
    float3 position : VES_POSITION;
    float2 uv	    : VES_TEXCOORD0;
    float4 color    : VES_COLOR;
};

struct VsOutput
{
    float4 position : HPOS;
    float2 uv	    : TEXCOORD0;
    float4 color    : COLOR0;
    float4 outPos   : TEXCOORD1;
};

VsOutput main(VsInput input)
{
    VsOutput vsOutput;
    vsOutput.position = MUL(float4(input.position, 1.0f), WorldViewProjection);
    vsOutput.uv = input.uv;
    vsOutput.color = input.color;
    vsOutput.outPos = vsOutput.position;

    return vsOutput;
}
struct PsInput
{
    float4 Position : HPOS;
    float2 UV	    : TEXCOORD0;
    float4 Color    : COLOR0;
    float4 outPos   : TEXCOORD1;
};

float4 startColor;
float4 endColor;
float offset;
float len;
bool isFixed;

float4 main(PsInput psInput) : COLOR
{
    psInput.outPos = psInput.outPos / psInput.outPos.w;
    float yScreenSize = 900.0f;
    float yPixelCoordinate = 0.0f;
    if (isFixed)
    {
	yPixelCoordinate = 0.5f * (1.0f - psInput.UV.y) * yScreenSize;
    }
    else
    {
        yPixelCoordinate = 0.5f * (psInput.outPos.y + 1.0f) * yScreenSize;
    }

    float gradient = (yPixelCoordinate + offset) / len;
    gradient = clamp(gradient, 0.0f, 1.0f);
    return lerp(startColor, endColor, gradient);
}
I think something's wrong, for example, with an offset of 0.0, the gradient starts from the bottom of the window and not from the bottom of the sprite. Another issue is that there is no correlation between the fixed and non-fixed mode.
 
I'm pretty sure that there's something correct and something wrong in my approach, so I'm here for any suggestions.
 
Thanks.
Edited by enigmagame

Share this post


Link to post
Share on other sites
Advertisement
If isFixed is false, it looks like the gradient is supposed to start at the bottom of the window. Have you verified that isFixed is false? You could also try passing psInput.UV.y as the output of the shader to verify that its value is correct.

Share this post


Link to post
Share on other sites

If isFixed is false, it looks like the gradient is supposed to start at the bottom of the window. Have you verified that isFixed is false? You could also try passing psInput.UV.y as the output of the shader to verify that its value is correct.

With isFixed false I want the gradient influenced by the camera position. My shader is wrong, since the start point of the gradient is the bottom of the window instead of the bottom of the sprite.

The question is: how can I modify the shader in order to have the gradient starting from the bottom of the sprite? Maybe I need the size of the sprite in pixel? Or there are other convenient ways?

 

The other question regards the "fixed gradient": if I want the gradient not influenced by the camera position, what is the convenient way? It's possibile to have these two behavior in the same shader?

 

Thanks.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!