- Home /
Horizontally gradient on image UI element
Hello,
I've created a material with a gradient texture. The gradient texture looks like the following:
This are my settings for the texture.
Now I create a material with this textura and "Bumbed diffuse" shader. Unfortunately if I assign this material to a "UI -> Image" element it will not be shown on it. Instead, the defined color will be shown.
How can I get the gradient to be shown instead of the color? Do I need a specific shader? If so, why since it is a normal texture assigned to the material!?
can't reproduce your problem. Without any light source in the scene, it shows O$$anonymous$$. If there is some light source in your scene, the gradient may be faded out by the light color which may be your actual problem.
Nope, deleting the light will not affect the problem. Did you assign the material on a cube? $$anonymous$$aybe this is why you can't reproduce the problem. I've assigned it to a UI Image
Hey any way to make the colors use alpha transparency? It looks great, but alpha would be better.
Answer by Max-Bot · Mar 03, 2015 at 10:53 AM
It's easy, my friend. Assign your sprite directly to sprite property of Image component, if you don't want to modify it at run time. Else, for more flexibility, you can use gradient shader in your material.
Create shader, call him SpriteGradient and replace code by this:
Shader "Custom/SpriteGradient" {
Properties {
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Left Color", Color) = (1,1,1,1)
_Color2 ("Right Color", Color) = (1,1,1,1)
_Scale ("Scale", Float) = 1
// these six unused properties are required when a shader
// is used in the UI system, or you get a warning.
// look to UI-Default.shader to see these.
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
// see for example
// http://answers.unity3d.com/questions/980924/ui-mask-with-shader.html
}
SubShader {
Tags {"Queue"="Background" "IgnoreProjector"="True"}
LOD 100
ZWrite On
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
fixed4 _Color2;
fixed _Scale;
struct v2f {
float4 pos : SV_POSITION;
fixed4 col : COLOR;
};
v2f vert (appdata_full v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.col = lerp(_Color,_Color2, v.texcoord.x );
// o.col = half4( v.vertex.y, 0, 0, 1);
return o;
}
float4 frag (v2f i) : COLOR {
float4 c = i.col;
c.a = 1;
return c;
}
ENDCG
}
}
}
Set up colors:
Tweak them from code:
using UnityEngine;
using System.Collections;
public class GradientTest : MonoBehaviour {
public Material yourGradientMaterial;
void Start () {
yourGradientMaterial.SetColor("_Color", Color.black); // the left color
yourGradientMaterial.SetColor("_Color2", Color.white); // the right color
}
}
Beautiful answer, I sent "reward points" :)
note, it's easy to remove the stencil properties
warnings. I edited in the simple fix for the warnings.
How to make this shader to colorize my texture with gradient? It seems to ignore alpha values of my texture assigned to it.
Hi Prosto, I encourage you to ask that as a new question on this site. This answer is too beautiful to edit more. Also it's a separate question. Some things that may help
Hello, your shader is so cool but maybe this is a more compatible one.
Shader "Custom/SpriteGradient" {
Properties{
[PerRendererData] _$$anonymous$$ainTex("Sprite Texture", 2D) = "white" {}
_Color("Left Color", Color) = (1,1,1,1)
_Color2("Right Color", Color) = (1,1,1,1)
_Scale("Scale", Float) = 1
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWrite$$anonymous$$ask("Stencil Write $$anonymous$$ask", Float) = 255
_StencilRead$$anonymous$$ask("Stencil Read $$anonymous$$ask", Float) = 255
_Color$$anonymous$$ask("Color $$anonymous$$ask", Float) = 15
// see for example
// http://answers.unity3d.com/questions/980924/ui-mask-with-shader.html
}
SubShader{
Tags{ "Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True" }
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
Read$$anonymous$$ask[_StencilRead$$anonymous$$ask]
Write$$anonymous$$ask[_StencilWrite$$anonymous$$ask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest[unity_GUIZTest$$anonymous$$ode]
Fog{ $$anonymous$$ode Off }
Blend SrcAlpha One$$anonymous$$inusSrcAlpha
Color$$anonymous$$ask[_Color$$anonymous$$ask]
Pass{
CGPROGRA$$anonymous$$
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
fixed4 _Color2;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_$$anonymous$$ATRIX_$$anonymous$$VP, IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw - 1.0)*float2(-1,1);
#endif
OUT.color = lerp(_Color, _Color2, IN.texcoord.x);
return OUT;
}
sampler2D _$$anonymous$$ainTex;
fixed4 frag(v2f i) : COLOR{
fixed4 c = tex2D(_$$anonymous$$ainTex, i.texcoord) * i.color;
clip(c.a - 0.01);
return c;
}
ENDCG
}
}
}
Thanks for this. Very helpful for beginners. One question. This creates the gradient from left to right, e.g. horizontal. What part of the Shader script addresses the direction? @$$anonymous$$ax-Bot Would it be trivial to make it vertical? How about as a Euler or Vector to be edited from C# or the editor as the colors are? Also, @esnho, I tried your shader as well, but don't really see any difference in the results other than the preview type. Can you explain why it's "more compatible"?
EDIT! DOH!! So I just realized where the vertical vs horizontal aspect is addressed. On line 47, simply changing to y does it. :) o.col = lerp(_Color,_Color2, v.texcoord.y );
Still curious how to make it an angle that could be edited from editor and scripts.
@agScreen This is more compatible because it doesn't glitch sort order if you overlap two gradients in Editor. And more, you can put images in! So you can gradient images and by using alpha channel it make possible to create gradients out of any shapes! In the end, it implements everything from the standard UI shader, so it should be perfect.
For an angle you should play with the lerp function using a function related to xy texcoord as input in the third parameter. For example try to put as third parameter the variable gradient generated from this:
float gradient = (texcoord.x+texcoord.y)/2.0;
@esnho thanks for the info. though i don't fully understand what you mean about using images.
"And more, you can put images in! So you can gradient images and by using alpha channel it make possible to create gradients out of any shapes!"
Huh?! Can you give an example or explain further? $$anonymous$$aybe some links to some reference material? Also, I tried using (texcoord.x+texcoord.y)/2.0
as the third argument in the lerp
method and didn't even get a gradient, but thanks for the pointer to learn about the lerp
method. It does look like where I'd address the angle.
Also, FWIW, I'm running the latest version of Unity and both above shaders cause issues with any other 2D Canvas UI elements unless you rename the _Color
variable to something like _Color1
, else it seems to "tint" all other 2D Canvas UI elements with the gradients first color. This confused me the first time it happened, because you also can't edit the Default UI $$anonymous$$aterial. (It seems to effectively set the Default UI $$anonymous$$aterial color to that of the _Color
variable -- as if maybe _Color is now a reserved name).
$$anonymous$$y two cents... ¯_(ツ)_/¯
Answer by Josh_He · Jul 17, 2019 at 12:30 PM
Hey, this is too late to be a helpful answer for the original author. But for everyone else looking for a way to use gradients on their UI, it might be useful. Unity's UI components use vertex colors to color the graphics. This saves draw calls because all elements can use the same material. One can easily use vertex colors to create a gradient. It is best implemented using the BaseMeshEffect class where you can simply set the vertex colors of the image. (https://docs.unity3d.com/2019.1/Documentation/ScriptReference/UI.BaseMeshEffect.html)
I have implemented a gradient component based on this. You can animate the colors or change them via a script, which is a bonus compared to using a texture. Here is the store link: http://u3d.as/1o5m
Answer by julmot · Mar 09, 2015 at 02:17 PM
Instead of creating a material with the texture assigned, assign the gradient texture to "Source image" of the element itself. This has solved the problem for me.
Answer by aybeone · Apr 08, 2019 at 07:37 PM
I've made shader for UI that uses UnityEngine.Gradient:
See the thread with code at:
https://forum.unity.com/threads/wiki-drawing-an-ui-element-using-unityengine-gradient.658120/
Your answer
Follow this Question
Related Questions
Need Mask Shader . 0 Answers
Slice-9-grid gradient shader 0 Answers
Show only specific part of UI.Image 0 Answers
Builtin Shader UI/Unlit/Transparent Yellow Pixels Read As White 0 Answers
Work with Gradient Alpha Mask UI 0 Answers