-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kerning implementation open for discussions #106
Conversation
examples/font_kerning.js
Outdated
|
||
|
||
|
||
let _overlap = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Poor's man gui
Hi ! First of all let me say that it looks really better with kerning, thanks a lot for digging into this. So to answer your points : Attribute nameAs for the attribute name I vote for Default value / Optional / Overlapping glitchesThe overlapping glitch is a big issue in my opinion... and setting Also if not wanted the user could trim out the As for Friendly font kerning values lookupThe lookup object is a wonderful idea IMO ! In cases like text editors or timers, updates to the Text might come very often, so optimizing this is a good idea indeed. As for removing the original Font classI can understand why you where confused about where to put your code in FontLibrary... I also think that a SuggestionsThe workaround in |
But this still have side effects. Such library as https://github.com/vanruesc/postprocessing or threejs postprocessing effects requires depth informations to compute the effect (GodRays, Bloom, etc... ) At first I workaround the overlap using Maybe something like discarding rendering of transparent pixels in the shader will have the best flexibility. But thats a guess, Im not sure it will. |
From my testing
Not sure we want that anyway, the characters quads are merged into a single mesh (single draw call, better perf).
Maybe yes, it's worth a try. |
It seems that |
The suggestions discussed here have been implemented.
|
Hi @swingingtom, it seems all good to me, but I just noticed a small issue I don't understand. In the InlineBlock example, there is one bit of text that should be kerned: If I look for the word "emojis" with the Roboto font on Google Fonts, the "o" and "j" are a kerned pair: I don't know if it's just an oversight in a previous version of the font, the evidence of a problem on our side, or maybe an issue with the generator. I checked and it looks like there is no "oj" pair in the font object after parsing by your |
Same issue with another font (Lato) : |
Im not sure this related to current kerning implementation, we can already notice this disgraceful space from current release https://felixmariotto.github.io/three-mesh-ui/#inline_block For further implementations, It would be great to have an html text reference overlay that display the same texts. We would then try to fit it as much as possible. Im currently struggling to have some documentation on the msdf format itself. Wouldn't be possible that this disgraceful space is caude by the fact that ThreeMeshUi use char.width instead of char.xadvance in order to compute nextChar.x ? Also, do you know if common.base represent the em reference value? Those values match, but I don't want to assume it. If you have some msdf format guide explained, or something detailing the format, it will still be christmas... |
Yes it's certainly the issue. This is indeed unrelated to the present PR so let's not worry about this now, I opened a new issue: #108 As for what msdf-bmfont-xml outputs, I must admit I'm not sure what standard it follows... I found this doc which was helpful but doesn't seem to be a very reliable source. |
Thanks ! |
Hey ! First and to be honest, Im not sure where this PR is going to. It may be better, to abort it. Then redo-ing one issue at the time. I succeed to have some good results, but it leads slightly out of the scope. What I really needed was to have an html overlay showing the same text with same properties as ThreeMeshUI but in html. Bref, current setup ( font_kerning example file ) :
current results :
ChangesScale FactorRely on
xadvance and xoffsetChars position x relies on xadvance and xoffset ( + kerning & + letterspacing ).
What could be an issue (performance and maintenance), is that inlineManager do computation for other kind of component than Text. I understand it now. Other examples filesGlobally, it impacts every file. Even with kerning set to "normal", texts are more spaced than it was before. Leading to example having more lines than before. Which goes fine again with the fresh export of Robot Medium font with space char included. Even with font being boldier Also note that xadvance and xoffset solved the "emoji" disgrace. LineheightI didn't change anything (at least I don't think so), but it currently doesnt match html. It's especially strange that lineheight can currently differs depending on which chars are on that line. Lines full of uppercase or lowercase, and also the previous screenshot also display it : IssueOn the nested block example, we can notice the behaviour commented here. But this time with a space char. ApproximationAs said before, there is still rendering differences between current implementation and html. Especially after many characters, we see it growing. Just a random guess, but as msdf converter tends to works in integers ( width ok, but xadvance, xoffset, kerning amount) we could try to set the initial size. Currently its automatically set to 42. Which may be not the perfect number. I think about 48 which is a lot more divisible than 42. That's it. |
OK, I just merged after fixing the examples where the new spacing introduced issues, because you're right it was becoming out of hand ! I changed the kerning example to make it only show the feature, but your example with an HTML overlay over three-mesh-ui is very interesting to test the difference between the 2. If you want to make a new PR to add a new "html comparison sandbox" example, maybe with an HTML input field so users can test any text, that would be very useful IMO. Thanks a lot for all this work, the readability of the text has improved a lot ! |
Hey, as the PR titled it, the current implementation of kerning raised some questions from my side, and therefore require others opinions and decisions.
The current implementation is functional, all examples are still up ( this time... ). Some parts are not production ready (ie: overlap toggler).
Questions
Attribute name
Lets start by an easy one:
kerning
,fontKerning
,somethingElse
?As inline elements doesn't always means a
Text
I slightly preferfontKerning
Default value / Optional
What should the default value ON or OFF ?
Kerning are made to offer better visual looking for particular character combinaisons. So I would think it would be better to set the kerning ON by default. But in the other hand this might slighty affect users who update the library on a existing project.
And if ON by default, should we still be able to optionally disable kerning ? Its always great to have options, but assuming it always on, it could ease the codebase. How many users will disable kerning (which improves visual looking)? In what purpose?
Friendly font kerning values lookup ( ok? going further? )
MSDF json stores kernings values in array

In order to ease selecting kerning values, the current implementation adds an internal object

Any kerning value of zero, is ignored. The number of kerning items drops from 3674 to 1856 (on the roboto font included, which contains a huge charset)
And the lookup object is eased IMO
So, what do you think about that ?
Would it go further ? Removing the original msdf kerning array from memory to store altered kerning object instead ? Having an internal Font class ?
Kerning location
Retrieving kerning has been implemented outside of
const glyphInfos = chars.map( (glyph)=> {...})
.Is font kerning option on is only checked once, and no checks to avoid kerning the first character.
While retrieving kerning inside would have required :
It annoyed me a bit that any glyph in a paragraph would have to check
index>0
when even a huge text, will only need to do the exception only for the first character. (lefthanded peer doesn't exists). Same apply for checking if kerning attribute is ON.Overlapping glitches
As the kerning is often negative values, some characters 'quad?' might overlap its previous character 'quad?'.
I currently fixed it by setting the
fontMaterial.depthWrite = false
which may have side effects for several users.I dont remember exactly what you said, but I remember to read something about dat.gui/lil.gui in an issue, so instead of adding a gui, I added a command on the window element. In the example 'font_kerning' we can type
overlap
in the console, and it will toggle on/offfontMaterial.depthWrite
property on Text Components. Be sure the be on the font_kerning frame in the console.Notes
FontLibrary
For friendly kerning lookup, I implemented it on FontLibrary. It confuse me a bit at first, because even if FontLibrary is a mandatory gateway, it has multiple available gates (
addFont()
,loadFontJson()
,setFamilyFont()
) without a centralized point of registering a fontJson.Having an abstract FontClass could be the centralized point. Then instead of asking
TextManager.getGlyphDimension()
which checktextType
to go onMSDFText.getGlyphDimension()
it could rely on abstract method ofFontClass.getGlyphDimension()
andMSDFFont extends FontClass
. Let's be clear: It's core changes, and clearly not the point in this PR. Just the feeling it miss something to ease future implementations.Linebreak can be the first character of a line
Not totally related to kerning, but sometimes I have the first character of a line that is a '\n'. LetterSpacing was introducing a bug when this case appears. A fix is made in this PR,
as kerning also have to be taken into account.The check
if( inline.width > 0 )
is only run when once per line, so it's not a performance issue, but the current resolution is not intuitive. Even being commented.Indentation
Some files are indented with tabs, while other with spaces. Honestly I don't care, just noticing.
TLDR; kerning was indeed an easy task, but I won't decide the path it should follow by my own.