Ich verwende die SDF-Technik http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification .pdf zum Rendern von Text in WebGL. Ich habe eine SDF-Textur für Schriftarten erstellt, BMFont-Textmetriken generiert und den Text mit einem einfachen Fragment-Shader angezeigt:

    precision mediump float;
    uniform sampler2D u_texture;        
    varying vec2 vUv;

    float aastep(float value) {
      float afwidth = 0.1;
      return smoothstep(0.5 - afwidth, 0.5 + afwidth, value);
    }

    void main(void)
    {            
        vec4 texColor = texture2D(u_texture, vUv);
        float alpha = aastep(texColor.a);
        gl_FragColor = vec4(0.0, 0.0, 0.0, alpha);            
    }

Ich habe ein Problem mit dem Breitenwert in der Aastep-Funktion. afwidth definiert einfach das Verwischen von Schriftrahmen. Wenn es klein ist, sieht weit entfernter Text hässlich aus. Wenn großer Text in meiner Nähe hässlich aussieht. Die Frage ist also, wie man die Breite im Fragment-Shader berechnet.

PS: Ich habe eine Formel, um sie mit GL_OES_standard_derivatives zu berechnen: float afwidth = length (vec2 (dFdx (Wert), dFdy (Wert))) * 0.70710678118654757; Meine Hardware unterstützt diese Erweiterung jedoch nicht. Ich denke, ich muss es basierend auf gl_FragCoord und der Transformationsmatrix berechnen.

1
Roman Kolesnikov 2 Jän. 2016 im 09:57

2 Antworten

Beste Antwort

Nur überprüfen, aber sind Sie sicher, dass Ihre Hardware OES_standard_derivatives nicht unterstützt? http://webglstats.com lässt es als unwahrscheinlich erscheinen.

In WebGL müssen Sie OES_standard_derivatives aktivieren, um es verwenden zu können.

ext = gl.getExtention("OES_standard_derivatives");
if (!ext) {
  // alert("no OES standard derivatives") or fallback to other technique
}

Dann müssen Sie es in Ihrem Shader einschalten

// at top of fragment shader
#extension GL_OES_standard_derivatives : enable

Führen Sie diesen Test aus, um zu überprüfen, ob sie funktionieren Ihr System. Wenn Sie ein sehr kurzes Ergebnis darüber erhalten, dass sie nicht vorhanden sind, haben Sie Recht, dass sie nicht vorhanden sind. Wenn Sie viele Ergebnisse erhalten, sind diese vorhanden und Sie haben sie in Ihrem Programm einfach nicht aktiviert

1
gman 2 Jän. 2016 im 16:39

Man könnte versuchen, eine einfache Annäherung der Entfernung zur Kamera basierend auf gl_FragCoord.w = 1.0 / gl_Position.w zu erstellen:

float aastep(float value)
{
      float distanceToCamera = 1.0 / gl_FragCoord.w;
      float afwidth = 0.1 * distanceToCamera;
      return smoothstep(0.5 - afwidth, 0.5 + afwidth, value);
}

Sie müssen wahrscheinlich die Konstante 0.1 nach Ihren Wünschen anpassen.

2
Niko Nevatie 2 Jän. 2016 im 11:24