OSG 使用整理(5):模板测试与边缘效果

osg 使用整理 (5):模板测试与边缘效果

1 模板测试

​ 在渲染管线中,模板测试在片段着色器后执行,通过像素与模板缓冲中的模板值比较,选择性丢弃或者保存这个像素颜色。我们可以通过更新模板测试来获得一些很有意思的效果。下图为LearnOpenGL网站一个例子。

​ 可以发现,颜色缓冲经过模板测试后,只保留了模板值为1的像素颜色。

​ 使用模板缓冲通常的流程:

a 开启模板测试

glEnable(GL_STENCIL_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

b 设置模板测试函数,决定如何使用模板缓冲丢弃片段

glStencilMask(0xFF); // 每一位写入模板缓冲时都保持原样
glStencilMask(0x00); // 每一位在写入模板缓冲时都会变成0(禁用写入)
/* brief:模板缓冲测试函数
para[in]: func 测试规则
para[in]: ref 模板测试参考值
para[in]: mask 掩码
*/
glStencilFunc(GLenum func, GLint ref, GLuint mask)
函数 描述
GL_ALWAYS 永远通过深度测试
GL_NEVER 永远不通过深度测试
GL_LESS 在片段深度值小于缓冲的深度值时通过测试
GL_EQUAL 在片段深度值等于缓冲区的深度值时通过测试
GL_LEQUAL 在片段深度值小于等于缓冲区的深度值时通过测试
GL_GREATER 在片段深度值大于缓冲区的深度值时通过测试
GL_NOTEQUAL 在片段深度值不等于缓冲区的深度值时通过测试
GL_GEQUAL 在片段深度值大于等于缓冲区的深度值时通过测试


c 渲染模型,更新模板缓冲,更新函数为

/* brief:模板缓冲更新函数
para[in]: sfail 模板测试失败时采取的行为
para[in]: dpfail 模板测试通过,但深度测试失败时采取的行为
para[in]: sfail 模板测试和深度测试都通过时采取的行为
*/
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
行为 描述
GL_KEEP 保持当前储存的模板值
GL_ZERO 将模板值设置为0
GL_REPLACE 将模板值设置为glStencilFunc函数设置的ref
GL_INCR 如果模板值小于最大值则将模板值加1
GL_INCR_WRAP 与GL_INCR一样,但如果模板值超过了最大值则归零
GL_DECR 如果模板值大于最小值则将模板值减1
GL_DECR_WRAP 与GL_DECR一样,但如果模板值小于0则将其设置为最大值
GL_INVERT 按位翻转当前的模板缓冲值

2 osg::Effect 后处理效果类

​ osg::Effect类如作者所述,用于实现特殊的渲染效果,其派生包括散射光,亮光,卡通等。它是一系列属性状态stateset的集合,允许采用多个osg::technique封装渲染状态,不同technique可以使用不同的渲染上下文。在使用时,只需要创建所需effect实例,然后添加到场景树中,最后把这个effect要影响的模型节点挂载到effect节点上。要创建自定义渲染效果类,可以继承osg::Effect类,然后重写 define_techniques方法,其中可以使用自定义的technique类,添加technique的顺序十分关键。
​ 勾勒对象的轮廓是用于在游戏,多媒体与工业应用表示特殊效果的实践技术。OpenGL的一个实现是在stencil buffer中写入固定值,然后使用细边线渲染对象。在两遍渲染过程之后,对像周围的轮廓就会显示出来。幸运的是,该效果已经由osgFX库中的osgFX::Effect的派生类osgFX::Outline类实现了。下面是使用示例。

#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgFX/Outline>
#include <osgViewer/Viewer>
void main()
{
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile( "cessna.osg" );
osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
outline->setWidth( 8 );
outline->setColor( osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) );
outline->addChild( model.get() );
osg::DisplaySettings::instance()->setMinimumNumStencilBits( 1 );
osgViewer::Viewer viewer;
viewer.getCamera()->setClearMask(
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
viewer.setSceneData( outline.get() );
return viewer.run();
}
posted @   王小于的啦  阅读(377)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示