Label Plus - 基于 SDF 的 BMFont 生成和渲染的免费插件来了

更新说明

Label Plus 插件更新了!!!(v1.1.0) - Store - Cocos中文社区

商店链接

label-plus | Cocos Store

插件介绍

开箱即用的 SDF BMFont 生成,及对应的渲染组件,相比常规的渲染方式,基于 SDF 渲染文字可无限放大并保持清晰,几乎没有开销就可实现描边,阴影等效果.且它只需要很小的纹理存储 SDF 信息。

版本支持

  • [x] Cocos Cretaor 3.6.x
  • [x] Cocos Cretaor 3.5.x

编辑器支持

  • [x] MacOS
  • [x] Windows

平台支持

  • [x] Android
  • [x] iOS
  • [x] Mac
  • [x] Windows
  • [x] Web (小游戏理论支持,没测试)

注意事项

  1. 遇到问题可加微信反馈 Bug:yanjifa2013
  2. 请确保电脑安装 nodejs 环境,生成字体工具依赖 nodejs 环境运行。
  3. 务必将插件安装到项目内, 不要全局安装,否则高版本运行时自动升级材质,会导致低版本打开报错!!!
  4. 安装插件后会导致模拟器预览启动时报错,可通过插件提供的修复功能,恢复模拟器预览。
    截屏20220810 01.57.14.png

功能介绍

  1. 组件添加方式 | 搜索名称添加

  2. 渲染组件介绍

  • 使用简单,像内置组件一样,不需要特别关心材质设置,从下图能看出 CustomMaterial 那里是空的

    功能

  • 字体粗细
  • 描边开关
  • 描边粗细
  • 描边颜色
  • 阴影开关
  • 阴影颜色
  • 阴影偏移


import 脚本

import { _decorator, Component } from 'cc';
import { LabelPlus } from 'db://label-plus/components/label-plus';
const { ccclass, property } = _decorator;

@ccclass('Test')
export class Test extends Component {
    @property(LabelPlus)
    private labelPlus: LabelPlus = null;

    private num = 0;

    onEnable() {
        this.labelPlus.outline = true;
    }

    update() {
        this.labelPlus.string = `${this.num++}`;
    }
}


  1. 字体生成器

通过扩展菜单打开插件面板
截屏20220810 01.57.14.png

  • 支持 SDF & MSDF (多通道,效果更好,不会出现放大圆角问题)。
  • 选择字体后点击生成按钮,生成成功后会出现预览图。
  • 然后点击另存按钮,存储到项目目录内会自动导入。
16赞

感谢大佬设计的字体方案, 文字很酷, :smile: :+1: :+1:

Label Plus 插件更新了!!!v1.0.1

1赞

字体生成器是相当于对ttf做裁剪么

是生成的 BMFont,里面的纹理保存的是距离场信息

支持!

优秀的插件,而且还是免费的哦,必须置顶,让更多人知道!

支持一波.

感谢支持 :handshake:

卷起来了,据说还有一款功能相似的插件在开发中:joy:

1赞

目前已知在 3.5.x Native 构建后启动报错,会尽快想办法修复!!!

1赞

这个是我们能免费用的? :joy:

mark 支持.

大佬,搞个2.*版本??可好?

//self defined effect         author:ljw 

CCEffect %{
techniques:

  • name: stroke
    passes:
    • vert: 2dvs:vert # builtin header
      frag: 2dfs:frag
      blendState:
      targets:
      • blend: true
        blendSrc: src_alpha
        blendDst: one_minus_src_alpha
        blendDstAlpha: one_minus_src_alpha
        properties: &props
        mainColor: { value: [1, 1, 1, 1], editor: { type: color } }
        strokeColor: {value: [1, 1, 1, 1] , editor: { type: color }}
        fillColor: {value: [1, 0, 0, 1], editor: { type: color }}
        strokeWidth: { value: 0.01}
  • name: stroke-drawShadow
    passes:
    • vert: 2dvs:vert # builtin header
      frag: 2dfs-shadow:frag
      blendState:
      targets:
      • blend: true
        blendSrc: src_alpha
        blendDst: one_minus_src_alpha
        blendDstAlpha: one_minus_src_alpha
        properties: &props
        mainColor: { value: [1, 1, 1, 1], editor: { type: color } }
        strokeColor: {value: [1, 1, 1, 1] , editor: { type: color }}
        fillColor: {value: [1, 0, 0, 1], editor: { type: color }}
        shaowColor: { value: [0,0,1,1], editor: { type: color }}
        strokeWidth: { value: 0.01}
        shadowWidth: {value: 0.02}
        }%

CCProgram 2dvs { precision highp float; #include <cc-global> #if USE_LOCAL #include <cc-local> #endif #if SAMPLE_FROM_RT #include <common> #endif in vec3 a_position; in vec2 a_texCoord; in vec4 a_color; out vec4 color; out vec2 uv0; vec4 vert () { vec4 pos = vec4(a_position, 1); #if USE_LOCAL pos = cc_matWorld * pos; #endif #if USE_PIXEL_ALIGNMENT pos = cc_matView * pos; pos.xyz = floor(pos.xyz); pos = cc_matProj * pos; #else pos = cc_matViewProj * pos; #endif uv0 = a_texCoord; #if SAMPLE_FROM_RT CC_HANDLE_RT_SAMPLE_FLIP(uv0); #endif color = a_color; return pos; } }

CCProgram 2dfs %{
precision highp float;
#include
#include

in vec2 uv0;

uniform Constant {
vec4 mainColor;
vec4 strokeColor;
vec4 fillColor;
float strokeWidth;
};
vec4 drawEdgeStroke(){
float alphaThreshold = 0.3;
vec4 col1 = texture(cc_spriteTexture, uv0);
if(col1.a>alphaThreshold) return fillColor;
else {
vec4 col2 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,0.));
vec4 col3 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,0.));
vec4 col4 = texture(cc_spriteTexture, uv0+vec2(0.,strokeWidth));
vec4 col5 = texture(cc_spriteTexture, uv0+vec2(0.,-strokeWidth));
vec4 col6 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,strokeWidth));
vec4 col7 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,-strokeWidth));
vec4 col8 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,strokeWidth));
vec4 col9 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,-strokeWidth));
if(col2.a>alphaThreshold||col3.a>alphaThreshold||col4.a>alphaThreshold||col5.a>alphaThreshold
||col6.a>alphaThreshold||col7.a>alphaThreshold||col8.a>alphaThreshold||col9.a>alphaThreshold) return strokeColor;
else discard;
}
}
vec4 frag () {
vec4 col = drawEdgeStroke();
return CCFragOutput(col);
}
}%

CCProgram 2dfs-shadow %{
precision highp float;
#include
#include

in vec2 uv0;

uniform Constant {
vec4 mainColor;
vec4 strokeColor;
vec4 fillColor;
vec4 shaowColor;
float strokeWidth;
float shadowWidth;

};
vec4 drawEdgeStroke(){
float alphaThreshold = 0.3;
vec4 col1 = texture(cc_spriteTexture, uv0);
if(col1.a>alphaThreshold) return fillColor;//文字 正常渲染
else {
//上下左右偏移 strokeWidth个长度后的坐标
vec4 col2 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,0.));
vec4 col3 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,0.));
vec4 col4 = texture(cc_spriteTexture, uv0+vec2(0.,strokeWidth));
vec4 col5 = texture(cc_spriteTexture, uv0+vec2(0.,-strokeWidth));
vec4 col6 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,strokeWidth));
vec4 col7 = texture(cc_spriteTexture, uv0+vec2(strokeWidth,-strokeWidth));
vec4 col8 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,strokeWidth));
vec4 col9 = texture(cc_spriteTexture, uv0+vec2(-strokeWidth,-strokeWidth));
// 下右偏移
vec4 col10 = texture(cc_spriteTexture,uv0+vec2(-shadowWidth));
if(col2.a>alphaThreshold||col3.a>alphaThreshold||col4.a>alphaThreshold||col5.a>alphaThreshold
||col6.a>alphaThreshold||col7.a>alphaThreshold||col8.a>alphaThreshold||col9.a>alphaThreshold) return strokeColor;
else if(col10.a>alphaThreshold){
return shaowColor;
}else discard;
}
}
vec4 frag () {
vec4 col = drawEdgeStroke();
return CCFragOutput(col);
}
}%

看这个效果用shader写了个脚本,感觉比插件可能方便点。版本是3.5

1赞

不过看作者之前的帖子,他好像做了合批处理。 :grinning:

Label Plus 插件更新了!!!(v1.0.2)

1赞

大佬我只想对你说 爱你 爱你 爱你,如果没时间,我们可以用金钱来赞助,做的更好

问下,这个字是不是每次都要自己去生成?手动一个个往里面输入吗,如果想要继续添加,界面关闭后又没了