probeManager.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "lighting/probeManager.h"
  24. #include "console/console.h"
  25. #include "console/consoleTypes.h"
  26. #include "core/util/safeDelete.h"
  27. #include "console/sim.h"
  28. #include "console/simSet.h"
  29. #include "scene/sceneManager.h"
  30. #include "materials/materialManager.h"
  31. #include "materials/sceneData.h"
  32. #include "lighting/lightInfo.h"
  33. #include "lighting/lightingInterfaces.h"
  34. #include "T3D/gameBase/gameConnection.h"
  35. #include "gfx/gfxStringEnumTranslate.h"
  36. #include "console/engineAPI.h"
  37. #include "renderInstance/renderDeferredMgr.h"
  38. #include "shaderGen/shaderGenVars.h"
  39. #include "math/util/sphereMesh.h"
  40. Signal<void(const char*,bool)> ProbeManager::smActivateSignal;
  41. ProbeManager *ProbeManager::smProbeManager = NULL;
  42. bool ProbeManager::smRenderReflectionProbes = true;
  43. //
  44. //
  45. ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
  46. mTransform(true),
  47. mDirty(false),
  48. mAmbient(0.0f, 0.0f, 0.0f, 1.0f),
  49. mPriority(1.0f),
  50. mScore(0.0f),
  51. mDebugRender(false),
  52. mCubemap(NULL),
  53. mIrradianceCubemap(NULL),
  54. mBRDFTexture(NULL),
  55. mRadius(1.0f),
  56. mIntensity(1.0f),
  57. mProbePosOffset(0,0,0),
  58. numPrims(0)
  59. {
  60. for (U32 i = 0; i < 5; ++i)
  61. {
  62. mSHConstants[i] = 0;
  63. }
  64. }
  65. ProbeRenderInst::~ProbeRenderInst()
  66. {
  67. if (mCubemap && mCubemap->isValid())
  68. {
  69. mCubemap->free();
  70. }
  71. if (mIrradianceCubemap && mIrradianceCubemap->isValid())
  72. {
  73. mIrradianceCubemap->free();
  74. }
  75. if (mBRDFTexture && mBRDFTexture->isValid())
  76. {
  77. mBRDFTexture->free();
  78. }
  79. }
  80. void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
  81. {
  82. mTransform = probeInfo->mTransform;
  83. mAmbient = probeInfo->mAmbient;
  84. mCubemap = probeInfo->mCubemap;
  85. mIrradianceCubemap = probeInfo->mIrradianceCubemap;
  86. mBRDFTexture = probeInfo->mBRDFTexture;
  87. mRadius = probeInfo->mRadius;
  88. mIntensity = probeInfo->mIntensity;
  89. mProbeShapeType = probeInfo->mProbeShapeType;
  90. numPrims = probeInfo->numPrims;
  91. numVerts = probeInfo->numVerts;
  92. numIndicesForPoly = probeInfo->numIndicesForPoly;
  93. mBounds = probeInfo->mBounds;
  94. for (U32 i = 0; i < 9; i++)
  95. {
  96. mSHTerms[i] = probeInfo->mSHTerms[i];
  97. }
  98. for (U32 i = 0; i < 5; i++)
  99. {
  100. mSHConstants[i] = probeInfo->mSHConstants[i];
  101. }
  102. }
  103. void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const
  104. {
  105. *outMatrix = getTransform();
  106. outMatrix->inverse();
  107. }
  108. ProbeShaderConstants::ProbeShaderConstants()
  109. : mInit(false),
  110. mShader(NULL),
  111. mProbeParamsSC(NULL),
  112. mProbePositionSC(NULL),
  113. mProbeRadiusSC(NULL),
  114. mProbeBoxMinSC(NULL),
  115. mProbeBoxMaxSC(NULL),
  116. mProbeIsSphereSC(NULL),
  117. mProbeLocalPosSC(NULL),
  118. mProbeCubemapSC(NULL)
  119. {
  120. }
  121. ProbeShaderConstants::~ProbeShaderConstants()
  122. {
  123. if (mShader.isValid())
  124. {
  125. mShader->getReloadSignal().remove(this, &ProbeShaderConstants::_onShaderReload);
  126. mShader = NULL;
  127. }
  128. }
  129. void ProbeShaderConstants::init(GFXShader* shader)
  130. {
  131. if (mShader.getPointer() != shader)
  132. {
  133. if (mShader.isValid())
  134. mShader->getReloadSignal().remove(this, &ProbeShaderConstants::_onShaderReload);
  135. mShader = shader;
  136. mShader->getReloadSignal().notify(this, &ProbeShaderConstants::_onShaderReload);
  137. }
  138. mProbeParamsSC = shader->getShaderConstHandle("$probeParams");
  139. //Reflection Probes
  140. mProbePositionSC = shader->getShaderConstHandle(ShaderGenVars::probePosition);
  141. mProbeRadiusSC = shader->getShaderConstHandle(ShaderGenVars::probeRadius);
  142. mProbeBoxMinSC = shader->getShaderConstHandle(ShaderGenVars::probeBoxMin);
  143. mProbeBoxMaxSC = shader->getShaderConstHandle(ShaderGenVars::probeBoxMax);
  144. mProbeIsSphereSC = shader->getShaderConstHandle(ShaderGenVars::probeIsSphere);
  145. mProbeLocalPosSC = shader->getShaderConstHandle(ShaderGenVars::probeLocalPos);
  146. mProbeCubemapSC = shader->getShaderConstHandle(ShaderGenVars::probeCubemap);
  147. mInit = true;
  148. }
  149. void ProbeShaderConstants::_onShaderReload()
  150. {
  151. if (mShader.isValid())
  152. init(mShader);
  153. }
  154. ProbeManager::ProbeManager()
  155. : mSceneManager( NULL ),
  156. mCullPos( Point3F::Zero )
  157. {
  158. mLastShader = NULL;
  159. mLastConstants = NULL;
  160. mSkylightMaterial = nullptr;
  161. mReflectProbeMaterial = nullptr;
  162. }
  163. ProbeManager::~ProbeManager()
  164. {
  165. }
  166. ProbeRenderInst* ProbeManager::createProbeInfo(ProbeRenderInst* probe /* = NULL */)
  167. {
  168. ProbeRenderInst *outProbe = (probe != NULL) ? probe : new ProbeRenderInst;
  169. /*ProbeManagerMap &ProbeManagers = _getProbeManagers();
  170. ProbeManagerMap::Iterator iter = ProbeManagers.begin();
  171. for ( ; iter != ProbeManagers.end(); iter++ )
  172. {
  173. ProbeManager *lm = iter->value;
  174. lm->_addLightInfoEx( outLight );
  175. }*/
  176. return outProbe;
  177. }
  178. void ProbeManager::registerProbe(U32 probeIdx)
  179. {
  180. //Mostly for consolidation, but also lets us sanity check or prep any other data we need for rendering this in one place at time of flagging for render
  181. if (probeIdx >= ProbeRenderInst::all.size())
  182. return;
  183. mRegisteredProbes.push_back_unique(probeIdx);
  184. }
  185. /*void ProbeManager::initLightFields()
  186. {
  187. ProbeManagerMap &ProbeManagers = _getProbeManagers();
  188. ProbeManagerMap::Iterator iter = ProbeManagers.begin();
  189. for ( ; iter != ProbeManagers.end(); iter++ )
  190. {
  191. ProbeManager *lm = iter->value;
  192. lm->_initLightFields();
  193. }
  194. }*/
  195. IMPLEMENT_GLOBAL_CALLBACK( onProbeManagerActivate, void, ( const char *name ), ( name ),
  196. "A callback called by the engine when a light manager is activated.\n"
  197. "@param name The name of the light manager being activated.\n"
  198. "@ingroup Lighting\n" );
  199. void ProbeManager::activate( SceneManager *sceneManager )
  200. {
  201. AssertFatal( sceneManager, "ProbeManager::activate() - Got null scene manager!" );
  202. //AssertFatal( mIsActive == false, "ProbeManager::activate() - Already activated!" );
  203. AssertFatal(smProbeManager == NULL, "ProbeManager::activate() - A previous ProbeManager is still active!" );
  204. mSceneManager = sceneManager;
  205. smProbeManager = this;
  206. }
  207. IMPLEMENT_GLOBAL_CALLBACK( onProbeManagerDeactivate, void, ( const char *name ), ( name ),
  208. "A callback called by the engine when a light manager is deactivated.\n"
  209. "@param name The name of the light manager being deactivated.\n"
  210. "@ingroup Lighting\n" );
  211. void ProbeManager::deactivate()
  212. {
  213. //AssertFatal( mIsActive == true, "ProbeManager::deactivate() - Already deactivated!" );
  214. AssertFatal( smProbeManager == this, "ProbeManager::activate() - This isn't the active light manager!" );
  215. //if( Sim::getRootGroup() ) // To protect against shutdown.
  216. // onProbeManagerDeactivate_callback( getName() );
  217. //mIsActive = false;
  218. mSceneManager = NULL;
  219. smProbeManager = NULL;
  220. }
  221. ProbeShaderConstants* ProbeManager::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
  222. {
  223. if (!buffer)
  224. return NULL;
  225. PROFILE_SCOPE(ProbeManager_GetProbeShaderConstants);
  226. GFXShader* shader = buffer->getShader();
  227. // Check to see if this is the same shader, we'll get hit repeatedly by
  228. // the same one due to the render bin loops.
  229. if (mLastShader.getPointer() != shader)
  230. {
  231. ProbeConstantMap::Iterator iter = mConstantLookup.find(shader);
  232. if (iter != mConstantLookup.end())
  233. {
  234. mLastConstants = iter->value;
  235. }
  236. else
  237. {
  238. ProbeShaderConstants* psc = new ProbeShaderConstants();
  239. mConstantLookup[shader] = psc;
  240. mLastConstants = psc;
  241. }
  242. // Set our new shader
  243. mLastShader = shader;
  244. }
  245. mLastConstants = new ProbeShaderConstants();
  246. // Make sure that our current lighting constants are initialized
  247. if (!mLastConstants->mInit)
  248. mLastConstants->init(shader);
  249. return mLastConstants;
  250. }
  251. void ProbeManager::_update4ProbeConsts( const SceneData &sgData,
  252. MatrixSet &matSet,
  253. GFXShaderConstHandle *probePositionSC,
  254. GFXShaderConstHandle *probeRadiusSC,
  255. GFXShaderConstHandle *probeBoxMinSC,
  256. GFXShaderConstHandle *probeBoxMaxSC,
  257. GFXShaderConstHandle *probeCubemapSC,
  258. GFXShaderConstHandle *probeIsSphereSC,
  259. GFXShaderConstHandle *probeLocalPosSC,
  260. GFXShaderConstBuffer *shaderConsts )
  261. {
  262. PROFILE_SCOPE( ProbeManager_Update4ProbeConsts );
  263. // Skip over gathering lights if we don't have to!
  264. if (probePositionSC->isValid() ||
  265. probeRadiusSC->isValid() ||
  266. probeBoxMinSC->isValid() ||
  267. probeBoxMaxSC->isValid() ||
  268. probeCubemapSC->isValid() && (!ProbeRenderInst::all.empty()))
  269. {
  270. PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
  271. static AlignedArray<Point3F> probePositions(4, sizeof(Point3F));
  272. static AlignedArray<F32> probeRadius(4, sizeof(F32));
  273. static AlignedArray<Point3F> probeBoxMins(4, sizeof(Point3F));
  274. static AlignedArray<Point3F> probeBoxMaxs(4, sizeof(Point3F));
  275. static AlignedArray<Point3F> probeLocalPositions(4, sizeof(Point3F));
  276. static AlignedArray<F32> probeIsSphere(4, sizeof(F32));
  277. //static AlignedArray<CubemapData> probeCubemap(4, sizeof(CubemapData));
  278. F32 range;
  279. // Need to clear the buffers so that we don't leak
  280. // lights from previous passes or have NaNs.
  281. dMemset(probePositions.getBuffer(), 0, probePositions.getBufferSize());
  282. dMemset(probeRadius.getBuffer(), 0, probeRadius.getBufferSize());
  283. dMemset(probeBoxMins.getBuffer(), 0, probeBoxMins.getBufferSize());
  284. dMemset(probeBoxMaxs.getBuffer(), 0, probeBoxMaxs.getBufferSize());
  285. dMemset(probeLocalPositions.getBuffer(), 0, probeLocalPositions.getBufferSize());
  286. dMemset(probeIsSphere.getBuffer(), 0, probeRadius.getBufferSize());
  287. //dMemset(probeCubemap.getBuffer(), 0, probeCubemap.getBufferSize());
  288. matSet.restoreSceneViewProjection();
  289. const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
  290. // Gather the data for the first 4 probes.
  291. const ProbeRenderInst *probe;
  292. for (U32 i = 0; i < 4; i++)
  293. {
  294. if (i >= ProbeRenderInst::all.size())
  295. break;
  296. probe = ProbeRenderInst::all[i];
  297. if (!probe)
  298. continue;
  299. if (!probe->mIsEnabled)
  300. continue;
  301. // The light positions and spot directions are
  302. // in SoA order to make optimal use of the GPU.
  303. const Point3F &probePos = probe->getPosition();
  304. probePositions[i].x = probePos.x;
  305. probePositions[i].y = probePos.y;
  306. probePositions[i].z = probePos.z;
  307. probeRadius[i] = probe->mRadius;
  308. const Point3F &minExt = probe->mBounds.minExtents;
  309. probeBoxMins[i].x = minExt.x;
  310. probeBoxMins[i].y = minExt.y;
  311. probeBoxMins[i].z = minExt.z;
  312. const Point3F &maxExt = probe->mBounds.maxExtents;
  313. probeBoxMaxs[i].x = maxExt.x;
  314. probeBoxMaxs[i].y = maxExt.y;
  315. probeBoxMaxs[i].z = maxExt.z;
  316. probeIsSphere[i] = probe->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0 : 0.0;
  317. Point3F localProbePos;
  318. worldToCameraXfm.mulP(probe->getPosition(), &localProbePos);
  319. probeLocalPositions[i].x = localProbePos.x;
  320. probeLocalPositions[i].y = localProbePos.y;
  321. probeLocalPositions[i].z = localProbePos.z;
  322. if (probe->mCubemap && !probe->mCubemap->isNull())
  323. {
  324. S32 samplerReg = probeCubemapSC->getSamplerRegister();
  325. if(samplerReg != -1)
  326. GFX->setCubeTexture(samplerReg + i, probe->mCubemap->getPointer());
  327. }
  328. }
  329. shaderConsts->setSafe(probePositionSC, probePositions);
  330. shaderConsts->setSafe(probeRadiusSC, probeRadius);
  331. shaderConsts->setSafe(probeBoxMinSC, probeBoxMins);
  332. shaderConsts->setSafe(probeBoxMaxSC, probeBoxMaxs);
  333. shaderConsts->setSafe(probeLocalPosSC, probeLocalPositions);
  334. shaderConsts->setSafe(probeIsSphereSC, probeIsSphere);
  335. //
  336. //shaderConsts->setSafe(lightSpotAngleSC, lightSpotAngle);
  337. //shaderConsts->setSafe(lightSpotFalloffSC, lightSpotFalloff);
  338. }
  339. else
  340. {
  341. /*if (probe->mCubemap && !probe->mCubemap->isNull())
  342. {
  343. GFX->setCubeTexture(1, probe->mCubemap->getPointer());
  344. }*/
  345. if (probeCubemapSC->isValid())
  346. {
  347. for(U32 i=0; i < 4; ++i)
  348. GFX->setCubeTexture(probeCubemapSC->getSamplerRegister() + i, NULL);
  349. }
  350. }
  351. }
  352. void ProbeManager::setProbeInfo(ProcessedMaterial *pmat,
  353. const Material *mat,
  354. const SceneData &sgData,
  355. const SceneRenderState *state,
  356. U32 pass,
  357. GFXShaderConstBuffer *shaderConsts)
  358. {
  359. // Skip this if we're rendering from the deferred bin.
  360. if ( sgData.binType == SceneData::DeferredBin )
  361. return;
  362. // if (mRegisteredProbes.empty())
  363. // return;
  364. PROFILE_SCOPE(ProbeManager_setProbeInfo);
  365. ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts);
  366. //ProbeInfo *probe;
  367. //probe = mRegisteredProbes[0];
  368. // NOTE: If you encounter a crash from this point forward
  369. // while setting a shader constant its probably because the
  370. // mConstantLookup has bad shaders/constants in it.
  371. //
  372. // This is a known crash bug that can occur if materials/shaders
  373. // are reloaded and the light manager is not reset.
  374. //
  375. // We should look to fix this by clearing the table.
  376. MatrixSet matSet = state->getRenderPass()->getMatrixSet();
  377. // Update the forward shading light constants.
  378. _update4ProbeConsts( sgData,
  379. matSet,
  380. psc->mProbePositionSC,
  381. psc->mProbeRadiusSC,
  382. psc->mProbeBoxMinSC,
  383. psc->mProbeBoxMaxSC,
  384. psc->mProbeCubemapSC,
  385. psc->mProbeIsSphereSC,
  386. psc->mProbeLocalPosSC,
  387. shaderConsts );
  388. // Static
  389. /*if (lsm && light->getCastShadows())
  390. {
  391. if (psc->mWorldToLightProjSC->isValid())
  392. shaderConsts->set(psc->mWorldToLightProjSC,
  393. lsm->getWorldToLightProj(),
  394. psc->mWorldToLightProjSC->getType());
  395. if (psc->mViewToLightProjSC->isValid())
  396. {
  397. // TODO: Should probably cache these results and
  398. // not do this mul here on every material that needs
  399. // this transform.
  400. shaderConsts->set(psc->mViewToLightProjSC,
  401. lsm->getWorldToLightProj() * state->getCameraTransform(),
  402. psc->mViewToLightProjSC->getType());
  403. }
  404. shaderConsts->setSafe(psc->mShadowMapSizeSC, 1.0f / (F32)lsm->getTexSize());
  405. // Do this last so that overrides can properly override parameters previously set
  406. lsm->setShaderParameters(shaderConsts, psc);
  407. }
  408. else
  409. {
  410. if (psc->mViewToLightProjSC->isValid())
  411. {
  412. // TODO: Should probably cache these results and
  413. // not do this mul here on every material that needs
  414. // this transform.
  415. MatrixF proj;
  416. light->getWorldToLightProj(&proj);
  417. shaderConsts->set(psc->mViewToLightProjSC,
  418. proj * state->getCameraTransform(),
  419. psc->mViewToLightProjSC->getType());
  420. }
  421. }
  422. // Dynamic
  423. if (dynamicShadowMap)
  424. {
  425. if (psc->mDynamicWorldToLightProjSC->isValid())
  426. shaderConsts->set(psc->mDynamicWorldToLightProjSC,
  427. dynamicShadowMap->getWorldToLightProj(),
  428. psc->mDynamicWorldToLightProjSC->getType());
  429. if (psc->mDynamicViewToLightProjSC->isValid())
  430. {
  431. // TODO: Should probably cache these results and
  432. // not do this mul here on every material that needs
  433. // this transform.
  434. shaderConsts->set(psc->mDynamicViewToLightProjSC,
  435. dynamicShadowMap->getWorldToLightProj() * state->getCameraTransform(),
  436. psc->mDynamicViewToLightProjSC->getType());
  437. }
  438. shaderConsts->setSafe(psc->mShadowMapSizeSC, 1.0f / (F32)dynamicShadowMap->getTexSize());
  439. // Do this last so that overrides can properly override parameters previously set
  440. dynamicShadowMap->setShaderParameters(shaderConsts, psc);
  441. }
  442. else
  443. {
  444. if (psc->mDynamicViewToLightProjSC->isValid())
  445. {
  446. // TODO: Should probably cache these results and
  447. // not do this mul here on every material that needs
  448. // this transform.
  449. MatrixF proj;
  450. light->getWorldToLightProj(&proj);
  451. shaderConsts->set(psc->mDynamicViewToLightProjSC,
  452. proj * state->getCameraTransform(),
  453. psc->mDynamicViewToLightProjSC->getType());
  454. }
  455. }*/
  456. }
  457. /// Allows us to set textures during the Material::setTextureStage call, return true if we've done work.
  458. bool ProbeManager::setTextureStage(const SceneData &sgData,
  459. const U32 currTexFlag,
  460. const U32 textureSlot,
  461. GFXShaderConstBuffer *shaderConsts,
  462. ShaderConstHandles *handles)
  463. {
  464. return false;
  465. }
  466. AvailableSLInterfaces* ProbeManager::getSceneLightingInterface()
  467. {
  468. //if ( !mAvailableSLInterfaces )
  469. // mAvailableSLInterfaces = new AvailableSLInterfaces();
  470. return NULL;
  471. }
  472. void ProbeManager::updateDirtyProbes()
  473. {
  474. for (U32 i = 0; i < ProbeRenderInst::all.size(); i++)
  475. {
  476. ProbeRenderInst* probe = ProbeRenderInst::all[i];
  477. if (probe->mDirty)
  478. {
  479. //make sure we have a fill-out on our primitives, materials, etc
  480. //so we don't have to always force an update when it's not needed
  481. if (probe->mIsSkylight)
  482. {
  483. setupSkylightProbe(probe);
  484. }
  485. else
  486. {
  487. if (probe->mProbeShapeType == ProbeRenderInst::Sphere)
  488. {
  489. setupSphereReflectionProbe(probe);
  490. }
  491. else if(probe->mProbeShapeType == ProbeRenderInst::Box)
  492. {
  493. setupConvexReflectionProbe(probe);
  494. }
  495. }
  496. probe->mDirty = false;
  497. }
  498. }
  499. }
  500. ProbeManager::SkylightMaterialInfo* ProbeManager::getSkylightMaterial()
  501. {
  502. PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial);
  503. //ReflectProbeMaterialInfo *info = NULL;
  504. if (!mSkylightMaterial)
  505. // Now create the material info object.
  506. mSkylightMaterial = new SkylightMaterialInfo("SkyLightMaterial",
  507. getGFXVertexFormat<GFXVertexPC>());
  508. return mSkylightMaterial;
  509. }
  510. ProbeManager::ReflectProbeMaterialInfo* ProbeManager::getReflectProbeMaterial()
  511. {
  512. PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial);
  513. //ReflectProbeMaterialInfo *info = NULL;
  514. if (!mReflectProbeMaterial)
  515. // Now create the material info object.
  516. mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial",
  517. getGFXVertexFormat<GFXVertexPC>());
  518. return mReflectProbeMaterial;
  519. }
  520. void ProbeManager::setupSkylightProbe(ProbeRenderInst *probeInfo)
  521. {
  522. probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
  523. if (!mSkylightMaterial)
  524. mSkylightMaterial = getSkylightMaterial();
  525. }
  526. void ProbeManager::setupSphereReflectionProbe(ProbeRenderInst *probeInfo)
  527. {
  528. probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
  529. if (!mReflectProbeMaterial)
  530. mReflectProbeMaterial = getReflectProbeMaterial();
  531. }
  532. void ProbeManager::setupConvexReflectionProbe(ProbeRenderInst *probeInfo)
  533. {
  534. static const Point3F cubePoints[8] =
  535. {
  536. Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1),
  537. Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
  538. };
  539. /*static const Point3F cubeNormals[6] =
  540. {
  541. Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0),
  542. Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1)
  543. };*/
  544. /*static const Point2F cubeTexCoords[4] =
  545. {
  546. Point2F(0, 0), Point2F(0, -1),
  547. Point2F(1, 0), Point2F(1, -1)
  548. };*/
  549. static const U32 cubeFaces[36][3] =
  550. {
  551. { 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 },
  552. { 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 },
  553. { 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 },
  554. { 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 },
  555. { 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 },
  556. { 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 },
  557. { 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 },
  558. { 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 },
  559. { 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 },
  560. { 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 },
  561. { 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 },
  562. { 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 }
  563. };
  564. // Fill the vertex buffer
  565. GFXVertexPC *pVert = NULL;
  566. probeInfo->numVerts = 36;
  567. probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic);
  568. pVert = probeInfo->vertBuffer.lock();
  569. Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius);
  570. for (U32 i = 0; i < 36; i++)
  571. {
  572. const U32& vdx = cubeFaces[i][0];
  573. pVert[i].point = cubePoints[vdx] * halfSize;
  574. }
  575. probeInfo->vertBuffer.unlock();
  576. // Fill the primitive buffer
  577. U16 *pIdx = NULL;
  578. probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic);
  579. probeInfo->primBuffer.lock(&pIdx);
  580. for (U16 i = 0; i < 36; i++)
  581. pIdx[i] = i;
  582. probeInfo->primBuffer.unlock();
  583. probeInfo->numPrims = 12;
  584. if (!mReflectProbeMaterial)
  585. mReflectProbeMaterial = getReflectProbeMaterial();
  586. //
  587. // mReflectProbeBin.push_back(pEntry);
  588. }
  589. GFXVertexBufferHandle<GFXVertexPC> ProbeManager::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives)
  590. {
  591. static SphereMesh sSphereMesh;
  592. if (mSphereGeometry.isNull())
  593. {
  594. const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3);
  595. S32 numPoly = sphereMesh->numPoly;
  596. mSpherePrimitiveCount = 0;
  597. mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic);
  598. mSphereGeometry.lock();
  599. S32 vertexIndex = 0;
  600. for (S32 i = 0; i<numPoly; i++)
  601. {
  602. mSpherePrimitiveCount++;
  603. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0];
  604. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  605. vertexIndex++;
  606. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1];
  607. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  608. vertexIndex++;
  609. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2];
  610. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  611. vertexIndex++;
  612. }
  613. mSphereGeometry.unlock();
  614. }
  615. outNumPrimitives = mSpherePrimitiveCount;
  616. outPrimitives = NULL; // For now
  617. return mSphereGeometry;
  618. }
  619. //
  620. //
  621. bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
  622. {
  623. bool success = Parent::init(features, vertexFormat);
  624. // If the initialization failed don't continue.
  625. if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
  626. return false;
  627. return true;
  628. }
  629. bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
  630. {
  631. // Go no further if the material failed to initialize properly.
  632. if (!mProcessedMaterial ||
  633. mProcessedMaterial->getNumPasses() == 0)
  634. return false;
  635. bool bRetVal = Parent::setupPass(state, sgData);;
  636. AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
  637. const RenderPassData *rpd = mProcessedMaterial->getPass(0);
  638. AssertFatal(rpd, "No render pass data!");
  639. AssertFatal(rpd->mRenderStates[0], "No render state 0!");
  640. if (!mProjectionState)
  641. {
  642. GFXStateBlockDesc desc;
  643. desc.setZReadWrite(false);
  644. desc.zWriteEnable = false;
  645. desc.setCullMode(GFXCullNone);
  646. desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendDestAlpha, GFXBlendOpMax);
  647. mProjectionState = GFX->createStateBlock(desc);
  648. }
  649. // Now override stateblock with our own
  650. GFX->setStateBlock(mProjectionState);
  651. return bRetVal;
  652. }
  653. //
  654. //
  655. ProbeManager::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName,
  656. const GFXVertexFormat *vertexFormat)
  657. : matInstance(NULL),
  658. zNearFarInvNearFar(NULL),
  659. farPlane(NULL),
  660. vsFarPlane(NULL),
  661. negFarPlaneDotEye(NULL),
  662. probeWSPos(NULL),
  663. attenuation(NULL),
  664. radius(NULL),
  665. cubeMips(NULL)
  666. {
  667. Material *mat = MATMGR->getMaterialDefinitionByName(matName);
  668. if (!mat)
  669. return;
  670. matInstance = new ReflectProbeMatInstance(*mat);
  671. const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
  672. for (U32 i = 0; i < macros.size(); i++)
  673. matInstance->addShaderMacro(macros[i].name, macros[i].value);
  674. matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
  675. attenuation = matInstance->getMaterialParameterHandle("$attenuation");
  676. radius = matInstance->getMaterialParameterHandle("$radius");
  677. probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos");
  678. probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos");
  679. farPlane = matInstance->getMaterialParameterHandle("$farPlane");
  680. vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
  681. negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
  682. zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
  683. useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
  684. cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
  685. cubeMips = matInstance->getMaterialParameterHandle("$cubeMips");
  686. eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
  687. bbMin = matInstance->getMaterialParameterHandle("$bbMin");
  688. bbMax = matInstance->getMaterialParameterHandle("$bbMax");
  689. useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode");
  690. for (U32 i = 0; i < 9; i++)
  691. shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
  692. for (U32 i = 0; i < 5; i++)
  693. shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
  694. }
  695. ProbeManager::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo()
  696. {
  697. SAFE_DELETE(matInstance);
  698. }
  699. void ProbeManager::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear,
  700. const F32 _zFar,
  701. const Point3F &_eyePos,
  702. const PlaneF &_farPlane,
  703. const PlaneF &_vsFarPlane)
  704. {
  705. MaterialParameters *matParams = matInstance->getMaterialParameters();
  706. matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
  707. matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
  708. if (negFarPlaneDotEye->isValid())
  709. {
  710. // -dot( farPlane, eyePos )
  711. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  712. matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
  713. }
  714. matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
  715. Point4F frPlane = *((const Point4F *)&_farPlane);
  716. Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
  717. Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
  718. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  719. }
  720. void ProbeManager::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
  721. {
  722. //Set up the params
  723. MaterialParameters *matParams = matInstance->getMaterialParameters();
  724. matParams->setSafe(radius, probeInfo->mRadius);
  725. Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset;
  726. //worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
  727. matParams->setSafe(probeWSPos, probePos);
  728. worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
  729. matParams->setSafe(probeLSPos, probePos);
  730. // Get the attenuation falloff ratio and normalize it.
  731. Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f);
  732. F32 total = attenRatio.x + attenRatio.y + attenRatio.z;
  733. if (total > 0.0f)
  734. attenRatio /= total;
  735. F32 probeRadius = probeInfo->mRadius;
  736. Point2F attenParams((1.0f / probeRadius) * attenRatio.y,
  737. (1.0f / (probeRadius * probeRadius)) * attenRatio.z);
  738. matParams->setSafe(attenuation, attenParams);
  739. NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
  740. NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
  741. NamedTexTarget* colorTexTarget = NamedTexTarget::find("color");
  742. if (!deferredTexTarget || !matInfoTexTarget || !colorTexTarget)
  743. {
  744. Con::errorf("ProbeManager::ReflectProbeMaterialInfo::setProbeParameters: Could not retrieve gbuffer");
  745. return;
  746. }
  747. //set textures
  748. GFX->setTexture(0, deferredTexTarget->getTexture());
  749. GFX->setTexture(1, matInfoTexTarget->getTexture());
  750. GFX->setTexture(2, colorTexTarget->getTexture());
  751. GFX->setCubeTexture(3, probeInfo->mCubemap->getPointer());
  752. GFX->setCubeTexture(4, probeInfo->mIrradianceCubemap->getPointer());
  753. GFX->setTexture(5, probeInfo->mBRDFTexture->getPointer());
  754. //set material params
  755. matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(), 2.0f));
  756. matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
  757. matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
  758. matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
  759. matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f);
  760. //SH Terms
  761. //static AlignedArray<Point3F> shTermsArray(9, sizeof(Point3F));
  762. //dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize());
  763. /*for (U32 i = 0; i < 9; i++)
  764. {
  765. matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
  766. }
  767. for (U32 i = 0; i < 5; i++)
  768. {
  769. matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
  770. }*/
  771. //const MatrixF worldToObjectXfm = probeInfo->mTransform;
  772. //MaterialParameterHandle *worldToObjMat = matInstance->getMaterialParameterHandle("$worldToObj");
  773. //matParams->setSafe(worldToObjMat, worldToObjectXfm);
  774. }
  775. //
  776. //
  777. //
  778. ProbeManager::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName,
  779. const GFXVertexFormat *vertexFormat)
  780. : ReflectProbeMaterialInfo(matName, vertexFormat)
  781. {
  782. Material *mat = MATMGR->getMaterialDefinitionByName(matName);
  783. if (!mat)
  784. return;
  785. matInstance = new SkylightMatInstance(*mat);
  786. const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
  787. for (U32 i = 0; i < macros.size(); i++)
  788. matInstance->addShaderMacro(macros[i].name, macros[i].value);
  789. matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
  790. farPlane = matInstance->getMaterialParameterHandle("$farPlane");
  791. vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
  792. negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
  793. zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
  794. useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
  795. cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
  796. eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
  797. /*for (U32 i = 0; i < 9; i++)
  798. shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
  799. for (U32 i = 0; i < 5; i++)
  800. shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));*/
  801. }
  802. ProbeManager::SkylightMaterialInfo::~SkylightMaterialInfo()
  803. {
  804. SAFE_DELETE(matInstance);
  805. }
  806. /*bool ProbeManager::lightScene( const char* callback, const char* param )
  807. {
  808. BitSet32 flags = 0;
  809. if ( param )
  810. {
  811. if ( !dStricmp( param, "forceAlways" ) )
  812. flags.set( SceneLighting::ForceAlways );
  813. else if ( !dStricmp(param, "forceWritable" ) )
  814. flags.set( SceneLighting::ForceWritable );
  815. else if ( !dStricmp(param, "loadOnly" ) )
  816. flags.set( SceneLighting::LoadOnly );
  817. }
  818. // The SceneLighting object will delete itself
  819. // once the lighting process is complete.
  820. SceneLighting* sl = new SceneLighting( getSceneLightingInterface() );
  821. return sl->lightScene( callback, flags );
  822. }*/
  823. /*RenderDeferredMgr* ProbeManager::_findDeferredRenderBin()
  824. {
  825. RenderPassManager* rpm = getSceneManager()->getDefaultRenderPass();
  826. for( U32 i = 0; i < rpm->getManagerCount(); i++ )
  827. {
  828. RenderBinManager *bin = rpm->getManager( i );
  829. if( bin->getRenderInstType() == RenderDeferredMgr::RIT_Deferred )
  830. {
  831. return ( RenderDeferredMgr* ) bin;
  832. }
  833. }
  834. return NULL;
  835. }*/
  836. DefineEngineFunction( CreateProbeManager, bool, (),,
  837. "Finds and activates the named light manager.\n"
  838. "@return Returns true if the light manager is found and activated.\n"
  839. "@ingroup Lighting\n" )
  840. {
  841. ProbeManager* probeManager = new ProbeManager();
  842. if (probeManager != nullptr && gClientSceneGraph != nullptr)
  843. {
  844. probeManager->activate(gClientSceneGraph);
  845. return true;
  846. }
  847. return false;
  848. }
  849. DefineEngineFunction( resetProbeManager, void, (),,
  850. "@brief Deactivates and then activates the currently active light manager."
  851. "This causes most shaders to be regenerated and is often used when global "
  852. "rendering changes have occured.\n"
  853. "@ingroup Lighting\n" )
  854. {
  855. ProbeManager *pm = PROBEMGR;
  856. if ( !pm)
  857. return;
  858. /*SceneManager *sm = lm->getSceneManager();
  859. lm->deactivate();
  860. lm->activate( sm );*/
  861. }