From 30ecf34b37f91967a7cb7ed134ecea39727406e3 Mon Sep 17 00:00:00 2001 From: Elderme Date: Fri, 7 Aug 2015 13:50:44 +0200 Subject: [PATCH] Spherical harmonics coefficients are no longer recomputed when the ambient light do not change --- src/graphics/irr_driver.cpp | 18 ++++++++---- src/graphics/sphericalHarmonics.cpp | 44 +++++++++++++++++++++-------- src/graphics/sphericalHarmonics.hpp | 13 ++++++--- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 6471a8c4f..9c6e8337a 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -159,6 +159,7 @@ IrrDriver::~IrrDriver() m_shadow_matrices = NULL; Shaders::destroy(); delete m_wind; + delete m_spherical_harmonics; } // ~IrrDriver // ---------------------------------------------------------------------------- @@ -507,6 +508,7 @@ void IrrDriver::initDevice() CVS->init(); + m_spherical_harmonics = new SphericalHarmonics(m_scene_manager->getAmbientLight().toSColor()); if (UserConfigParams::m_shadows_resolution != 0 && (UserConfigParams::m_shadows_resolution < 512 || @@ -1375,8 +1377,11 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector &tex //prepareSkybox(); //m_skybox_ready = true; m_skybox = new Skybox(texture); - if(spherical_harmonics_textures.size() == 6) + { + m_spherical_harmonics->setTextures(spherical_harmonics_textures); + } + /*if(spherical_harmonics_textures.size() == 6) { if(m_spherical_harmonics != NULL) { @@ -1387,7 +1392,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector &tex else { //m_spherical_harmonic = new SphericalHarmonic(m_scene_manager->getAmbientLight().toSColor()); - } + }*/ return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1], texture[2], texture[3], @@ -1409,8 +1414,8 @@ void IrrDriver::suppressSkyBox() SkyboxSpecularProbe = 0;*/ delete m_skybox; m_skybox = NULL; - delete m_spherical_harmonics; - m_spherical_harmonics = NULL; + //delete m_spherical_harmonics; + //m_spherical_harmonics = NULL; } // ---------------------------------------------------------------------------- @@ -1790,10 +1795,11 @@ void IrrDriver::onUnloadWorld() void IrrDriver::setAmbientLight(const video::SColorf &light) { m_scene_manager->setAmbientLight(light); + m_spherical_harmonics->setAmbientLight(light.toSColor()); //TODO! - if(m_spherical_harmonics == NULL) - m_spherical_harmonics = new SphericalHarmonics(light.toSColor()); + //if(m_spherical_harmonics == NULL) + // m_spherical_harmonics = new SphericalHarmonics(light.toSColor()); //m_skybox_ready = false; } // setAmbientLight diff --git a/src/graphics/sphericalHarmonics.cpp b/src/graphics/sphericalHarmonics.cpp index a26b413e9..a0c812433 100644 --- a/src/graphics/sphericalHarmonics.cpp +++ b/src/graphics/sphericalHarmonics.cpp @@ -357,6 +357,23 @@ void SphericalHarmonics::generateSphericalHarmonics(Color *cubemap_face[6], size // ---------------------------------------------------------------------------- SphericalHarmonics::SphericalHarmonics(const std::vector &spherical_harmonics_textures) +{ + setTextures(spherical_harmonics_textures); +} + +// ---------------------------------------------------------------------------- +/** When spherical harmonics textures are not defined, SH coefficents are computed + * from ambient light + */ +SphericalHarmonics::SphericalHarmonics(const video::SColor &ambient) +{ + //make sure m_ambient and ambient are not equal + m_ambient = (ambient==0) ? 1 : 0; + setAmbientLight(ambient); +} + +/** Compute spherical harmonics coefficients from 6 textures */ +void SphericalHarmonics::setTextures(const std::vector &spherical_harmonics_textures) { assert(spherical_harmonics_textures.size() == 6); @@ -399,16 +416,19 @@ SphericalHarmonics::SphericalHarmonics(const std::vector &sph { delete[] sh_rgba[i]; delete[] float_tex_cube[i]; - } - -}// SphericalHarmonics(const std::vector &spherical_harmonics_textures) + } +} //setSphericalHarmonicsTextures -// ---------------------------------------------------------------------------- -/** When spherical harmonics textures are not defined, SH coefficents are computed - * from ambient light - */ -SphericalHarmonics::SphericalHarmonics(const video::SColor &ambient) -{ +/** Compute spherical harmonics coefficients from ambient light */ +void SphericalHarmonics::setAmbientLight(const video::SColor &ambient) +{ + //do not recompute SH coefficients if we already use the same ambient light + if((m_spherical_harmonics_textures.size() != 6) && (ambient == m_ambient)) + return; + + m_spherical_harmonics_textures.clear(); + m_ambient = ambient; + unsigned char *sh_rgba[6]; unsigned sh_w = 16; unsigned sh_h = 16; @@ -442,11 +462,11 @@ SphericalHarmonics::SphericalHarmonics(const video::SColor &ambient) m_blue_SH_coeff[i] *= 4; m_green_SH_coeff[i] *= 4; m_red_SH_coeff[i] *= 4; - } - -}// SphericalHarmonics(const video::SColor &ambient) + } +} //setAmbientLight // ---------------------------------------------------------------------------- +/** Print spherical harmonics coefficients (debug) */ void SphericalHarmonics::printCoeff() { Log::debug("SphericalHarmonics", "Blue_SH:"); displayCoeff(m_blue_SH_coeff); diff --git a/src/graphics/sphericalHarmonics.hpp b/src/graphics/sphericalHarmonics.hpp index b56366ac3..2b2e714cd 100644 --- a/src/graphics/sphericalHarmonics.hpp +++ b/src/graphics/sphericalHarmonics.hpp @@ -35,11 +35,15 @@ class SphericalHarmonics private: /** The 6 spherical harmonics textures */ std::vector m_spherical_harmonics_textures; - + + /** Ambient light is used for tracks without spherical harmonics textures */ + irr::video::SColor m_ambient; + /** The spherical harmonics coefficients */ float m_blue_SH_coeff[9]; float m_green_SH_coeff[9]; - float m_red_SH_coeff[9]; + float m_red_SH_coeff[9]; + void projectSH(Color *cubemap_face[6], size_t edge_size, float *Y00[], float *Y1minus1[], float *Y10[], float *Y11[], @@ -52,14 +56,15 @@ public: SphericalHarmonics(const std::vector &spherical_harmonics_textures); SphericalHarmonics(const irr::video::SColor &ambient); + void setTextures(const std::vector &spherical_harmonics_textures); + void setAmbientLight(const irr::video::SColor &ambient); + inline const float* getBlueSHCoeff () const {return m_blue_SH_coeff; } inline const float* getGreenSHCoeff() const {return m_green_SH_coeff; } inline const float* getRedSHCoeff () const {return m_red_SH_coeff; } - /** Print spherical harmonics coefficients (debug) */ void printCoeff(); - /** Compute environment map from the spherical harmonics */ void unprojectSH (size_t width, size_t height, float *Y00[], float *Y1minus1[], float *Y10[], float *Y11[], float *Y2minus2[], float *Y2minus1[],