Skip to content

Large amounts of "whitespace" around lowercase glyphs #2

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

Open
mattparks opened this issue Feb 4, 2020 · 8 comments
Open

Large amounts of "whitespace" around lowercase glyphs #2

mattparks opened this issue Feb 4, 2020 · 8 comments

Comments

@mattparks
Copy link
Contributor

mattparks commented Feb 4, 2020

I've noticed that msdf-c generates some glyphs, mostly lower-case glyphs, with more space around the main character data than msdfgen provides.

Here are some examples. Glyphs generated from Roboto Regular at 32x32, a range of 1, and with autoframe.

Chars: a, @, h, c, -

Chlumsky/msdfgen:
image
image
image
image
image

exezin/msdf-c:
image
image
image
image
image

256x256 Example:
image
image

@solenum
Copy link
Owner

solenum commented Feb 4, 2020

Interesting, I'm currently using this in my other project (https://github.com/exezin/exengine) and the final rendering results seem correct.

It's been a while since I have touched this project but I suspect I could be pre-scaling things to be the appropriate scale for what it is, so you don't have to store meta-data and scale anything when rendering them out at the end.

I'll take a look at this 👍

Edit;

Could this also be the result of using the 'autoframe' option? Could you also confirm that this actually presents issues when attempting to use the generated MSDF to render a line of text?

Here is my implementation.

@mattparks
Copy link
Contributor Author

The rendering results are mostly correct, but with some glyphs a lot of texture space is underutilized; in comparison, msdfgen fits the glyph mutch closer to the edge of the bitmap.

Another variable that can effect quality is RANGE, your constant for range does not appear to produce the same results as pxrange in msdfgen:
msdfgen
msdf-c

msdfgen creates this glyph without autoframe (256x256):
msdfgen

@solenum
Copy link
Owner

solenum commented Feb 4, 2020

I'm actually struggling to find the right metrics for the scale (line 975 msdf.c) using stb_truetype.h, as far as I can tell stb_truetype only supplies two functions to get this metric and the current one used produces the a larger glyph than the other function.

As for the px_range value, does changing the iteration count here produce results that look closer to that of msdfgen?

~ main.c:121 ~
  for(int i=0; i<4; ++i)
    p += ((PX_RANGE*otf)/size)*size;

@mattparks
Copy link
Contributor Author

The output only looks right when both RANGE from msdf.c and PX_RANGE in main.cpp match, otherwise the shape has little antialiasing.

Right now in main bitmap_sdf represents the actaual MSDF image, and bitmap represents the example rendered image using that sdf. I would suggest having these two images use a seperate size value (one for thge MSDF, one for the test render).

@solenum
Copy link
Owner

solenum commented Feb 4, 2020

That's a valid point, I'll work on that soon and also have a look into the RANGE and PX_RANGE thing, though I'm really not sure what the issue is there.

@solenum
Copy link
Owner

solenum commented Feb 7, 2020

Hi, as of commit a2b0008 I have implemented auto-fit, this needs some testing though.

There's no way to enable it via the command-line yet, I hadn't really planned for this to become a tool, just code one could use in their own projects but perhaps that will change soon.

Anyway, change this line in main.c as shown here (last argument enables auto-fit) and give it a test, see how it works for you.

~ main.c:109 ~
   float *msdf = ex_msdf_glyph(&font, ex_utf8(c), size, size, &metrics, 1);

No auto-fit:
msdf_out

With auto-fit:
msdf_out

@mattparks
Copy link
Contributor Author

Your auto-fit is working well for me, this is what my 256x256 example looks like with auto-fit=1.
26

I'm still not 100% sure how I will use RANGE and PX_RANGE in my font shader, but this is my shader:

uniform sampler2DArray msdf;

in vec3 vTexCoords;

layout(location = 0) out vec4 outColor;

float median(float r, float g, float b) {
	return max(min(r, g), min(max(r, g), b));
}

void main() {
	vec3 msdfSample = texture(msdf, vTexCoords).rgb;
	float sigDist = median(msdfSample.r, msdfSample.g, msdfSample.b);
	float w = fwidth(sigDist);
	float opacity = smoothstep(0.5 - w, 0.5 + w, sigDist);
	outColor = vec4(1.0, 1.0, 1.0, opacity);
}

@solenum
Copy link
Owner

solenum commented Feb 7, 2020

Here's my text shader, I have to dynamically calculate the scale factor u_scale based on some values to keep the antialiasing consistent regardless of render size, its a bit strange but it works. I think the reason I need to do this is as you said before, there's something wrong with the RANGE and PX_RANGE aspects of the generator.

See here for how I calculate u_scale, it should also be noted that RANGE never actually touches my shader, those values are only used for generating.

#version 330 core

in vec2 uv;

out vec4 color;

uniform sampler2D u_texture;
uniform float     u_scale;

float median(float r, float g, float b) {
    return max(min(r, g), min(max(r, g), b));
}

void main()
{
  vec3 sample = texture(u_texture, uv).rgb;
  float dist = u_scale * (median(sample.r, sample.g, sample.b) - 0.5);
  float o = clamp(dist + 0.5, 0.0, 1.0);
  color = vec4(vec3(1.0), o);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants