Shader not working in Android build

Hi all,

I’m a total beginer with shaders and was glad having figured out a shader to do some recoloring. What I wanted to do is to replace the colors red and black in a sprite with some given color by the user (for multiple colors on a shirt for example)
This works very nicely in the editor but once I build an apk and run the program on my phone, the sprites disappear. I traced the problem down to my shader and if I modify the code slightly, the sprites get rendered (though in a wrong way but at least I see somehting). But I don’t understand why so maybe one of you experts can help me out :slight_smile:

Shader "Unlit/ReplaceRed"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    _ColorShirt("Shirt",Color) = (1,1,1,1)
        _ColorOutline("Outline",Color)=(0,0,0,1)
    }
        SubShader
    {
        Tags{
        "RenderType" = "Transparent"
        "Queue" = "Transparent"
    }
        LOD 100


        Blend SrcAlpha OneMinusSrcAlpha

        Pass
    {
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
        // make fog work


#include "UnityCG.cginc"

    struct appdata
    {
        float4 vertex : POSITION;
        fixed4 color : COLOR;
        float2 uv : TEXCOORD0;
    };

    struct v2f
    {
        float2 uv : TEXCOORD0;
        fixed4 color : COLOR;
        float4 vertex : SV_POSITION;
    };

    sampler2D _MainTex;
    fixed4 _MainTex_ST;
    fixed4 _ColorShirt;
    fixed4 _ColorOutline;

    v2f vert(appdata v)
    {
        v2f o;
        o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
        o.color = v.color;

        return o;
    }

    fixed4 frag(v2f i) : SV_Target
    {
        // sample the texture
        fixed4 col = tex2D(_MainTex, i.uv);
        return step(1.0,col.r)*step(1.0, 1-col.g)*_ColorShirt;
     
/*return step(1.0, col.r)*step(1.0, 1 - col.g)*step(1.0, 1 - col.b)*step(1.0, col.a)*_ColorShirt //pure red
             +step(1.0, 1-col.r)*step(1.0, 1 - col.g)*step(1.0, 1 - col.b)*step(1.0, col.a)*_ColorOutline //pure black
        +(1 - step(1.0, col.r)*step(1.0, 1 - col.g)*step(1.0, 1 - col.b))*step(1.0, col.a)*col; //use default color
        */
                                                                                             

    }
        ENDCG
    }
    }
}

I commented the original return statement in the frag out to find the error…the code now only renders the re-colorized red pixels. But when I change this:

return step(1.0,col.r)step(1.0, 1-col.g)_ColorShirt;

into:

return step(1.0,col.r)*step(1.0, 1-col.g)step(1.0, 1-col.b)_ColorShirt;

then nothing gets rendered. There are other combinations that don’t work but this is a very simple example that should work. Basically it says when the red of the original pixel is full bright (1.0) and green and blue are 0.0 then render the replacement color.

Maybe it is very obvious but I don’t see it :frowning:

Thanks for any help!

I agree that this line should render only if red is one and blue and green are exactly zero. Otherwise the shader won’t render anything (because alpha would be 0 in that case). Maybe there is a precision problem with the compression of your texture so the blue and red channel get altered a bit (so they are not exactly zero anymore)?

I would define a threshold after which the replacement color should be activated. e.g.

half replacementThreshold = 0.95;
return step(replacementThreshold,col.r)*step(replacementThreshold, 1-col.g)*step(replacementThreshold, 1-col.b)*_ColorShirt;

Maybe that already solves the problem. In the end I’m not sure if you really want this threshold change, you could also lerp the colors to get a smooth transition to the replacement color.

Edit: Oh and by the way: You don’t need to pass the color from the vertex to fragment shader. Those are vertex color properties tied to the mesh. If you don’t need them, you can ignore them :slight_smile:

Thanks, good suggestions I can try but I replaced the expression with an if-statement (not very fast, I know) and there it works. I also found an error message in Unity in the Inspector when I select the shader, I will look it up later when I’m home.
Thanks again!