Open mattparks opened 4 years ago
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 :+1:
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.
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 creates this glyph without autoframe (256x256):
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;
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).
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.
Hi, as of commit https://github.com/exezin/msdf-c/commit/a2b0008c70e7e4093b170082f8d4a599832bc5e0 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:
With auto-fit:
Your auto-fit is working well for me, this is what my 256x256 example looks like with auto-fit=1.
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);
}
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);
}
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:
exezin/msdf-c:
256x256 Example: