Re: [osg-users] blending with shader
yeah basically you want to use un-warped coordinates for your blending image, and warped coordinates for your scene image. If not you would have to warp your blending image, which may be easier for you depending on process. As per passing your texture width, you can use the function textureSize, that will get the dimensions of the image: https://www.opengl.org/sdk/docs/man4/html/textureSize.xhtml Do keep in mind, you need to set the version number in your shader to use this. In our case case we basically hard coded texture width as we generated the shader code with our blending image, as well as a few parameters for color correction and a few other other things. You can also query the size of your texture and do a text replace on your shader code before loading it. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69335#69335 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Hi David, thanks it works! Here are my vertex and fragment shaders: Code: varying vec2 texCoord; void main(void) { gl_Position = ftransform(); texCoord = gl_MultiTexCoord0.xy; } Code: uniform float width; uniform float height; uniform float gamma; uniform sampler2D sceneTexture; uniform sampler2D blendTexture; uniform sampler2D blackTexture; varying vec2 texCoord; void main(void) { vec4 sceneColor = texture2D(sceneTexture, texCoord); vec2 fragCoord = vec2(gl_FragCoord.x/width, gl_FragCoord.y/height); vec4 blendColor = texture2D(blendTexture, fragCoord); vec4 blackColor = texture2D(blackTexture, fragCoord); vec4 gammaVector = vec4(gamma, gamma, gamma, 1.0); gl_FragColor = pow(pow(sceneColor*blendColor, gammaVector) * (1.0 - pow(blackColor, gammaVector)) + pow(blackColor, gammaVector), 1.0/gammaVector); }; I had to use fragCoord for blending images because those images must not be distorted. Is that code correct? I mean, it works but maybe there is a cleaner way to implement that. In particulare, is there a way to avoid passing "width' and "height" variables to the shader? Regards, Gianni[/img] -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69332#69332 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
OK, I see it now. Taking a quick look at the code, it seems what you want to do is to add a vertex shader, and pass the texture coordinates from you Mesh, into your fragment shader. Then in your fragment shader use the texture coordinates in this line: "vec4 sceneColor = texture2D(sceneTexture, texCoord); \n" If you use the texCoord, texture coordinate for the sceneColor, its just going to pull the pixel from your first rendering pass from its space on the screen. The point of the warping mesh is it maps the pixel to a new place. You will still want to use texCoord to get the blending value. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69312#69312 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Hi David, you should find the complete code (including the shader) in the "osgdistortion.cpp" file I attached in a previous message. I modified the original OSG example to include the blending shader I used. If you download it and the "blending.png" image (attached to the same message) and modify the path properly inside the cpp file, you can have a full example. Thanks for your support, Gianni -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69311#69311 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Can you post your shader code? For testing you might try just rendering your texture coordinates for the scene texture, and the texture coordinates for your blending texture, they should be different. If you are still using this: " vec4 sceneColor = texture2D(sceneTexture, texCoord);\n" " vec4 blendingColor = texture2D(blendTexture, texCoord);\n" Using the screen space coordinate for your sceneColor, is basically going to have the affect of undoing the warping. You need a texture coordinate from your warping geometry. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69310#69310 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Hi All, I can apply blending to a texture rendered with a RTT camera from a shader but now I have a different problem. Before blending I have to apply a distortion to the scene because of a projection on a curved screen. Blending image is already distorted so I have to apply blending on an already distorted texture of the scene. I'm trying to implement distortion/warping moving texcoords of a Geometry node (i.e. geometry->setTexCoordArray(0, tcoords);). That geometry is a grid where the texture, that comes from RTT camera, is applied. Here is the code to attach the blending shader to the Geometry/Geode: Code: void addShader(osg::Geode* node, double width, double height) { osg::StateSet * stateset = node->getOrCreateStateSet(); osg::Program * program = new osg::Program; stateset->setAttribute(program); addFragmentShader(program, blendingShaderFilePath); stateset->addUniform(new osg::Uniform("width", (float)width)); stateset->addUniform(new osg::Uniform("height", (float)height)); stateset->addUniform(new osg::Uniform("gamma", gamma)); stateset->addUniform(new osg::Uniform("eye", osg::Vec3(0.0f, 0.0f, 0.0f))); osg::ref_ptr< osg::Image> blendingImage = osgDB::readImageFile(blendingImagePath); osg::Texture2D* blendingTexture = new osg::Texture2D(blendingImage.get()); blendingTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); blendingTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); stateset->setTextureAttribute(1, blendingTexture); stateset->addUniform(new osg::Uniform("blendTexture", 1)); } The problem is that I can just see the blended image, while distortion is lost. How could I make distortion/warping live together with blending? Regards, Gianni -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69297#69297 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Thanks for the explanations. d_a_heitbrink wrote: > > As per the inout, this states the parameter into the function is both an > input and an output. I set the version for my shader to something like 4.5 in > compatibility mode. The function was called last in my shader. > I was just asking how do you get the value of color parameter passed to the function not the meaning of "inout" (I already read that from documentation ;)) Regards, Gianni -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68969#68969 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
The function I posted was similar to a function I called from my shader I ran in my final pass. What you have is functionally the similar. As per the inout, this states the parameter into the function is both an input and an output. I set the version for my shader to something like 4.5 in compatibility mode. The function was called last in my shader. https://www.opengl.org/wiki/Core_Language_(GLSL) As per your program I think you were are getting into trouble is here: vec2 texCoord = vec2(gl_FragCoord.x/width, gl_FragCoord.y/height); vec4 sceneColor = texture2D(sceneTexture, texCoord); vec4 blendingColor = texture2D(blendTexture, texCoord); Your texCoord, is basically the location on your display device. This is what you want to use to lookup your blending value. But you will want to use a separate coordinate for your scene color. You basically need the texture coordinate from your warping geometry. As per not setting a uniform for the sampler if I remember which I might be totally wrong about, the value of the uniform is going to default to 0, which in this case will default to texture unit 0, if the uniform is never set. Also with texture attribute 0, I assume that's being used for your scene texture. So your scene texture and your blending texture must use different texture units. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68966#68966 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
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" "}\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. Then, just like the osgdistortion example, I have the following OSG node structure: Code: 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: Code: void OsgPlugin::addShader(osg::Geode* node) { osg::StateSet * stateset = node->getOrCreateStateSet(); osg::Program * program = new osg::Program; stateset->setAttribute(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, Gianni -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68949#68949 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Taking a quick look at the code, yes it seems like it is a good example. So basically taking a quick read of this, you render your scene to a texture, then render a dome basically setup to do your warping, with the results from the render to texture, as its texture. You basically want to attach your blending shader to this 2nd rendering pass where you render the dome. You might also look at osg::viewer::PanoramicSphericalDisplay. Also a quick tip when you do the render to texture, you need to set the multisampleSamples, and multisampleColorSamples, this basically sets your anti-aliasing. At least the last time I checked, the over-ride program settings for most graphics drivers do not effect render to texture rendering. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68884#68884 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Hi, do ypu think the osgdistortion example is a good starting point to create the proper osg structure to render the scent into a texture? Cheers, Gianni -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68881#68881 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
You should be able to grab the state set in the pre-render callback and bind your image for blending + add any uniforms you need there. You will want to pick a texture level that you are not going to use rendering your scene. You will also need to bind your shader the the scene as well. One thing you might consider if you are using a NVidia Quardro card, is they do have API for warping and blending which will work at the driver level, so you will not make any coding changes with your application to use it: http://on-demand.gputechconf.com/gtc/2012/presentations/S0322-Warping-Blending-for-Multi-Display-Systems.pdf I think ATI has something similar for there professional cards as well but I am not familiar with them. One thing you will likely run into problems with if you do not use a professional card is dealing with sync. From past experience we have had two identical displays attached to the same video card not run at the same, and have had different vertical syncs on each display. Having the vertical syncs different on each display can lead to tear lines in your blend regions. Also there a few companies like Scalable Display (Http://www.scalabledisplay.com/) that have warping + blending software. What I have done for warping and blending is to write my own Shader for doing blending, and then to use the API I mentioned above for the warping. We did our own blending to deal with the gamma curve for the projectors. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68839#68839 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] blending with shader
Its kind of tough to say without having a good idea about what exactly you can do with your plugin. I can say what you most likely need to do is to bind a texture with your blend map to your scene some how. Ideally you would do this in a 2nd rendering pass. Basically you want to perform blending on a final image. In your fragment shader you can use gl_FragCoord, this will get you the screen coordinate of the current fragment (basically pixel). Then you can use texelFetch to lookup a scaler for your output pixel. For example if you had this function you called last in your fragment shader: uniform sampler2D blendTexture; void BlendFunct(inout vec4 color){ vec4 blendVal = texalFetch(blendTexture,gl_FragCoord.xy,0); color.rgb = color.rgb * blendVal.rgbl; } In practical terms you often have to deal with the gamma settings for your projectors, and things are not always linear. When you have things in your scene with transparency were things get blended together, its ideal to do a multi-pass rendering. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68835#68835 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org