2个版本
0.1.1 | 2022年8月22日 |
---|---|
0.1.0 | 2022年8月22日 |
#78 in 渲染
120KB
1K SLoC
Easy signed distance field
Easy signed distance field 是一个简单、纯Rust的符号距离场渲染器。它旨在作为一个简单、更灵活、更完整功能的替代品,替代crates.io上其他sdf包。
Easy signed distance field 目前支持原始线条输入和ttf/otf字体输入。它还支持CPU渲染以供调试。
符号距离场是一种渲染技术,可以生成非常小的符号,可以以牺牲锐角周围质量为代价在更高的分辨率下渲染。该技术还附带“免费”抗锯齿和一些文字效果。
通常,这项技术在游戏中用来创建小字符符号的图集,然后可以在任何分辨率下渲染。渲染是在GPU上的片段着色器上完成的。
要查看实时演示,请访问 https://gabdube.github.io/easy-signed-distance-field/
有关文档,请参阅 https://docs.rs/easy-signed-distance-field/0.1.0/easy_signed_distance_field/
功能
默认情况下,此库无依赖项,仅支持从线条集合中进行渲染。可以启用额外功能
font
:导入字体家族并将字符符号渲染为sdfexport
:将sdf导出为图像render
:(与export一起使用) 将sdf渲染到文件
[features]
default = []
render = []
font = ["ttf-parser"]
export = ["image"]
用法
从线条集合渲染简单的三角形
use easy_signed_distance_field as sdf;
let lines = [
Line::Line { start: vec2(0.5, 0.0), end: vec2(1.0, 1.0) },
Line::Line { start: vec2(1.0, 1.0), end: vec2(0.0, 1.0) },
Line::Line { start: vec2(0.0, 1.0), end: vec2(0.5, 0.0) },
];
let width: u32 = 32;
let height: u32 = 32;
let padding = 2;
let spread = 5.0;
let sdf = sdf::sdf_generate(
width,
height,
padding,
spread,
&lines,
);
#[cfg(feature="export")]
sdf::sdf_to_file("test_outputs/triangle.png", &sdf).unwrap();
let render_scale = 512.0 / (size as f32);
#[cfg(feature="render")]
#[cfg(feature="export")]
sdf::sdf_render_to_file("test_outputs/triangle_render.png", render_scale, 0.5, 0.02, &sdf).unwrap();
从字体渲染字符
use std::fs;
use easy_signed_distance_field as sdf;
let font_data = fs::read("./test_fixtures/Questrial-Regular.ttf").expect("Failed to read font file");
let font = sdf::Font::from_bytes(font_data.as_slice(), Default::default()).expect("Failed to parse font file");
let px = 64.0;
let padding = 2;
let spread = 6.0;
let (a_metrics, a_glyph_sdf) = font.sdf_generate(px, padding, spread, 'a').unwrap();
#[cfg(feature="export")]
sdf::sdf_to_file("test_outputs/font_a.png", &a_glyph_sdf).unwrap();
#[cfg(feature="render")]
#[cfg(feature="export")]
sdf::sdf_render_to_file("test_outputs/font_a_render.png", render_scale, 0.5, 0.02, &a_glyph_sdf).unwrap();
将sdf上传到webgl纹理
性能
根据基准测试,生成64px的单个字符的sdf大约需要2ms。在相同分辨率下生成整个字母表(大小写),大约需要66ms。这个时间将根据您的字体/形状的复杂程度而变化。
这意味着如果您打算在实时环境中使用此库(例如,在用户键入时生成sdf),最好在主线程之外运行代码或预先在启动时生成字符。
尽管如此,该算法是单线程的并且非常简单,可能有很多改进的方法。
路线图
该项目是为了用于我的个人项目之一而开发的,因此除非该项目需要,否则不会进行进一步的开发/维护。话虽如此,我不介意合并贡献者的功能,只要在问题部分与我讨论即可,如果这是个大项目。
在某个时候实现多签名距离场(msdf)也是我想添加的功能之一。
添加多线程支持也是我想探索的。尽管如此,这并不是优先事项,因为我打算从wasm中使用它。
直到我(或其他人)在一个严肃的项目中使用它之前,该项目不会达到1.0
。在此之前,API可能会发生变化。
许可证
本代码遵循MIT许可证。
致谢
虽然我对数学不是很差,但我不算是一个数学家;这个项目中使用的算法大多数都是由比我更有能力的人创建的。
- https://www.shadertoy.com/view/MlKcDD(用于四边形贝塞尔距离函数)
- https://pomax.github.io/bezierinfo/#introduction(用于贝塞尔曲线背后的整体理论)
- MsdfGen https://github.com/Chlumsky/msdfgen 作为本项目的灵感来源
- Fontdue: https://github.com/mooman219/fontdue,用于设计字体界面模板
- bezierjs https://github.com/Pomax/bezierjs
依赖项
~0–2.7MB
~13K SLoC