// author: Szabolcs Czuczor (BME-IIT) #include "Ogre.h" #include "OgreEffectWrapper.h" #include "ManagedOgreRenderTexturePass.h" #include "PMFFilteringPass.h" /** * @brief: Construtor. */ PMFFilteringPass::PMFFilteringPass( Root* mRoot,unsigned int width,unsigned int height, TextureType texType, PixelFormat internalFormat, const NameValuePairList *miscParams, bool fullScreenQuadRenderer,String renderTextureName) :ManagedOgreRenderTexturePass(mRoot,renderTextureName,width,height,texType,internalFormat,miscParams,fullScreenQuadRenderer) { this->setMaterialName("PMF/PhotonMapFiltering"); generateFilterKernel(PMF_KT_UNIFORM, 2); areaCompensation = 1.0f; normalThreshold = 1.0f; } /** * @brief: Destructor. */ PMFFilteringPass::~PMFFilteringPass() { } void PMFFilteringPass::onRenderStart(NameValuePairList* namedParams){ effectWrapper->SetTechniqueToUse(0); effectWrapper->BeginPass(); effectWrapper->SetFragmentProgramParameters(); effectWrapper->SetFloatArray("filterKernel", f_pmfFilterKernel, 25); effectWrapper->SetFloat("g_fPMTextRes",resolution); effectWrapper->SetFloat("g_fAreaCompensation", areaCompensation); effectWrapper->SetFloat("g_fNormalThreshold", normalThreshold); } void PMFFilteringPass::onRenderEnd(NameValuePairList* namedParams){ effectWrapper->EndPass(); } float PMFFilteringPass::getResolution(){ return resolution; } void PMFFilteringPass::setResolution(float resolution){ this->resolution=resolution; } void PMFFilteringPass::generateFilterKernel(t_pmfKernelType kt, int kernelSize) { i_pmfKernelType = kt; i_pmfKernelSize = kernelSize; for (int i = 0; i < 25; i++) f_pmfFilterKernel[i] = 0.0f; float x; int idx; for (int j = 0; j <= kernelSize; j++) for (int i = 0; i <= kernelSize; i++) { idx = j * 5 + i; x = (float)sqrt((double)(_pmf_sqr(i) + _pmf_sqr(j))) / (float)(kernelSize + 1); switch (kt) { case PMF_KT_UNIFORM: { if (x <= (float)kernelSize) f_pmfFilterKernel[idx] = 0.5f; else f_pmfFilterKernel[idx] = 0.0f; } break; case PMF_KT_TRIANGLE: { f_pmfFilterKernel[idx] = 1.0f - x; } break; case PMF_KT_EPANECHNIKOV: { f_pmfFilterKernel[idx] = 0.75f * (1.0f - _pmf_sqr(x)); } break; case PMF_KT_QUARTIC: { f_pmfFilterKernel[idx] = (15.0f / 16.0f) * _pmf_sqr(1.0f - _pmf_sqr(x)); } break; case PMF_KT_TRIWEIGHT: { f_pmfFilterKernel[idx] = (35.0f / 32.0f) * _pmf_cube(1.0f - _pmf_sqr(x)); } break; case PMF_KT_GAUSS: { f_pmfFilterKernel[idx] = 0.39894228f * (float)exp((double)-_pmf_sqr(x) / 2.0f); } break; case PMF_KT_COSINE: { f_pmfFilterKernel[idx] = (float)cos((_PMF_PI / 2.0f) * x); } break; } if ((kt != PMF_KT_GAUSS) && (x > kernelSize)) f_pmfFilterKernel[idx] = 0.0f; } } void PMFFilteringPass::setAreaCompensation(float ac) { this->areaCompensation = ac; } float PMFFilteringPass::getAreaCompensation() { return this->areaCompensation; } void PMFFilteringPass::setNormalThreshold(float nt) { this->normalThreshold = nt; } float PMFFilteringPass::getNormalThreshold() { return this->normalThreshold; }