第 17 章 文字渲染

📅 2026/8/19 9:17:55
第 17 章 文字渲染
摘要本章全面介绍了 VulkanSceneGraph 的vsg::text模块该模块已并入核心库采用 SDF有向距离场图集技术实现高质量文字渲染。主要内容包括核心类型Text、Font、TextGroup的功能与用法字体加载与文字创建流程Text::setup()的关键作用多段文字批量处理的TextGroup容器性能优化与裁剪注意事项以及完整的代码示例和常见问题解决方案。重点强调文字节点默认不带视锥剔除大场景中需使用CullNode或LOD进行装饰。本章定位叠加文字HUD、标注、调试信息需要高质量字形。vsg::text模块已并入核心非外部库用 SDF有向距离场图集渲染文字。17.1 本章目标认识vsg::text模块的核心类型Text/Font/TextGroup加载字体并创建一段文字理解Text::setup()的作用知道文字节点默认不带视锥剔除需要时用CullNode/LOD装饰。17.2 前置准备第 6 章场景图节点已读一个字体资源.ttf或预生成的字体图集。文本模块由 VSG 核心提供无需额外链接。17.3vsg::text模块构成类型说明Text文字节点继承Node渲染单段文字FontSDF 字形图集含atlas、glyphMetrics、charmapTextLayout文字布局位置/对齐/换行TextTechnique渲染后端CpuLayoutTechnique/GpuLayoutTechniqueTextGroup多段文字容器批量/实例化字形createTextShaderSet(options)生成文字专用ShaderSet⚠️vsg::text已并入核心仓库include/vsg/text/不要再去find_package(vsgText)。17.4Text的关键成员class Text : public InheritNode, Text { ref_ptrFont font; ref_ptrShaderSet shaderSet; ref_ptrTextTechnique technique; ref_ptrTextLayout layout; ref_ptrData text; // 字符数据stringValue / ushortArray / ... void setup(uint32_t minimumAllocation 0, ref_ptrconst Options options {}); };text是字符数据常用vsg::stringValue::create(Hello VSG)font是 SDF 字体图集setup()会创建真正的渲染后端technique必须在挂入场景图前调用。17.5 加载字体字体图集通过文本模块的读取器加载通常用vsg::read读取.ttf或预生成的字体资源auto font vsg::readvsg::Font(fonts/arial.ttf); if (!font) { std::cerr 字体加载失败\n; return 1; }字体资源具体格式取决于文本模块提供的读取器若你的资产是预生成的 SDF 字体图集直接用对应扩展名读取即可。生产环境推荐预生成图集以避免运行时栅格化开销。17.6 创建并渲染一段文字auto font vsg::readvsg::Font(fonts/arial.ttf); auto text vsg::Text::create(); text-font font; text-text vsg::stringValue::create(Hello, VulkanSceneGraph!); text-setup(); // 关键创建渲染后端technique // 用文本专用 ShaderSet可选也可复用 Options 中的 shaderSet[text] auto textShader vsg::createTextShaderSet(); // 让文字的 StateGroup 使用该 shaderSet见下方说明 root-addChild(text);Text默认带一个technique它内部已经把几何体/状态准备好若需要自定义管线可在setup()前给text-shaderSet赋值如createTextShaderSet(options)的结果。17.7TextGroup多段文字需要同时渲染多行/多块文字时用TextGroup把它们合成一组便于批量更新与实例化auto textGroup vsg::TextGroup::create(); textGroup-font font; textGroup-addChild(text1); textGroup-addChild(text2); textGroup-setup();17.8 性能与裁剪注意Text默认不带视锥剔除与 LOD头文件注释明确说明若文字出现在大场景中用CullNode/LOD装饰Text并在setup()后用technique-extents()设置包围体频繁变动的文字如 FPS每帧更新text数据即可setup()只在首次或字号/字体变化时调用。17.9 完整示例场景中央显示文字auto window vsg::Window::create(vsg::WindowTraits::create(800, 600, VSG Text)); auto viewer vsg::Viewer::create(); viewer-addWindow(window); auto font vsg::readvsg::Font(fonts/arial.ttf); auto label vsg::Text::create(); label-font font; label-text vsg::stringValue::create(VulkanSceneGraph); label-setup(); auto root vsg::Group::create(); root-addChild(label); auto camera vsg::Camera::create(); camera-projectionMatrix vsg::Orthographic::create(-1.0, 1.0, -1.0, 1.0, 0.0, 10.0); // 用正交投影做 2D HUD camera-viewMatrix vsg::LookAt::create(vsg::dvec3(0,0,1), vsg::dvec3(0,0,0), vsg::dvec3(0,1,0)); camera-viewportState vsg::ViewportState::create(window-extent2D()); auto commandGraph vsg::createCommandGraphForView(window, camera, root); viewer-assignRecordAndSubmitTaskAndPresentation({commandGraph}); auto cr viewer-compile(); updateViewer(viewer, cr); while (viewer-advanceToNextFrame()) { viewer-handleEvents(); viewer-update(); viewer-recordAndSubmit(); viewer-present(); }上例用正交相机把文字当 2D HUD 显示若要 3D 世界中漂浮的文字改用透视相机并把Text放进对应MatrixTransform。17.10 常见问题现象原因解决文字不显示没调用setup()或font为空挂入场景前调用text-setup()确认font已加载文字颜色无法自定义默认使用白色文字未设置自定义颜色在setup()前设置text-color属性或通过自定义ShaderSet传递颜色 uniform多语言字符如中文、日文显示为方块字体文件不包含对应字符的 glyph或字符编码不匹配使用包含目标字符集的字体文件如思源黑体并确保text数据使用正确的编码如 UTF-8编译报vsgText找不到误把 text 当外部库text 已并入核心直接#include vsg/text/Text.h文字被裁掉默认无视锥剔除或正交范围不对用CullNode装饰检查正交投影范围字体模糊SDF 图集分辨率不足用更高分辨率的预生成字体图集17.11 小结vsg::text已并入核心用 SDF 图集高质量渲染文字Text需设fonttext并在挂入前setup()字体经文本模块读取器加载多段文字用TextGroupText默认无视锥剔除大场景用CullNode/LOD装饰。17.12 延伸阅读与下一章预告第 22 章《ImGui 集成》另一种更灵活的 2D UI/调试面板方案第 6 章《场景图基础》CullNode/LOD装饰文字第 24 章《模型查看器》在查看器里叠加标注文字。