【OSG学习笔记】Day 63: Cartoon(卡通渲染)
·

卡通渲染特效 osgFX::Cartoon
在三维图形渲染领域,除了追求逼真的真实感渲染外,非真实感渲染(NPR) 也有着广泛的应用场景,卡通渲染(Cel-Shading)就是其中最具代表性的技术之一。
OpenSceneGraph(OSG)作为成熟的三维图形引擎,通过内置的 osgFX::Cartoon 类封装了完整的卡通渲染功能,无需手动编写复杂的着色器代码,即可快速为三维模型实现卡通风格的渲染效果。
本文将全面介绍 osgFX::Cartoon 类的核心特性、继承关系、关键接口,并提供完整可运行的实战代码,带你从零掌握 OSG 卡通渲染的实现。
osgFX::Cartoon 核心特性
osgFX::Cartoon 是 OSG 特效库中专门用于实现卡通渲染的核心类,它具备以下关键特性:
- 双通道渲染:采用两个渲染通道完成效果,第一个通道绘制模型实体表面,实现块状化的卡通光照效果;第二个通道绘制模型轮廓线,勾勒出卡通画特有的边缘线条。
- GPU 着色器支持:依赖 OpenGL 顶点着色器处理纹理坐标与光照计算,需要硬件支持 ARB_vertex_program 扩展或 GLSL 着色语言,保证渲染效率。
- 高度可定制:支持自定义轮廓线颜色、线宽,可配置光照数量,灵活调整卡通渲染的视觉效果。
- 节点式集成:作为 OSG 场景树节点使用,可直接挂载任意模型节点,无缝接入 OSG 渲染流程。
类继承关系
osgFX::Cartoon 并非独立存在,而是遵循 OSG 严谨的类继承体系,其完整继承关系如下:
osg::Object
└── osg::BaseNode
└── osg::Node <--- 这里!它最终继承自 Node!
└── osg::Group
└── osgFX::Effect
└── osgFX::Cartoon
osgFX::Cartoon 核心接口
在使用该类前,我们先了解最常用的几个成员函数,这是实现自定义卡通效果的关键:
| 函数接口 | 功能说明 |
|---|---|
setOutlineColor(const osg::Vec4& color) |
设置轮廓线颜色,参数为 RGBA 四维向量(取值 0.0~1.0) |
getOutlineColor() const |
获取当前轮廓线颜色 |
setOutlineLineWidth(float width) |
设置轮廓线宽度(单位:像素) |
getOutlineLineWidth() const |
获取当前轮廓线宽度 |
setLightNumber(int num) |
设置参与渲染的光源数量,0 表示关闭光照,纯卡通平涂效果 |
完整实战代码
以下代码实现加载 cessna 飞机模型 + 卡通渲染,包含完整的注释,可直接编译运行:
1. 主程序代码(main.cpp)
// 包含OSG核心头文件
#include <osgDB/ReadFile> // 模型文件读取
#include <osgViewer/Viewer> // OSG视图器,负责窗口管理与渲染
#include <osgFX/Cartoon> // 卡通渲染特效头文件
#include <osgUtil/Optimizer> // 场景优化工具
#include <osg/Group> // 场景组节点,用于管理子节点
#include <iostream> // 控制台输出
// 主函数
int main()
{
// ===================== 1. 初始化渲染窗口 =====================
// 创建OSG视图器对象,自动管理窗口、相机、渲染循环
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
// ===================== 2. 创建场景根节点 =====================
// 创建组节点,作为整个场景的根节点,统一管理所有子对象
osg::ref_ptr<osg::Group> root = new osg::Group;
// ===================== 3. 加载三维模型 =====================
// 读取cessna.osg模型(OSG官方示例模型,需放在程序运行目录)
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg");
// 判断模型是否加载成功
if (!model)
{
std::cerr << "错误:无法加载模型文件 cessna.osg,请检查文件路径!" << std::endl;
return -1;
}
// ===================== 4. 创建并配置卡通特效 =====================
// 实例化卡通渲染特效节点
osg::ref_ptr<osgFX::Cartoon> cartoonEffect = new osgFX::Cartoon;
// 设置轮廓线颜色:黑色 (R=0, G=0, B=0, A=1)
cartoonEffect->setOutlineColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
// 设置轮廓线宽度:2像素
cartoonEffect->setOutlineLineWidth(2.0f);
// 设置光源数量:0,关闭光照,实现纯卡通平涂效果
cartoonEffect->setLightNumber(0);
// ===================== 5. 构建场景树 =====================
// 将模型添加到卡通特效节点中(特效作用于该模型)
cartoonEffect->addChild(model);
// 将卡通特效节点添加到场景根节点
root->addChild(cartoonEffect);
// ===================== 6. 优化场景(提升渲染效率) =====================
osgUtil::Optimizer optimizer;
optimizer.optimize(root);
// ===================== 7. 启动渲染循环 =====================
// 为视图器设置场景数据
viewer->setSceneData(root);
// 初始化窗口、相机等渲染资源
viewer->realize();
// 启动渲染循环,直到关闭窗口
return viewer->run();
}

代码解析
我们将代码分为初始化、模型加载、特效配置、场景构建、渲染启动五大模块,逐行解析:
模块1:渲染窗口初始化
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr:OSG 智能指针,自动管理内存,防止内存泄漏。osgViewer::Viewer:OSG 核心视图类,封装了窗口创建、相机控制、渲染循环、交互事件等所有基础功能。
模块2:场景根节点创建
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::Group:组节点,是 OSG 场景树的核心容器,可挂载模型、特效、相机等所有子节点,统一管理场景结构。
模块3:模型加载
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg");
osgDB::readNodeFile:OSG 文件读取工具,支持.osg、.obj、.fbx等主流三维模型格式。- 异常判断:如果文件路径错误或文件损坏,会输出错误信息并退出程序,保证程序健壮性。
模块4:卡通特效核心配置
osg::ref_ptr<osgFX::Cartoon> cartoonEffect = new osgFX::Cartoon;
- 实例化卡通特效节点,这是实现卡通渲染的核心对象。
cartoonEffect->setOutlineColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
- 设置轮廓线为黑色,如果设置为白色(1,1,1,1),在默认白色背景下会无法显示轮廓,这是新手最容易踩的坑。
cartoonEffect->setOutlineLineWidth(2.0f);
- 轮廓线宽度设为 2 像素,粗细适中,视觉效果最佳。
cartoonEffect->setLightNumber(0);
- 关闭光照,让模型呈现纯平面卡通效果;如果设置为 1,会保留基础光照,增加立体感。
模块5:场景树构建
cartoonEffect->addChild(model);
root->addChild(cartoonEffect);
- OSG 场景树遵循父子节点结构:模型 → 卡通特效节点 → 根节点。
- 渲染时,特效节点会自动作用于其子节点(模型),实现卡通渲染。
模块6:场景优化
osgUtil::Optimizer optimizer;
optimizer.optimize(root);
- OSG 内置优化工具,对场景进行几何体合并、状态优化等操作,大幅提升渲染效率。
模块7:渲染启动
viewer->setSceneData(root);
viewer->realize();
return viewer->run();
setSceneData:为视图器绑定场景根节点,告诉引擎需要渲染的内容。realize:初始化 OpenGL 上下文、窗口、相机等底层渲染资源。run:启动无限渲染循环,直到用户关闭窗口,程序退出。
总结
osgFX::Cartoon 是 OSG 中实现卡通渲染的极简方案,它依托 OSG 成熟的继承体系和渲染架构,将复杂的双通道渲染、GPU 着色器逻辑完全封装,开发者只需几行代码即可实现专业的卡通效果。

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)