Hi, I would really appreciate any help with a color tint shader that can be used on mobile. I don’t have any idea about shaders yet.
The goal is to apply a color to a sprite’s material and change the tint intensity by changing the alpha chanel of that color. The shader should not alter the sprite’s blending with other elements on the scene, just the blending of the sprite image with its own material. Transparent pixels of the original sprite should remain transparent after the tinting.
Por example color 1,0,0,1 (RGBA) will tint a sprite fully red, while 1,0,0,0.5f will display the sprite in its half way to red from its original colour.
I guess it should work with some kind of formula like:
RGBChanels = original_colour_chanel + (distination_colour_chanel - original_colour_chanel) * Alpha;
ALPHAChanel = original_alpha_chanel;
Is that possible? Would anyone be so kind to help me with the shader code?
I can’t believe, but I achieved it myself, even if I’m not sure if my code is Ok, but it is working. Probably it can be done in a better manner, it is my first shader and I don’t even know what is the use of most of the code.
I’ll post the code since it can be useful for someone:
No, I was wrong. The shader is almost ok, it works just fine with tint color values with alpha 0 or 1, but it fails in between.
It was expected to maintain the origin sprite alpha values regardless of the tinting color opacity, but when the tint’s opacity is between 0 and 1 the sprite is half transparent (look at the attached picture). Tomorrow I’ll try to fix it, but if anyone knows what I’m doing wrong I would really appreciate it.
Hi again, I’m still asking for help. My shader works just great on Desktop, but on mobile it shows sprites transparent and their transparent portion of image tinted in pink. Any advice? Why this shader is working fine on Desktop and wrong on Mobile? Can anyone help me to fix it? Thank you!
I found a very strange behaviour: when I add at least one instance with that tint material on the scene using the Unity editor, then all the other instances created programmatically and using that tint shader work great on mobile too. Instances are instantiated using GameObject.Instantiate(Resources.Load(“name”)) method and are assigned to the tint material programmatically.
If I don’t add that dummy instance, then all other instances created programatically are shown using wrong colours (transparent and pink, as shown above). It is not a huge issue, since I can add a hidden dummy tinted sprite somewhere in the scene, but I would like to know why this is happening and if it can be fixed.
Thank you for the suggestion, I tried it but unfortunately it doesn’t change anything using fixed4 or float4.
What do you think about the fact that if at least one item is instatied on the stage using the Unity’s built in scene editor then all other instances work just fine even in mobile? Does it have any sense?
You want to tint a sprite with one color and change it’s alpha with another? The problem with your fragment shader is most likely in that “if” statement. mobile GPUs don’t really like that and very few even support that (it requires a hardware extension on ES 2.0 devices)
Please provide a complete example of what you are trying to achieve (like 5-10 different variants of a sprite with different tint/color settings) so we can help you
The shader is working just as expected, the problem is that I don’t understand why I have to have at least one instance of a sprite using that shader-material on the scene created using the Unity’s editor in order to make all the other sprites (instiated programatically) to work as well. On desktop it works always, but on mobile it is needed at least one sprite created using the unity editor in order to prevent those strange artefacts shown in the picture above.
The shader should work as explained in this video (excuse me for my bad english), and I actually achieved it as it can be seen (probably it can be done in a better way). The opacity of the original sprite should never change, just its color, that should be between the original sprite’s color (when the tint color alpha is 0) and the tint color when the opacity of the tinting color is 1. An alpha value in between, lets say 30% should be as expected: 70% original sprite’s color and 30% tinting color.
I tried removing the if statement and it happens the same on mobile. It just works as expected if I remain 1 tinted sprite created using the Unity editor.
I have attached two versions - simple one for understanding how it works, and a separate zip archive with all the built-in unity stuff like instancing, stereo projection, per rendererer color etc. Most likely you’ll be good to go with a simple one. Cheers
Initially I had the same issue with your shader, those pink borders appear on mobile unless I add a dummy sprite somewhere on the scene with that shader-material using the Unity’s scene editor. This lead me to guess that the failure should not be the shader itself, but other piece of my code, and I found it.
It seems that if instead of creating the material programmatically I expose it as a public variable and assign it using the Inspector, then both your shader and mine work just fine on mobile without the need of that dummy sprite already instantiated on the scene.
It is strange to me, because it should be the same, since the material is not assigned to any sprite until a certain time in the future when certain event rises. At that time, the start function was already called long time ago and the programmatically created material was already created , but for whatever reason it doesn’t work well on mobile if the material is not already there on the scene since the beginning. It is also strange because on desktop works just fine and because I don’t see why adding and additional tinted sprite could fix my initial code. Probably a Unity’s bug? Or probably a material can not be created using a shader name if it was not used before? I don’t know…
However, million thanks for being so kind to share your shaders, your code is cleaner and shorter than mine. I will use yours and try to learn from it!
Oh, I see your problem now. Your Shader.Find couldn’t find a shader because Unity thought that it’s not used anywhere and thus didn’t include it in build. If you use shaders programmatically, you have to either put it inside of the Resources folder, Create and use a material with it (like you do with a dummy object), or add it as “Always Include” in graphics settings
I see, sorry, probably it was a newbie failure but I’m just starting to learn Unity and I didn’t know that shaders have to be located in the Resources folder as well. Thanks a lot!
Cool. That`s that I was in pain trying to figure out.
Could you guys elaborate on how change dynamically the texture and the color of independent objects?
Answering myself with code to use with the shader Graph for someone who need it.
*strings with odd numbers are the exact field name of the shader property that i made.
public Color color;
public Texture sprite;
Renderer m_renderer;
private void Start()
{
m_renderer = GetComponent<Renderer>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
m_renderer.material.SetColor("Color_52A2175E", color);
m_renderer.material.SetTexture("Texture2D_4442BA5F", sprite);
}
}