renderProbeMgr.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  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. IMPLEMENT_CONOBJECT(RenderProbeMgr);
  34. ConsoleDocClass( RenderProbeMgr,
  35. "@brief A render bin which uses object callbacks for rendering.\n\n"
  36. "This render bin gathers object render instances and calls its delegate "
  37. "method to perform rendering. It is used infrequently for specialized "
  38. "scene objects which perform custom rendering.\n\n"
  39. "@ingroup RenderBin\n" );
  40. S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
  41. {
  42. // Debug Profiling.
  43. PROFILE_SCOPE(AdvancedLightBinManager_AscendingReflectProbeInfluence);
  44. // Fetch asset definitions.
  45. const ProbeRenderInst* pReflectProbeA = static_cast<ProbeRenderInst*>(((RenderBinManager::MainSortElem*)(a))->inst);
  46. const ProbeRenderInst* pReflectProbeB = static_cast<ProbeRenderInst*>(((RenderBinManager::MainSortElem*)(b))->inst);
  47. // Sort.
  48. //First, immediate check on if either is a skylight. Skylight always gets the highest priority
  49. //if (pReflectProbeA->mIsSkylight)
  50. // return 1;
  51. //else if (pReflectProbeB->mIsSkylight)
  52. // return -1;
  53. //No? then sort by score
  54. if (pReflectProbeA->mScore > pReflectProbeB->mScore)
  55. return 1;
  56. else if (pReflectProbeA->mScore < pReflectProbeB->mScore)
  57. return -1;
  58. return 0;
  59. }
  60. RenderProbeMgr::RenderProbeMgr()
  61. : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f)
  62. {
  63. mReflectProbeMaterial = nullptr;
  64. mSkylightMaterial = nullptr;
  65. }
  66. RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
  67. : RenderBinManager(riType, renderOrder, processAddOrder)
  68. {
  69. mReflectProbeMaterial = nullptr;
  70. mSkylightMaterial = nullptr;
  71. }
  72. void RenderProbeMgr::initPersistFields()
  73. {
  74. Parent::initPersistFields();
  75. }
  76. void RenderProbeMgr::addElement(RenderInst *inst)
  77. {
  78. // If this instance is translucent handle it in RenderTranslucentMgr
  79. if (inst->translucentSort)
  80. return;
  81. //AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
  82. internalAddElement(inst);
  83. ProbeRenderInst* probeInst = static_cast<ProbeRenderInst*>(inst);
  84. if (probeInst->mIsSkylight)
  85. {
  86. addSkylightProbe(probeInst);
  87. }
  88. else
  89. {
  90. if (probeInst->mProbeShapeType == ProbeInfo::Sphere)
  91. addSphereReflectionProbe(probeInst);
  92. else
  93. addConvexReflectionProbe(probeInst);
  94. }
  95. }
  96. //remove
  97. //Con::setIntVariable("lightMetrics::activeReflectionProbes", mReflectProbeBin.size());
  98. //Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/);
  99. //
  100. GFXVertexBufferHandle<GFXVertexPC> RenderProbeMgr::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives)
  101. {
  102. static SphereMesh sSphereMesh;
  103. if (mSphereGeometry.isNull())
  104. {
  105. const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3);
  106. S32 numPoly = sphereMesh->numPoly;
  107. mSpherePrimitiveCount = 0;
  108. mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic);
  109. mSphereGeometry.lock();
  110. S32 vertexIndex = 0;
  111. for (S32 i = 0; i<numPoly; i++)
  112. {
  113. mSpherePrimitiveCount++;
  114. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0];
  115. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  116. vertexIndex++;
  117. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1];
  118. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  119. vertexIndex++;
  120. mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2];
  121. mSphereGeometry[vertexIndex].color = ColorI::WHITE;
  122. vertexIndex++;
  123. }
  124. mSphereGeometry.unlock();
  125. }
  126. outNumPrimitives = mSpherePrimitiveCount;
  127. outPrimitives = NULL; // For now
  128. return mSphereGeometry;
  129. }
  130. void RenderProbeMgr::addSkylightProbe(ProbeRenderInst *probeInfo)
  131. {
  132. probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
  133. if (!mSkylightMaterial)
  134. mSkylightMaterial = _getSkylightMaterial();
  135. }
  136. void RenderProbeMgr::addSphereReflectionProbe(ProbeRenderInst *probeInfo)
  137. {
  138. probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
  139. if (!mReflectProbeMaterial)
  140. mReflectProbeMaterial = _getReflectProbeMaterial();
  141. }
  142. void RenderProbeMgr::addConvexReflectionProbe(ProbeRenderInst *probeInfo)
  143. {
  144. static const Point3F cubePoints[8] =
  145. {
  146. Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1),
  147. Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
  148. };
  149. /*static const Point3F cubeNormals[6] =
  150. {
  151. Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0),
  152. Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1)
  153. };*/
  154. /*static const Point2F cubeTexCoords[4] =
  155. {
  156. Point2F(0, 0), Point2F(0, -1),
  157. Point2F(1, 0), Point2F(1, -1)
  158. };*/
  159. static const U32 cubeFaces[36][3] =
  160. {
  161. { 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 },
  162. { 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 },
  163. { 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 },
  164. { 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 },
  165. { 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 },
  166. { 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 },
  167. { 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 },
  168. { 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 },
  169. { 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 },
  170. { 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 },
  171. { 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 },
  172. { 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 }
  173. };
  174. // Fill the vertex buffer
  175. GFXVertexPC *pVert = NULL;
  176. probeInfo->numVerts = 36;
  177. probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic);
  178. pVert = probeInfo->vertBuffer.lock();
  179. Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius);
  180. for (U32 i = 0; i < 36; i++)
  181. {
  182. const U32& vdx = cubeFaces[i][0];
  183. pVert[i].point = cubePoints[vdx] * halfSize;
  184. }
  185. probeInfo->vertBuffer.unlock();
  186. // Fill the primitive buffer
  187. U16 *pIdx = NULL;
  188. probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic);
  189. probeInfo->primBuffer.lock(&pIdx);
  190. for (U16 i = 0; i < 36; i++)
  191. pIdx[i] = i;
  192. probeInfo->primBuffer.unlock();
  193. probeInfo->numPrims = 12;
  194. if (!mReflectProbeMaterial)
  195. mReflectProbeMaterial = _getReflectProbeMaterial();
  196. //
  197. // mReflectProbeBin.push_back(pEntry);
  198. }
  199. void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
  200. {
  201. PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
  202. const Frustum &frustum = state->getCameraFrustum();
  203. MatrixF invCam(frustum.getTransform());
  204. invCam.inverse();
  205. const Point3F *wsFrustumPoints = frustum.getPoints();
  206. const Point3F& cameraPos = frustum.getPosition();
  207. // Perform a camera offset. We need to manually perform this offset on the sun (or vector) light's
  208. // polygon, which is at the far plane.
  209. Point3F cameraOffsetPos = cameraPos;
  210. // Now build the quad for drawing full-screen vector light
  211. // passes.... this is a volatile VB and updates every frame.
  212. FarFrustumQuadVert verts[4];
  213. {
  214. verts[0].point.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraPos);
  215. invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal);
  216. verts[0].texCoord.set(-1.0, 1.0);
  217. verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos);
  218. verts[1].point.set(wsFrustumPoints[Frustum::FarTopRight] - cameraPos);
  219. invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal);
  220. verts[1].texCoord.set(1.0, 1.0);
  221. verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos);
  222. verts[2].point.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos);
  223. invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal);
  224. verts[2].texCoord.set(-1.0, -1.0);
  225. verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos);
  226. verts[3].point.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraPos);
  227. invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal);
  228. verts[3].texCoord.set(1.0, -1.0);
  229. verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos);
  230. }
  231. mFarFrustumQuadVerts.set(GFX, 4);
  232. dMemcpy(mFarFrustumQuadVerts.lock(), verts, sizeof(verts));
  233. mFarFrustumQuadVerts.unlock();
  234. PlaneF farPlane(wsFrustumPoints[Frustum::FarBottomLeft], wsFrustumPoints[Frustum::FarTopLeft], wsFrustumPoints[Frustum::FarTopRight]);
  235. PlaneF vsFarPlane(verts[0].normal, verts[1].normal, verts[2].normal);
  236. MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
  237. matrixSet.restoreSceneViewProjection();
  238. const MatrixF &worldToCameraXfm = matrixSet.getWorldToCamera();
  239. MatrixF inverseViewMatrix = worldToCameraXfm;
  240. //inverseViewMatrix.fullInverse();
  241. //inverseViewMatrix.transpose();
  242. //inverseViewMatrix = MatrixF::Identity;
  243. // Parameters calculated, assign them to the materials
  244. if (mSkylightMaterial != nullptr && mSkylightMaterial->matInstance != nullptr)
  245. {
  246. mSkylightMaterial->setViewParameters(frustum.getNearDist(),
  247. frustum.getFarDist(),
  248. frustum.getPosition(),
  249. farPlane,
  250. vsFarPlane, inverseViewMatrix);
  251. }
  252. if (mReflectProbeMaterial != nullptr && mReflectProbeMaterial->matInstance != nullptr)
  253. {
  254. mReflectProbeMaterial->setViewParameters(frustum.getNearDist(),
  255. frustum.getFarDist(),
  256. frustum.getPosition(),
  257. farPlane,
  258. vsFarPlane, inverseViewMatrix);
  259. }
  260. }
  261. //-----------------------------------------------------------------------------
  262. // render objects
  263. //-----------------------------------------------------------------------------
  264. void RenderProbeMgr::render( SceneRenderState *state )
  265. {
  266. PROFILE_SCOPE(RenderProbeMgr_render);
  267. // Early out if nothing to draw.
  268. if(!mElementList.size())
  269. return;
  270. GFXTransformSaver saver;
  271. NamedTexTargetRef diffuseLightingTarget = NamedTexTarget::find("diffuseLighting");
  272. if (diffuseLightingTarget.isNull())
  273. return;
  274. NamedTexTargetRef specularLightingTarget = NamedTexTarget::find("specularLighting");
  275. if (specularLightingTarget.isNull())
  276. return;
  277. GFXTextureTargetRef probeLightingTargetRef = GFX->allocRenderToTextureTarget();
  278. if (probeLightingTargetRef.isNull())
  279. return;
  280. probeLightingTargetRef->attachTexture(GFXTextureTarget::Color0, diffuseLightingTarget->getTexture());
  281. probeLightingTargetRef->attachTexture(GFXTextureTarget::Color1, specularLightingTarget->getTexture());
  282. GFX->pushActiveRenderTarget();
  283. GFX->setActiveRenderTarget(probeLightingTargetRef);
  284. GFX->setViewport(diffuseLightingTarget->getViewport());
  285. //GFX->setViewport(specularLightingTarget->getViewport());
  286. // Restore transforms
  287. MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
  288. matrixSet.restoreSceneViewProjection();
  289. const MatrixF &worldToCameraXfm = matrixSet.getWorldToCamera();
  290. // Set up the SG Data
  291. SceneData sgData;
  292. sgData.init(state);
  293. // Initialize and set the per-frame parameters after getting
  294. // the vector light material as we use lazy creation.
  295. _setupPerFrameParameters(state);
  296. //Order the probes by size, biggest to smallest
  297. dQsort(mElementList.address(), mElementList.size(), sizeof(const MainSortElem), AscendingReflectProbeInfluence);
  298. //Specular
  299. PROFILE_START(RenderProbeManager_ReflectProbeRender);
  300. for (U32 i = 0; i<mElementList.size(); i++)
  301. {
  302. ProbeRenderInst *curEntry = static_cast<ProbeRenderInst*>(mElementList[i].inst);
  303. if (curEntry->numPrims == 0)
  304. continue;
  305. if (curEntry->mIsSkylight && (!mSkylightMaterial || !mSkylightMaterial->matInstance))
  306. continue;
  307. if (!curEntry->mIsSkylight && (!mReflectProbeMaterial || !mReflectProbeMaterial->matInstance))
  308. break;
  309. //Setup
  310. MatrixF probeTrans = curEntry->getTransform();
  311. if (!curEntry->mIsSkylight)
  312. {
  313. if (curEntry->mProbeShapeType == ProbeInfo::Sphere)
  314. probeTrans.scale(curEntry->mRadius * 1.01f);
  315. }
  316. else
  317. {
  318. probeTrans.scale(10); //force it to be big enough to surround the camera
  319. }
  320. sgData.objTrans = &probeTrans;
  321. if(curEntry->mIsSkylight)
  322. mSkylightMaterial->setSkylightParameters(curEntry, state, worldToCameraXfm);
  323. else
  324. mReflectProbeMaterial->setProbeParameters(curEntry, state, worldToCameraXfm);
  325. // Set geometry
  326. GFX->setVertexBuffer(curEntry->vertBuffer);
  327. GFX->setPrimitiveBuffer(curEntry->primBuffer);
  328. if (curEntry->mIsSkylight)
  329. {
  330. while (mSkylightMaterial->matInstance->setupPass(state, sgData))
  331. {
  332. // Set transforms
  333. matrixSet.setWorld(*sgData.objTrans);
  334. mSkylightMaterial->matInstance->setTransforms(matrixSet, state);
  335. mSkylightMaterial->matInstance->setSceneInfo(state, sgData);
  336. GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims);
  337. }
  338. }
  339. else
  340. {
  341. while (mReflectProbeMaterial->matInstance->setupPass(state, sgData))
  342. {
  343. // Set transforms
  344. matrixSet.setWorld(*sgData.objTrans);
  345. mReflectProbeMaterial->matInstance->setTransforms(matrixSet, state);
  346. mReflectProbeMaterial->matInstance->setSceneInfo(state, sgData);
  347. GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims);
  348. }
  349. }
  350. }
  351. probeLightingTargetRef->resolve();
  352. GFX->popActiveRenderTarget();
  353. PROBEMGR->unregisterAllProbes();
  354. PROFILE_END();
  355. GFX->setVertexBuffer(NULL);
  356. GFX->setPrimitiveBuffer(NULL);
  357. // Fire off a signal to let others know that light-bin rendering is ending now
  358. //getRenderSignal().trigger(state, this);
  359. }
  360. //
  361. RenderProbeMgr::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName,
  362. const GFXVertexFormat *vertexFormat)
  363. : matInstance(NULL),
  364. zNearFarInvNearFar(NULL),
  365. farPlane(NULL),
  366. vsFarPlane(NULL),
  367. negFarPlaneDotEye(NULL),
  368. probeWSPos(NULL),
  369. attenuation(NULL),
  370. radius(NULL),
  371. invViewMat(NULL)
  372. {
  373. Material *mat = MATMGR->getMaterialDefinitionByName(matName);
  374. if (!mat)
  375. return;
  376. matInstance = new ReflectProbeMatInstance(*mat);
  377. const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
  378. for (U32 i = 0; i < macros.size(); i++)
  379. matInstance->addShaderMacro(macros[i].name, macros[i].value);
  380. matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
  381. attenuation = matInstance->getMaterialParameterHandle("$attenuation");
  382. radius = matInstance->getMaterialParameterHandle("$radius");
  383. probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos");
  384. probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos");
  385. farPlane = matInstance->getMaterialParameterHandle("$farPlane");
  386. vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
  387. negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
  388. zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
  389. invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
  390. useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
  391. cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
  392. eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
  393. bbMin = matInstance->getMaterialParameterHandle("$bbMin");
  394. bbMax = matInstance->getMaterialParameterHandle("$bbMax");
  395. useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode");
  396. for(U32 i=0; i < 9; i++)
  397. shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d",i));
  398. for (U32 i = 0; i < 5; i++)
  399. shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
  400. }
  401. RenderProbeMgr::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo()
  402. {
  403. SAFE_DELETE(matInstance);
  404. }
  405. void RenderProbeMgr::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear,
  406. const F32 _zFar,
  407. const Point3F &_eyePos,
  408. const PlaneF &_farPlane,
  409. const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix)
  410. {
  411. MaterialParameters *matParams = matInstance->getMaterialParameters();
  412. matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
  413. matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
  414. if (negFarPlaneDotEye->isValid())
  415. {
  416. // -dot( farPlane, eyePos )
  417. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  418. matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
  419. }
  420. matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
  421. matParams->setSafe(invViewMat, _inverseViewMatrix);
  422. Point4F frPlane = *((const Point4F *)&_farPlane);
  423. Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
  424. Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
  425. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  426. }
  427. void RenderProbeMgr::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
  428. {
  429. //Set up the params
  430. MaterialParameters *matParams = matInstance->getMaterialParameters();
  431. matParams->setSafe(radius, probeInfo->mRadius);
  432. Point3F probePos = probeInfo->getPosition();
  433. //worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
  434. matParams->setSafe(probeWSPos, probePos);
  435. worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
  436. matParams->setSafe(probeLSPos, probePos);
  437. // Get the attenuation falloff ratio and normalize it.
  438. Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f);
  439. F32 total = attenRatio.x + attenRatio.y + attenRatio.z;
  440. if (total > 0.0f)
  441. attenRatio /= total;
  442. F32 radius = probeInfo->mRadius;
  443. Point2F attenParams((1.0f / radius) * attenRatio.y,
  444. (1.0f / (radius * radius)) * attenRatio.z);
  445. matParams->setSafe(attenuation, attenParams);
  446. NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
  447. GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
  448. if (!deferredTexObject) return;
  449. GFX->setTexture(0, deferredTexObject);
  450. NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
  451. GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
  452. if (!matInfoTexObject) return;
  453. GFX->setTexture(1, matInfoTexObject);
  454. if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
  455. {
  456. GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
  457. }
  458. else
  459. {
  460. GFX->setCubeTexture(2, NULL);
  461. }
  462. if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
  463. {
  464. GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
  465. }
  466. else
  467. {
  468. GFX->setCubeTexture(3, NULL);
  469. }
  470. if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
  471. {
  472. GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
  473. }
  474. else
  475. {
  476. GFX->setTexture(4, NULL);
  477. }
  478. matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
  479. matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
  480. matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
  481. matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeInfo::Sphere ? 1.0f : 0.0f);
  482. //SH Terms
  483. //static AlignedArray<Point3F> shTermsArray(9, sizeof(Point3F));
  484. //dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize());
  485. for (U32 i = 0; i < 9; i++)
  486. {
  487. matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
  488. }
  489. for (U32 i = 0; i < 5; i++)
  490. {
  491. matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
  492. }
  493. }
  494. bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
  495. {
  496. bool success = Parent::init(features, vertexFormat);
  497. // If the initialization failed don't continue.
  498. if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
  499. return false;
  500. return true;
  501. }
  502. bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
  503. {
  504. // Go no further if the material failed to initialize properly.
  505. if (!mProcessedMaterial ||
  506. mProcessedMaterial->getNumPasses() == 0)
  507. return false;
  508. bool bRetVal = Parent::setupPass(state, sgData);;
  509. AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
  510. const RenderPassData *rpd = mProcessedMaterial->getPass(0);
  511. AssertFatal(rpd, "No render pass data!");
  512. AssertFatal(rpd->mRenderStates[0], "No render state 0!");
  513. if (!mProjectionState)
  514. {
  515. GFXStateBlockDesc desc;
  516. desc.setZReadWrite(false);
  517. desc.zWriteEnable = false;
  518. desc.setCullMode(GFXCullNone);
  519. desc.setBlend(true, GFXBlendOne, GFXBlendOne);
  520. mProjectionState = GFX->createStateBlock(desc);
  521. }
  522. // Now override stateblock with our own
  523. GFX->setStateBlock(mProjectionState);
  524. return bRetVal;
  525. }
  526. RenderProbeMgr::ReflectProbeMaterialInfo* RenderProbeMgr::_getReflectProbeMaterial()
  527. {
  528. PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial);
  529. //ReflectProbeMaterialInfo *info = NULL;
  530. if (!mReflectProbeMaterial)
  531. // Now create the material info object.
  532. mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial",
  533. getGFXVertexFormat<GFXVertexPC>());
  534. return mReflectProbeMaterial;
  535. }
  536. //
  537. RenderProbeMgr::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName,
  538. const GFXVertexFormat *vertexFormat)
  539. : matInstance(NULL),
  540. zNearFarInvNearFar(NULL),
  541. farPlane(NULL),
  542. vsFarPlane(NULL),
  543. negFarPlaneDotEye(NULL),
  544. invViewMat(NULL)
  545. {
  546. Material *mat = MATMGR->getMaterialDefinitionByName(matName);
  547. if (!mat)
  548. return;
  549. matInstance = new SkylightMatInstance(*mat);
  550. const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
  551. for (U32 i = 0; i < macros.size(); i++)
  552. matInstance->addShaderMacro(macros[i].name, macros[i].value);
  553. matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
  554. farPlane = matInstance->getMaterialParameterHandle("$farPlane");
  555. vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
  556. negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
  557. zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
  558. invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
  559. useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
  560. cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
  561. eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
  562. for (U32 i = 0; i < 9; i++)
  563. shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
  564. for (U32 i = 0; i < 5; i++)
  565. shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
  566. }
  567. RenderProbeMgr::SkylightMaterialInfo::~SkylightMaterialInfo()
  568. {
  569. SAFE_DELETE(matInstance);
  570. }
  571. void RenderProbeMgr::SkylightMaterialInfo::setViewParameters(const F32 _zNear,
  572. const F32 _zFar,
  573. const Point3F &_eyePos,
  574. const PlaneF &_farPlane,
  575. const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix)
  576. {
  577. MaterialParameters *matParams = matInstance->getMaterialParameters();
  578. matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
  579. matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
  580. if (negFarPlaneDotEye->isValid())
  581. {
  582. // -dot( farPlane, eyePos )
  583. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  584. matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
  585. }
  586. matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
  587. matParams->setSafe(invViewMat, _inverseViewMatrix);
  588. Point4F frPlane = *((const Point4F *)&_farPlane);
  589. Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
  590. Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
  591. const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
  592. }
  593. void RenderProbeMgr::SkylightMaterialInfo::setSkylightParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
  594. {
  595. //Set up the params
  596. MaterialParameters *matParams = matInstance->getMaterialParameters();
  597. NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
  598. GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
  599. if (!deferredTexObject) return;
  600. GFX->setTexture(0, deferredTexObject);
  601. NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
  602. GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
  603. if (!matInfoTexObject) return;
  604. GFX->setTexture(1, matInfoTexObject);
  605. if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
  606. {
  607. GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
  608. }
  609. else
  610. {
  611. GFX->setCubeTexture(2, NULL);
  612. }
  613. if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
  614. {
  615. GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
  616. }
  617. else
  618. {
  619. GFX->setCubeTexture(3, NULL);
  620. }
  621. if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
  622. {
  623. GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
  624. }
  625. else
  626. {
  627. GFX->setTexture(4, NULL);
  628. }
  629. matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
  630. for (U32 i = 0; i < 9; i++)
  631. {
  632. matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
  633. }
  634. for (U32 i = 0; i < 5; i++)
  635. {
  636. matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
  637. }
  638. }
  639. bool SkylightMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
  640. {
  641. bool success = Parent::init(features, vertexFormat);
  642. // If the initialization failed don't continue.
  643. if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
  644. return false;
  645. return true;
  646. }
  647. bool SkylightMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
  648. {
  649. // Go no further if the material failed to initialize properly.
  650. if (!mProcessedMaterial ||
  651. mProcessedMaterial->getNumPasses() == 0)
  652. return false;
  653. bool bRetVal = Parent::setupPass(state, sgData);;
  654. AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
  655. const RenderPassData *rpd = mProcessedMaterial->getPass(0);
  656. AssertFatal(rpd, "No render pass data!");
  657. AssertFatal(rpd->mRenderStates[0], "No render state 0!");
  658. if (!mProjectionState)
  659. {
  660. GFXStateBlockDesc desc;
  661. desc.setZReadWrite(false);
  662. desc.zWriteEnable = false;
  663. desc.setCullMode(GFXCullNone);
  664. desc.setBlend(true, GFXBlendOne, GFXBlendOne);
  665. mProjectionState = GFX->createStateBlock(desc);
  666. }
  667. // Now override stateblock with our own
  668. GFX->setStateBlock(mProjectionState);
  669. return bRetVal;
  670. }
  671. RenderProbeMgr::SkylightMaterialInfo* RenderProbeMgr::_getSkylightMaterial()
  672. {
  673. PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial);
  674. //ReflectProbeMaterialInfo *info = NULL;
  675. if (!mSkylightMaterial)
  676. // Now create the material info object.
  677. mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial",
  678. getGFXVertexFormat<GFXVertexPC>());
  679. return mSkylightMaterial;
  680. }
  681. //
  682. //
  683. ProbeRenderInst::ProbeRenderInst()
  684. : mTransform(true),
  685. mAmbient(0.0f, 0.0f, 0.0f, 1.0f),
  686. mPriority(1.0f),
  687. mScore(0.0f),
  688. mDebugRender(false),
  689. mCubemap(NULL),
  690. mRadius(1.0f),
  691. mIntensity(1.0f)
  692. {
  693. }
  694. ProbeRenderInst::~ProbeRenderInst()
  695. {
  696. SAFE_DELETE(mCubemap);
  697. }
  698. void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
  699. {
  700. mTransform = probeInfo->mTransform;
  701. mAmbient = probeInfo->mAmbient;
  702. mCubemap = probeInfo->mCubemap;
  703. mIrradianceCubemap = probeInfo->mIrradianceCubemap;
  704. mBRDFTexture = probeInfo->mBRDFTexture;
  705. mRadius = probeInfo->mRadius;
  706. mIntensity = probeInfo->mIntensity;
  707. mProbeShapeType = probeInfo->mProbeShapeType;
  708. numPrims = probeInfo->numPrims;
  709. numVerts = probeInfo->numVerts;
  710. numIndicesForPoly = probeInfo->numIndicesForPoly;
  711. mBounds = probeInfo->mBounds;
  712. mScore = probeInfo->mScore;
  713. mIsSkylight = probeInfo->mIsSkylight;
  714. for (U32 i = 0; i < 9; i++)
  715. {
  716. mSHTerms[i] = probeInfo->mSHTerms[i];
  717. }
  718. for (U32 i = 0; i < 5; i++)
  719. {
  720. mSHConstants[i] = probeInfo->mSHConstants[i];
  721. }
  722. }
  723. void ProbeRenderInst::set(const ProbeInfo *probeInfo)
  724. {
  725. mTransform = probeInfo->mTransform;
  726. mAmbient = probeInfo->mAmbient;
  727. mCubemap = probeInfo->mCubemap;
  728. mIrradianceCubemap = probeInfo->mIrradianceCubemap;
  729. mBRDFTexture = probeInfo->mBRDFTexture;
  730. mRadius = probeInfo->mRadius;
  731. mIntensity = probeInfo->mIntensity;
  732. mProbeShapeType = probeInfo->mProbeShapeType;
  733. numPrims = probeInfo->numPrims;
  734. numVerts = probeInfo->numVerts;
  735. numIndicesForPoly = probeInfo->numIndicesForPoly;
  736. mBounds = probeInfo->mBounds;
  737. mScore = probeInfo->mScore;
  738. mIsSkylight = probeInfo->mIsSkylight;
  739. for (U32 i = 0; i < 9; i++)
  740. {
  741. mSHTerms[i] = probeInfo->mSHTerms[i];
  742. }
  743. for (U32 i = 0; i < 5; i++)
  744. {
  745. mSHConstants[i] = probeInfo->mSHConstants[i];
  746. }
  747. }
  748. void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const
  749. {
  750. *outMatrix = getTransform();
  751. outMatrix->inverse();
  752. }