SPIN Framework
|
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