How to make gradients like this?

I want a gradient that doesn’t ever show a single static color, so don’t tell me “use offset”
(2 Colors & Tri-Colors, I want to make a theme system like video shown to make a UI for settings in my game)

1 Like

use offset-

don't hurt me pls. just use offset!!111!

Okay I am joking.
Here:

local c1 = Color3.fromRGB(252, 211, 234)
local c2 =  Color3.fromRGB(189, 55, 124)

local numVal = Instance.new("NumberValue")
numVal.Value = 0

local tweenService = game:GetService("TweenService")
local info = TweenInfo.new(4,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1)
local goal = {Value = 2}
local tween = tweenService:Create(numVal,info,goal)
tween:Play()

numVal.Changed:Connect(function()
	local color
	if numVal.Value < 1 then
		color = ColorSequence.new({
			ColorSequenceKeypoint.new(0,c2:Lerp(c1,numVal.Value)),
			ColorSequenceKeypoint.new(numVal.Value,c2),
			ColorSequenceKeypoint.new(1,c1:Lerp(c2,numVal.Value))
		})
	else 
		color = ColorSequence.new({
		ColorSequenceKeypoint.new(0,c1:Lerp(c2,numVal.Value-1)),
		ColorSequenceKeypoint.new(1,c2:Lerp(c1,numVal.Value-1))
		})
	end
	script.Parent.Color = color
end)

what if it is tri color / rainbow
(rainbow: HSV(0 ~ 1, 0.6, 1))

(that is left to right, but idk how to do right to left)

Well I won’t tell you because I want to encourage self-learning on this platform. I recommend tinkering with the code and figuring out yourself.

that animation just “rotates” (or replaces but a lil animation not shifting) the right color (color1) from right to left instead of shifting :thinking:
pls also explain how it works :pray:t2:

That’s from an exploiting library ui?
You can just use it normally, I managed to convert an exploiting library ui to work normally to utilize its notification system.
image

Yes I’m aware it’s from minecraft but since you already cheat, you can find a similar library.

not rly completely good as the color looks like a line but

nv.Changed:Connect(function()
	local color
	if nv.Value < 1 then
		color = ColorSequence.new({
			ColorSequenceKeypoint.new(0, color2:Lerp(color1, nv.Value)),
			ColorSequenceKeypoint.new(math.max(nv.Value, 0.1), color2),
			ColorSequenceKeypoint.new(1, color1:Lerp(color2, nv.Value))
		})
	else
		local firstColor = color1:Lerp(color2, nv.Value - 1)
		color = ColorSequence.new({
			ColorSequenceKeypoint.new(0, firstColor),
			ColorSequenceKeypoint.new(nv.Value - 1, color1),
			ColorSequenceKeypoint.new(1, color2:Lerp(color1, nv.Value - 1))
		})
	end
	print(nv.Value)
	for _, v in ({script.Parent.Gradient, script.Parent.Shaders.Gradient}) do
		v.Color = color
	end
end)

(cant record as OBS will just lag much and frame drops 99%)

Have you messed around with Rotation?

rotation & offset looks bad, it can be easily observed, I don’t want trash things to be in my GUIs


local UiGradient = script.Parent.UIGradient
local TweenService = game:GetService("TweenService")

local c1 = Color3.new(0.611765, 0.403922, 0.701961)
local c2 = Color3.new(1, 0.647059, 0.65098)
local directionReverse = false

local numValue = Instance.new("NumberValue")
local info = TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1)
local goal = {Value = directionReverse and 0 or 2}
numValue.Value = directionReverse and 2 or 0
TweenService:Create(numValue,info,goal):Play()
local function UpdateGradient()
	local colA,colB = numValue.Value > 1 and c1 or c2, numValue.Value > 1 and c2 or c1
	local centerTime = numValue.Value > 1 and numValue.Value-1 or numValue.Value
	local initialColor = colA:Lerp(colB,centerTime)
	local centerColor = colA
	local endColor = colA:Lerp(colB,math.abs(1-centerTime))
	
	UiGradient.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0,initialColor),
		ColorSequenceKeypoint.new(centerTime,centerColor),
		ColorSequenceKeypoint.new(1,endColor),
	})
end

numValue.Changed:Connect(UpdateGradient)

For explanation of the new improved code it’s quite simple.

First we take 3 points on a gradient; A,B and C. A is at the start and C is at the end. Then we add a number which transition from 0 to 1. As the number increased from 0 to 1 we move the time for B from 0 to 1 as well. With this, we also lerp the color of A and C accordingly. Now, this only works one way, to make it two way we increase the range to 2 but as the number reaches 1 we take out 1 from our calculation so that the range actually stays from 0 to 1.
That’s the basic concept. Read the code for more info.

but the gradient look like a single vertical line ( | ) for static color then a drastic change (kinda unrealistic*), how to make it wider and better?
(I tried for loop but it looks the same)

Use less contrasting colors. Simple.

like if a theme is like
(255, 64, 64)
(255, 255, 255)
(64, 255, 64)
but I don’t want to change the colors
how do I make it better

like make the 1st color closer to the second color? (when animation)

For that, use Google and then show me your progress.

(ThemeComponent.java), (rgqtest.glsl)

#version 120

uniform vec2 u_size;
uniform float u_radius;
uniform vec4 u_first_color;
uniform vec4 u_second_color;
uniform float u_time;
uniform int u_direction;
uniform vec4 u_edges;

void main() {
    vec2 tex_coord = gl_TexCoord[0].st;
    float newTexCoord = u_direction > 0.0 ? tex_coord.y : tex_coord.x;

    vec4 color = mix(u_first_color, u_second_color, 0.5 + 0.5 * sin(3.0 * (newTexCoord + u_time)));

    if (tex_coord.x < 0.5 && tex_coord.y > 0.5 && u_edges.x == 0.0 ||
    tex_coord.x > 0.5 && tex_coord.y > 0.5 && u_edges.y == 0.0 ||
    tex_coord.x > 0.5 && tex_coord.y < 0.5 && u_edges.z == 0.0 ||
    tex_coord.x < 0.5 && tex_coord.y < 0.5 && u_edges.w == 0.0) {
        gl_FragColor = color;
    } else {
        gl_FragColor = vec4(color.rgb, color.a * smoothstep(1.0, 0.0, length(max((abs(tex_coord - 0.5) + 0.5) * u_size - u_size + u_radius, 0.0)) - u_radius + 0.5));
    }
}

(mc, shader, video shown above, 2 colors)

:thinking:

GL Shaders :dizzy::dizzy_face::face_with_spiral_eyes: (I can’t understand a thing inside D:)

local u_first_color = Color3.fromRGB(170, 7, 107)
local u_second_color = Color3.fromRGB(97, 4, 95)
local function mix(firstColor, secondColor, blendFactor)
	local inverseBlendFactor = 1 - blendFactor
	return Color3.new(
		firstColor.R * blendFactor + secondColor.R * inverseBlendFactor,
		firstColor.G * blendFactor + secondColor.G * inverseBlendFactor,
		firstColor.B * blendFactor + secondColor.B * inverseBlendFactor
	)
end
local runService = game:GetService("RunService")
local u_time = 0
local sin = math.sin
runService.RenderStepped:Connect(function(deltaTime)
	u_time = u_time + deltaTime
	local colorseq = {}
	for i = 0, 19, 1 do -- roblox only allows 20 max
		local tex_coord = {x = i / 19}
		local color = mix(u_first_color, u_second_color, 0.5 + 0.5 * sin(3.0 * (tex_coord.x + u_time)))
		table.insert(colorseq, ColorSequenceKeypoint.new(i / 19, color))
	end
	local cx = ColorSequence.new(colorseq)
	script.Parent.Gradient.Color = 			cx
	script.Parent.Shaders.Gradient.Color = 	cx
end)

(based on Rise 6’s shader glsl code)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.