Search Unity

Why won't my multiply shader work with a texture set to Point (no filter)?

Discussion in 'Shaders' started by Reverend-Speed, Sep 14, 2017.

  1. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    Hey folks!

    So, I'm working on my first shader - shader newbie here - which takes a greyscale section of a texture (UV) and multiplies it by a block of colour on the same texture (UV2). This works great, but I'm also hoping to get a retro-ish pixel-art effect with the texture - so I set the texture filter to 'point' (or 'no filter')...

    Immediately the colour tinting stops working - the texture is sharp and pixelated, but it's no-longer tinted by the color block.

    Can anybody tell me how to get my tinting shader to work with a texture set to point ('no filter')?

    Shader code follows...

    Shader "OldSchool/TranspSkinTone"
    {
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
    Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    LOD 100

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

    #include "UnityCG.cginc"

    struct appdata
    {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float2 uv2Tone : TEXCOORD1;
    };

    struct v2f
    {
    float2 uv : TEXCOORD0;
    float2 uv2 : TEXCOORD1;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;

    v2f vert (appdata v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
    }

    fixed4 frag (v2f i) : SV_Target
    {
    // sample the texture
    fixed4 col = tex2D(_MainTex, i.uv);
    fixed4 colTone = tex2D(_MainTex, i.uv2);
    col *= colTone;
    clip(col.a - 1);

    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
    }
    ENDCG
    }
    }
    }​
    Thanks in advance,

    --Rev
     
  2. skilfuldriver

    skilfuldriver

    Joined:
    May 20, 2015
    Posts:
    19
    Hi Rev,

    It doesn't look like you initialise your 2nd uv set in the vertex program so it doesn't contain anything in the fragment program. You are initialising the 1st uv set so under that initialise the 2nd too and hopefully that'll fix it. I don't think the filtering is the issue.

    v2f vert (appdata v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    o.uv2 = v.uv2Tone;
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
    }

    or if you want to use the Tiling and Offsets from the material in both uv sets...

    v2f vert (appdata v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    o.uv2 = TRANSFORM_TEX(v.uv2Tone, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
    }

    Also change UNITY_FOG_COORDS(1) to UNITY_FOG_COORDS(2) as the value should be 1 more than the highest TEXCOORD used (it's a macro that creates another TEXCOORD using the value specified)
     
  3. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    Hey, both suggestions worked - I used your second block of code. Much obliged!

    --Rev
     
  4. skilfuldriver

    skilfuldriver

    Joined:
    May 20, 2015
    Posts:
    19
    You're welcome. By the way there was a warning on the console for 'vert' not being completely initialised so keep an eye out for that in the future to help you track down problems like this :)