Nivdia stuff.

:-) tangent and depth maps are no in first texture

missing
(1) fovy / ratio (x,y) one step == meters
(2) radian insteat of box (squre)

but this will become nie

2008/12/19 yann le paih <lepaih.y...@gmail.com>

> Third step could be to implement this new paper : SSDO (Approximating
> Dynamic Global Illumination in Image Space)
>
> http://www.uni-koblenz.de/~ritschel/<http://www.uni-koblenz.de/%7Eritschel/>
>
>
>
>
>
> On Fri, Dec 19, 2008 at 11:45 AM, Raymond de Vries <ree...@xs4all.nl>wrote:
>
>> Hi Adrian,
>>
>> Thnx for the info, cool that it's already implemented in Blender :-)
>>
>> Cheers, have fun.
>>
>> Raymond
>>
>>
>> Adrian Egli OpenSceneGraph (3D) wrote:
>>
>>> Starting point of this first version is this very simple algorithm:
>>> http://mikepan.homeip.net/ssaowcn
>>>
>>> once this will perfectly work, then we can implementing a more complex
>>> one.
>>>
>>> there are many diferent papers describing how we can implementing high
>>> quality SSAO
>>>
>>> /adrian
>>>
>>> 2008/12/18 Raymond de Vries <ree...@xs4all.nl <mailto:ree...@xs4all.nl>>
>>>
>>>
>>>    Hi Adrian,
>>>
>>>    This looks very nice! Could you give a little more background
>>>    info? Did you use the nvidia paper as starting point? E.g. I am
>>>    curious if this technique is applicable for large outdoor
>>>    environments.
>>>
>>>    Thanks a lot
>>>    Raymond
>>>
>>>
>>>
>>>    Adrian Egli OpenSceneGraph (3D) wrote:
>>>
>>>        Hi Robert,
>>>
>>>        i implement a first version of SSAO effect and i have only one
>>>        issue left in the implementation. the whole thing works nicely
>>>        with GLSL shader, mutlipass-rendering when we don't resize the
>>>        window, actually 512x512. so
>>>        what sould i do, to replace this issue. ?
>>>
>>>        Another thing is to remove the last pass GLSL shader, is there
>>>        a way to solve it under common openGL textureing?
>>>        Mutlitextureing? Or any other idea.
>>>
>>>        This version supports:
>>>
>>>        (Transparant faces: just disable for transparent faces like
>>>        window, glass the detph writing, the depth buffer will hold
>>>        only un-transparent z-values (alpha > 0.9) )
>>>
>>>        toggle ssao on/off with key 'a'
>>>
>>>        have a look and i will be happy to get any ideas to improve
>>>        the stuff.
>>>        FPS is about 30.
>>>
>>>        /adrian
>>>        --        ********************************************
>>>        Adrian Egli
>>>
>>>  ------------------------------------------------------------------------
>>>
>>>        _______________________________________________
>>>        osg-users mailing list
>>>        osg-users@lists.openscenegraph.org
>>>        <mailto:osg-users@lists.openscenegraph.org>
>>>
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>
>>>
>>>    _______________________________________________
>>>    osg-users mailing list
>>>    osg-users@lists.openscenegraph.org
>>>    <mailto:osg-users@lists.openscenegraph.org>
>>>
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>
>>>
>>>
>>>
>>> --
>>> ********************************************
>>> Adrian Egli
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> osg-users mailing list
>>> osg-users@lists.openscenegraph.org
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>
>>>
>>
>> _______________________________________________
>> osg-users mailing list
>> osg-users@lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
>
>
>
> --
> Yann Le Paih
> Keraudrono
> 56150 BAUD
> Portable: +33(0)610524356
> lepaih.y...@gmail.com
>
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>


-- 
********************************************
Adrian Egli
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
*
* This application is open source and may be redistributed and/or modified   
* freely and without restriction, both in commericial and non commericial 
applications,
* as long as this copyright notice is maintained.
* 
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Uniform>

#include <osgText/Text>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/BlendFunc>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>

#include <osgFX/Effect>
#include <osgFX/Technique>
#include <osgFX/Registry>

#include <osg/TexGen>
#include <osg/Texture2D>

#include <osg/PolygonOffset>
#include <osgDB/WriteFile>





struct WriteCameraPostDrawCallback : public osg::Camera::DrawCallback
{
        WriteCameraPostDrawCallback(osg::Image* image,std::string filename, 
bool write):
_image(image),
_filename(filename),
_write(write)
{
        char* write_file = getenv("DEBUG");
        if ( write_file ) _write = true;
}

virtual void operator () (const osg::Camera& /*camera*/) const
{

        _image->dirty();

        if ( _write ) {
                std::cout << "write " << _filename << std::endl;
                osgDB::writeImageFile(*(_image.get()),_filename);
        }

}

osg::ref_ptr<osg::Image> _image;
std::string _filename;
bool _write;
};


namespace osgFX {
        class SSAO : public Effect {
        public:
                SSAO() {};
                SSAO(osg::Group*);
                SSAO(const SSAO& copy, const osg::CopyOp& copyop = 
osg::CopyOp::SHALLOW_COPY);

                META_Effect(osgFX, SSAO, 

                        "Screen Space Ambient Occlusion", 

                        "SSAO : test implementation", 

                        "Adrian Egli");
        protected:
                virtual ~SSAO() {}
                SSAO& operator=(const SSAO&) { return *this; }

                bool define_techniques();

                osg::ref_ptr<osg::Group> _root;
        };

}



using namespace osgFX;


namespace
{


        osg::Node* createBase(osg::Texture2D* texture ,osg::Texture2D* 
texture2=NULL )
        {

                osg::ref_ptr<osg::Geode> geode = new osg::Geode;

                // set up the texture of the base.
                osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
                
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
                if 
(texture2)stateset->setTextureAttributeAndModes(1,texture2,osg::StateAttribute::ON);
                geode->setStateSet( stateset.get() );


                osg::ref_ptr<osg::HeightField> grid = new osg::HeightField;
                grid->allocate(2,2);
                grid->setOrigin(osg::Vec3(0.0,0.0,0.0));
                grid->setXInterval(1.0);
                grid->setYInterval(1.0);

                grid->setHeight(0,0,-1.0);
                grid->setHeight(0,1,-1.0);
                grid->setHeight(1,1,-1.0);
                grid->setHeight(1,0,-1.0);

                geode->addDrawable(new osg::ShapeDrawable(grid.get()));

                osg::Group* group = new osg::Group;
                group->addChild(geode.get());

                return group;

        }

        Registry::Proxy proxy(new SSAO);

        class DefaultTechnique: public Technique {
        public:

                DefaultTechnique(osg::Group* scene,osg::Group* ssaoFX) :    
                  Technique(),
                          _scene(scene)
                  {

                          // texture resolution 
                          _RTTInfoDepth._resolution_x = 512;
                          _RTTInfoDepth._resolution_y = 512;


                          // texture
                          _RTTInfoDepth._texture = new osg::Texture2D;
                          
_RTTInfoDepth._texture->setTextureSize(_RTTInfoDepth._resolution_x, 
_RTTInfoDepth._resolution_y);
                          _RTTInfoDepth._texture->setInternalFormat(GL_RGBA);
                          
_RTTInfoDepth._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoDepth._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoDepth._camera = new osg::Camera;
                          
_RTTInfoDepth._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoDepth._camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoDepth._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoDepth._camera->setViewport(0,0,_RTTInfoDepth._resolution_x,_RTTInfoDepth._resolution_y);
                          // set the camera to render before the main camera.
                          
_RTTInfoDepth._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoDepth._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoDepth._image=new osg::Image;
                          
_RTTInfoDepth._image->allocateImage(_RTTInfoDepth._resolution_x, 
_RTTInfoDepth._resolution_y,  1, GL_RGBA, GL_UNSIGNED_BYTE);
                          
_RTTInfoDepth._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoDepth._image.get(),0,0);
                          _RTTInfoDepth._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoDepth._image.get(),"RTTInfoDepth.png",false));
                          
_RTTInfoDepth._texture->setImage(0,_RTTInfoDepth._image.get());
                          // add subgraph to render
                          _RTTInfoDepth._camera->addChild(_scene.get());




                          
////////////////////////////////////////////////////////////////////////// SSAO 
difference
                          // texture resolution 
                          _RTTInfoSSAO._resolution_x = 512;
                          _RTTInfoSSAO._resolution_y = 512;

                          // texture
                          _RTTInfoSSAO._texture = new osg::Texture2D;
                          
_RTTInfoSSAO._texture->setTextureSize(_RTTInfoSSAO._resolution_x, 
_RTTInfoSSAO._resolution_y);
                          _RTTInfoSSAO._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoSSAO._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoSSAO._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoSSAO._camera = new osg::Camera;
                          
_RTTInfoSSAO._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoSSAO._camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoSSAO._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoSSAO._camera->setViewport(0,0,_RTTInfoSSAO._resolution_x,_RTTInfoSSAO._resolution_y);
                          
_RTTInfoSSAO._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1),osg::Vec3(0.5,0.5,0),osg::Vec3(0,1,0));
                          
_RTTInfoSSAO._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);

                          // set the camera to render before the main camera.
                          
_RTTInfoSSAO._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoSSAO._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoSSAO._image=new osg::Image;
                          
_RTTInfoSSAO._image->allocateImage(_RTTInfoSSAO._resolution_x, 
_RTTInfoSSAO._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoSSAO._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoSSAO._image.get(),0,0);
                          _RTTInfoSSAO._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoSSAO._image.get(),"RTTInfoSSAO.png",false));
                          
_RTTInfoSSAO._texture->setImage(0,_RTTInfoSSAO._image.get());
                          // add subgraph to render
                          
_RTTInfoSSAO._camera->addChild(createBase(_RTTInfoDepth._texture.get()));



                          
////////////////////////////////////////////////////////////////////////// 
Gaussian Vertical
                          // texture resolution 
                          _RTTInfoGaussianV._resolution_x = 512;
                          _RTTInfoGaussianV._resolution_y = 512;


                          // texture
                          _RTTInfoGaussianV._texture = new osg::Texture2D;
                          
_RTTInfoGaussianV._texture->setTextureSize(_RTTInfoGaussianV._resolution_x, 
_RTTInfoGaussianV._resolution_y);
                          _RTTInfoGaussianV._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoGaussianV._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoGaussianV._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoGaussianV._camera = new osg::Camera;
                          
_RTTInfoGaussianV._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoGaussianV._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoGaussianV._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoGaussianV._camera->setViewport(0,0,_RTTInfoGaussianV._resolution_x,_RTTInfoGaussianV._resolution_y);
                          
_RTTInfoGaussianV._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1.0),osg::Vec3(0.5,0.5,0.0),osg::Vec3(0,1,0));
                          
_RTTInfoGaussianV._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);
                          // set the camera to render before the main camera.
                          
_RTTInfoGaussianV._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoGaussianV._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoGaussianV._image=new osg::Image;
                          
_RTTInfoGaussianV._image->allocateImage(_RTTInfoGaussianV._resolution_x, 
_RTTInfoGaussianV._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoGaussianV._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoGaussianV._image.get(),0,0);
                          _RTTInfoGaussianV._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoGaussianV._image.get(),"RTTInfoGaussianV.png",false));
                          
_RTTInfoGaussianV._texture->setImage(0,_RTTInfoGaussianV._image.get());
                          // add subgraph to render
                          
_RTTInfoGaussianV._camera->addChild(createBase(_RTTInfoSSAO._texture.get()));

                          
////////////////////////////////////////////////////////////////////////// 
Gaussian Horizontal
                          // texture resolution 
                          _RTTInfoGaussianH._resolution_x = 512;
                          _RTTInfoGaussianH._resolution_y = 512;


                          // texture
                          _RTTInfoGaussianH._texture = new osg::Texture2D;
                          
_RTTInfoGaussianH._texture->setTextureSize(_RTTInfoGaussianH._resolution_x, 
_RTTInfoGaussianH._resolution_y);
                          _RTTInfoGaussianH._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoGaussianH._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoGaussianH._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoGaussianH._camera = new osg::Camera;
                          
_RTTInfoGaussianH._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoGaussianH._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoGaussianH._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoGaussianH._camera->setViewport(0,0,_RTTInfoGaussianH._resolution_x,_RTTInfoGaussianH._resolution_y);
                          
_RTTInfoGaussianH._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1),osg::Vec3(0.5,0.5,0),osg::Vec3(0,1,0));
                          
_RTTInfoGaussianH._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);

                          // set the camera to render before the main camera.
                          
_RTTInfoGaussianH._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoGaussianH._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoGaussianH._image=new osg::Image;
                          
_RTTInfoGaussianH._image->allocateImage(_RTTInfoGaussianH._resolution_x, 
_RTTInfoGaussianH._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoGaussianH._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoGaussianH._image.get(),0,0);
                          _RTTInfoGaussianH._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoGaussianH._image.get(),"RTTInfoGaussianH.png",false));
                          
_RTTInfoGaussianH._texture->setImage(0,_RTTInfoGaussianH._image.get());
                          // add subgraph to render
                          
_RTTInfoGaussianH._camera->addChild(createBase(_RTTInfoGaussianV._texture.get()));



                          
////////////////////////////////////////////////////////////////////////// SSAO 
final pass

                          osg::ref_ptr<osg::StateSet> ss = 
ssaoFX->getOrCreateStateSet();
                          {
                                  unsigned int textLoop(0); 
                                  // fake texture for baseTexture, add a fake 
texture
                                  // we support by default at least one texture 
layer
                                  // without this fake texture we can not 
support
                                  // textured and not textured scene

                                  // TODO: at the moment the PSSM supports just 
one texture layer in the GLSL shader, multitexture are
                                  //       not yet supported !

                                  osg::ref_ptr<osg::Image> image = new 
osg::Image;
                                  // allocate the image data, noPixels x 1 x 1 
with 4 rgba floats - equivalent to a Vec4!
                                  int noPixels = 1;
                                  
image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
                                  image->setInternalTextureFormat(GL_RGBA);
                                  // fill in the image data.
                                  osg::Vec4* dataPtr = 
(osg::Vec4*)image->data();
                                  osg::Vec4f color(1.0f,1.0f,1.0f,0.0f);
                                  *dataPtr = color;
                                  // make fake texture
                                  osg::ref_ptr<osg::Texture2D> texture = new 
osg::Texture2D;
                                  
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
                                  
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
                                  
texture->setBorderColor(osg::Vec4(1.0,1.0,1.0,1.0));
                                  
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
                                  
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
                                  texture->setImage(image.get());
                                  // add fake texture
                                  
ss->setTextureAttribute(textLoop,texture.get(),osg::StateAttribute::ON);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_1D,osg::StateAttribute::OFF);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_2D,osg::StateAttribute::ON);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_3D,osg::StateAttribute::OFF);
                          }


                          
ss->setTextureAttributeAndModes(1,_RTTInfoGaussianV._texture.get(),osg::StateAttribute::ON);

                          osg::ref_ptr<osg::Program> program = new osg::Program;
                          ss->setAttribute(program.get());

                          osg::ref_ptr<osg::Uniform> samplerText = new 
osg::Uniform("samplerText",0);
                          ss->addUniform(samplerText.get());

                          osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",1);
                          ss->addUniform(samplerRTScene.get());


                          osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                  "uniform sampler2D samplerRTScene;"\
                                  "uniform sampler2D samplerText;"\
                                  "void main(void)"\
                                  "{"\
                                  "   vec4 text = 
texture2D(samplerText,gl_TexCoord[0].st);"\
                                  "     vec4 ssao = texture2D(samplerRTScene, 
vec2(1.0/512.0*gl_FragCoord.x, 1.0/512.0*gl_FragCoord.y));"\
                                  "     float lenRGB = length(ssao.rgb);"\
                                  " lenRGB = (1.0-(1.0-lenRGB)*(1.0-lenRGB));"\
                                  "     gl_FragColor = (text*gl_Color - 0.25* 
(vec4(lenRGB,lenRGB,lenRGB,0.0)));"\
                                  "}"   
                                  );
                          program->addShader(fragment_shader.get());
                  }

                  virtual void getRequiredExtensions(std::vector<std::string>& 
extensions)
                  {
                  }

                  bool validate(osg::State& state) const
                  {
                          if (!Technique::validate(state)) return false;

                          //osg::TextureCubeMap::Extensions *ext = 
osg::TextureCubeMap::getExtensions(state.getContextID(), true);
                          //if (ext) {
                          //    return ext->isCubeMapSupported();
                          //}
                          return true;
                  }


                  /** optional: return a node that overrides the child node on 
a specified pass */
                  inline virtual osg::Node* getOverrideChild(int passNum)  { 
                          if ( passNum == 0 ) { //Depth
                                  return _RTTInfoDepth._camera.get();
                          }
                          if ( passNum == 1 ) { // SSAO
                                  return _RTTInfoSSAO._camera.get();
                          }                      
                          if ( passNum == 2 ) { // Gaussian V
                                  return _RTTInfoGaussianV._camera.get();
                          }
                          if ( passNum == 3) { // Gaussian H
                                  return _RTTInfoGaussianH._camera.get();
                          }

                          return 0; 

                  }

                  inline virtual void traverse(osg::NodeVisitor& nv, Effect* 
fx) {

                          // special actions must be taken if the node visitor 
is actually a CullVisitor
                          osgUtil::CullVisitor *cv = 
dynamic_cast<osgUtil::CullVisitor *>(&nv);
                          if ( cv ) {   
                                  osgUtil::RenderStage* orig_rs = 
cv->getRenderStage();
                                  
_RTTInfoDepth._camera->setViewMatrix(cv->getRenderInfo().getView()->getCamera()->getViewMatrix());
                                  
_RTTInfoDepth._camera->setProjectionMatrix(cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix());
                                  osg::ref_ptr<osg::Viewport> vp = 
cv->getRenderInfo().getView()->getCamera()->getViewport();
                                  osg::ref_ptr<osg::Viewport> vpCam = 
_RTTInfoDepth._camera->getViewport();
                                  if ( vpCam->width()!=vp->width() || 
vpCam->height()!=vp->height()  ) {
                                          
_RTTInfoDepth._camera->getViewport()->setViewport(
                                                  0,
                                                  0,
                                                  std::min((unsigned 
int)vp->width(),_RTTInfoDepth._resolution_x),
                                                  std::min((unsigned 
int)vp->height(),_RTTInfoDepth._resolution_y)
                                                  );            
                                  }

                                  double f,a,zn,zf;
                                  
cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix().getPerspective(f,a,zn,zf);
                                  if ( nearUniform.valid() ) 
nearUniform->set((float)zn);
                                  if ( farUniform.valid() )  
farUniform->set((float)zf); 
                          }


                          traverse_implementation(nv, fx);

                  }


        protected:

                void define_passes()
                {

                        {   // Depth Pass 1
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;


                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                nearUniform = new 
osg::Uniform("nearUniform",FLT_MIN);
                                farUniform  = new 
osg::Uniform("farUniform",FLT_MAX);
                                ss->addUniform(nearUniform.get());
                                ss->addUniform(farUniform.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec3 vTangent;"\
                                        "void main(void)"\
                                        "{"\
                                        "       vec3 normal = gl_Normal;"\
                                        "       vec3 c1 = cross(normal, 
normalize(vec3(1.0, 1.0, 1.0))); "\
                                        "       vTangent = normalize(c1);"\
                                        "       gl_Position = ftransform();"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());

                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform float nearUniform;"\
                                        "uniform float farUniform;"\
                                        "varying vec3 vTangent;"\
                                        "void main() {"\
                                        "   float z = 
((gl_FragCoord.z/gl_FragCoord.w)/(farUniform));"\
                                        "       gl_FragColor = 
vec4(0.5*z+0.5*vTangent.r,0.5*z+0.5*vTangent.g,0.5*z+0.5*vTangent.b,step(0.9,gl_FrontMaterial.diffuse.a));"\
                                        "} "
                                        );
                                program->addShader(fragment_shader.get());


                                addPass(ss.get());
                        }

                        {   // SSAO 2
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;


                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerNormal3Depth1 
= new osg::Uniform("samplerNormal3Depth1",0);
                                ss->addUniform(samplerNormal3Depth1.get());

 

                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());

                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D 
samplerNormal3Depth1;"\
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       float ao = 0.0;"\
                                        "       vec4 normalDepth0 = 
texture2D(samplerNormal3Depth1, vec2(vTexCoord.x, vTexCoord.y));"\
                                        "       float depth0 = 
length(normalDepth0.rgb)-0.5;"\
                                        "       vec3 normal0 = 
2.0*(normalDepth0.rgb - vec3(depth0,depth0,depth0));"\
                                        "       depth0 = 2.0*depth0;"\
                                        "       float runX = 5.0;"\
                                        "       float runY = 5.0;"\
                                        "   for (float iX=-runX; iX < runX+1.0; 
iX+=1.0)"\
                                        "   {"\
                                        "     for (float iY=-runY; iY < 
runY+1.0; iY+=1.0)"\
                                        "     {"\
                                        "       vec2 offsetXY = 
vec2(iX,iY)/512.0;"\
                                        "           vec4 normalDepth = 
texture2D(samplerNormal3Depth1, offsetXY+vec2(vTexCoord.x, vTexCoord.y));"\
                                        "               float depth = 
length(normalDepth.rgb)-0.5;"\
                                        "               vec3 normal = 
2.0*(normalDepth.rgb - vec3(depth,depth,depth));"\
                                        "               depth = 2.0*depth;"\
                                        "           float aoH = 
sin(atan((depth0-depth)/12.0/length(offsetXY)));"\
                                        "           float aoT = 
sin(atan(normal.z/length(normal.xy)));"\
                                        "       ao += 
step(0.0,aoH)*step(0.0,aoT)*(aoH-aoT);"\
                                        "     }"\
                                        "   }"\
                                        "   ao = clamp(ao,0.0,1.0);"\
                                        "       gl_FragColor.rgb = 
vec3(ao,ao,ao);"\
                                        "       gl_FragColor.a = 1.0;"\
                                        "}"     
                                        );
                                program->addShader(fragment_shader.get());
                                addPass(ss.get());
                        }

                        {   // Gaussian V  3
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;

                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",0);
                                ss->addUniform(samplerRTScene.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());


                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D samplerRTScene;"\
                                        "varying vec2 vTexCoord;"\
                                        "const float blurSize = 1.0/256.0; "\
                                        "void main(void)"\
                                        "{"\
                                        "       vec4 sum = vec4(0.0);"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) *   
1.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) *   
2.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) *   
3.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - blurSize    , vTexCoord.y)) *  
10.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x               , vTexCoord.y)) *  
15.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + blurSize    , vTexCoord.y)) *  
10.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) *   
3.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) *   
2.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) *   
1.0/47.0;"\
                                        "       gl_FragColor = sum;"\
                                        "}"     
                                        );
                                program->addShader(fragment_shader.get());


                                addPass(ss.get());
                        }
                        {   // Gaussian H  4
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;



                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",0);
                                ss->addUniform(samplerRTScene.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());


                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D samplerRTScene;"\
                                        "varying vec2 vTexCoord;"\
                                        "const float blurSize = 1.0/256.0; "\
                                        "void main(void)"\
                                        "{"\
                                        "       vec4 sum = vec4(0.0);"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 4.0*blurSize)) *    
1.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 3.0*blurSize)) *    
2.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 2.0*blurSize)) *    
3.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - blurSize    )) *   
10.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y               )) *   
15.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + blurSize    )) *   
10.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 2.0*blurSize)) *    
3.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 3.0*blurSize)) *    
2.0/47.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 4.0*blurSize)) *    
1.0/47.0;"\
                                        "       gl_FragColor = sum;"\
                                        "}"     
                                        );
                                program->addShader(fragment_shader.get());
                                addPass(ss.get());
                        }



                        {   // Final Pass
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;
                                addPass(ss.get());
                        }
                }

        private:

                struct RTTInfo {
                        // RTT
                        osg::ref_ptr<osg::Camera>       _camera;
                        osg::ref_ptr<osg::TexGen>       _texgen;
                        osg::ref_ptr<osg::Texture2D>    _texture;
                        osg::ref_ptr<osg::StateSet>     _stateset;
                        osg::ref_ptr<osg::Image>        _image;

                        unsigned int                                    
_resolution_x;
                        unsigned int                                    
_resolution_y;
                };

                RTTInfo                                         _RTTInfoDepth;
                RTTInfo                                         _RTTInfoSSAO;

                RTTInfo                                         
_RTTInfoGaussianH;
                RTTInfo                                         
_RTTInfoGaussianV;

                osg::ref_ptr<osg::Group>                _scene;

                osg::ref_ptr<osg::Uniform> nearUniform;
                osg::ref_ptr<osg::Uniform> farUniform;

        };

}

SSAO::SSAO(osg::Group* rootGrp)  :    Effect(),_root(rootGrp) {
}

SSAO::SSAO(const SSAO& copy, const osg::CopyOp& copyop)   :    Effect(copy, 
copyop){
}

bool SSAO::define_techniques()
{
        addTechnique(new DefaultTechnique(_root.get(),this));
        return true;
}





class SSAOViewerEventHandler : public osgGA::GUIEventHandler
{
public:
        SSAOViewerEventHandler(osg::Switch* s) : 
          _switch(s)
          {
          }
          virtual bool handle(const osgGA::GUIEventAdapter& 
ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*) 
          { 
                  osgViewer::Viewer* viewer = 
dynamic_cast<osgViewer::Viewer*>(&aa);
                  if (!viewer) return false;



                  if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN)
                  {
                          switch (ea.getKey())
                          {
                          case 'a': 
                                  if ( _switch->getValue(0) ) {
                                          _switch->setAllChildrenOff();
                                          _switch->setValue(1,true);
                                  } else {
                                          _switch->setAllChildrenOff();
                                          _switch->setValue(0,true);
                                  }
                                  return true;
                          }
                  }

                  return false;

          }

          osg::ref_ptr<osg::Switch> _switch;
};

int main(int argc, char** argv)
{

        putenv("OSG_WINDOW=128 128 512 512");

        // use an ArgumentParser object to manage the program arguments.
        osg::ArgumentParser arguments(&argc,argv);

        
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
        
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+"
 is the standard OpenSceneGraph example which loads and visualises 3d models.");
        
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
 [options] filename ...");
        arguments.getApplicationUsage()->addCommandLineOption("--image 
<filename>","Load an image and render it on a quad");
        arguments.getApplicationUsage()->addCommandLineOption("--dem 
<filename>","Load an image/DEM and render it on a HeightField");
        arguments.getApplicationUsage()->addCommandLineOption("--login <url> 
<username> <password>","Provide authentication information for http file 
access.");

        osgViewer::Viewer viewer(arguments);

        unsigned int helpType = 0;
        if ((helpType = arguments.readHelpType()))
        {
                arguments.getApplicationUsage()->write(std::cout, helpType);
                return 1;
        }

        // report any errors if they have occurred when parsing the program 
arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }

        if (arguments.argc()<=1)
        {
                
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
                return 1;
        }

        std::string url, username, password;
        while(arguments.read("--login",url, username, password))
        {
                if (!osgDB::Registry::instance()->getAuthenticationMap())
                {
                        osgDB::Registry::instance()->setAuthenticationMap(new 
osgDB::AuthenticationMap);
                        
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
                                url,
                                new osgDB::AuthenticationDetails(username, 
password)
                                );
                }
        }

        // set up the camera manipulators.
        {
                osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> 
keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

                keyswitchManipulator->addMatrixManipulator( '1', "Trackball", 
new osgGA::TrackballManipulator() );
                keyswitchManipulator->addMatrixManipulator( '2', "Flight", new 
osgGA::FlightManipulator() );
                keyswitchManipulator->addMatrixManipulator( '3', "Drive", new 
osgGA::DriveManipulator() );
                keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new 
osgGA::TerrainManipulator() );

                std::string pathfile;
                char keyForAnimationPath = '5';
                while (arguments.read("-p",pathfile))
                {
                        osgGA::AnimationPathManipulator* apm = new 
osgGA::AnimationPathManipulator(pathfile);
                        if (apm || !apm->valid()) 
                        {
                                unsigned int num = 
keyswitchManipulator->getNumMatrixManipulators();
                                keyswitchManipulator->addMatrixManipulator( 
keyForAnimationPath, "Path", apm );
                                
keyswitchManipulator->selectMatrixManipulator(num);
                                ++keyForAnimationPath;
                        }
                }

                viewer.setCameraManipulator( keyswitchManipulator.get() );
        }

        // add the state manipulator
        viewer.addEventHandler( new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

        // add the thread model handler
        viewer.addEventHandler(new osgViewer::ThreadingHandler);

        // add the window size toggle handler
        viewer.addEventHandler(new osgViewer::WindowSizeHandler);

        // add the stats handler
        viewer.addEventHandler(new osgViewer::StatsHandler);

        // add the help handler
        viewer.addEventHandler(new 
osgViewer::HelpHandler(arguments.getApplicationUsage()));

        // add the record camera path handler
        viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

        // add the LOD Scale handler
        viewer.addEventHandler(new osgViewer::LODScaleHandler);

        // add the screen capture handler
        viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);

        osg::ref_ptr<osg::Switch> switchNode = new osg::Switch;
        osg::ref_ptr<SSAOViewerEventHandler> ssaoViewerEventHandler= new 
SSAOViewerEventHandler(switchNode.get());
        viewer.addEventHandler(ssaoViewerEventHandler.get());


        // load the data
        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
        if (!loadedModel) 
        {
                std::cout << arguments.getApplicationName() <<": No data 
loaded" << std::endl;
                loadedModel = osgDB::readNodeFile("cow.osg");
                if (!loadedModel) return 1;
        }

        // any option left unread are converted into errors to write out later.
        arguments.reportRemainingOptionsAsUnrecognized();

        // report any errors if they have occurred when parsing the program 
arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }


        // optimize the scene graph, remove redundant nodes and state etc.
        osgUtil::Optimizer optimizer;
        optimizer.optimize(loadedModel.get());

        // SWITCH
        switchNode->addChild(loadedModel.get(),false);

        // SSAO
        osg::ref_ptr<osg::Group> grpSSAOModel = new osg::Group;
        grpSSAOModel->addChild(loadedModel.get());
        osg::ref_ptr<SSAO> ssao = new SSAO(grpSSAOModel.get());
        ssao->addChild(grpSSAOModel.get());
        osg::ref_ptr<osg::Group> grpSSAO = new osg::Group;
        grpSSAO->addChild(ssao.get());
        switchNode->addChild(grpSSAO.get(),true);

        viewer.setSceneData( switchNode.get() );


        viewer.realize();

        return viewer.run();

}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to