GradientStyle & Custom Gradient Texture input

UIGradient has been a great gift to us developers ever since its introduction as it’s simple to use and can be quite powerful when combined with other features to create nice effects. The only drawback to it is that it’s quite limited, only offering a Linear Gradient style. The effectiveness and power of UIGradients would increase EXPONENTIALLY if they had the ability to render using different gradient styles.

Mockup

image

Proposed new properties of UIGradient:

  • Style: A new enum with a selection of gradient styles

    • GradientStyle.Linear - What we currently have and are used to.
    • GradientStyle.Radial - Gradient begins from a central point and spreads outwards in a circular shape.
    • GradientStyle.Conic (or Angle as in PS) - Gradient revolves around a central point.
    • GradientStyle.Square (or Diamond as in PS) - Similar to Radial, except it forms a square/diamond shape.
    • GradientStyle.CustomImage - Gradient forms using an inputted Texture map. Texture map should be greyscale (black/white only).
  • StyleTextureId: The image asset for which the gradient is based off if the style is set to ‘Custom Image’

    • Used only when GradientStyle is set to Custom Image.
    • Image should be a greyscale opaque bitmap.
    • Color from the gradient ColorSequence is interpolated from how dark/light each pixel on the texture is.
      • Black pixels = ColorSequence [0%] (The leftmost ColorSequenceKeypoint)
      • 50% grey pixels = ColorSequence [50%] (The central ColorSequenceKeypoint)
      • White pixels = ColorSequence [100%] (The rightmost ColorSequenceKeypoint)
    • This is something I commonly used in Unreal Engine using their material setup and UMG to create custom progress/health bar shapes and transition effects.
  • Scale: The scale offset of the gradient, similar to how Photoshop handles it

    • Low scale example
      image
    • High scale example
      image

Use case example

I like to create radial progress bars, however the best way to achieve them currently is as follows (for a clockwise-depleting radial bar):

  • Have two ImageLabels centralised on the same point with half of a hollow circle image on either side.
  • The left half must have a UIGradient with the Transparency suddenly jumping to 1 at 50%.
  • Use scripting to animate the wheel
    • When progress is 50-100%, rotate the right half into the left half
    • When progress is 0-50%, hide the right half and set the Rotation of the left half’s UIGradient so that it depletes the semi-circle into nothingness.

01ac6fb58bcace01e165772910681959

As you can see, it surely works, but it’s a little convoluted (takes a little trial and error to get the maths set up correctly), has a mild rendering artefact (the right half bulges out of the left half by 1 pixel when it is rotated into the left half) and could certainly be made 100x more convenient and easy to set up with one single UIGradient set to Conic and a little basic scripting setting the Transparency numbersequence.


Further potential use cases for enhanced GradientStyles:

The following images are taken from some of my projects at university in Unreal Engine.
Inventory opening transition
939f7c83ec6934d839f047cf53b93b7c

Texture input used

Custom progress bars

This example also uses a texture input to distort the image. Texture distortion on UI plz Roblox :star_struck:?
9e500d86c7863eea4565a451f8c1077c

The XP bar is a painted horseshoe shape with a distorted Conic gradient.

Images used to set up the health bar:
(1. Gradient mask) (2. Foreground to be masked) (3. Background)

More hypothetical use cases:

  1. Loading screen animations
  2. Transition effects
    • Something more complex than a simple fade or swipe. Such as a custom shape filling & unfilling on the screen, such as a star.
  3. Visual & particle effects
    • These new gradients could be used to mimic particles or on-screen particles with enhanced shape animation capability.
  4. Ripple effects using circular gradients that grow & shrink.
33 Likes

I need this NOW. I have no idea how many times I’ve seen something like this and being sent back cuz it’s complicated and I’m stupid.

2 Likes

A while back I made the base code for 2-colour radial gradients using editable images. I’ve attached it below if you want to try to mess around with it and try to make it work more desirably.

RadialGradient.rbxm (5.0 KB)

(Note that it probably doesn’t work with transparency)

3 Likes

This would be such a lifesaver if it’s added soon

2 Likes

Ooh, that would be super useful! I’ve got some extra ideas that could be super useful too. If we could get the option to have the gradients tile, and have multiple gradients on one object, so many more effects could be possible!

3 Likes

I have a plugin made for… almost the exact thing.

But yeah, I get it. There is a difference. This still would be cool!

3 Likes

Fun fact - You can actually make radial gradients natively using gradients themselves - with a weird hack using UIStroke on a 0x0 pixel Frame

Here’s what it looks like:
image

Here’s the tree (it’s really that simple):
image

And here’s the script I used to make it (I selected the UIGradient and ran it in the command bar).

game.Selection:Get()[1].Color = ColorSequence.new({
	ColorSequenceKeypoint.new(0, Color3.new(1, 0, 0)), --[[Red]]
	ColorSequenceKeypoint.new(0.499995, Color3.new(0, 1, 0)), --[[Green]]
	ColorSequenceKeypoint.new(0.5, Color3.new(1, 1, 1)), --[[White]]
	ColorSequenceKeypoint.new(0.500005, Color3.new(1, 1, 0)), --[[Yellow]]
	ColorSequenceKeypoint.new(1, Color3.new(0, 0, 1)) --[[Blue]]
})

Kinda hacky, but hey, it works!

If you want to take a look, here’s a file containing the radial gradient:
RadialGradientExample.rbxl (51.9 KB)

Also note that the LineJoinMode of the UIStroke must be set to Enum.LineJoinMode.Round in order for this to work.

edit: sorry, hit wrong reply button

edit 2: Also, you can make it take up a rectangle by using a bit of trigonometry (I did a rough estimate here) to fit the circle to fill a Frame with ClipsDescendants set to true.
image

Here’s the place file for that, if anyone is curious how exactly I did it:
ClippedRadialGradient.rbxl (52.1 KB)

edit 3: I think this is actually part conic gradient (the rainbow color effect) and part radial (the white that spreads out from the center)

4 Likes

I made a module for radial progress bars using EditableImage which may able to be used as an alternative to this feature request for some use cases. It supports Transparency, Rounded Edges and Images.

https://github.com/MightyPart/Radialicious


5 Likes

I personally have always felt like Roblox’s UI was a mixed bag, some parts of it are really nice and intuitive to work with (at least when compared to other engines), but then when you want to do more advanced UI animations with complex visuals it gets dicey and borderline frustrating.

Almost anything can be implemented in code manually but this has it’s own implications with performance on low-end CPUs.

Ideally, Roblox really should add a lot more UI functionality to bring the 2D rendering up to standard with other big name engines, saves time for developers, would make good looking UI easier to create, and possibly will make games that need to use a lot of hacky solutions for advanced UI visuals run faster on CPU bottlenecked systems (though I’m unsure as to if this would actually be noticeable in practice). Additionally, the use cases for more gradient styles are pretty much endless (I can think of several places where I’d want to use them) so this gets a big :+1: from me!

I’m sure that more UI tools will be coming in the future, the recent UIDragDetectors show that they indeed are interested in furthering UI tools on Roblox.

3 Likes

This is a conical or angular gradient but I won’t really say this is useful as the gradient seems quite inaccurate. But still a good trick.

It of course can’t really compare to my method which provides accurate results as it uses editable images soooo yeah.

1 Like

Both are superb creative methods utilising both new technology and unintended behaviours of existing technology, however they both still have drawbacks - mainly being unable to quickly blend with other UI objects how UIGradients do every render frame.

3 Likes

Yeah… that’s the ONLY drawback that I mean I could fix if I could make a system to render gui frame simultaneously which does seem possible but not really that effective maybe?

But basically, I make a system to render gui frames on to editable images that is also dynamic and then I could basically implement various algorithms like blurring and what you say.

What do you think? Should I try that?

2 Likes

It sounds interesting, so totally go for it. I’m interested to see your solution :slightly_smiling_face:

1 Like