Skip to content

Commit

Permalink
Updates documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
JujuAdams committed Nov 7, 2020
1 parent 29b3c27 commit df71c20
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 7 deletions.
1 change: 1 addition & 0 deletions MSDF charset example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!,'.<>?@^)(*%±$#£ "
3 changes: 2 additions & 1 deletion Scribble.yyp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 157 additions & 0 deletions notes/MSDF_Documentation/MSDF_Documentation.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
**@jujuadams 2020-11-07**

Written for version 1.1 of the MSDF atlas generator, released 18th October 2020

&nbsp;

## Introduction

MSDF fonts allow for text to be rendered at any size without needing to generate a unique font
for each size. This effectively means MSDF fonts are resolution-independent, making them useful
for software UIs in general, but essential for mobile game development. MSDFs reduce the texture
memory usage of your game whilst also being easier to use and maintain. With Scribble, MSDF fonts
are rendered at the same speed as normal fonts. MSDF fonts are supported for all of Scribble's
target platforms.


MSDF stands for "Multi-channel Signed Distance Field". It is a relatively new technique invented
by Viktor Chlumsky in 2015 designed to address the limitations of the famous SDF method proposed
by Valve in their 2007 SIGGRAPH paper. MSDFs typically produce superior results to SDFs owing to
their better representation of sharp edges, and their more efficient use of RGB colourspace to
allow for greater information about the shape to be stored.


This guide won't explain how MSDFs work at the implementation level; I recommend reading Chlumsky's
own words if you'd like to understand the method in detail. This guide will explain how to generate
MSDF font atlases and will lay out best practice when using MSDF fonts with Scribble.


At this time, this guide will only explain how to generate MSDF fonts on Windows. It is entirely
possible to generate fonts on MacOS as well, but I don't have access to hardware to test the
process out myself. If you'd like to collaberate on writing a MacOS-specific guide, please get
in touch.

&nbsp;

## Generating an MSDF Atlas

Download the Windows binaries [here](https://github.com/Chlumsky/msdf-atlas-gen/releases/tag/v1.1)
(you'll probably want the 64-bit binaries) and extract the .zip file to a directory - it only
contains a single executable, `msdf-atlas-gen.exe`. This is a command line tool; we'll be
controlling it with a batch file.

In addition to `msdf-atlas-gen.exe`, we'll need two other source files in the directory:

1. TrueType Font (.ttf) file for your font

2. UTF-8 encoded text file that contains all the characters that you want to use with the font. This is similar to the "mapstring" for [`scribble_font_add_from_sprite()`](https://github.com/JujuAdams/ScribbleNewDocs/wiki/Functions-(Font-Setup)#scribble_font_add_from_spritefontname-mapstring-separation-spacewidth-proportional) or [`font_add_sprite_ext()`](https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/fonts/font_add_sprite_ext.html).

Let's assume our font file is called `font.ttf` and our character textfile is called `charset.txt`.
This means your directory should contain `msdf-atlas-gen.exe`, `font.ttf`, and `charset.txt`.

&nbsp;

Next, we need to create a batch file to get the tool to do what we want. There are a few
ways to do this, but the easiest is usually to create a text file and then change the file
extension to `.bat`.

Here's an example of a batch file command:

`msdf-atlas-gen.exe -font font.ttf -size 12 -charset charset.txt -format png -imageout font.png -json font.json -pxrange 4`

And here's what the parameters mean:

`-font font.ttf`<br>
What font we're going to target, in this case "font.ttf"

`-size 12`<br>
Size of the glyphs in the atlas in pixels per EM

`-charset charset.txt`<br>
Where the tool should look for a string of characters to render i.e. "charset.txt"

`-format png`<br>
Image format for the texture atlas (PNG)

`-imageout font.png`<br>
Name of the image file to output

`-json font.json`<br>
Name of the glyph data file to ouput, as a JSON

`-pxrange 4`<br>
Range of the SDF function. Leave this at 4 unless you need to tweak the generator's output

*Full tool documentation can be found [here](https://github.com/Chlumsky/msdf-atlas-gen/)*

&nbsp;

Once you've made your batch, run it! You should see a .png and .json file appear in the directory
indicating that the generator completed successfully. If you run into trouble, put a `pause` command
on a new line in the batch file to check what the tool is outputting.

&nbsp;

## Using an MSDF Font with Scribble

Once you've run the atlas generator using the batch file, you'll received a .png file (the atlas)
and a .json file (the glyph data). Scribble needs both to draw MSDF fonts, and Scribble also
needs a line of code to tie the two resources together.

1. Import the .png image as a standard GameMaker resource. We'll call this sprite `spr_msdf_font`

2. Add the .json file as an Included File. We'll call this file `font.json`

3. During your game's initialisation flow, call [`scribble_font_add_msdf()`](Functions-(Font-Setup)#scribble_font_add_msdffontname-sprite-jsonname).
If you're not sure where/when to call the function, then call it in the same place that you'd call [`scribble_font_add_from_sprite()`](https://github.com/JujuAdams/ScribbleNewDocs/wiki/Functions-(Font-Setup)#scribble_font_add_from_spritefontname-mapstring-separation-spacewidth-proportional) or [`font_add_sprite_ext()`](https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/fonts/font_add_sprite_ext.html)

For our example, the code to execute would be:
`scribble_font_add_msdf("MSDF font", spr_msdf_font, "font.json");`

&nbsp;

Once you've done that, now you can use the MSDF font in exactly the same way that you'd use a
standard font or a sprite font e.g.

`scribble("[MSDF font]This is [scale,1.5]an MSDF [scale,2]font!").draw(x, y);`

If everything has gone accordingly to plan, you'll see a clean and crisp line of text.

&nbsp;

## Best Practice for MSDF Fonts

MSDF fonts are more capable than standard fonts, but accordingly they are rather more complex
to set up. The above example will get you started, but you may run into some issues as you're
using MSDF fonts. Here are some things to look out for:

1. **Use the smallest `-size` value you can get away with, and only generate the glyphs that you need**

Glyphs take up space on an atlas, and having too many glyphs or glyphs that are too large
will cause the atlas size to become very large. Not only will this end up using loads of
texture memory, but it may also cause visual artefacts if GameMaker tries to scale down the
atlas texture

2. **Avoid scaling down**

MSDF, as a technique, is designed to be scaled up. Use a small `-size` parameter when generating
the atlas, then use the in-line `[scale]` tag or `.transform()` method to increase the size of
your text. You can get away with scaling down, but it can lead to issues due to the way
texture interpolation works on GPUs

3. **When things look weird, try increasing the `-pxrange` and/or `-size` parameters**

The `-pxrange` parameter represents the maximum distance that can be encoded by the MSDF
output. A small value will lead to a more locally accurate output, but for complicated shapes
(such as CJK glyphs) this might lead to glitchy output. A large `-size` parameter will allow
for more space for details to be expressed by the MSDF generator

&nbsp;

## References

[MSDF font atlas generator](https://github.com/Chlumsky/msdf-atlas-gen)

[Original MSDF thesis paper](https://github.com/Chlumsky/msdfgen/files/3050967/thesis.pdf)

[Valve's 2007 SIGGRAPH paper (SDF)](https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf)
10 changes: 10 additions & 0 deletions notes/MSDF_Documentation/MSDF_Documentation.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 25 additions & 6 deletions notes/Quick_Reference/Quick_Reference.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ Methods are broken down into several categories:
4. [**Typewriter**](scribble()-Methods#typewriter)
- [`.typewriter_off()`](scribble()-Methods#typewriter_off)
- [`.typewriter_reset()`](scribble()-Methods#typewriter_reset)
- [`.typewriter_in()`](scribble()-Methods#typewriter_inspeed-smoothness)
- [`.typewriter_out()`](scribble()-Methods#typewriter_outspeed-smoothness)
- [`.typewriter_ease()`](scribble()-Methods#typewriter_easeeasemethod-dx-dy-xscale-yscale-rotation-alphaduration)
- [`.typewriter_in(speed, smoothness)`](scribble()-Methods#typewriter_inspeed-smoothness)
- [`.typewriter_out(speed, smoothness)`](scribble()-Methods#typewriter_outspeed-smoothness)
- [`.typewriter_ease(easeMethod, dx, dy, xscale, yscale, rotation, alphaDuration)`](scribble()-Methods#typewriter_easeeasemethod-dx-dy-xscale-yscale-rotation-alphaduration)
- [`.get_typewriter_state()`](scribble()-Methods#get_typewriter_state)
- [`.typewriter_pause()`](scribble()-Methods#typewriter_pause)
- [`.typewriter_unpause()`](scribble()-Methods#typewriter_unpause)
- [`.get_typewriter_paused()`](scribble()-Methods#get_typewriter_paused)
- [`.typewriter_sound()`](scribble()-Methods#typewriter_soundsoundarray-overlap-pitchmin-pitchmax)
- [`.typewriter_sound_per_char()`](scribble()-Methods#typewriter_sound_per_charsoundarray-pitchmin-pitchmax)
- [`.typewriter_function()`](scribble()-Methods#typewriter_functionfunction)
- [`.typewriter_sound(soundArray, overlap, pitchMin, pitchMax)`](scribble()-Methods#typewriter_soundsoundarray-overlap-pitchmin-pitchmax)
- [`.typewriter_sound_per_char(soundArray, pitchMin, pitchMax)`](scribble()-Methods#typewriter_sound_per_charsoundarray-pitchmin-pitchmax)
- [`.typewriter_function(function)`](scribble()-Methods#typewriter_functionfunction)
5. [**Size Getters**](scribble()-Methods#size-getters)
- [`.get_bbox([x], [y], [leftPad], [topPad], [rightPad], [bottomPad])`](scribble()-Methods#get_bboxx-y-leftpad-toppad-rightpad-bottompad)
- [`.get_width()`](scribble()-Methods#get_width)
Expand All @@ -56,6 +56,7 @@ Methods are broken down into several categories:
- [`.animation_wheel(size, frequency, speed)`](scribble()-Methods#animation_wheelsize-frequency-speed)
- [`.animation_cycle(speed, saturation, value)`](scribble()-Methods#animation_cyclespeed-saturation-value)
- [`.animation_jitter(minScale, maxScale, speed)`](scribble()-Methods#animation_jitterminscale-maxscale-speed)
- [`.animation_blink(onDuration, offDuration, startOn)`](scribble()-Methods#animation_blinkonduration-offduration-starton)
7. [**MSDF**](scribble()-Methods#msdf)
- [`.msdf_shadow(colour, alpha, xOffset, yOffset)`](scribble()-Methods#msdf_shadowcolour-alpha-xoffset-yoffset)
- [`.msdf_border(colour, thickness)`](scribble()-Methods#msdf_bordercolour-thickness)
Expand Down Expand Up @@ -629,6 +630,20 @@ This function controls behaviour of the `[jitter]` effect across all uses in the

&nbsp;

### `.animation_blink(onDuration, offDuration, startOn)`

**Returns**: The text element

|Name |Datatype|Purpose |
|-------------|--------|---------------------------------------------------------------|
|`onDuration` |real |Number of ticks that blinking text is shown for |
|`offDuration`|real |Number of ticks that blinking text is hidden for |
|`startOn` |boolean |Whether the text starts visible (`true`) or invisible (`false`)|

This function controls behaviour of the `[blink]` effect across all uses in the text element.

&nbsp;

&nbsp;

&nbsp;
Expand Down Expand Up @@ -661,6 +676,10 @@ This function controls behaviour of the `[jitter]` effect across all uses in the

## MSDF

*MSDF fonts require special considerations. Please read [the MSDF article](MSDF-Fonts) for more information.*

&nbsp;

### `.msdf_shadow(colour, alpha, xoffset, yoffset)`

**Returns**: The text element
Expand Down

0 comments on commit df71c20

Please sign in to comment.