Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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: an offset applied to 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);
}

When isFixed is false I want the gradient influenced by the camera position. But my shader is wrong, since the starting 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 possible to have these two behaviors in the same shader?

Thanks.

Edit: more details based on DMGregory suggestion.

Maybe the sentence gradient influenced by the camera, it is not correct. I'll try to be more clear with a few images (taken using the shaders above).

In the first image you can see a base sprite (in black) with an orange gradient applied to it. On top of the base you can see the player sprite; the camera is attached to this one.

In the second image the player has jumped and the camera follows him: the isFixed attribute is false and, as you can see, the gradiend moves with the player and the camera.

The third image shows the same situation of the second image, but the isFixed attribute is true and, as you can see, the gradient don't moves with the player and the camera.

I hope it's a bit more clear what I'm looking for.

share|improve this question
    
Can you describe in what way you want the gradient influenced by the camera? Pictures of each case would help (mock up the look you want in Photoshop or similar programs) – DMGregory May 5 at 11:21
    
@DMGregory you are right, maybe the sentence gradient influenced by the camera is not correct. I've just added some more details. Thanks. – enigma May 5 at 15:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.