shlajin

Text smooth scaling / text mipmaps

Recommended Posts

Hey there!

I'm trying to scale text during animation (namely – during camera zooming) while keeping it smooth & sharp.

Scaling with `.scale` doesn't work well for this case – text gets pixelated, so I went with redrawing the text by changing the text style `fontSize` property. This is slow, but this isn't shown to the user in real-time, so I don't care about FPS during that.

The problem with this approach is that text shakes/shivers during the animation. This doesn't happen when I animate `.scale` property and I want to avoid that.

So I tried different approach: I created text at maximum fontSize and then shrank it down via scale and animated scale. Shivering almost gone, but some nasty artifacts such as over-sharpness appear when scale is low... so I thought – maybe mipmaps can help me there? I hacked pixi and tried to do this inside Text#updateText:

 

const width1 = Math.ceil((Math.max(1, width) + style.padding * 2) * this.resolution)
this.canvas.width = Math.pow(2, Math.round(Math.log(aSize) / Math.log(2))) width1;
const height1 = Math.ceil((Math.max(1, height) + style.padding * 2) * this.resolution)
this.canvas.height = height1;

this impacted text metrics a lot, mangling text positions but I didn't notice any positive change on the text quality. So, maybe I'm doing something completely wrong.

What's the correct way of doing this?

Thank you in advance!

Share this post


Link to post
Share on other sites

You could get really good looking fonts by using sdf-fonts (signed distance field). Though implementing one requires lot of knowledge on shaders. Luckily there's a plugin https://github.com/PixelsCommander/pixi-sdf-text

What I usually do though is to have basic textfield with double the fontsize and then use it at 50% scale and try to avoid going over 125% scaling as then it starts to look pretty bad.

With the method of forcing to pot I think you need to say in addition that the texture should use mipmapping.

Share this post


Link to post
Share on other sites

Thank you for your response.

SDF Text doesn't seem to fit my goals, unfortunately. I made a quick video where I animate the text using this package and, as you see, on smaller font sizes it has some extra-sharpness artifacts. Same as if I go with big fontSize and just scale it down via `scale.x / scale.y`. Tried with antialias on and off, no real difference :(

Quote

What I usually do though is to have basic textfield with double the fontsize and then use it at 50% scale and try to avoid going over 125% scaling as then it starts to look pretty bad.

That's what I did for now – I took the middle between the largest and the smallest sizes, so if text animates from 80 to 160, I use fontSize of 120. This ensures that the text doesn't look too bad when it's big and when it's small... However, I really want to try to make it look better than that.

 

Quote

With the method of forcing to pot I think you need to say in addition that the texture should use mipmapping.

I tried with no effect – AFAIK Pixi always forces mipmaps whenever possible. I'm starting to think of reinventing the wheel and switch textFont size only on certain values and use scale.x/scale.y in between...

Share this post


Link to post
Share on other sites

That's one of big problems with text. WebGL and animated vector text aren't made for each other.

Text texture never mipmapped because we cant be certain if texture are pow2, and pixi-v4 cant just change the filtering on fly. Did you read "Text" code? you can actually hack it that way the canvas size is pow2, and PIXI.Texture takes only part of its area.

If you go further in Text code you'll see how it works - it actually renders canvas2d css text and uploads stuff to videomemory only if it was changed (changes texture updateID). If you store some FIXED pow2 size, and set the mipmap, pixi-v5 can also generate new mipmaps every time this things is updated, but I'm not sure about v4. That way there'll be no allocations.

There are many ways to solve those issues, like sdf, msdf, I have experimented with them a lot, but I cant teach you all that in 5 minutes. You have to spend time to get good result for your case, because its not the easy task.

Share this post


Link to post
Share on other sites

I'm glad you that my old plugin can offer some help :) It is still at an early stage and only tested in pixi.js v4.7. Don't even have a README yet. Since pixiv5 have breaking changes in mesh & bitmap font classes, I still need time to learn and adapt. PR is welcomed!

Take this snippet as a quick-start if you don't want to clone my repo and build it yourself:  https://jsfiddle.net/g04xLqdh/

BTW: Here is a command line tool to help you generate MSDF bitmap font assets: https://github.com/soimy/msdf-bmfont-xml

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.