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 // PPU setup for SSAO (ambient occlusion) rendering 00018 /**********************************************/ 00019 class SSAORendering : virtual public osg::Referenced 00020 { 00021 private: 00022 float dofGaussSigma; 00023 float dofGaussRadius; 00024 00025 osgPPU::ShaderAttribute* ssaoShaderAttr; 00026 osgPPU::ShaderAttribute* gaussx; 00027 osgPPU::ShaderAttribute* gaussy; 00028 osgPPU::ShaderAttribute* compositeAttr; 00029 00030 00031 public: 00032 /********************/ 00033 SSAORendering() 00034 { 00035 dofGaussSigma = 1.5f; 00036 dofGaussRadius = 3.0f; 00037 } 00038 00039 /*******************/ 00040 void setPower(float pPower) 00041 { 00042 ssaoShaderAttr->set("vPower", pPower); 00043 } 00044 00045 /*******************/ 00046 void createSSAOPipeline(osgPPU::Processor* pParent, osgPPU::Unit*& pLastUnit, 00047 osg::Texture* pColor1, osg::Texture* pColor2, osg::Texture* pColor3, 00048 osg::Matrixf pProjMat) 00049 { 00050 double fovy, aspect, lNear, lFar; 00051 pProjMat.getPerspective(fovy, aspect, lNear, lFar); 00052 00053 osg::ref_ptr<osgDB::ReaderWriter::Options> fragmentOptions = new osgDB::ReaderWriter::Options("fragment"); 00054 osg::ref_ptr<osgDB::ReaderWriter::Options> vertexOptions = new osgDB::ReaderWriter::Options("vertex"); 00055 00056 // We need to get the ptr to the texture attached to the camera 00057 //osg::Camera::BufferAttachmentMap lBufferMap = pCamera->getBufferAttachmentMap(); 00058 //osg::Texture* lColorTexture1 = lBufferMap[osg::Camera::COLOR_BUFFER0]._texture; 00059 //osg::Texture* lColorTexture2 = lBufferMap[osg::Camera::COLOR_BUFFER1]._texture; 00060 00061 // Now we are ready for the PPU 00062 // The first unit gets the first color buffer 00063 osgPPU::UnitTexture* lColor1 = new osgPPU::UnitTexture(); 00064 lColor1->setName("Color1"); 00065 lColor1->setTexture(pColor1); 00066 pParent->addChild(lColor1); 00067 00068 // The second unit gets the second color buffer 00069 osgPPU::UnitTexture* lColor2 = new osgPPU::UnitTexture(); 00070 lColor2->setName("Color2"); 00071 lColor2->setTexture(pColor2); 00072 pParent->addChild(lColor2); 00073 00074 // The third unit gets the third color buffer 00075 osgPPU::UnitTexture* lColor3 = new osgPPU::UnitTexture(); 00076 lColor3->setName("Color3"); 00077 lColor3->setTexture(pColor3); 00078 pParent->addChild(lColor3); 00079 00080 // The fourth unit gets the noise texture 00081 // It is read from an image file 00082 osg::ref_ptr<osg::Image> lNoiseImage = osgDB::readImageFile("ssao_noise.png"); 00083 osg::Texture* lNoiseTex = new osg::Texture2D; 00084 lNoiseTex->setWrap(osg::Texture::WRAP_S, osg::Texture::MIRROR); 00085 lNoiseTex->setWrap(osg::Texture::WRAP_T, osg::Texture::MIRROR); 00086 lNoiseTex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); 00087 lNoiseTex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); 00088 lNoiseTex->setImage(0, lNoiseImage.get()); 00089 00090 osgPPU::UnitTexture* lNoise = new osgPPU::UnitTexture(); 00091 lNoise->setName("Noise"); 00092 lNoise->setTexture(lNoiseTex); 00093 pParent->addChild(lNoise); 00094 00095 // The 5th unit gets the depth buffer 00096 osgPPU::UnitDepthbufferBypass* lDepth = new osgPPU::UnitDepthbufferBypass(); 00097 lDepth->setName("Depth"); 00098 pParent->addChild(lDepth); 00099 00100 // And the unit to apply our shader 00101 osgPPU::UnitInOut* ssao = new osgPPU::UnitInOut(); 00102 ssao->setName("ssao"); 00103 00104 // Setup the ssao shader 00105 ssaoShaderAttr = new osgPPU::ShaderAttribute(); 00106 { 00107 ssaoShaderAttr->addShader(osgDB::readShaderFile("screenSpaceAmbientOcc_vp.glsl", vertexOptions.get())); 00108 ssaoShaderAttr->addShader(osgDB::readShaderFile("screenSpaceAmbientOcc_fp.glsl", fragmentOptions.get())); 00109 ssaoShaderAttr->setName("ssaoShader"); 00110 00111 ssaoShaderAttr->add("vPower", osg::Uniform::FLOAT); 00112 ssaoShaderAttr->add("vPixelSize", osg::Uniform::FLOAT); 00113 ssaoShaderAttr->add("vNear", osg::Uniform::FLOAT); 00114 ssaoShaderAttr->add("vFar", osg::Uniform::FLOAT); 00115 ssaoShaderAttr->add("vProjectionMatrix", osg::Uniform::FLOAT_MAT4); 00116 ssaoShaderAttr->add("vInvProjectionMatrix", osg::Uniform::FLOAT_MAT4); 00117 00118 ssaoShaderAttr->set("vPixelSize", 1.f); 00119 ssaoShaderAttr->set("vNear", (float)lNear); 00120 ssaoShaderAttr->set("vFar", (float)lFar); 00121 ssaoShaderAttr->set("vProjectionMatrix", pProjMat); 00122 ssaoShaderAttr->set("vInvProjectionMatrix", osg::Matrixf::inverse(pProjMat)); 00123 00124 ssao->getOrCreateStateSet()->setAttributeAndModes(ssaoShaderAttr); 00125 ssao->setInputTextureIndexForViewportReference(0); 00126 00127 //ssao->setInputToUniform(lColor1, "vColor1", true); 00128 ssao->setInputToUniform(lColor2, "vColor2", true); 00129 ssao->setInputToUniform(lColor3, "vColor3", true); 00130 ssao->setInputToUniform(lNoise, "vNoiseMap", true); 00131 ssao->setInputToUniform(lDepth, "vDepth", true); 00132 } 00133 00134 // Now we will filter the ssao as it's quite noisy 00135 gaussx = new osgPPU::ShaderAttribute(); 00136 gaussy = new osgPPU::ShaderAttribute(); 00137 { 00138 // read shaders from file 00139 osg::Shader* vshader = osgDB::readShaderFile("gauss_convolution_vp.glsl", vertexOptions.get()); 00140 osg::Shader* fhshader = osgDB::readShaderFile("gauss_convolution_1Dx_fp.glsl", fragmentOptions.get()); 00141 osg::Shader* fvshader = osgDB::readShaderFile("gauss_convolution_1Dy_fp.glsl", fragmentOptions.get()); 00142 00143 // setup horizontal blur shaders 00144 gaussx->addShader(vshader); 00145 gaussx->addShader(fhshader); 00146 gaussx->setName("BlurHorizontalShader"); 00147 00148 gaussx->add("sigma", osg::Uniform::FLOAT); 00149 gaussx->add("radius", osg::Uniform::FLOAT); 00150 gaussx->add("texUnit0", osg::Uniform::SAMPLER_2D); 00151 00152 gaussx->set("sigma", dofGaussSigma); 00153 gaussx->set("radius", dofGaussRadius); 00154 gaussx->set("texUnit0", 0); 00155 00156 // setup vertical blur shaders 00157 gaussy->addShader(vshader); 00158 gaussy->addShader(fvshader); 00159 gaussy->setName("BlurVerticalShader"); 00160 00161 gaussy->add("sigma", osg::Uniform::FLOAT); 00162 gaussy->add("radius", osg::Uniform::FLOAT); 00163 gaussy->add("texUnit0", osg::Uniform::SAMPLER_2D); 00164 00165 gaussy->set("sigma", dofGaussSigma); 00166 gaussy->set("radius", dofGaussRadius); 00167 gaussy->set("texUnit0", 0); 00168 } 00169 00170 osgPPU::UnitInOut* blurxlight = new osgPPU::UnitInOut(); 00171 osgPPU::UnitInOut* blurylight = new osgPPU::UnitInOut(); 00172 { 00173 // set name and indicies 00174 blurxlight->setName("BlurHorizontalLight"); 00175 blurylight->setName("BlurVerticalLight"); 00176 00177 //blurxlight->setShader(gaussx); 00178 //blurylight->setShader(gaussy); 00179 blurxlight->getOrCreateStateSet()->setAttributeAndModes(gaussx); 00180 blurylight->getOrCreateStateSet()->setAttributeAndModes(gaussy); 00181 } 00182 ssao->addChild(blurxlight); 00183 blurxlight->addChild(blurylight); 00184 00185 // Last step: multiplication of the SSAO and the previous rendering 00186 osgPPU::Unit* composite = new osgPPU::UnitInOut(); 00187 compositeAttr = new osgPPU::ShaderAttribute(); 00188 { 00189 compositeAttr->addShader(osgDB::readShaderFile("screenSpaceAO_composite_vp.glsl", vertexOptions.get())); 00190 compositeAttr->addShader(osgDB::readShaderFile("screenSpaceAO_composite_fp.glsl", fragmentOptions.get())); 00191 compositeAttr->setName("compositeSSAO"); 00192 00193 compositeAttr->add("vSSAO", osg::Uniform::SAMPLER_2D); 00194 compositeAttr->add("vColor", osg::Uniform::SAMPLER_2D); 00195 00196 //compositeAttr->set("vSSAO", 0); 00197 00198 composite->getOrCreateStateSet()->setAttributeAndModes(compositeAttr); 00199 00200 composite->setInputToUniform(blurylight, "vSSAO", true); 00201 composite->setInputToUniform(lColor1, "vColor", true); 00202 } 00203 blurylight->addChild(composite); 00204 00205 pLastUnit = composite; 00206 } 00207 };