[osg-users] Why does the computeshaderblur program not display properly?

OpenSceneGraph Users osg-users at lists.openscenegraph.org
Thu Jun 18 22:27:24 PDT 2020


/* -*-c++-*- OpenSceneGraph example, osgcomputeshaders.
*
*  Permission is hereby granted, free of charge, to any person obtaining a 
copy
*  of this software and associated documentation files (the "Software"), to 
deal
*  in the Software without restriction, including without limitation the 
rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

// Written by Wang Rui
// This example can work only if GL version is 4.3 or greater

#include <osg/Texture2D>
#include <osg/BindImageTexture>
#include <osg/DispatchCompute>
#include <osg/Geode>
#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

static const char* computeSrc = {
"#version 430\n"
"precision highp float;\n"
"precision highp int;\n"
    "layout (rgba32f, binding =0) highp uniform image2D uImageIn;\n"
"layout (rgba32f, binding =1) highp uniform image2D uImageOut;\n"
    "layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;\n"
    "void main() {\n"
" ivec2 id   = ivec2(gl_GlobalInvocationID.xy);        \n"
" ivec2 size = imageSize(uImageOut); \n"
" if (id.x >= size.x || id.y >= size.y) { \n"
" return; \n"
" } \n"
"   const int uSigma = 15;\n"
" // 0.9544 \n"
" int kernel   = int(ceil(2.0 * uSigma)); \n"
" \n"
" vec4 pixel = vec4(0.0); \n"
" float coef = 0.0; \n"
" for (int dx = -kernel; dx <= kernel; dx++) { \n"
" for (int dy = -kernel; dy <= kernel; dy++) { \n"
" int x = id.x + dx; \n"
" int y = id.y + dy; \n"
" if (x < 0 || x >= size.x || \n"
" y < 0 || y >= size.y) { \n"
" continue; \n"
" } \n"
" float c = exp(-float(dx * dx + dy * dy) / (2.0 * uSigma * uSigma + 1e-5)); 
\n"
" pixel += (imageLoad(uImageIn, ivec2(x, y)) * c); \n"
" coef  += c; \n"
" } \n"
" } \n"
" imageStore(uImageOut, id, pixel / (coef + 1e-5)); \n"
    "}\n"
};

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments( &argc, argv );

    // Create the texture as both the output of compute shader and the 
input of a normal quad
    osg::ref_ptr<osg::Texture2D> tex2D = new osg::Texture2D;
osg::Image* pImage = osgDB::readImageFile("Images/man.png");
pImage->setDataVariance(osg::Object::DYNAMIC);
tex2D->setImage(pImage);
    tex2D->setTextureSize( 512, 512 );
    tex2D->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
    tex2D->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
tex2D->setInternalFormat(GL_RGBA32F_ARB);
tex2D->setSourceFormat(GL_RGBA);
    tex2D->setSourceType( GL_FLOAT );
    // So we can use 'image2D' in the compute shader
    osg::ref_ptr<osg::BindImageTexture> imagbinding = new 
osg::BindImageTexture(0, tex2D.get(), osg::BindImageTexture::READ_WRITE, 
GL_RGBA32F_ARB);
    
osg::ref_ptr<osg::Texture2D> tex2D2 = new osg::Texture2D;
tex2D2->setTextureSize(512, 512);
tex2D2->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex2D2->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
tex2D2->setInternalFormat(GL_RGBA32F_ARB);
tex2D2->setSourceFormat(GL_RGBA);
tex2D2->setSourceType(GL_FLOAT);
// So we can use 'image2D' in the compute shader
osg::ref_ptr<osg::BindImageTexture> imagbinding2 = new 
osg::BindImageTexture(0, tex2D2.get(), osg::BindImageTexture::READ_WRITE, 
GL_RGBA32F_ARB);

// The compute shader can't work with other kinds of shaders
    // It also requires the work group numbers. Setting them to 0 will 
disable the compute shader
    osg::ref_ptr<osg::Program> computeProg = new osg::Program;
    computeProg->addShader( new osg::Shader(osg::Shader::COMPUTE, 
computeSrc) );

    // Create a node for outputting to the texture.
    // It is OK to have just an empty node here, but seems inbuilt uniforms 
like osg_FrameTime won't work then.
    // TODO: maybe we can have a custom drawable which also will implement 
glMemoryBarrier?
    osg::ref_ptr<osg::Node> sourceNode = new osg::DispatchCompute(512/16, 
512/16, 1 );
    sourceNode->setDataVariance( osg::Object::DYNAMIC );
    sourceNode->getOrCreateStateSet()->setAttributeAndModes( 
computeProg.get() );
    sourceNode->getOrCreateStateSet()->addUniform( new 
osg::Uniform("uImageIn", (int)0) );
    sourceNode->getOrCreateStateSet()->setTextureAttributeAndModes(0, 
tex2D.get() );
sourceNode->getOrCreateStateSet()->addUniform(new osg::Uniform("uImageOut", 
(int)1));
sourceNode->getOrCreateStateSet()->setTextureAttributeAndModes(1, 
tex2D2.get());

    // Display the texture on a quad. We will also be able to operate on 
the data if reading back to CPU side
    osg::Geometry* geom = osg::createTexturedQuadGeometry(
        osg::Vec3(), osg::Vec3(1.0f,0.0f,0.0f), osg::Vec3(0.0f,0.0f,1.0f) );
    osg::ref_ptr<osg::Geode> quad = new osg::Geode;
    quad->addDrawable( geom );
    quad->getOrCreateStateSet()->setMode( GL_LIGHTING, 
osg::StateAttribute::OFF );
    quad->getOrCreateStateSet()->setTextureAttributeAndModes( 0, 
tex2D2.get() );
    quad->getOrCreateStateSet()->setAttributeAndModes(imagbinding2.get());
    // Create the scene graph and start the viewer
    osg::ref_ptr<osg::Group> scene = new osg::Group;
    scene->addChild( sourceNode );
    scene->addChild( quad.get() );

    osgViewer::Viewer viewer;
    viewer.addEventHandler( new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
    viewer.addEventHandler( new osgViewer::StatsHandler );
    viewer.addEventHandler( new osgViewer::WindowSizeHandler );
    viewer.setSceneData( scene.get() );
    return viewer.run();
}



-- 
You received this message because you are subscribed to the Google Groups "OpenSceneGraph Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osg-users+unsubscribe at googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osg-users/f560c951-678e-4b67-b7bb-e4c4569207cco%40googlegroups.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20200618/2bd18197/attachment.html>


More information about the osg-users mailing list