Improvements to the Signed Distance Field implementation.
This commit is contained in:
parent
d2fa7c4317
commit
2f19cd4b87
@ -27,8 +27,13 @@ DefaultFont::DefaultFont()
|
||||
_fontSize = FontResolution(8,12);
|
||||
|
||||
_minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR;
|
||||
_magFilterHint = osg::Texture::NEAREST;
|
||||
_magFilterHint = osg::Texture::LINEAR;
|
||||
|
||||
char *ptr;
|
||||
if ((ptr = getenv("OSG_SDF_TEXT")) != 0)
|
||||
{
|
||||
_glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES;
|
||||
}
|
||||
|
||||
constructGlyphs();
|
||||
}
|
||||
|
@ -60,7 +60,9 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
||||
int GlyphTexture::getEffectMargin(const Glyph* glyph)
|
||||
{
|
||||
if (_glyphTextureFeatures==GREYSCALE) return 0;
|
||||
else return glyph->getFontResolution().second/4;
|
||||
// else return glyph->getFontResolution().second/4;
|
||||
else return osg::maximum(glyph->getFontResolution().second/6, 2u);
|
||||
// else return osg::maximum(glyph->getFontResolution().second/8,1u);
|
||||
}
|
||||
|
||||
int GlyphTexture::getTexelMargin(const Glyph* glyph)
|
||||
|
@ -47,6 +47,17 @@ Text::Text():
|
||||
{
|
||||
_supportsVertexBufferObjects = true;
|
||||
|
||||
char *ptr;
|
||||
if ((ptr = getenv("OSG_SDF_TEXT")) != 0)
|
||||
{
|
||||
_backdropImplementation = USE_SHADERS;
|
||||
}
|
||||
else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0)
|
||||
{
|
||||
_backdropImplementation = DELAYED_DEPTH_WRITES;
|
||||
}
|
||||
|
||||
|
||||
assignStateSet();
|
||||
}
|
||||
|
||||
@ -80,11 +91,10 @@ osg::StateSet* Text::createStateSet()
|
||||
|
||||
Font::StateSets& statesets = activeFont->getCachedStateSets();
|
||||
|
||||
std::stringstream ss;
|
||||
osg::StateSet::DefineList defineList;
|
||||
if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss.str("");
|
||||
ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")";
|
||||
|
||||
@ -122,15 +132,19 @@ osg::StateSet* Text::createStateSet()
|
||||
|
||||
}
|
||||
|
||||
if (_fontSize.second>16/* && _backdropImplementation==USE_SHADERS*/)
|
||||
if (activeFont->getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE)
|
||||
{
|
||||
OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<<std::endl;
|
||||
ss.str("");
|
||||
ss << _fontSize.second;
|
||||
|
||||
defineList["GLYPH_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
|
||||
|
||||
ss.str("");
|
||||
ss << activeFont->getTextureWidthHint();
|
||||
defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
|
||||
|
||||
defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"Disabling SDF support _fontSize.second="<<_fontSize.second<<std::endl;
|
||||
}
|
||||
|
||||
#if 0
|
||||
OSG_NOTICE<<"Text::createStateSet() _backdropType="<<_backdropType<<", _backdropImplementation="<<_backdropImplementation<<std::endl;
|
||||
@ -151,7 +165,7 @@ osg::StateSet* Text::createStateSet()
|
||||
{
|
||||
if ((*itr)->getDefineList()==defineList)
|
||||
{
|
||||
OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<<itr->get()<<std::endl;
|
||||
// OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<<itr->get()<<std::endl;
|
||||
return itr->get();
|
||||
}
|
||||
else
|
||||
@ -180,7 +194,7 @@ osg::StateSet* Text::createStateSet()
|
||||
osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint();
|
||||
if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE)
|
||||
{
|
||||
OSG_INFO<<"Font::Font() Fixed function pipeline"<<std::endl;
|
||||
OSG_NOTICE<<"Font::Font() Fixed function pipeline"<<std::endl;
|
||||
|
||||
stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
||||
return stateset.release();
|
||||
|
@ -1,21 +1,17 @@
|
||||
char text_sdf_frag[] = "$OSG_GLSL_VERSION\n"
|
||||
"\n"
|
||||
"#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD )\n"
|
||||
"#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n"
|
||||
"\n"
|
||||
"#if !defined(GL_ES)\n"
|
||||
" #if __VERSION__>=400\n"
|
||||
" #define osg_TextureQueryLOD textureQueryLod\n"
|
||||
" #else\n"
|
||||
" #extension GL_ARB_texture_query_lod : enable\n"
|
||||
" #ifdef GL_ARB_texture_query_lod\n"
|
||||
" #define osg_TextureQueryLOD textureQueryLOD\n"
|
||||
" #endif\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" #extension GL_OES_standard_derivatives : enable\n"
|
||||
" #ifndef GL_OES_standard_derivatives\n"
|
||||
" #undef SIGNED_DISTNACE_FIELD\n"
|
||||
" #endif\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"$OSG_PRECISION_FLOAT\n"
|
||||
"\n"
|
||||
"//#undef USE_SIGNED_DISTNACE_FIELD\n"
|
||||
"#undef SIGNED_DISTNACE_FIELD\n"
|
||||
"\n"
|
||||
"#if __VERSION__>=130\n"
|
||||
" #define TEXTURE texture\n"
|
||||
@ -32,13 +28,138 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n"
|
||||
"$OSG_VARYING_IN vec2 texCoord;\n"
|
||||
"$OSG_VARYING_IN vec4 vertexColor;\n"
|
||||
"\n"
|
||||
"#ifdef SIGNED_DISTNACE_FIELD\n"
|
||||
"\n"
|
||||
"float distanceFromEdge(vec2 tc)\n"
|
||||
"{\n"
|
||||
" float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).r;\n"
|
||||
" if (center_alpha==0.0) return -1.0;\n"
|
||||
"\n"
|
||||
" //float distance_scale = (1.0/4.0)*1.41;\n"
|
||||
" float distance_scale = (1.0/6.0)*1.41;\n"
|
||||
" //float distance_scale = (1.0/8.0)*1.41;\n"
|
||||
"\n"
|
||||
" return (center_alpha-0.5)*distance_scale;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n"
|
||||
"{\n"
|
||||
"#ifdef OUTLINE\n"
|
||||
" float outline_width = OUTLINE*0.5;\n"
|
||||
" if (edge_distance>blend_half_width)\n"
|
||||
" {\n"
|
||||
" return vertexColor;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-blend_half_width)\n"
|
||||
" {\n"
|
||||
" return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>(blend_half_width-outline_width))\n"
|
||||
" {\n"
|
||||
" return BACKDROP_COLOR;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-(outline_width+blend_half_width))\n"
|
||||
" {\n"
|
||||
" return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return vec4(0.0, 0.0, 0.0, 0.0);\n"
|
||||
" }\n"
|
||||
"#else\n"
|
||||
" if (edge_distance>blend_half_width)\n"
|
||||
" {\n"
|
||||
" return vertexColor;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-blend_half_width)\n"
|
||||
" {\n"
|
||||
" return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return vec4(0.0, 0.0, 0.0, 0.0);\n"
|
||||
" }\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 distanceFieldColor()\n"
|
||||
"{\n"
|
||||
" float sample_distance_scale = 0.75;\n"
|
||||
" vec2 dx = dFdx(texCoord)*sample_distance_scale;\n"
|
||||
" vec2 dy = dFdy(texCoord)*sample_distance_scale;\n"
|
||||
"\n"
|
||||
" #ifndef TEXTURE_DIMENSION\n"
|
||||
" float TEXTURE_DIMENSION = 1024.0;\n"
|
||||
" #endif\n"
|
||||
"\n"
|
||||
" #ifndef GLYPH_DIMENSION\n"
|
||||
" float GLYPH_DIMENSION = 32.0;\n"
|
||||
" #endif\n"
|
||||
"\n"
|
||||
" float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n"
|
||||
"\n"
|
||||
" // compute the appropriate number of samples required to avoid aliasing.\n"
|
||||
" int maxNumSamplesAcrossSide = 4;\n"
|
||||
"\n"
|
||||
" int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n"
|
||||
" int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n"
|
||||
" if (numSamplesX<2) numSamplesX = 2;\n"
|
||||
" if (numSamplesY<2) numSamplesY = 2;\n"
|
||||
" if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n"
|
||||
" if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" vec2 delta_tx = dx/float(numSamplesX-1);\n"
|
||||
" vec2 delta_ty = dy/float(numSamplesY-1);\n"
|
||||
"\n"
|
||||
" float numSamples = float(numSamplesX)*float(numSamplesY);\n"
|
||||
" float scale = 1.0/numSamples;\n"
|
||||
" vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n"
|
||||
"\n"
|
||||
" float blend_width = 1.5*distance_across_pixel/numSamples;\n"
|
||||
" float blend_half_width = blend_width*0.5;\n"
|
||||
"\n"
|
||||
" // check whether fragment is wholly within or outwith glyph body+outline\n"
|
||||
" float cd = distanceFromEdge(texCoord); // central distance (distance from center to edge)\n"
|
||||
" if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n"
|
||||
"\n"
|
||||
" #ifdef OUTLINE\n"
|
||||
" float outline_width = OUTLINE*0.5;\n"
|
||||
" if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n"
|
||||
" #else\n"
|
||||
" if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n"
|
||||
" #endif\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" // use multi-sampling to provide high quality antialised fragments\n"
|
||||
" vec2 origin = texCoord - dx*0.5 - dy*0.5;\n"
|
||||
" for(;numSamplesY>0; --numSamplesY)\n"
|
||||
" {\n"
|
||||
" vec2 pos = origin;\n"
|
||||
" int numX = numSamplesX;\n"
|
||||
" for(;numX>0; --numX)\n"
|
||||
" {\n"
|
||||
" vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n"
|
||||
" total_color = total_color + c * c.a;\n"
|
||||
" pos += delta_tx;\n"
|
||||
" }\n"
|
||||
" origin += delta_ty;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" total_color.rgb /= total_color.a;\n"
|
||||
" total_color.a *= scale;\n"
|
||||
"\n"
|
||||
" return total_color;\n"
|
||||
"}\n"
|
||||
"#else\n"
|
||||
"\n"
|
||||
"vec4 textureColor()\n"
|
||||
"{\n"
|
||||
" #ifdef OUTLINE\n"
|
||||
" // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n"
|
||||
" vec4 glyph = TEXTURE(glyphTexture, texCoord);\n"
|
||||
"\n"
|
||||
" float outline_alpha = (OUTLINE<=0.1) ? glyph.g : glyph.b;\n"
|
||||
" float outline_alpha = (OUTLINE<=0.05) ? glyph.g : glyph.b;\n"
|
||||
"\n"
|
||||
" float alpha = glyph.a+outline_alpha;\n"
|
||||
" if (alpha>1.0) alpha = 1.0;\n"
|
||||
@ -52,53 +173,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n"
|
||||
" #endif\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"#ifdef SIGNED_DISTNACE_FIELD\n"
|
||||
"vec4 distanceFieldColor()\n"
|
||||
"{\n"
|
||||
" float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n"
|
||||
" //float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n"
|
||||
"\n"
|
||||
" float blend_width = 0.005;\n"
|
||||
" float distance_scale = 0.25;\n"
|
||||
" float edge_distance = (center_alpha-0.5)*distance_scale;\n"
|
||||
"\n"
|
||||
" #ifdef OUTLINE\n"
|
||||
" float outline_width = OUTLINE*0.5;\n"
|
||||
" if (edge_distance>blend_width*0.5)\n"
|
||||
" {\n"
|
||||
" return vertexColor;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-blend_width*0.5)\n"
|
||||
" {\n"
|
||||
" return mix(vertexColor, BACKDROP_COLOR, (blend_width*0.5-edge_distance)/(blend_width));\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>(blend_width-outline_width))\n"
|
||||
" {\n"
|
||||
" return BACKDROP_COLOR;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-outline_width)\n"
|
||||
" {\n"
|
||||
" return vec4(BACKDROP_COLOR.rgb, (outline_width+edge_distance)/blend_width);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return vec4(0.0, 0.0, 0.0, 0.0);\n"
|
||||
" }\n"
|
||||
" #else\n"
|
||||
" if (edge_distance>0.0)\n"
|
||||
" {\n"
|
||||
" return vertexColor;\n"
|
||||
" }\n"
|
||||
" else if (edge_distance>-blend_width)\n"
|
||||
" {\n"
|
||||
" return vec4(vertexColor.rgb, 1.0+edge_distance/blend_width);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return vec4(0.0, 0.0, 0.0, 0.0);\n"
|
||||
" }\n"
|
||||
" #endif\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"\n"
|
||||
@ -110,36 +184,12 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" float near_fade_away = 2.0;\n"
|
||||
" float far_fade_away = near_fade_away+5.0;\n"
|
||||
"\n"
|
||||
"#ifdef osg_TextureQueryLOD\n"
|
||||
" float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n"
|
||||
" if (mml>far_fade_away) discard;\n"
|
||||
"#else\n"
|
||||
" float mml = 0.0;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"#ifdef SIGNED_DISTNACE_FIELD\n"
|
||||
"\n"
|
||||
" float near_transition = 0.0;\n"
|
||||
" float far_transition = near_transition+1.0;\n"
|
||||
"\n"
|
||||
" vec4 color;\n"
|
||||
" if (mml<near_transition) color = distanceFieldColor();\n"
|
||||
" else if (mml>far_transition) color = textureColor();\n"
|
||||
" else color = mix(distanceFieldColor(), textureColor(), (mml-near_transition)/(far_transition-near_transition));\n"
|
||||
"\n"
|
||||
" vec4 color = distanceFieldColor();\n"
|
||||
"#else\n"
|
||||
"\n"
|
||||
" vec4 color = textureColor();\n"
|
||||
"\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" if (mml>near_fade_away) color.a *= (far_fade_away-mml)/(far_fade_away-near_fade_away);\n"
|
||||
"\n"
|
||||
" if (color.a==0.0) discard;\n"
|
||||
"\n"
|
||||
" osg_FragColor = color;\n"
|
||||
|
Loading…
Reference in New Issue
Block a user