Discussion:
[osg-users] Problem with output - OSG/Shader
Rômulo Cerqueira
2018-08-04 18:37:18 UTC
Permalink
Hi,

I would like to write the output/buffer of fragment shader to texture (RTT) as I wish (e.g. all red), however this result is depending of the model's shapes visible in the scene. How can I proceed with this correctly?

Follow below my minimal source code and the results.

Thanks in advance!

Expected:
[Image: Loading Image... ]

Current:
[Image: Loading Image... ]


Code:
#include <osg/TextureRectangle>
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PolygonMode>
#include <osg/Texture>
#include <osg/Camera>
#include <osgText/Text>

static const char *mrtVertSource = {
"#version 130\n"
"out vec3 worldNormal;\n"
"void main(void)\n"
"{\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" worldNormal = normalize(gl_NormalMatrix * gl_Normal);\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n"};

static const char *mrtFragSource = {
"#version 130\n"
"in vec3 worldNormal;\n"
"void main(void)\n"
"{\n"
" gl_FragData[0] = vec4(worldNormal, 0.0);\n"
"}\n"};

osg::Geode *createScreenQuad(float width, float height, float scale = 1.0f)
{
osg::Geometry *geom = osg::createTexturedQuadGeometry(
osg::Vec3(), osg::Vec3(width, 0.0f, 0.0f), osg::Vec3(0.0f, height, 0.0f),
0.0f, 0.0f, width * scale, height * scale);
osg::ref_ptr<osg::Geode> quad = new osg::Geode;
quad->addDrawable(geom);

int values = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED;
quad->getOrCreateStateSet()->setAttribute(
new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), values);
quad->getOrCreateStateSet()->setMode(GL_LIGHTING, values);
return quad.release();
}

osg::Camera *createRTTCamera(osg::Camera::BufferComponent buffer, osg::Texture *tex)
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setClearColor(osg::Vec4());
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setViewport(0, 0, tex->getTextureWidth(), tex->getTextureHeight());
camera->attach(buffer, tex);

return camera.release();
}

osg::Camera *createHUDCamera(double left, double right, double bottom, double top)
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setAllowEventFocus(false);
camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top));
camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
return camera.release();
}

osg::TextureRectangle *createFloatTexture(uint w, uint h)
{
osg::ref_ptr<osg::TextureRectangle> tex2D = new osg::TextureRectangle;
tex2D->setTextureSize(w, h);
tex2D->setInternalFormat(GL_RGB32F_ARB);
tex2D->setSourceFormat(GL_RGBA);
tex2D->setSourceType(GL_FLOAT);
tex2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
return tex2D.release();
}

int main(int argc, char **argv)
{
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("/home/romulo/Tools/OpenSceneGraph-Data/cow.osg");

unsigned int w = 800, h = 800;
osg::Texture *normalTex = createFloatTexture(w, h);

osg::ref_ptr<osg::Camera> rttCamera = createRTTCamera(osg::Camera::COLOR_BUFFER0, normalTex);
rttCamera->addChild(scene.get());

osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(new osg::Shader(osg::Shader::VERTEX, mrtVertSource));
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, mrtFragSource));
rttCamera->getOrCreateStateSet()->setAttributeAndModes(program.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
rttCamera->getOrCreateStateSet()->addUniform(new osg::Uniform("defaultTex", 0));

osg::ref_ptr<osg::Camera> hudCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0);
hudCamera->addChild(createScreenQuad(1.f, 1.0f, w));
hudCamera->getOrCreateStateSet()->setTextureAttributeAndModes(0, normalTex);

osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(rttCamera.get());
root->addChild(hudCamera.get());
root->addChild(scene.get());

osgViewer::Viewer viewer;
viewer.setUpViewInWindow(0, 0, w, h);
viewer.setSceneData(root.get());
return viewer.run();
}




RÃŽmulo

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74467#74467
Johny Canes
2018-08-05 11:40:00 UTC
Permalink
Hi,

It could be that maybe the black portion of the texture you are doing postproc on has the wrong alpha value... just a stab in the dark lol.

And why exactly would you want an all red scene?

Cheers,
Johny

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74469#74469
RÃŽmulo Cerqueira
2018-08-05 19:08:26 UTC
Permalink
Hi Johny,

I would like to draw what I want... the red was just an example.

My main goal is to simulate the reverberation phenomena using rasterization (for the first reflection) + ray tracing (for the second reflection). I would like to output the surface of reflected scenes, which are always not visible from the viewpoint.

...

Thank you!

Cheers,
Rômulo

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74470#74470
Johny Canes
2018-08-07 10:07:03 UTC
Permalink
Hi,

That makes zero sense to me. Can you show the glsl?

Thank you!

Cheers,
Johny

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74477#74477

Loading...