What I’d like to do this week is explore how the individual characters are arranged.
[X]
sink into ground (cut off the bottom as the top sinks down)[X]
rise out of ground[X]
bold[X]
slant[X]
rotate[X]
wavy (left/right) character (slant is a special case of this)[ ]
shadow with variable distance (maybe a second pass)[X]
fall from above, maybe with a bounce when it hits the ground[X]
apply any of the above effects with a ramp or sine wave pattern to some characters[X]
curved path[ ]
break into smaller squares / dissolve[X]
horizontal spin[ ]
flip up/down like a train station sign[ ]
rotate left/right on a cube[ ]
text rotates on a giant wheel like price of right[X]
fly out of a gun
1 Initial setup#
I’m starting with the code from last week’s projects, but last week it was all about changing the uniforms to the shader (interactively in the browser) and trying different parameters for msdf generation (command line, a bit more manual to experiment with). This week the experiments are going to involve changing the sprite positions and changing the per-sprite rendering, so the uniforms will need to be attributes instead. It’s probably a good chance to try instanced rendering again. I have tried it a few times but not enough for the concepts to “stick”.
I often start from previously working code. Sometimes it’s easier to start with working code and remove stuff, than to start with an empty file and add stuff until it works.
[X]
get a basic demo working[X]
remove parts I don’t need anymore[ ]
changeuniform
toattribute
so I can set it per letter[ ]
use instanced drawing to reduce the number of attributes I’m sending[ ]
change atlas.js to support multiple fonts
I had started out thinking I will need to update the buffers every frame, and that I need to change the uniform
parameters to attribute
so that they can vary per letter. And then maybe I should use GL instancing to reduce the number of attributes being sent. And do I need to use gl static draw or gl dynamic draw?
And then I remembered the purpose of this is to quickly experiment. I am prematurely optimizing. Argh.
I should just draw one letter per draw call! I can optimize later.
[X]
create an object to store the data per letter[X]
draw one letter per draw call[X]
separate the x,y out so that I can change positions for each letter individually
It’s quite a bit slower to load than the previous project with only one draw call, so maybe I will optimize it sooner rather than later.
2 Experiments#
Although I checked in a lot of the code, I didn’t write most of it up. Sorry. I got some screenshots and movies.
Letter thickness:
Letter widths:
Vertical movement:
War And Peace Gun:
- lots of sprites
- ended up optimizing by putting everything into one draw call
- when I add a sprite, I should use subdata to set just that one sprite’s data (but I didn’t implement this optimization yet)
- put all the animation onto the gpu, so that I don’t have to update the sprite’s data every frame
- read in war and peace chapter 1 as a text file, swapped some unicode to ascii, then erased the rest of the unicode chars
Dancing Characters:
- three phases
- slant left and right a few times
- rotate left and right a few times, may have to move up to keep baseline same
- spin around a few times
- not many sprites, will move animation control back to cpu
3 Accidental find#
This is how I normally render the font:
but by tweaking the corners I can get these:
I don’t quite understand why this happens! Look closely and there are corners in what used to be straight lines. It’s a mystery I can investigate later. But it’s also a cool effect — I can get these fonts with more personality out of a base font! (I did investigate a few weeks later)
4 More#
MacOS has a way to capture a movie in mov/h265 format, but for wider compatibility (see caniuse[1] and mdn[2]) I converted to mp4/h264 and webm with:
for f in *.mov do ffmpeg -i $f ${f%%.mov}.mp4 ffmpeg -i $f ${f%%.mov}.webm done
With these settings, mp4 was smaller than webm or mov. I didn’t try other settings.
This week was the end of my font experiments for now.
Source: text-effects.js (for the dancing animation only)