一、前言
利用着色器,实现模型的闪烁效果,实现原理是获取材质颜色和纹理颜色进行混合,利用sin函数产生[0,1]的值实现闪烁。
二、效果
三、环境
osg3.4,osgearth2.7,qt5.9.5,vs2015。
四、着色器代码
osg::ref_ptr<osg::Program> program = new osg::Program;
// 顶点着色器(增加纹理坐标传递)
program->addShader(new osg::Shader(osg::Shader::VERTEX,
"#version 120\n"
"varying vec2 v_texCoord;\n"
"varying vec4 v_vertexColor;\n"
"void main() {\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" v_vertexColor = gl_Color;\n"
" v_texCoord = gl_MultiTexCoord0.xy;\n" // 传递纹理坐标
"}"
));
// 片段着色器(采样纹理后混合)
program->addShader(new osg::Shader(osg::Shader::FRAGMENT,
"#version 120\n"
"varying vec2 v_texCoord;\n"
"varying vec4 v_vertexColor;\n"
"uniform sampler2D u_diffuseTexture;\n"
"uniform float u_damageIntensity;\n"
"uniform vec3 u_damageColor;\n"
"void main() {\n"
"vec4 baseColor;\n"
"// 优先级1:纹理颜色(如果存在有效纹理)\n"
"if (texture2D(u_diffuseTexture, v_texCoord).a > 0.0) {\n"
" baseColor = texture2D(u_diffuseTexture, v_texCoord);\n"
"}\n"
"// 优先级2:材质颜色(默认)\n"
"else {\n"
" baseColor = gl_FrontMaterial.diffuse;\n"
"}\n"
"\n"
"// 混合毁伤颜色\n"
"vec3 finalColor = mix(baseColor.rgb, u_damageColor, u_damageIntensity);\n"
"gl_FragColor = vec4(finalColor, baseColor.a);\n"
"}\n"
));
// 应用到模型
if (m_pModelNode) {
osg::StateSet* stateset = m_pModelNode->getOrCreateStateSet();
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
// 绑定原有纹理(假设在纹理单元0)
stateset->addUniform(new osg::Uniform("u_diffuseTexture", 0));
// 设置毁伤参数
stateset->addUniform(new osg::Uniform("u_damageColor", osg::Vec3(1, 0, 0)));
stateset->addUniform(new osg::Uniform("u_damageIntensity", m_fDamageIntensity));
}
五、在回调中更新
if (m_bIsShowDamageEffect) {//毁伤闪缩效果
osg::StateSet* stateset = m_pModelNode->getOrCreateStateSet();
osg::Uniform* intensityUniform = stateset->getUniform("u_damageIntensity");
intensityUniform->set((float)(0.5f + 0.5f * sin(osg::Timer::instance()->time_s() * 5)));
}
原创不易,记得点赞加关注哦,我会持续分享实用的功能(:-