Mip Map biasing in Unity shaders

March 1st, 2014 | Posted by bluescrn in Uncategorized

A couple of people have asked how to do this, after my post on bitmap font rendering. It only takes a small change your shaders (so long as they’re CG shaders to begin with, not fixed-function ‘shaders’), so it’s quite easy to use with 2DToolkit or NGUI.

Start by making a copy of the shader (if you’re not sure which one, find the material used by your font).

Open the shader in a text editor. If you’ve never messed with shaders, it might be worth pointing out that the shader name at the top of the .shader file is the name used when selecting shaders within Unity – so give that a new name.

The most important change is in the fragment shader, where the texture needs to be sampled using tex2Dbias(), rather than the regular tex2D().

Here’s the modified version for one of the standard 2DToolkit shaders (for NGUI it should be very similar, just with some slightly different variable names):

fixed4 frag_mult(v2f_vct i) : COLOR
{
fixed4 col = tex2Dbias(_MainTex, half4(i.texcoord.x,i.texcoord.y,0.0,_MainTexBias)) * i.color;
return col;
}

Then all you need to do is add and expose the new _MainTexBias parameter, so add it to the Properties section of the shader:

Properties
{
_MainTex (“Base (RGB) Trans (A)”, 2D) = “white” {}
_MainTexBias (“Mip Bias (-1 to 1)”, float) = -0.65
}

And at the top of the CGPROGRAM section of the shader, add the declaration of the shader parameter:

sampler2D _MainTex;
float4 _MainTex_ST;
half _MainTexBias;

And that’s all there is to it, really.

For sharpening up UI and font textures, you’ll want a mip bias between 0.0 and -1.0 (-1.0 means ‘sample one mip level higher than normal’). Positive values are usually bad, as they make things blurrier.

If changes to the bias parameter are not visible immediately in the editor, it’s probably because your 2D framework has created an instance of the material internally, so it isn’t getting the parameter changes. It should normally update when you press the play/run button, though. If you want to check that it’s having any effect, try an extreme value such as 4.0, which should make things very blurry.

(And make sure that your textures have mipmapping enabled, and trilinear filtering enabled, otherwise you won’t get the desired results!)

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

2 Responses

  • Mike says:

    Just to let you know, I tried this in Unity and it throws errors. To get it to work correctly, I had to add “#pragma glsl” under CGPROGRAM.

    Thanks for the otherwise great instructions! Perfect for those of us who’d prefer to not get our hands dirty with shaders. Everyone needs sharp text!

  • laurent says:

    It’s nice and simple, I was going to use it for outlines that grab the material color.
    Is there a similar function without using #pragma glsl?



Leave a Reply

Your email address will not be published. Required fields are marked *