Jump to content

Text as polygon mesh

The Leftover

Recommended Posts

Well, you know... Jerome and I being the type we are... we're always thinking about ransom note text:D

Words are next.  :)

Ya know what would be cool?  When the word "dog" comes scrolling-past, its 3 characters contain a picture of a dog... one image... spread across the entire word.

Like this... cmoo8.gif

Natually, blocky-fonts with large facial surface-area and very small holes and slots... works best for this effect.  I don't know what it's called... but kids LOVE having a different picture of "Spot"... painted across the word "Spot"... every time they read... "See Spot run.  Run Spot run."  :)

Link to comment
Share on other sites

1 hour ago, jerome said:

the pivot of each particle (so each letter) can be set with particle.pivot

*nod*  That's what I used.  But... I was looking for values to use in .pivot...  something easy.  Like maybe particle.setPivotToLocalCenter().  (oh, that's not a value, eh?)  :)

Better yet... sps.allParticlesUseCenterPivot = true;   Yeah.  :) (Wingnut dreaming big, again).

There is an effect that uses the specular lighting shine.  By slightly tipping (pitching) all the chars in a word... in sequence... in a wave-like fashion, the specular shine will travel across the word.  "Waving" is more of a "sentence" thing, but it will work on words, too. Rotation waves, position waves, scaling waves, color waves.  Nice.

Rotation waves can create a nice specular light reflection effect.  But it starts with all characters in the word... having their pivots centered-up (or somehow standardized).

Jerome, that last demo... gettin' a little "expressive", eh?  So cool!  Is it time to map a renderTargetTexture from a far-away second camera... targeting a morphing spherical harmonics mesh... onto the font textures?  OMG!  Then we'll godray the fonts... using that texture.  Wow!


Using null in line 81, but would love to use first.

Link to comment
Share on other sites

Actually the "local center" isn't really a notion from the particle point of view.

To understand better, the pivot is a Vector3 that will be used to translate the particle in its local space before rotating it (whereas the standard transformation workflow is : scale first, then rotate and finally translate).

If a character isn't initially centered in its local space, what seems to be the case here, we could compute its barycenter from all his vertex positions and then set the pivot with this barycenter value to the character particle.

I guess that each character is built yet translated in the sps local space. Another approach (maybe more usefull imho) would be that each character of a given string would be created at the sps origin and then each particle (so character) would be positioned to its right location in the string with particle.position. This would allow the final user to handle each character position, rotation and scaling the expected way.

Not sure I'm really clear.

Link to comment
Share on other sites

Need.  More.  Coffee.

Jerome, I get the bit about using particle position to position each letter - in broad terms.  I am supportive of the notion that polygon strings are constructed so that programmers can use SPS features easily.  (The details of the previous sentence probably need more definition, yeah?)

But not yet .  FIrst I should finish 1.0.

But not yet.  I need coffee.

Link to comment
Share on other sites

hehe.  TL, you funny!  Yeah, when Jerome uses that "barycenter" term... my dog starts whining.  :)  JohnK uses it sometimes, too... scares all the squirrels away.

Basically, I think he said that... 'pivot' is mostly used to translate the particle.  Because of the "scale first, then rotate and finally translate" -order... there is not a "natural" way of finding the true center (barycenter) of the character... without doing vert position minimum/maximum calculations... on each character shape.

Thinking about this... reminds me of a concern I had earlier... when I said...

20 hours ago, Wingnut said:

having their pivots centered-up (or somehow standardized)

I think... letter shapes could have varying heights/widths, depending upon which letters.  Soooo... on-the-fly barycenter calculations... might be the ONLY way to get usable centers... due to varying character sizes.  The "standardized" I mention... simply "pretends" that each character is in a fixed boundingBox size.  Letters with descenders (such as low-case g and p - portions below baseline) could be a problem.

But yeah... create all particles at SPS origin... that would be fine.  Build an easy initTransforms(particles) func... allows positioning and orientation.  In a way, it is a custom SPS.startPosition().

But but but... kerning.  How to programmatically determine correct space between varying-width letters... of a word?  We're STILL needing to measure the min/max extends of the shape... just to learn how wide it is.  Then the autoKern() knows what to do. 

We gotta think about the ransom note text.  Each character could be a different font family and different size.  IF autoKern() ... the letter spacing robot... can measure each character of a word... on the fly, then it can do smart kerning, no matter WHAT the next/previous character's width... was.  :)   Smart-kerning.  Smart vertical positioning, too (descenders).  hmm.

Wow, is that difficult to say!  I spit quite a bit.  :)

Measuring all the shapes used in a word... that would be a one-time measurement... not something that would bogishly persist, I think.

Still, spawn at sps origin might be a good start... even if we want to do further size calcs in autoKern()/autoPosition(). 

But but but but... will autoKern()/autoPosition() need to be able to detect descenders... so it can auto-position the characters vertically, too?  I wonder if there is an .isDescender bool flag nearby?  ;)  What the heck is inside that imported JS file?  Probably json... I should look... but I'm scared.  Maybe there is .isDescender flags in there.  If we don't know which chars descend below baseline, autoKern()/autoPosition() will mis-position the p q y g j, etc... they'll be positioned too high within the word (lower case issue only, of course). 

Link to comment
Share on other sites

Hey, I just sent the hirukopro js file... thru an online beautifier (a maximizer)... and guess what?

All lower case chars with descenders... have a yMin = -205... MUCH more negative than any other yMin values.

So, yeah... we can use .yMin from the file... as our descender determiner "thing".

Hey, there's xMin and xMax too.  I YEARN.... TO KERN!!!  :D

Those are usable values for determining char size... even in BJS sceneLand!  YAY!

We're fartin' thru silk, now, boys!  (ick)  letter.showBoundingBox = true... and letter.getBoundingInfo()... is within reach!  (likely overkill)

Link to comment
Share on other sites

Can I ask... How many hours of manual tweaking were needed... on these two font families?

And, maybe, if ya want to say, what part of the planet is under you?  (You can do it in PM if ya like, too).

I was rambling-on earlier... about different font families on each char... but... I'm a little pre-mature on that advanced feature.

I get overly-excited sometimes.  :)

Link to comment
Share on other sites

Servants.  I need servants for font files.

I would say the font files were 90% of the work to-date.  It probably takes 10 minutes for an easy symbol (one shape, no holes, like 'F').  The percent symbol was pretty challenging - 30 minutes.  (Three shapes and two holes)

One can extract the paths from https://opentype.js.org/glyph-inspector.html  Take it straight from the .ttf file.  Which means we can support any font.  There is one path per hole and one path per shape but they might be in any order -- and paths/holes are undifferentiated.  It is one long string of shape-paths/hole-paths.  And, for Babylon, I need to have the holes lines up with the shape they subtract from.  So some organization is needed on many symbols.   (I had to rewrite stuff when I hit the 'B', two holes from the same shape.)
       ==> I have not tried to automate this

The good news is that this takes less time than the original creator did.     ?

I reside in beautiful Palo Alto where - apparently - we won't have summer this year.

Link to comment
Share on other sites


Come to southern Canada (almost)... where it's ALWAYS warm.  (sorry, ahem)  :)

I went touring P.A. temps in the last month.  Did you guys get above 70 once?  At all?  VERY unusual!  Almost scary-level unusual.

Also, thx for the insider info about the fonts.  I've been looking-over https://github.com/briantbutton/BabylonType/blob/master/index.js ...you're a good coder.  Geez... I hope I can be like you when I grow up.

Link to comment
Share on other sites

TL (Brian)...  I can't seem to fig where/how you do kerning.  Your code is too tech-heavy for me... it's giving me a brain tumor.

Would you know an easy way.... for me to calc the center of each letter, so I can set each letter's spsParticle.pivot... to that location?

Anyone?  Any help would be appreciated... if it doesn't interrupt anyone's other projects.

I might be able to grind-out my own center-determiner function, but... TL... if you could point me to the place where you calc default kerning, that might help me along.  thx.

xOffset+xTra ?  hmm.

Link to comment
Share on other sites

I figured I would put in something to that effect eventually after I did V1.0 and figured out what Jerome was saying.

Writing a function to return a center in two dimensions (relative to the anchor point) is probably easier than describing it right now.  There are multiple levels of scales and offsets.  I can take a look at that some time today.

BTW, I don't really do kerning.  The font itself gives me width of each letter and I add this (with appropriate scaling) every time I finish one.  Look at 'xTra' in index.js.  (Small possibility a better variable name is called for.)

Link to comment
Share on other sites

So I did a quick mod.  New method:  getLetterCenter() is called with a number, the index of the letter you want.  It will return a Babylon.Vector2 with the center of that letter, compared to the 'x' and 'y' position of the instance.  If you haven't rotated the mesh, it should be a useful value.


Link to comment
Share on other sites

uhn!  Cool!  No, I haven't tried it... been screwin' with a lawn mower carb for most of the day.  I'll check it out soon... and THANK YOU!!!

Ok, vector 2.  So to convert to vector 3, just append a z value that is 1/2 letterThickness?  Yeah.... that should work.

Then we can dangle a word... down a string...  pretend string going down thru the center of each vertical-stacked letter of the word.

Then rock the rotations in the breeze... and every time a letter crosses 0 y-rot... the light specular color flashes us...  COOOOOOL.

Word-on-a-rope.  :) errr... word on a cord.  hrm, no rhyme, no reason ;)

Link to comment
Share on other sites


So far, lookin' good, TL.

ALL occurrences of 'first' now changed to BB... which is... the letter B of course.

Line 61 - tipped the entire sps.mesh up... to face horizontal z-looking cam.  Stand-up, boys!

Lines 76-80 - Build the V3 from the getLetterCenter() V2.  Axes mistakes surely possible/likely  :)

Lines 83/84 - shove my new V3 into BB.pivot.

Testing lines... 93 & 94. 

Line 94 is actually rocking BB on its x-axis.  Hey, ONE axis correct.

Line 93 (when activated) is doing word-on-a-rope Y-rocking, even though we're adjusting Z.  Oh well, its the rocking I want... it just got its axis a-skewed somehow.  :)

See line 77?  Gruesome.  I had to compensate for sps.mesh.position.x, which was throwing an unwanted -10.465 world-units into the pie.  :)

All in all, and half'n'half... not bad, not bad at all.  Some stuff could be done.  Demented experiments and benchtop explosions!  YEAH! 

Thanks again, TL, nice work!

update:   I lost my thickness somewhere.  (that's what SHE said about ME)   :)  hmm.  Height and thickness are now sent as args... to Writer(args).  I guess they call them params 'round these parts.   Press RUN again, thickness returns.  Interesting.

Link to comment
Share on other sites

I like it!

What I wish is that the vertical axis would rotate when the camera does so it always looks like it is pendulous.  (ar)

Remember, getLetterCenter is relative to the anchor of the string.  So if your playground sets anchor/center (as it does) the x value of 'B' will be close to zero.  If you leave default (left), it will be a positive number; if you use anchor/right it will be negative.
1) was the clear before now?
2) is that the correct behavior?

I went with two dimensions because this is kindof a hack and that was the only thing I could deliver fast.  I figure a more proper solution will leverage SPS particle positioning somehow.  I presume this could conceivably be done with letter symbols:  https://www.babylonjs-playground.com/#WCDZS#2

Link to comment
Share on other sites

Yeah, I like it, too.  Pendulous?  hehe.  We'll talk.

Yeah, I forgot about anchor... works good.  Plus Type has a working position (lines 44-45):


And line 64 works.  Lots of positioning fun.

But... you know... you have heard me talk about word-on-a-rope (vertical layout).


A separate Type object for each letter... would work for verti-words.  But but but... if you're bored someday... TYPE.direction: vertical  ?

I can eventually code it, too.  But, you're all familiar with the code and all... ahem.  Got a beer fund or something... I can make a donation?  Some nice sausages for your icicle-adorned grill, perhaps?  ;)

If a guy REALLY had powerful coding muscles... a guy might want to make TYPE.direction be a BJS vector3.  The letters would still be "upright"... no rotation.  But... default type.direction would be v3(1,0,0)  +x... left to right.  It could be ANY vector3 direction. 

And if ya think about it... 3 different kerns.  vertical-spacing, horizontal-spacing, and thickness-spacing, all used at the same time (for a diagonal letter-flow/direction).  WOW!

Do you hate me yet?  I know, I know, we're asking TYPE class to "reach across into SPS land", right?  But it uses SPS as a helper ONLY, and it never claims to be a word/sentence layout manager, right?

And so, yeah... perhaps another object/class should get involved... a middleware thing that can nicely interact with TYPE, and nicely manipulate the SPS system, as well.

It should be really user friendly... an object made JUST FOR people wanting to do fun text layouts... AND special effects... like positional and rotational animated waves (ok, scaling waves, too)... and fancy color phasing and easy texture fun.  Maybe some Path3D following.  All 3 kerns are included, full powered vec3 .direction, just a fun shop.  Users piling-on new text effects every 3 days.  err...  yeah.  Plugins. TextEffects 1.0 API.  :)

For a little while in my life... I worked with video editing and live-show production... shoestring budgets.  Everyone... wanted to have a "DVE"... digital video effects (page turns, fancy wipes and dissolves, fly-ins, fly-outs, things that were seen on "big dog" TV stations and videos - Dubner, Grass Valley, Abekas, $$$$)  Eventually, came the NewTek Video Toaster... a device based on the Amiga (2000?).... and we all went crazy.  The other fun device we all wanted... was a Chyron character generator.  If your edit bay had a Chyron and a Video Toaster... you were set to take over the world.  Even JUST a Toaster... it had plenty of character gen powers all by itself.

So, yeah, Wingy sees things in his head... that... might be a little unrealistic here in webGL land.  Wingy is a bit "over-presentation" retarded.  :)

Worse than this... I really dislike advertising.  Yet big, flashy, flying, in-your-face fonts... is one of the most-used advertising methods ever.  So, let's pretend we DO build an "EZ Text Efx" object/userface, and allow users to build add-on effect-modules that easily plug-into it... and it grows and grows.  By promoting this idea, am I contributing to the delinquency of a... umm... advertisement-free scene?  :)  Should I gun myself down in the street... to prevent conduct unbecoming of an ads-hater?  heh.  I'm thinkin' yeah.

Link to comment
Share on other sites

More fun happenin'...


In MY browser, I have to press RUN after loading... or else the letters don't have letter-thickness.

Working ok, though, eh?  Dancing words.  :)

What a messy playground.  It looks like someone has been playing in there.  ;)

Seems like the "N" position is a tiny bit too far right-ward... but it could be an optical confusion protrusion conclusion infusion illusion on my part.  The looping positioner is at line 126.  The -6.7 and -8 were found by trial/error, of course.  Change the letter sizes... and all the positioning will go to hell, of course. 

I hope to improve the positioner for this word-on-a-rope... soon.  Party on!

Link to comment
Share on other sites

Wow, those really . . . . dangle.  I am not even sure how you did that.  I will check it out.

So I put an adjustment in your code so it loads thickness first time.  https://www.babylonjs-playground.com/#XWVXN9#42  Please note changes at lines 17 to 22.  That's it.

(I also encourage you to review the playground I sent to you on PM a couple days ago.  I wrote commentary in that just 4U.  There are several ways to do this - although they are effectively the same thing.  Writing code that makes functions on the fly can actually speed some kinds of processing a lot.  Better yet, it drives server guys, especially Java server guys, nuts.)


Link to comment
Share on other sites

Not really dangling, yet, but, vertical, for sure.  :)

I knew you were going to say that... about calling functions with functions for params.

That just scares the hell out of me, and makes the code even scarier for newbies to read.

When you tour the BJS docs... do you see any commands that use functions as the parameters for calling other functions?

I know your intentions were/are good, and I appreciate the consids/effort.

Perhaps... the wise move... is the user-interface API with easy textEffects plugin efx.  I'd prefer to put a cowling over the ugly, so this machine looks smooth and drives easy... and nobody gets greasy.  heh

Lines 22-25 in the PM-reffed playground... is not newbie-readable, I would say.

I dunno.  I'm torn.  Maybe I'm just resisting change.  :) Can I just paste that new stuff into my PG, and then continue moving fonts around and animating words?  That's the fun part, for me, but, I bet I'm being shallow and pedantic.  :D

Link to comment
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.

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.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...