SPIN Framework

include/dofppu.h

00001 #include <osgPPU/Processor.h>
00002 #include <osgPPU/Unit.h>
00003 #include <osgPPU/UnitInOut.h>
00004 #include <osgPPU/UnitText.h>
00005 #include <osgPPU/UnitInResampleOut.h>
00006 #include <osgPPU/UnitInMipmapOut.h>
00007 #include <osgPPU/UnitOut.h>
00008 #include <osgPPU/UnitOutCapture.h>
00009 #include <osgPPU/UnitBypass.h>
00010 #include <osgPPU/UnitTexture.h>
00011 #include <osgPPU/UnitDepthbufferBypass.h>
00012 #include <osgDB/ReaderWriter>
00013 #include <osgDB/ReadFile>
00014 #include <osgPPU/ShaderAttribute.h>
00015 
00016 
00017 //---------------------------------------------------------------
00018 // PPU setup for DoF Rendering
00019 //
00020 //---------------------------------------------------------------
00021 class DoFRendering : virtual public osg::Referenced
00022 {
00023     private:
00024     
00025         float dofGaussSigma;
00026         float dofGaussRadius;
00027         float dofFocalLength;
00028         float dofFocalRange;
00029         
00030         osgPPU::ShaderAttribute* gaussx;
00031         osgPPU::ShaderAttribute* gaussy;
00032         osgPPU::ShaderAttribute* dofShaderAttr;
00033         
00034     public:
00035 
00036         DoFRendering()
00037         {
00038             dofGaussSigma = 1.5f;
00039             dofGaussRadius = 5.0f;
00040 
00041             dofFocalLength = 0.0f;
00042             dofFocalRange = 50.0f;
00043 
00044         }
00045         
00046         void setGaussSigma(float sigma)
00047         {
00048             gaussx->set("sigma", sigma);
00049             gaussy->set("sigma", sigma);
00050         }
00051 
00052         void setGaussRadius(float radius)
00053         {
00054             gaussx->set("radius", radius);
00055             gaussy->set("radius", radius);
00056         }
00057 
00058         void setFocalLength(float f)
00059         {
00060             dofShaderAttr->set("focalLength", f);
00061         }
00062 
00063         void setFocalRange(float range)
00064         {
00065             dofShaderAttr->set("focalRange", range);
00066         }
00067 
00068         void setNear(float near)
00069         {
00070             dofShaderAttr->set("zNear", near);
00071         }
00072 
00073         void setFar(float far)
00074         {
00075             dofShaderAttr->set("zFar", far);
00076         }
00077 
00078         //------------------------------------------------------------------------
00079         void createDoFPipeline(osgPPU::Processor* parent, osgPPU::Unit*& lastUnit, float zNear, float zFar)
00080         {
00081             osg::ref_ptr<osgDB::ReaderWriter::Options> fragmentOptions = new osgDB::ReaderWriter::Options("fragment");
00082             osg::ref_ptr<osgDB::ReaderWriter::Options> vertexOptions = new osgDB::ReaderWriter::Options("vertex");
00083 
00084             // the first unit will bypass the color output of the camera
00085             osgPPU::UnitBypass* bypass = new osgPPU::UnitBypass();
00086             bypass->setName("ColorBypass");
00087             parent->addChild(bypass);
00088 
00089             // next unit will bypass the depth output of the camera
00090             osgPPU::UnitDepthbufferBypass* depthbypass = new osgPPU::UnitDepthbufferBypass();
00091             depthbypass->setName("DepthBypass");
00092             parent->addChild(depthbypass);
00093 
00094             // we need to blur the output of the color texture to emulate
00095             // the depth of field. Therefore first we just resample
00096             osgPPU::UnitInResampleOut* resampleLight = new osgPPU::UnitInResampleOut();
00097             {
00098                 resampleLight->setName("ResampleLight");
00099                 // mikewoz: original factor was 0.5 here and 0.25 for the strong
00100                 resampleLight->setFactorX(0.9f);
00101                 resampleLight->setFactorY(0.9f);
00102             }
00103             bypass->addChild(resampleLight);
00104 
00105 
00106             // helper shader class to perform gauss blur
00107             //osgPPU::ShaderAttribute* gaussx = new osgPPU::ShaderAttribute();
00108             //osgPPU::ShaderAttribute* gaussy = new osgPPU::ShaderAttribute();
00109             gaussx = new osgPPU::ShaderAttribute();
00110             gaussy = new osgPPU::ShaderAttribute();
00111             {
00112                 // read shaders from file
00113                 osg::Shader* vshader = osgDB::readShaderFile("gauss_convolution_vp.glsl", vertexOptions.get());
00114                 osg::Shader* fhshader = osgDB::readShaderFile("gauss_convolution_1Dx_fp.glsl", fragmentOptions.get());
00115                 osg::Shader* fvshader = osgDB::readShaderFile("gauss_convolution_1Dy_fp.glsl", fragmentOptions.get());
00116 
00117                 // setup horizontal blur shaders
00118                 gaussx->addShader(vshader);
00119                 gaussx->addShader(fhshader);
00120                 gaussx->setName("BlurHorizontalShader");
00121 
00122                 gaussx->add("sigma", osg::Uniform::FLOAT);
00123                 gaussx->add("radius", osg::Uniform::FLOAT);
00124                 gaussx->add("texUnit0", osg::Uniform::SAMPLER_2D);
00125 
00126                 gaussx->set("sigma", dofGaussSigma);
00127                 gaussx->set("radius", dofGaussRadius);
00128                 gaussx->set("texUnit0", 0);
00129 
00130                 // setup vertical blur shaders
00131                 gaussy->addShader(vshader);
00132                 gaussy->addShader(fvshader);
00133                 gaussy->setName("BlurVerticalShader");
00134 
00135                 gaussy->add("sigma", osg::Uniform::FLOAT);
00136                 gaussy->add("radius", osg::Uniform::FLOAT);
00137                 gaussy->add("texUnit0", osg::Uniform::SAMPLER_2D);
00138 
00139                 gaussy->set("sigma", dofGaussSigma);
00140                 gaussy->set("radius", dofGaussRadius);
00141                 gaussy->set("texUnit0", 0);
00142             }
00143 
00144             // now we perform a gauss blur on the downsampled data
00145             osgPPU::UnitInOut* blurxlight = new osgPPU::UnitInOut();
00146             osgPPU::UnitInOut* blurylight = new osgPPU::UnitInOut();
00147             {
00148                 // set name and indicies
00149                 blurxlight->setName("BlurHorizontalLight");
00150                 blurylight->setName("BlurVerticalLight");
00151 
00152                 //blurxlight->setShader(gaussx);
00153                 //blurylight->setShader(gaussy);
00154                 blurxlight->getOrCreateStateSet()->setAttributeAndModes(gaussx);
00155                 blurylight->getOrCreateStateSet()->setAttributeAndModes(gaussy);
00156             }
00157             resampleLight->addChild(blurxlight);
00158             blurxlight->addChild(blurylight);
00159 
00160 
00161             // and also a stronger blurred/resampled texture is required
00162             osgPPU::UnitInResampleOut* resampleStrong = new osgPPU::UnitInResampleOut();
00163             {
00164                 resampleStrong->setName("ResampleStrong");
00165                 // mikewoz: original factor was 0.25 here and 0.5 for the light
00166                 resampleStrong->setFactorX(0.75f);
00167                 resampleStrong->setFactorY(0.75f);
00168             }
00169             bypass->addChild(resampleStrong);
00170 
00171             // now we perform a gauss blur on the downsampled data
00172             osgPPU::UnitInOut* blurxstrong = new osgPPU::UnitInOut();
00173             osgPPU::UnitInOut* blurystrong = new osgPPU::UnitInOut();
00174             {
00175                 // set name and indicies
00176                 blurxstrong->setName("BlurHorizontalStrong");
00177                 blurystrong->setName("BlurVerticalStrong");
00178 
00179                 //blurxstrong->setShader(gaussx);
00180                 //blurystrong->setShader(gaussy);
00181                 blurxstrong->getOrCreateStateSet()->setAttributeAndModes(gaussx);
00182                 blurystrong->getOrCreateStateSet()->setAttributeAndModes(gaussy);
00183             }
00184             resampleStrong->addChild(blurxstrong);
00185             blurxstrong->addChild(blurystrong);
00186 
00187 
00188             // And finally we add a ppu which do use all the computed results:
00189             osgPPU::Unit* dof = new osgPPU::UnitInOut();
00190             {
00191                 // setup inputs, name and index
00192                 dof->setName("DoF-Result");
00193 
00194                 // setup shader
00195                 dofShaderAttr = new osgPPU::ShaderAttribute();
00196                 dofShaderAttr->addShader(osgDB::readShaderFile("depth_of_field_fp.glsl", fragmentOptions.get()));
00197                 dofShaderAttr->setName("DoFResultShader");
00198 
00199                 dofShaderAttr->add("focalLength", osg::Uniform::FLOAT);
00200                 dofShaderAttr->add("focalRange", osg::Uniform::FLOAT);
00201                 dofShaderAttr->add("zNear", osg::Uniform::FLOAT);
00202                 dofShaderAttr->add("zFar", osg::Uniform::FLOAT);
00203 
00204                 dofShaderAttr->set("focalLength", dofFocalLength);
00205                 dofShaderAttr->set("focalRange", dofFocalRange);
00206                 dofShaderAttr->set("zNear", zNear);
00207                 dofShaderAttr->set("zFar", zFar);
00208 
00209                 //dof->setShader(sh);
00210                 dof->getOrCreateStateSet()->setAttributeAndModes(dofShaderAttr);
00211                 dof->setInputTextureIndexForViewportReference(0); // we want to setup viewport based on this input
00212 
00213                 // add inputs as uniform parameters
00214                 dof->setInputToUniform(bypass, "texColorMap", true);
00215                 dof->setInputToUniform(blurylight, "texBlurredColorMap", true);
00216                 dof->setInputToUniform(blurystrong, "texStrongBlurredColorMap", true);
00217                 dof->setInputToUniform(depthbypass, "texDepthMap", true);
00218             }
00219 
00220             // this is the last unit
00221             lastUnit = dof;
00222         }
00223 };
00224