透视投影中的SDF文本渲染

时间:2016-01-02 06:57:57

标签: fonts opengl-es webgl

我正在使用SDF技术http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf在WebGL中呈现文本。我制作了SDF纹理字体,生成BMFont文本指标并使用简单的片段着色器显示文本:

    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);            
    }

我在aastep函数中遇到了afwidth值问题。 afwidth只是定义了字体边框的模糊。如果它很小,那么遥远的文字看起来很难看。如果靠近我的大文字看起来很难看。那么问题是如何在片段着色器中计算afwidth?

PS:我有一个使用GL_OES_standard_derivatives来计算它的公式: float afwidth = length(vec2(dFdx(value),dFdy(value)))* 0.70710678118654757; 但我的硬件不支持此扩展。所以我认为我需要根据gl_FragCoord和变换矩阵来计算它。

2 个答案:

答案 0 :(得分:2)

有人可能会尝试根据gl_FragCoord.w = 1.0 / gl_Position.w创建一个简单的距离到相机的近似值:

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);
}

您可能需要根据自己的喜好调整常量0.1

答案 1 :(得分:1)

只是检查,但您确定您的硬件不支持 {% if loop.index % 5 == 0 %} </div><div class="span5"> {% endif %} {% endfor %} </div> <!-- close the span5 we opened --> </div> <!-- close the parent loop container --> 吗? http://webglstats.com使其看起来不太可能。

在WebGL中,您必须启用OES_standard_derivatives才能使用它。

OES_standard_derivatives

然后在你的着色器中你必须打开它

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

Run this test to check if they work on your system。如果你得到一个非常短暂的结果,那么你就不会存在,那么你就会纠正它们并不存在。如果你得到了很多结果,那么它们确实存在,你只是没有在你的程序中启用它们