renderProbeMgr.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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 "renderProbeMgr.h"
  23. #include "console/consoleTypes.h"
  24. #include "scene/sceneObject.h"
  25. #include "materials/materialManager.h"
  26. #include "scene/sceneRenderState.h"
  27. #include "math/util/sphereMesh.h"
  28. #include "math/util/matrixSet.h"
  29. #include "materials/processedMaterial.h"
  30. #include "renderInstance/renderDeferredMgr.h"
  31. #include "math/mPolyhedron.impl.h"
  32. #include "gfx/gfxTransformSaver.h"
  33. #include "gfx/gfxDebugEvent.h"
  34. #include "materials/shaderData.h"
  35. IMPLEMENT_CONOBJECT(RenderProbeMgr);
  36. ConsoleDocClass( RenderProbeMgr,
  37. "@brief A render bin which uses object callbacks for rendering.\n\n"
  38. "This render bin gathers object render instances and calls its delegate "
  39. "method to perform rendering. It is used infrequently for specialized "
  40. "scene objects which perform custom rendering.\n\n"
  41. "@ingroup RenderBin\n" );
  42. S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
  43. {
  44. // Debug Profiling.
  45. PROFILE_SCOPE(AdvancedLightBinManager_AscendingReflectProbeInfluence);
  46. // Fetch asset definitions.
  47. const ProbeRenderInst* pReflectProbeA = (*(ProbeRenderInst**)a);
  48. const ProbeRenderInst* pReflectProbeB = (*(ProbeRenderInst**)b);
  49. //sort by score
  50. return pReflectProbeA->mScore - pReflectProbeB->mScore;
  51. }
  52. RenderProbeMgr::RenderProbeMgr()
  53. : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f)
  54. {
  55. }
  56. RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
  57. : RenderBinManager(riType, renderOrder, processAddOrder)
  58. {
  59. }
  60. void RenderProbeMgr::initPersistFields()
  61. {
  62. Parent::initPersistFields();
  63. }
  64. void RenderProbeMgr::addElement(RenderInst *inst)
  65. {
  66. // If this instance is translucent handle it in RenderTranslucentMgr
  67. //if (inst->translucentSort)
  68. return;
  69. //AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
  70. /*internalAddElement(inst);
  71. ProbeRenderInst* probeInst = static_cast<ProbeRenderInst*>(inst);
  72. if (probeInst->mIsSkylight)
  73. {
  74. addSkylightProbe(probeInst);
  75. }
  76. else
  77. {
  78. if (probeInst->mProbeShapeType == ProbeInfo::Sphere)
  79. addSphereReflectionProbe(probeInst);
  80. else
  81. addConvexReflectionProbe(probeInst);
  82. }*/
  83. }
  84. //remove
  85. //Con::setIntVariable("lightMetrics::activeReflectionProbes", mReflectProbeBin.size());
  86. //Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/);
  87. //
  88. void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
  89. {
  90. PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
  91. const Frustum &frustum = state->getCameraFrustum();
  92. MatrixF invCam(frustum.getTransform());
  93. invCam.inverse();
  94. const Point3F *wsFrustumPoints = frustum.getPoints();
  95. const Point3F& cameraPos = frustum.getPosition();
  96. // Perform a camera offset. We need to manually perform this offset on the sun (or vector) light's
  97. // polygon, which is at the far plane.
  98. Point3F cameraOffsetPos = cameraPos;
  99. // Now build the quad for drawing full-screen vector light
  100. // passes.... this is a volatile VB and updates every frame.
  101. GFXVertexPC verts[4];
  102. {
  103. verts[0].point.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraPos);
  104. //invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal);
  105. //verts[0].texCoord.set(-1.0, 1.0);
  106. //verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos);
  107. verts[1].point.set(wsFrustumPoints[Frustum::FarTopRight] - cameraPos);
  108. // invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal);
  109. //verts[1].texCoord.set(1.0, 1.0);
  110. //verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos);
  111. verts[2].point.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos);
  112. //invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal);
  113. // verts[2].texCoord.set(-1.0, -1.0);
  114. // verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos);
  115. verts[3].point.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraPos);
  116. // invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal);
  117. // verts[3].texCoord.set(1.0, -1.0);
  118. // verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos);
  119. }
  120. Point3F norms[4];
  121. {
  122. invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &norms[0]);
  123. invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &norms[1]);
  124. invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &norms[2]);
  125. invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &norms[3]);
  126. }
  127. mFarFrustumQuadVerts.set(GFX, 4);
  128. dMemcpy(mFarFrustumQuadVerts.lock(), verts, sizeof(verts));
  129. mFarFrustumQuadVerts.unlock();
  130. PlaneF farPlane(wsFrustumPoints[Frustum::FarBottomLeft], wsFrustumPoints[Frustum::FarTopLeft], wsFrustumPoints[Frustum::FarTopRight]);
  131. PlaneF vsFarPlane(norms[0], norms[1], norms[2]);
  132. // Parameters calculated, assign them to the materials
  133. ProbeManager::SkylightMaterialInfo* skylightMat = PROBEMGR->getSkylightMaterial();
  134. if (skylightMat != nullptr && skylightMat->matInstance != nullptr)
  135. {
  136. skylightMat->setViewParameters(frustum.getNearDist(),
  137. frustum.getFarDist(),
  138. frustum.getPosition(),
  139. farPlane,
  140. vsFarPlane);
  141. }
  142. ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial();
  143. if (reflProbeMat != nullptr && reflProbeMat->matInstance != nullptr)
  144. {
  145. reflProbeMat->setViewParameters(frustum.getNearDist(),
  146. frustum.getFarDist(),
  147. frustum.getPosition(),
  148. farPlane,
  149. vsFarPlane);
  150. }
  151. ProbeManager::ReflectionProbeArrayMaterialInfo* reflProbeArrayMat = PROBEMGR->getReflectProbeArrayMaterial();
  152. if (reflProbeArrayMat != nullptr && reflProbeArrayMat->matInstance != nullptr)
  153. {
  154. reflProbeArrayMat->setViewParameters(frustum.getNearDist(),
  155. frustum.getFarDist(),
  156. frustum.getPosition(),
  157. farPlane,
  158. vsFarPlane);
  159. }
  160. }
  161. //-----------------------------------------------------------------------------
  162. // render objects
  163. //-----------------------------------------------------------------------------
  164. void RenderProbeMgr::render( SceneRenderState *state )
  165. {
  166. PROFILE_SCOPE(RenderProbeMgr_render);
  167. // Early out if nothing to draw.
  168. if (!ProbeRenderInst::all.size())
  169. return;
  170. if (!ProbeManager::smRenderReflectionProbes)
  171. return;
  172. GFXTransformSaver saver;
  173. GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE);
  174. NamedTexTargetRef sceneColorTargetRef = NamedTexTarget::find("AL_FormatToken");
  175. if (sceneColorTargetRef.isNull())
  176. return;
  177. GFXTextureTargetRef probeLightingTargetRef = GFX->allocRenderToTextureTarget();
  178. if (probeLightingTargetRef.isNull())
  179. return;
  180. //Do a quick pass to update our probes if they're dirty
  181. PROBEMGR->updateDirtyProbes();
  182. probeLightingTargetRef->attachTexture(GFXTextureTarget::Color0, sceneColorTargetRef->getTexture(0));
  183. GFX->pushActiveRenderTarget();
  184. GFX->setActiveRenderTarget(probeLightingTargetRef);
  185. GFX->setViewport(sceneColorTargetRef->getViewport());
  186. // Restore transforms
  187. MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
  188. matrixSet.restoreSceneViewProjection();
  189. const MatrixF &worldToCameraXfm = matrixSet.getWorldToCamera();
  190. // Set up the SG Data
  191. SceneData sgData;
  192. sgData.init(state);
  193. // Initialize and set the per-frame parameters after getting
  194. // the vector light material as we use lazy creation.
  195. _setupPerFrameParameters(state);
  196. //Order the probes by size, biggest to smallest
  197. //dQsort(ProbeRenderInst::all.address(), ProbeRenderInst::all.size(), sizeof(const ProbeRenderInst*), AscendingReflectProbeInfluence);
  198. //Specular
  199. PROFILE_START(RenderProbeManager_ReflectProbeRender);
  200. ProbeManager::SkylightMaterialInfo* skylightMat = PROBEMGR->getSkylightMaterial();
  201. ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial();
  202. /*for (U32 i = 0; i < ProbeRenderInst::all.size(); i++)
  203. {
  204. ProbeRenderInst* curEntry = ProbeRenderInst::all[i];
  205. if (!curEntry->mIsEnabled)
  206. continue;
  207. if (curEntry->numPrims == 0)
  208. continue;
  209. if (curEntry->mIsSkylight && (!skylightMat || !skylightMat->matInstance))
  210. continue;
  211. if (!curEntry->mIsSkylight && (!reflProbeMat || !reflProbeMat->matInstance))
  212. break;
  213. if (curEntry->mIsSkylight)
  214. {
  215. //Setup
  216. MatrixF probeTrans = curEntry->getTransform();
  217. // Set geometry
  218. GFX->setVertexBuffer(curEntry->vertBuffer);
  219. GFX->setPrimitiveBuffer(curEntry->primBuffer);
  220. probeTrans.scale(10); //force it to be big enough to surround the camera
  221. sgData.objTrans = &probeTrans;
  222. skylightMat->setProbeParameters(curEntry, state, worldToCameraXfm);
  223. while (skylightMat->matInstance->setupPass(state, sgData))
  224. {
  225. // Set transforms
  226. matrixSet.setWorld(*sgData.objTrans);
  227. skylightMat->matInstance->setTransforms(matrixSet, state);
  228. skylightMat->matInstance->setSceneInfo(state, sgData);
  229. GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims);
  230. }
  231. }
  232. }*/
  233. //Array rendering
  234. static U32 MAXPROBECOUNT = 50;
  235. U32 probeCount = ProbeRenderInst::all.size();
  236. if (probeCount != 0)
  237. {
  238. MatrixF trans = MatrixF::Identity;
  239. sgData.objTrans = &trans;
  240. AlignedArray<Point3F> probePositions(MAXPROBECOUNT, sizeof(Point3F));
  241. Vector<MatrixF> probeWorldToObj;
  242. AlignedArray<Point3F> probeBBMin(MAXPROBECOUNT, sizeof(Point3F));
  243. AlignedArray<Point3F> probeBBMax(MAXPROBECOUNT, sizeof(Point3F));
  244. AlignedArray<float> probeUseSphereMode(MAXPROBECOUNT, sizeof(float));
  245. AlignedArray<float> probeRadius(MAXPROBECOUNT, sizeof(float));
  246. AlignedArray<float> probeAttenuation(MAXPROBECOUNT, sizeof(float));
  247. dMemset(probePositions.getBuffer(), 0, probePositions.getBufferSize());
  248. probeWorldToObj.setSize(MAXPROBECOUNT);
  249. dMemset(probeBBMin.getBuffer(), 0, probeBBMin.getBufferSize());
  250. dMemset(probeBBMax.getBuffer(), 0, probeBBMax.getBufferSize());
  251. dMemset(probeUseSphereMode.getBuffer(), 0, probeUseSphereMode.getBufferSize());
  252. dMemset(probeRadius.getBuffer(), 0, probeRadius.getBufferSize());
  253. dMemset(probeAttenuation.getBuffer(), 0, probeAttenuation.getBufferSize());
  254. Vector<GFXCubemapHandle> cubeMaps;
  255. Vector<GFXCubemapHandle> irradMaps;
  256. if (reflProbeMat && reflProbeMat->matInstance)
  257. {
  258. MaterialParameters *matParams = reflProbeMat->matInstance->getMaterialParameters();
  259. MaterialParameterHandle *numProbesSC = reflProbeMat->matInstance->getMaterialParameterHandle("$numProbes");
  260. MaterialParameterHandle *probePositionSC = reflProbeMat->matInstance->getMaterialParameterHandle("$inProbePosArray");
  261. MaterialParameterHandle *probeWorldToObjSC = reflProbeMat->matInstance->getMaterialParameterHandle("$worldToObjArray");
  262. MaterialParameterHandle *probeBBMinSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMinArrayy");
  263. MaterialParameterHandle *probeBBMaxSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMaxArray");
  264. MaterialParameterHandle *probeUseSphereModeSC = reflProbeMat->matInstance->getMaterialParameterHandle("$useSphereMode");
  265. MaterialParameterHandle *probeRadiusSC = reflProbeMat->matInstance->getMaterialParameterHandle("$radius");
  266. MaterialParameterHandle *probeAttenuationSC = reflProbeMat->matInstance->getMaterialParameterHandle("$attenuation");
  267. MaterialParameterHandle *probeCubemapArraySC = reflProbeMat->matInstance->getMaterialParameterHandle("$cubeMap");
  268. MaterialParameterHandle *probeIrradianceArraySC = reflProbeMat->matInstance->getMaterialParameterHandle("$irradianceCubemap");
  269. U32 effectiveProbeCount = 0;
  270. for (U32 i = 0; i < probeCount; i++)
  271. {
  272. if (effectiveProbeCount >= MAXPROBECOUNT)
  273. break;
  274. ProbeRenderInst* curEntry = ProbeRenderInst::all[i];
  275. if (!curEntry->mIsEnabled)
  276. continue;
  277. if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull())
  278. continue;
  279. if (!curEntry->mCubemap->isInitialised())
  280. continue;
  281. //Setup
  282. const Point3F &probePos = curEntry->getPosition();
  283. probePositions[i] = probePos + curEntry->mProbePosOffset;
  284. MatrixF trans = curEntry->getTransform();
  285. trans.inverse();
  286. probeWorldToObj[i] = trans;
  287. probeBBMin[i] = curEntry->mBounds.minExtents;
  288. probeBBMax[i] = curEntry->mBounds.maxExtents;
  289. probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0;
  290. probeRadius[i] = curEntry->mRadius;
  291. probeAttenuation[i] = 1;
  292. cubeMaps.push_back(curEntry->mCubemap);
  293. irradMaps.push_back(curEntry->mIrradianceCubemap);
  294. effectiveProbeCount++;
  295. }
  296. if (effectiveProbeCount != 0)
  297. {
  298. matParams->setSafe(numProbesSC, (float)effectiveProbeCount);
  299. GFXCubemapArrayHandle mCubemapArray;
  300. mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
  301. GFXCubemapArrayHandle mIrradArray;
  302. mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray());
  303. mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size());
  304. mIrradArray->initStatic(irradMaps.address(), irradMaps.size());
  305. GFX->setCubeArrayTexture(3, mCubemapArray);
  306. GFX->setCubeArrayTexture(4, mIrradArray);
  307. matParams->set(probePositionSC, probePositions);
  308. matParams->set(probeWorldToObjSC, probeWorldToObj.address(), probeWorldToObj.size());
  309. matParams->set(probeBBMinSC, probeBBMin);
  310. matParams->set(probeBBMaxSC, probeBBMax);
  311. matParams->set(probeUseSphereModeSC, probeUseSphereMode);
  312. matParams->set(probeRadiusSC, probeRadius);
  313. matParams->set(probeAttenuationSC, probeAttenuation);
  314. // Set geometry
  315. GFX->setVertexBuffer(mFarFrustumQuadVerts);
  316. GFX->setPrimitiveBuffer(NULL);
  317. while (reflProbeMat->matInstance->setupPass(state, sgData))
  318. {
  319. // Set transforms
  320. matrixSet.setWorld(*sgData.objTrans);
  321. reflProbeMat->matInstance->setTransforms(matrixSet, state);
  322. reflProbeMat->matInstance->setSceneInfo(state, sgData);
  323. GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
  324. }
  325. }
  326. }
  327. }
  328. //
  329. //
  330. /*ProbeManager::ReflectionProbeArrayMaterialInfo* reflProbeArrayMat = PROBEMGR->getReflectProbeArrayMaterial();
  331. for (U32 i = 0; i < ProbeRenderInst::all.size(); i++)
  332. {
  333. if (i > 0)
  334. return;
  335. ProbeRenderInst* curEntry = ProbeRenderInst::all[i];
  336. if (!reflProbeArrayMat || !reflProbeArrayMat->matInstance)
  337. break;
  338. //Setup
  339. //MatrixF probeTrans = curEntry->getTransform();
  340. //if (!curEntry->mIsSkylight)
  341. {
  342. //if (curEntry->mProbeShapeType == ProbeRenderInst::Sphere)
  343. // probeTrans.scale(curEntry->mRadius * 1.01f);
  344. //sgData.objTrans = &state-;
  345. reflProbeArrayMat->setProbeParameters(curEntry, state, worldToCameraXfm);
  346. // Set geometry
  347. GFX->setVertexBuffer(mFarFrustumQuadVerts);
  348. GFX->setPrimitiveBuffer(NULL);
  349. while (reflProbeArrayMat->matInstance->setupPass(state, sgData))
  350. {
  351. // Set transforms
  352. //matrixSet.setWorld(*sgData.objTrans);
  353. reflProbeArrayMat->matInstance->setTransforms(matrixSet, state);
  354. reflProbeArrayMat->matInstance->setSceneInfo(state, sgData);
  355. GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
  356. }
  357. }
  358. }*/
  359. //
  360. //
  361. GFX->popActiveRenderTarget();
  362. //PROBEMGR->unregisterAllProbes();
  363. //PROBEMGR->mRegisteredProbes.clear();
  364. PROFILE_END();
  365. GFX->setVertexBuffer(NULL);
  366. GFX->setPrimitiveBuffer(NULL);
  367. // Fire off a signal to let others know that light-bin rendering is ending now
  368. //getRenderSignal().trigger(state, this);
  369. }