sprite fragment shader
- ccShader_PositionTextureColor_noMVP.frag
void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); }
lable outline shader
- ccShader_Label_outline.frag
void main() { vec4 sample = texture2D(CC_Texture0, v_texCoord); // fontAlpha == 1 means the area of solid text (without edge) // fontAlpha == 0 means the area outside text, including outline area // fontAlpha == (0, 1) means the edge of text float fontAlpha = sample.a; // outlineAlpha == 1 means the area of 'solid text' and 'solid outline' // outlineAlpha == 0 means the transparent area outside text and outline // outlineAlpha == (0, 1) means the edge of outline float outlineAlpha = sample.r; if (u_effectType == 0) // draw text { gl_FragColor = v_fragmentColor * vec4(u_textColor.rgb, u_textColor.a * fontAlpha); } else if (u_effectType == 1) // draw outline { // multipy (1.0 - fontAlpha) to make the inner edge of outline smoother and make the text itself transparent. gl_FragColor = v_fragmentColor * vec4(u_effectColor.rgb, u_effectColor.a * outlineAlpha * (1.0 - fontAlpha)); } else // draw shadow { gl_FragColor = v_fragmentColor * vec4(u_effectColor.rgb, u_effectColor.a * outlineAlpha); } }
字符纹理基准
base font atlas = 字号+描边宽度
大家都要放到同一张RT里面
不使用shader着色(creator也采用的这种方案)
优点:
- 能够和sprite无缝合批,完美实现图文合批
缺点:
- font atls = 字号+描边宽度+
描边颜色
+字体颜色
,产生大量冗余字符纹理
- 需要使用CPU生成不同样式的字符纹理,并且需要保证新的算法和之前的文字描边效果一致
使用shader着色
优点:
- 可以复用之前的文字效果shader,保证效果不会发生大的变化
- 相对于CPU生成带效果的字符纹理,性能更好
- 没有冗余的字符纹理
缺点:
- 如果和图片合批(
ttf label / ttf label / bmfont / sprite
),受sprite shader的限制,需要改造sprite shader,因为大家的ashader必须一致才有机会合批,多重纹理也有改造sprite shader
这种方案改动大,但是彻底能解决图文合批问题,并且兼顾性能,能够和原有的文字效果保持一致
- 如果仅仅lable合批(
ttf label / ttf label
/ bmfont / sprite),因为只有triangles command
才能合批,可以开发一个继承triangle command
的render command
, 这样仅仅是ttf label
能够合批,无法和bmfont合批,因为使用的shader不一样
这种方案改动较小,同时能够保证和原有的文字效果一致,但是无法彻底解决图文合批,仅仅是ttf合批
bmfont使用的QuadCommand也是这个思路实现和sprite合批
if (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP){ setGLProgramState(GLProgramState::getOrCreateWithGLProgramName( _shadowEnabled ? GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR : GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP // sprite use this , _getTexture(this))); }