LinearGradient - is there any way to improve transition smoothness

  1. Summary

There is an issue with color transition in LinearGradient when a solid background color is placed behind the gradient. The transition between colors appears visually uneven and not smooth.

App Name: Joyn

Bug Severity
Select one that applies

Impacts operation of app
Blocks current development
Improvement suggestion
Issue with documentation (If selected, please share the doc link and describe the issue)
Other


import LinearGradient from '@amazon-devices/react-linear-gradient';

...

{isMenuFocused ? <GradientBackground {...GRADIENT_PROPS} /> : null}

...

export const GRADIENT_PROPS = {
  colors: ['#00191CFC', '#00191CE6', '#00000000'],
  locations: [0.1, 0.62, 1],
  start: { x: 0, y: 0 },
  end: { x: 1, y: 0 },
};
  1. Observed Behavior

When a LinearGradient is rendered on top of a solid background color, the color transition is not smooth. Instead of a seamless gradient, visible color banding/steps can be observed during the transition. This results in a noticeable visual artifact that degrades the overall UI appearance (see attached screenshot).

  1. Expected Behavior

The gradient should blend smoothly into the underlying solid color without visible banding or abrupt transitions. Color interpolation should appear continuous and visually seamless.

The issue is especially noticeable on flat backgrounds and larger gradient areas, where the gradient is expected to fade naturally into the solid color.

4. Summary

Could you please recommend me how to improve the transition smoothness?
Or could you mind to validate if it is possible to improve inside the library the amount of transition steps on big gradinents (height 1080px; width 1054px)?

Hi @Yeldar_Kossynbay,

Thank you for your question about improving LinearGradient transition smoothness.

Our team is looking into this and will provide an update as soon as we have more information. In the meantime, you might want to try the following potential solutions:

Option 1 - Convert to RGBA Format (minimal change):

export const GRADIENT_PROPS = {
  colors: ['rgba(0, 25, 28, 0.988)', 'rgba(0, 25, 28, 0.902)', 'rgba(0, 0, 0, 0)'],
  locations: [0.1, 0.62, 1],
  start: { x: 0, y: 0 },
  end: { x: 1, y: 0 },
};

Option 2 - Add More Color Stops:

export const GRADIENT_PROPS = {
  colors: [
    'rgba(0, 25, 28, 0.988)',
    'rgba(0, 25, 28, 0.95)',
    'rgba(0, 25, 28, 0.902)',
    'rgba(0, 12, 14, 0.5)',
    'rgba(0, 0, 0, 0)',
  ],
  locations: [0.1, 0.35, 0.62, 0.8, 1],
  start: { x: 0, y: 0 },
  end: { x: 1, y: 0 },
};

If you’d like to test these approaches, I’ve attached an example code snippet (attached: GradientComparison.tsx (4.6 KB)) that may help you compare the different gradient implementations on your Vega hardware.

Please test these solutions and let us know if they resolve the banding issue.

Reference: Vega LinearGradient API Documentation

Thanks for helping us improve the Vega platform.

Warm regards,
Aishwarya

Hi Amen, unfortunately suggested options did not solved the problem.

Hi @Yeldar_Kossynbay ,

Thank you for your patience.

Our team is still looking into this and we will get back to you when there is an update.

Thanks,
Rohit

Chiming in as someone with gfx experience - looks like the kind of thing that can happen when working in an 8-bit pixel format, which gives surprisingly few blending steps, and banding can be more visible in the lower (darker) end of the spectrum as well due to perceptual issues / gamma correction.

Guessing this may need to be resolved by using a 16bit per channel working buffer and ensuring things are handled correctly color-space-wise during blend (i.e. sRGB vs linear).

my 2c, and may be wrong ofc.

Hi @Yeldar_Kossynbay ,

Thank you for your patience on this.

As Jason correctly identified, this is related to 8-bit color depth limitations causing visible banding, particularly in darker color ranges.

Here are the recommended workarounds:

  1. Add significantly more color stops - We understand you’ve already tried adding a few, but introducing even more intermediate color stops with finer alpha variations may help reduce the visible banding.

  2. Use a PNG image instead of LinearGradient - Replace the LinearGradient shader with a pre-rendered PNG gradient image. This approach avoids the floating-point to integer conversion issues that cause the banding. You can generate a PNG with the desired gradient (keeping RGB fixed and only varying alpha linearly) and use it as an image overlay instead of the LinearGradient component.

Our team is investigating a long-term fix for this.

Thanks,
Aishwarya