GithubHelp home page GithubHelp logo

Comments (7)

Chlumsky avatar Chlumsky commented on July 26, 2024

A sufficient border for this exact purpose is already included. When used correctly, there is absolutely no possibility of this happening. I can help you figure out what you're doing wrong but there is no reason to add the feature you requested.

from msdf-atlas-gen.

Phildo avatar Phildo commented on July 26, 2024

interesting- thanks for the response!

I don't quite understand, though. in the extreme example, lets say you're rendering the font at approximately the texture resolution (lets say 80px/glyph). if you want a 100px border (using the alpha channel of mtsdf texture), how can that be accomplished?

NOTE: don't worry about scouring this huge information dump- I just figured it's better to include more info than less. :)

This is what the issue looks like in my case. See the right side of the 'k's, you can see a sliver of white from the adjacent glyph ('l').

font

I noticed when I bring the mesh very close to the camera, the artifact actually goes away. So this is it from a bit of distance (zoom in to see the artifact). In my case, the artifact is very visible when viewed through a Valve Index HMD.

k

k_wire

Each glyph is 5 quads, one which minimally fits the character, and 4 extending the quad to the height of the row and the width of its spacing (so I can have black text with a thin white outline on a red background).

meshquads

Here's my code that constructs the mesh (per character):

The vertexs are a vec2 for position, and a vec2 for UV. The "FontGlyph" struct just has "pl,pb,pr,pt" which are "place {left,bottom,right,top}", and correspond to where the glyph quad should be placed relative to the cursor and baseline, and "access {left,bottom,right,top}", aka its UVs. (and size(height) just multiplies the "place" values).

void DoRendererMenu::setChar(FontGlyph *charLut, char c, glm::vec2 key_p, float cursor, float key_h, float *mesh_x, float *cursor_x, CharVertexBufferObject *vertexs)
{
  FontGlyph lut = charLut[c];
  FontGlyph elut = charLut[' '];
  float char_s = key_h*0.8;
  lut.size(char_s);
  float gw = lut.pr-lut.pl;
  float gh = lut.pt-lut.pb;
  float gl = cursor;
  float gr = cursor+gw;
  float gb = key_p.y-key_h*0.9+lut.pb;
  if(gb < key_p.y-key_h) gb = key_p.y-key_h;
  float gt = gb+gh;
  *cursor_x = cursor+lut.advance;
  float new_meshx = gr+(*cursor_x-gr)/2.0;
  *mesh_x = new_meshx;

  //top
  vertexs[0]  = {glm::vec2(key_p.x,  key_p.y),       glm::vec2(elut.al,elut.at)};
  vertexs[1]  = {glm::vec2(new_meshx,key_p.y),       glm::vec2(elut.ar,elut.at)};
  vertexs[2]  = {glm::vec2(gl       ,gt),            glm::vec2(elut.al,elut.ab)};
  vertexs[3]  = {glm::vec2(gr       ,gt),            glm::vec2(elut.ar,elut.ab)};
  //left
  vertexs[4]  = {glm::vec2(key_p.x  ,key_p.y),       glm::vec2(elut.al,elut.at)};
  vertexs[5]  = {glm::vec2(gl       ,gt),            glm::vec2(elut.ar,elut.at)};
  vertexs[6]  = {glm::vec2(key_p.x  ,key_p.y-key_h), glm::vec2(elut.al,elut.ab)};
  vertexs[7]  = {glm::vec2(gl       ,gb),            glm::vec2(elut.ar,elut.ab)};
  //glyph
  vertexs[8]  = {glm::vec2(gl,gt),                   glm::vec2(lut.al,lut.at)};
  vertexs[9]  = {glm::vec2(gr,gt),                   glm::vec2(lut.ar,lut.at)};
  vertexs[10] = {glm::vec2(gl,gb),                   glm::vec2(lut.al,lut.ab)};
  vertexs[11] = {glm::vec2(gr,gb),                   glm::vec2(lut.ar,lut.ab)};
  //right
  vertexs[12] = {glm::vec2(gr       ,gt     ),       glm::vec2(elut.al,elut.at)};
  vertexs[13] = {glm::vec2(new_meshx,key_p.y),       glm::vec2(elut.ar,elut.at)};
  vertexs[14] = {glm::vec2(gr       ,gb           ), glm::vec2(elut.al,elut.ab)};
  vertexs[15] = {glm::vec2(new_meshx,key_p.y-key_h), glm::vec2(elut.ar,elut.ab)};
  //bottom
  vertexs[16] = {glm::vec2(gl       ,gb     ),       glm::vec2(elut.al,elut.at)};
  vertexs[17] = {glm::vec2(gr       ,gb     ),       glm::vec2(elut.ar,elut.at)};
  vertexs[18] = {glm::vec2(key_p.x  ,key_p.y-key_h), glm::vec2(elut.al,elut.ab)};
  vertexs[19] = {glm::vec2(new_meshx,key_p.y-key_h), glm::vec2(elut.ar,elut.ab)};
}

and here's the shader I use:

#version 450
#extension GL_KHR_vulkan_glsl : enable
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_multiview : enable
layout(set = 0, binding = 2) uniform sampler2D colorSampler;
layout(location = 0) in vec2 fragUV;
layout(location = 1) in vec3 fragNormal;
layout(location = 0) out vec4 outColor;
void main()
{
  vec4 s = texture(colorSampler,fragUV);
  float bsd = max(min(s.r,s.g), min(max(s.r,s.g), s.b));
  float wsd = s.a;
  float omega = 5.0;
  float black = clamp(omega*(bsd-0.5)+0.5, 0.0, 1.0);
  omega = 1.0;
  float white = clamp(omega*(wsd-0.5)+0.5, 0.0, 1.0);
  float omblack = 1.0-black;
  float a = max(white,black);
  outColor = vec4(mix(vec3(0.8,0.1,0.1),vec3(omblack,omblack,omblack),a),0.8+(a*0.2));
}

If there's anything weird about how I'm approaching this, I'd love to be pointed in a more sensible direction! Thanks for your help, and for your work on this library :)

from msdf-atlas-gen.

Phildo avatar Phildo commented on July 26, 2024

oh wow I'm just realizing that this might be a mipmapping issue. let me test that real quick

from msdf-atlas-gen.

Chlumsky avatar Chlumsky commented on July 26, 2024

That's quite likely if the artifact disappears when the camera is closer. Mipmapping should never be used with distance field textures as it doesn't help. However you need to increase the distance range significantly to be able to achieve anti-aliasing for minification. Also, looking at your texture, it is generated incorrectly due to overlapping parts in the font, so I would strongly recommend the latest version with Skia geometry preprocessing.

from msdf-atlas-gen.

Phildo avatar Phildo commented on July 26, 2024

Would you mind expanding on what you mean by "you need to increase the distance range significantly to be able to achieve anti-aliasing for minification"? Also, I've updated to the latest (1.1), and will try with that, but where do you see "overlapping parts in the font"?

Thanks for your help!

from msdf-atlas-gen.

Chlumsky avatar Chlumsky commented on July 26, 2024

To be able to achieve anti-aliasing using the signed distance retrieved from the distance field, you need to have a range of distances covering at least two screen-space pixels. Assuming the texture you posted is the one you're using, it is very much insufficient for this purpose at the minification level in your screenshots. You can increase the distance range coverage with the -pxrange and -emrange arguments. Specifically, pxrange should be at least 2/s where s is the lowest display scale (on-screen size / texture size). I'd say the texture is also about 4 times bigger than it needs to be but that's beside the point (although it can become a problem as a larger texture size requires a greater pxrange and at pxrange around 128 the smooth gradient starts breaking down in a typical 8-bit color encoding).

As for the overlapping parts, I mean self-intersecting paths. You can see that there are certain strange indentations near some corners in the generated atlas, which are due to the geometry of the glyphs being composed of overlapping segments, which is something that requires additional preprocessing. That was added in the latest version with the help of the Skia library. Before that, fonts like these were simply not supported (the preprocessing can be performed in a font editor software instead). Proper fonts have these self-intersections resolved and do not cause this issue. Sometimes it happens with certain accents or extended character sets like CJK, but this is the first time I've seen this with the base ASCII character set. A good example is the ampersand character in your image. Normally, it would be composed of three contours, seen below as red, green, and blue, but in your font, it is presumably realized as a single self-intersecting contour (bottom right).

ampersands

from msdf-atlas-gen.

Phildo avatar Phildo commented on July 26, 2024

ah that's so helpful! thank you so much. issue closed

from msdf-atlas-gen.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.