[osg-users] blending with shader

Gianni Ambrosio g.ambrosio+osg at gmail.com
Mon Oct 10 07:57:05 PDT 2016

Hi David,
I'm not able to use the BlendFunct you posted but it seems I can get something nice with the following (fragment) shader:

char myBlendingProgram[] =
"uniform float width;\n"
"uniform float height;\n"
"uniform sampler2D sceneTexture;\n"
"uniform sampler2D blendTexture;\n"
"void main(void) {\n"
"	vec2 texCoord = vec2(gl_FragCoord.x/width, gl_FragCoord.y/height);\n"
"	vec4 sceneColor = texture2D(sceneTexture, texCoord);\n"
"	vec4 blendingColor = texture2D(blendTexture, texCoord);\n"
"	gl_FragColor = sceneColor * blendingColor;\n"

Anyway I have some questions.

In your BlendFunct I don't know how you get the "inout vec4 color" parameter. I guess it's something like "sceneColor" in my shader. But I would like to know the proper way you suggest to get it.

just like the osgdistortion example, I have the following OSG node structure:

root (osg::Group)
+--- renderToTextureCamera (osg::Camera)
|      +--- (Scene)
+--- hudCamera(osg::Camera)
       +--- geode (osg::Geode)
              +--- geometry (osg::Geometry)

To the renderToTextureCamera I call:
camera->attach(osg::Camera::COLOR_BUFFER, texture);

While I attach the texture to the geometry with the code:
osg::StateSet* stateset = geometry->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute:: ON);
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

And I attach the shader to the Geode node.

Is it correct to attach the shader to the geode?

Anyway, here is the code I use to attach the shader and related uniforms to the geode stateset:

void OsgPlugin::addShader(osg::Geode* node)
	osg::StateSet * stateset = node->getOrCreateStateSet();

	osg::Program * program = new osg::Program;
	program->addShader(new osg::Shader(osg::Shader::FRAGMENT, myBlendingProgram));

	stateset->addUniform(new osg::Uniform("width", (float)1280.0));
	stateset->addUniform(new osg::Uniform("height", (float)720.0));

	osg::ref_ptr< osg::Image> blendingImage = osgDB::readImageFile("C:/Users/User/Desktop/temp/blending.png");
	osg::Texture2D* texture = new osg::Texture2D(blendingImage.get());
	texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
	texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);

	stateset->setTextureAttribute(1, texture);
	stateset->addUniform(new osg::Uniform("blendTexture", 1));

One note: I have to use 1 as first parameter of setTextureAttribute to make my example working (with 0 it didn't work).
On the other hand I was surprised to have a valid sceneTexture in my shader without setting it on the stateset of the geode nor adding a uniform for it! Can you exaplain me why? I can suppose the TextureAttribute can be inherited from the stateset of the related geometry but I can't understand why the uniform is not needed.

Moreover, the "sceneTexture" variable I get in the shader is not distorted. In fact I used the same code of osgdistortion exampe for the moment where a sort of distortion is implemented on the geometry.
If I remove the shader I can correctly see the distortion. Can you explain me why please?

I have one more question (problem to solve) but I think that's enough for the moment.

Best regards,

Read this topic online here:

More information about the osg-users mailing list