一直在源码中找不到默认的Shader 原因是原有的Shader是由字符串组合而来. osg::setNotifyLevel(osg::INFO);//加上这句全局设置后, 在控制台会打印出当前所使用的Shader:
顶点着色器:
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ModelViewMatrix;
varying vec2 texCoord;
varying vec4 vertexColor;
void main(void)
{
gl_Position = osg_ModelViewProjectionMatrix * gl_Vertex;
texCoord = gl_MultiTexCoord0.xy;
vertexColor = gl_Color;
#if !defined(GL_ES) && __VERSION__<140
gl_ClipVertex = osg_ModelViewMatrix * gl_Vertex;
#endif
}
片元着色器:
#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE)
#pragma import_defines( SIGNED_DISTANCE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)
#ifdef GL_ES
#extension GL_OES_standard_derivatives : enable
#ifndef GL_OES_standard_derivatives
#undef SIGNED_DISTANCE_FIELD
#endif
#endif
#if !defined(GL_ES)
#if __VERSION__>=400
#define osg_TextureQueryLOD textureQueryLod
#else
#extension GL_ARB_texture_query_lod : enable
#ifdef GL_ARB_texture_query_lod
#define osg_TextureQueryLOD textureQueryLOD
#endif
#endif
#endif
#if __VERSION__>=130
#define TEXTURE texture
#define TEXTURELOD textureLod
out vec4 osg_FragColor;
#else
#define TEXTURE texture2D
#define TEXTURELOD texture2DLod
#define osg_FragColor gl_FragColor
#endif
#if !defined(GL_ES) && __VERSION__>=130
#define ALPHA r
#define SDF g
#else
#define ALPHA a
#define SDF r
#endif
uniform sampler2D glyphTexture;
varying vec2 texCoord;
varying vec4 vertexColor;
#ifndef TEXTURE_DIMENSION
const float TEXTURE_DIMENSION = 1024.0;
#endif
#ifndef GLYPH_DIMENSION
const float GLYPH_DIMENSION = 32.0;
#endif
#ifdef SIGNED_DISTANCE_FIELD
float distanceFromEdge(vec2 tc)
{
float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;
if (center_alpha==0.0) return -1.0;
//float distance_scale = (1.0/4.0)*1.41;
float distance_scale = (1.0/6.0)*1.41;
//float distance_scale = (1.0/8.0)*1.41;
return (center_alpha-0.5)*distance_scale;
}
vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)
{
#ifdef OUTLINE
float outline_width = OUTLINE*0.5;
if (edge_distance>blend_half_width)
{
return vertexColor;
}
else if (edge_distance>-blend_half_width)
{
return mix(vertexColor, vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a), smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));
}
else if (edge_distance>(blend_half_width-outline_width))
{
return vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a);
}
else if (edge_distance>-(outline_width+blend_half_width))
{
return vec4(BACKDROP_COLOR.rgb, vertexColor.a * ((blend_half_width+outline_width+edge_distance)/blend_width));
}
else
{
return vec4(0.0, 0.0, 0.0, 0.0);
}
#else
if (edge_distance>blend_half_width)
{
return vertexColor;
}
else if (edge_distance>-blend_half_width)
{
return vec4(vertexColor.rgb, vertexColor.a * smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));
}
else
{
return vec4(0.0, 0.0, 0.0, 0.0);
}
#endif
}
vec4 textColor(vec2 src_texCoord)
{
float sample_distance_scale = 0.75;
vec2 dx = dFdx(src_texCoord)*sample_distance_scale;
vec2 dy = dFdy(src_texCoord)*sample_distance_scale;
float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);
// compute the appropriate number of samples required to avoid aliasing.
int maxNumSamplesAcrossSide = 4;
int numSamplesX = int(TEXTURE_DIMENSION * length(dx));
int numSamplesY = int(TEXTURE_DIMENSION * length(dy));
if (numSamplesX<2) numSamplesX = 2;
if (numSamplesY<2) numSamplesY = 2;
if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;
if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;
vec2 delta_tx = dx/float(numSamplesX-1);
vec2 delta_ty = dy/float(numSamplesY-1);
float numSamples = float(numSamplesX)*float(numSamplesY);
float scale = 1.0/numSamples;
vec4 total_color = vec4(0.0,0.0,0.0,0.0);
float blend_width = 1.5*distance_across_pixel/numSamples;
float blend_half_width = blend_width*0.5;
// check whether fragment is wholly within or outwith glyph body+outline
float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)
if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body
#ifdef OUTLINE
float outline_width = OUTLINE*0.5;
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
#else
if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body
#endif
// use multi-sampling to provide high quality antialised fragments
vec2 origin = src_texCoord - dx*0.5 - dy*0.5;
for(;numSamplesY>0; --numSamplesY)
{
vec2 pos = origin;
int numX = numSamplesX;
for(;numX>0; --numX)
{
vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);
total_color = total_color + c * c.a;
pos += delta_tx;
}
origin += delta_ty;
}
total_color.rgb /= total_color.a;
total_color.a *= scale;
return total_color;
}
#else
vec4 textColor(vec2 src_texCoord)
{
#ifdef OUTLINE
float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;
float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;
float outline_alpha = alpha;
vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);
float numSamples = 3.0;
delta_tc = delta_tc/(numSamples-1.0);
float background_alpha = 1.0;
for(float i=0.0; i<numSamples; ++i)
{
for(float j=0.0; j<numSamples; ++j)
{
float local_alpha = TEXTURE(glyphTexture, origin + vec2(i*delta_tc, j*delta_tc)).ALPHA;
outline_alpha = max(outline_alpha, local_alpha);
background_alpha = background_alpha * (1.0-local_alpha);
}
}
#ifdef osg_TextureQueryLOD
float mipmapLevel = osg_TextureQueryLOD(glyphTexture, src_texCoord).x;
if (mipmapLevel<1.0)
{
outline_alpha = mix(1.0-background_alpha, outline_alpha, mipmapLevel/1.0);
}
#endif
if (outline_alpha<alpha) outline_alpha = alpha;
if (outline_alpha>1.0) outline_alpha = 1.0;
if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline
vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));
color.a = vertexColor.a * smoothstep(0.0, 1.0, outline_alpha);
return color;
#else
float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;
if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);
return vec4(vertexColor.rgb, vertexColor.a * alpha);
#endif
}
#endif
void main(void)
{
if (texCoord.x<0.0 && texCoord.y<0.0)
{
osg_FragColor = vertexColor;
return;
}
#ifdef SHADOW
float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;
vec2 delta_tc = SHADOW*scale;
vec4 shadow_color = textColor(texCoord+delta_tc);
shadow_color.rgb = BACKDROP_COLOR.rgb;
vec4 glyph_color = textColor(texCoord);
// lower the alpha_power value the greater the staturation, no need to be so aggressive with SDF than GREYSCALE
#if SIGNED_DISTANCE_FIELD
float alpha_power = 0.6;
#else
float alpha_power = 0.5;
#endif
// over saturate the alpha values to make sure the font and it's shadow are clear
shadow_color.a = pow(shadow_color.a, alpha_power);
glyph_color.a = pow(glyph_color.a, alpha_power);
vec4 color = mix(shadow_color, glyph_color, glyph_color.a);
#else
vec4 color = textColor(texCoord);
#endif
if (color.a==0.0) discard;
osg_FragColor = color;
}