Label is blurry

Hello!

I am struggling with a really strange problem: I have 2 sprites where each sprite has a TTF label als child. I create both labels in the exact same way:

Label* lblMainMenu = Label::createWithTTF(ttfConfig, "Main menu");
lblMainMenu->setColor( g_menuLabelColor );
lblMainMenu->setPosition( Vec2(buttonSize.width / 2 + 0.5f, buttonSize.height / 2 + 0.5f) );
btnMainMenu->addChild(lblMainMenu);

// Second label
Label* lblSelectLevel = Label::createWithTTF(ttfConfig, "Main level");
lblSelectLevel->setColor( g_menuLabelColor );
lblSelectLevel->setPosition( Vec2(buttonSize.width / 2 + 0.5f, buttonSize.height / 2 + 0.5f) );
btnSelectLevel->addChild(lblSelectLevel);

The problem is: The first label “Main menu” is rendered with sharp edges, but the second label “Main level” is much more blurry! I made a screenshot (zoomed in) to show the effect:

Just look at the word “Main”. The top one is much more blurry. It is especially noticable at vertical lines. The vertical lines of the “M” at the bottom are straight lines, while the verticles lines of the top “M” are blurred.

As you can see in my code I tried to play around with 0.5f offsets onto the position, because (strangely enough) this 0.5f offset makes the bottom label sharp. Even though the top label ALSO gets a 0.5f offset (the world space coordiantes of both labels has a .5 fraction; it is not a clamped integer) it is blurry!

Anyone knows this effect and has an idea how I can make my labels sharp?

what is in your ttfConfig?

Try to disable AntiAlias label

lblSelectLevel->getFontAtlas()->setAliasTexParameters();

it looks like he is using the same ttfConfig for both labels, however…

Thanks for your replies!

My TTFConfig looks like this:

TTFConfig ttfConfig( "LiberationSans-Bold.ttf", 55 * mGame->getLabelScaleFactor() );

getLabelScaleFactor() returns 1. My game uses screen resolution of 1334x750 and all my images are designed for this resolution. Like you said slackmoehrle, it should either be blurry for both labels or sharp for both. But it is only blurry for one label. Strange…

I also tried calling setAlisTexParameters() and indeed the label became sharp! But the problem is: It is only sharp if the device runs in exactly (!) 1334x750. If for example the device resolution is 1200x800, I have to scale the label slightly down and then the label looks terrible (cause of the disabled anti aliasing). So I guess I can’t disable AA since I want my game to run for all resolutions.

Looks like there was a issue tracked for this for this, but it has been marked as closed.

It’s a subpixel rendering issue, exasperated by centre text alignment. I’m guessing the correct fix would be to floor each letter quad’s position.

@zhangxm Was this issue actually solved? Why was it closed?

@almax27 i close the issue because the issue is moved from other place which is one year old and no one add comments there. I think it is better to open a new one if it has problem.

@compyler about this issue i think it something like subpixeling issue. Could you disable CC_SPRITEBATCHNODE_RENDER_SUBPIXEL in ccConfig.h to have a try?

@zhangxm: Thanks for your reply!

I set CC_SPRITEBATCHNODE_RENDER_SUBPIXEL to 0 and unfortunately the fonts are still blurry. I also tried to set CC_NODE_RENDER_SUBPIXEL to 0 but this also didn’t change anything.

I played around with some parameters and calling setAliasTexParameters() on the Label’s FontAtlas definitely makes the font sharper. I made a screenshot:


On the left side is the result when I do NOT call setAliasTexParameters(), on the right side is the result if I call the method. The blurriness is especially visible if you compare the word “Main”.

I am not doing anything special in my code. I just create a ui::Button and add a ttf font as child to the button:

TTFConfig ttfConfig( "LiberationSans-Bold.ttf", 55 );

ui::Button* btnSkipLevel = ui::Button::create("Ingame_Menu_Button.png");
btnSkipLevel->setName("Skip level");
btnSkipLevel->addTouchEventListener(CC_CALLBACK_2(Level::hudButtonPressed, this));
btnSkipLevel->setAnchorPoint( Vec2(0.5f, 0.5f) ); 
btnSkipLevel->setPosition( Vec2(ingameMenuSize.width / 2, bottomMargin + 2 * buttonDistance) );

mIngameMenuSprite->addChild(btnSkipLevel);

Label* lblSkipLevel = Label::createWithTTF(ttfConfig, "Skip level");
lblSkipLevel->setColor( g_menuLabelColor );
lblSkipLevel->setPosition( Vec2(buttonSize.width / 2, buttonSize.height / 2) );
btnSkipLevel->addChild(lblSkipLevel);

lblSkipLevel->getFontAtlas()->setAliasTexParameters();

Like I said setAliasTexParameters is not a feasible solution for me because it only works if the device resolution is exactly the same like my resource resolution. I.e. if I pick image resource made for 1337x750 and the device resolution is slightly smaller (lets say 1200x750) of course I have to scale down all images a little bit and then the label looks terrible because of the missing anti-aliasing.

Is this a bug in cocos or do I overlook something? Any other ideas how to make the font sharp?

1 Like

@compyler sorry, i have no idea currently. Would you please create an issue in cocos2d-x github issue system, and paste needed resources? And i will ask more developers to take a look.

I got the same result. Does this issue fixed?

This issue seems like it’s still persisting.

I’m able to have a blurry TTF label with an outline on Windows 10, by setting the framesize to 1920x1080, and setting design resolution to 940x640 with EXACT_FIT.

It’s as if it’s rendering the fonts for 640p and scaling it up to the framesize. I figure that’s why setting the fonts twice as big and scaling it down to half as big works. The problem with that is that when you start using ScaleBy and other size actions, you need to consider that original scale, it’s kind of a pain.

I’m not sure there is a good fix without a special case in the Label’s rendering to account for the different here.