BsRenderBeast.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsRenderBeast.h"
  4. #include "BsCCamera.h"
  5. #include "BsCRenderable.h"
  6. #include "BsMaterial.h"
  7. #include "BsMesh.h"
  8. #include "BsPass.h"
  9. #include "BsSamplerState.h"
  10. #include "BsCoreApplication.h"
  11. #include "BsViewport.h"
  12. #include "BsRenderTarget.h"
  13. #include "BsRenderQueue.h"
  14. #include "BsCoreThread.h"
  15. #include "BsGpuParams.h"
  16. #include "BsProfilerCPU.h"
  17. #include "BsProfilerGPU.h"
  18. #include "BsShader.h"
  19. #include "BsGpuParamBlockBuffer.h"
  20. #include "BsTime.h"
  21. #include "BsRenderableElement.h"
  22. #include "BsCoreObjectManager.h"
  23. #include "BsRenderBeastOptions.h"
  24. #include "BsSamplerOverrides.h"
  25. #include "BsLight.h"
  26. #include "BsGpuResourcePool.h"
  27. #include "BsRenderTargets.h"
  28. #include "BsRendererUtility.h"
  29. #include "BsAnimationManager.h"
  30. #include "BsSkeleton.h"
  31. #include "BsGpuBuffer.h"
  32. #include "BsGpuParamsSet.h"
  33. #include "BsRendererExtension.h"
  34. #include "BsReflectionCubemap.h"
  35. #include "BsMeshData.h"
  36. #include "BsLightGrid.h"
  37. using namespace std::placeholders;
  38. namespace bs { namespace ct
  39. {
  40. RenderBeast::RenderBeast()
  41. : mDefaultMaterial(nullptr), mTiledDeferredLightingMats(), mFlatFramebufferToTextureMat(nullptr)
  42. , mSkyboxMat(nullptr), mSkyboxSolidColorMat(nullptr), mGPULightData(nullptr), mLightGrid(nullptr)
  43. , mObjectRenderer(nullptr), mOptions(bs_shared_ptr_new<RenderBeastOptions>()), mOptionsDirty(true)
  44. { }
  45. const StringID& RenderBeast::getName() const
  46. {
  47. static StringID name = "RenderBeast";
  48. return name;
  49. }
  50. void RenderBeast::initialize()
  51. {
  52. Renderer::initialize();
  53. gCoreThread().queueCommand(std::bind(&RenderBeast::initializeCore, this), CTQF_InternalQueue);
  54. }
  55. void RenderBeast::destroy()
  56. {
  57. Renderer::destroy();
  58. gCoreThread().queueCommand(std::bind(&RenderBeast::destroyCore, this));
  59. gCoreThread().submit(true);
  60. }
  61. void RenderBeast::initializeCore()
  62. {
  63. RendererUtility::startUp();
  64. mCoreOptions = bs_shared_ptr_new<RenderBeastOptions>();
  65. mObjectRenderer = bs_new<ObjectRenderer>();
  66. mDefaultMaterial = bs_new<DefaultMaterial>();
  67. mSkyboxMat = bs_new<SkyboxMat<false>>();
  68. mSkyboxSolidColorMat = bs_new<SkyboxMat<true>>();
  69. mFlatFramebufferToTextureMat = bs_new<FlatFramebufferToTextureMat>();
  70. mTiledDeferredLightingMats[0] = bs_new<TTiledDeferredLightingMat<1>>();
  71. mTiledDeferredLightingMats[1] = bs_new<TTiledDeferredLightingMat<2>>();
  72. mTiledDeferredLightingMats[2] = bs_new<TTiledDeferredLightingMat<4>>();
  73. mTiledDeferredLightingMats[3] = bs_new<TTiledDeferredLightingMat<8>>();
  74. mGPULightData = bs_new<GPULightData>();
  75. mLightGrid = bs_new<LightGrid>();
  76. GpuResourcePool::startUp();
  77. PostProcessing::startUp();
  78. }
  79. void RenderBeast::destroyCore()
  80. {
  81. if (mObjectRenderer != nullptr)
  82. bs_delete(mObjectRenderer);
  83. for (auto& entry : mRenderables)
  84. bs_delete(entry);
  85. for (auto& entry : mCameras)
  86. bs_delete(entry.second);
  87. mRenderTargets.clear();
  88. mCameras.clear();
  89. mRenderables.clear();
  90. mRenderableVisibility.clear();
  91. PostProcessing::shutDown();
  92. GpuResourcePool::shutDown();
  93. bs_delete(mDefaultMaterial);
  94. bs_delete(mSkyboxMat);
  95. bs_delete(mSkyboxSolidColorMat);
  96. bs_delete(mGPULightData);
  97. bs_delete(mLightGrid);
  98. bs_delete(mFlatFramebufferToTextureMat);
  99. UINT32 numDeferredMats = sizeof(mTiledDeferredLightingMats) / sizeof(mTiledDeferredLightingMats[0]);
  100. for (UINT32 i = 0; i < numDeferredMats; i++)
  101. bs_delete(mTiledDeferredLightingMats[i]);
  102. RendererUtility::shutDown();
  103. assert(mSamplerOverrides.empty());
  104. }
  105. void RenderBeast::notifyRenderableAdded(Renderable* renderable)
  106. {
  107. UINT32 renderableId = (UINT32)mRenderables.size();
  108. renderable->setRendererId(renderableId);
  109. mRenderables.push_back(bs_new<RendererObject>());
  110. mRenderableCullInfos.push_back(CullInfo(renderable->getBounds(), renderable->getLayer()));
  111. mRenderableVisibility.push_back(false);
  112. RendererObject* rendererObject = mRenderables.back();
  113. rendererObject->renderable = renderable;
  114. rendererObject->updatePerObjectBuffer();
  115. SPtr<Mesh> mesh = renderable->getMesh();
  116. if (mesh != nullptr)
  117. {
  118. const MeshProperties& meshProps = mesh->getProperties();
  119. SPtr<VertexDeclaration> vertexDecl = mesh->getVertexData()->vertexDeclaration;
  120. for (UINT32 i = 0; i < meshProps.getNumSubMeshes(); i++)
  121. {
  122. rendererObject->elements.push_back(BeastRenderableElement());
  123. BeastRenderableElement& renElement = rendererObject->elements.back();
  124. renElement.mesh = mesh;
  125. renElement.subMesh = meshProps.getSubMesh(i);
  126. renElement.renderableId = renderableId;
  127. renElement.animType = renderable->getAnimType();
  128. renElement.animationId = renderable->getAnimationId();
  129. renElement.morphShapeVersion = 0;
  130. renElement.morphShapeBuffer = renderable->getMorphShapeBuffer();
  131. renElement.boneMatrixBuffer = renderable->getBoneMatrixBuffer();
  132. renElement.morphVertexDeclaration = renderable->getMorphVertexDeclaration();
  133. renElement.material = renderable->getMaterial(i);
  134. if (renElement.material == nullptr)
  135. renElement.material = renderable->getMaterial(0);
  136. if (renElement.material != nullptr && renElement.material->getShader() == nullptr)
  137. renElement.material = nullptr;
  138. // If no material use the default material
  139. if (renElement.material == nullptr)
  140. renElement.material = mDefaultMaterial->getMaterial();
  141. // Determine which technique to use
  142. static StringID techniqueIDLookup[4] = { StringID::NONE, RTag_Skinned, RTag_Morph, RTag_SkinnedMorph };
  143. static_assert((UINT32)RenderableAnimType::Count == 4, "RenderableAnimType is expected to have four sequential entries.");
  144. UINT32 techniqueIdx = -1;
  145. RenderableAnimType animType = renderable->getAnimType();
  146. if(animType != RenderableAnimType::None)
  147. techniqueIdx = renElement.material->findTechnique(techniqueIDLookup[(int)animType]);
  148. if (techniqueIdx == (UINT32)-1)
  149. techniqueIdx = renElement.material->getDefaultTechnique();
  150. renElement.techniqueIdx = techniqueIdx;
  151. // Validate mesh <-> shader vertex bindings
  152. if (renElement.material != nullptr)
  153. {
  154. UINT32 numPasses = renElement.material->getNumPasses(techniqueIdx);
  155. for (UINT32 j = 0; j < numPasses; j++)
  156. {
  157. SPtr<Pass> pass = renElement.material->getPass(j, techniqueIdx);
  158. SPtr<VertexDeclaration> shaderDecl = pass->getVertexProgram()->getInputDeclaration();
  159. if (!vertexDecl->isCompatible(shaderDecl))
  160. {
  161. Vector<VertexElement> missingElements = vertexDecl->getMissingElements(shaderDecl);
  162. // If using morph shapes ignore POSITION1 and NORMAL1 missing since we assign them from within the renderer
  163. if(animType == RenderableAnimType::Morph || animType == RenderableAnimType::SkinnedMorph)
  164. {
  165. auto removeIter = std::remove_if(missingElements.begin(), missingElements.end(), [](const VertexElement& x)
  166. {
  167. return (x.getSemantic() == VES_POSITION && x.getSemanticIdx() == 1) ||
  168. (x.getSemantic() == VES_NORMAL && x.getSemanticIdx() == 1);
  169. });
  170. missingElements.erase(removeIter, missingElements.end());
  171. }
  172. if (!missingElements.empty())
  173. {
  174. StringStream wrnStream;
  175. wrnStream << "Provided mesh is missing required vertex attributes to render with the provided shader. Missing elements: " << std::endl;
  176. for (auto& entry : missingElements)
  177. wrnStream << "\t" << toString(entry.getSemantic()) << entry.getSemanticIdx() << std::endl;
  178. LOGWRN(wrnStream.str());
  179. break;
  180. }
  181. }
  182. }
  183. }
  184. // Generate or assigned renderer specific data for the material
  185. renElement.params = renElement.material->createParamsSet(techniqueIdx);
  186. renElement.material->updateParamsSet(renElement.params, true);
  187. // Generate or assign sampler state overrides
  188. SamplerOverrideKey samplerKey(renElement.material, techniqueIdx);
  189. auto iterFind = mSamplerOverrides.find(samplerKey);
  190. if (iterFind != mSamplerOverrides.end())
  191. {
  192. renElement.samplerOverrides = iterFind->second;
  193. iterFind->second->refCount++;
  194. }
  195. else
  196. {
  197. SPtr<Shader> shader = renElement.material->getShader();
  198. MaterialSamplerOverrides* samplerOverrides = SamplerOverrideUtility::generateSamplerOverrides(shader,
  199. renElement.material->_getInternalParams(), renElement.params, mCoreOptions);
  200. mSamplerOverrides[samplerKey] = samplerOverrides;
  201. renElement.samplerOverrides = samplerOverrides;
  202. samplerOverrides->refCount++;
  203. }
  204. mObjectRenderer->initElement(*rendererObject, renElement);
  205. }
  206. }
  207. }
  208. void RenderBeast::notifyRenderableRemoved(Renderable* renderable)
  209. {
  210. UINT32 renderableId = renderable->getRendererId();
  211. Renderable* lastRenerable = mRenderables.back()->renderable;
  212. UINT32 lastRenderableId = lastRenerable->getRendererId();
  213. RendererObject* rendererObject = mRenderables[renderableId];
  214. Vector<BeastRenderableElement>& elements = rendererObject->elements;
  215. for (auto& element : elements)
  216. {
  217. SamplerOverrideKey samplerKey(element.material, element.techniqueIdx);
  218. auto iterFind = mSamplerOverrides.find(samplerKey);
  219. assert(iterFind != mSamplerOverrides.end());
  220. MaterialSamplerOverrides* samplerOverrides = iterFind->second;
  221. samplerOverrides->refCount--;
  222. if (samplerOverrides->refCount == 0)
  223. {
  224. SamplerOverrideUtility::destroySamplerOverrides(samplerOverrides);
  225. mSamplerOverrides.erase(iterFind);
  226. }
  227. element.samplerOverrides = nullptr;
  228. }
  229. if (renderableId != lastRenderableId)
  230. {
  231. // Swap current last element with the one we want to erase
  232. std::swap(mRenderables[renderableId], mRenderables[lastRenderableId]);
  233. std::swap(mRenderableCullInfos[renderableId], mRenderableCullInfos[lastRenderableId]);
  234. lastRenerable->setRendererId(renderableId);
  235. for (auto& element : elements)
  236. element.renderableId = renderableId;
  237. }
  238. // Last element is the one we want to erase
  239. mRenderables.erase(mRenderables.end() - 1);
  240. mRenderableCullInfos.erase(mRenderableCullInfos.end() - 1);
  241. mRenderableVisibility.erase(mRenderableVisibility.end() - 1);
  242. bs_delete(rendererObject);
  243. }
  244. void RenderBeast::notifyRenderableUpdated(Renderable* renderable)
  245. {
  246. UINT32 renderableId = renderable->getRendererId();
  247. mRenderables[renderableId]->updatePerObjectBuffer();
  248. mRenderableCullInfos[renderableId].bounds = renderable->getBounds();
  249. }
  250. void RenderBeast::notifyLightAdded(Light* light)
  251. {
  252. if (light->getType() == LightType::Directional)
  253. {
  254. UINT32 lightId = (UINT32)mDirectionalLights.size();
  255. light->setRendererId(lightId);
  256. mDirectionalLights.push_back(RendererLight(light));
  257. }
  258. else
  259. {
  260. if (light->getType() == LightType::Point)
  261. {
  262. UINT32 lightId = (UINT32)mRadialLights.size();
  263. light->setRendererId(lightId);
  264. mRadialLights.push_back(RendererLight(light));
  265. mPointLightWorldBounds.push_back(light->getBounds());
  266. }
  267. else // Spot
  268. {
  269. UINT32 lightId = (UINT32)mSpotLights.size();
  270. light->setRendererId(lightId);
  271. mSpotLights.push_back(RendererLight(light));
  272. mSpotLightWorldBounds.push_back(light->getBounds());
  273. }
  274. }
  275. }
  276. void RenderBeast::notifyLightUpdated(Light* light)
  277. {
  278. UINT32 lightId = light->getRendererId();
  279. if (light->getType() == LightType::Point)
  280. mPointLightWorldBounds[lightId] = light->getBounds();
  281. else if(light->getType() == LightType::Spot)
  282. mSpotLightWorldBounds[lightId] = light->getBounds();
  283. }
  284. void RenderBeast::notifyLightRemoved(Light* light)
  285. {
  286. UINT32 lightId = light->getRendererId();
  287. if (light->getType() == LightType::Directional)
  288. {
  289. Light* lastLight = mDirectionalLights.back().getInternal();
  290. UINT32 lastLightId = lastLight->getRendererId();
  291. if (lightId != lastLightId)
  292. {
  293. // Swap current last element with the one we want to erase
  294. std::swap(mDirectionalLights[lightId], mDirectionalLights[lastLightId]);
  295. lastLight->setRendererId(lightId);
  296. }
  297. // Last element is the one we want to erase
  298. mDirectionalLights.erase(mDirectionalLights.end() - 1);
  299. }
  300. else
  301. {
  302. if (light->getType() == LightType::Point)
  303. {
  304. Light* lastLight = mRadialLights.back().getInternal();
  305. UINT32 lastLightId = lastLight->getRendererId();
  306. if (lightId != lastLightId)
  307. {
  308. // Swap current last element with the one we want to erase
  309. std::swap(mRadialLights[lightId], mRadialLights[lastLightId]);
  310. std::swap(mPointLightWorldBounds[lightId], mPointLightWorldBounds[lastLightId]);
  311. lastLight->setRendererId(lightId);
  312. }
  313. // Last element is the one we want to erase
  314. mRadialLights.erase(mRadialLights.end() - 1);
  315. mPointLightWorldBounds.erase(mPointLightWorldBounds.end() - 1);
  316. }
  317. else // Spot
  318. {
  319. Light* lastLight = mSpotLights.back().getInternal();
  320. UINT32 lastLightId = lastLight->getRendererId();
  321. if (lightId != lastLightId)
  322. {
  323. // Swap current last element with the one we want to erase
  324. std::swap(mSpotLights[lightId], mSpotLights[lastLightId]);
  325. std::swap(mSpotLightWorldBounds[lightId], mSpotLightWorldBounds[lastLightId]);
  326. lastLight->setRendererId(lightId);
  327. }
  328. // Last element is the one we want to erase
  329. mSpotLights.erase(mSpotLights.end() - 1);
  330. mSpotLightWorldBounds.erase(mSpotLightWorldBounds.end() - 1);
  331. }
  332. }
  333. }
  334. void RenderBeast::notifyCameraAdded(const Camera* camera)
  335. {
  336. RendererCamera* renCamera = updateCameraData(camera);
  337. renCamera->updatePerViewBuffer();
  338. }
  339. void RenderBeast::notifyCameraUpdated(const Camera* camera, UINT32 updateFlag)
  340. {
  341. RendererCamera* rendererCam;
  342. if((updateFlag & (UINT32)CameraDirtyFlag::Everything) != 0)
  343. {
  344. rendererCam = updateCameraData(camera);
  345. }
  346. else if((updateFlag & (UINT32)CameraDirtyFlag::PostProcess) != 0)
  347. {
  348. rendererCam = mCameras[camera];
  349. rendererCam->setPostProcessSettings(camera->getPostProcessSettings());
  350. }
  351. else // Transform
  352. {
  353. rendererCam = mCameras[camera];
  354. rendererCam->setTransform(
  355. camera->getPosition(),
  356. camera->getForward(),
  357. camera->getViewMatrix(),
  358. camera->getProjectionMatrixRS(),
  359. camera->getWorldFrustum());
  360. }
  361. rendererCam->updatePerViewBuffer();
  362. }
  363. void RenderBeast::notifyCameraRemoved(const Camera* camera)
  364. {
  365. updateCameraData(camera, true);
  366. }
  367. SPtr<PostProcessSettings> RenderBeast::createPostProcessSettings() const
  368. {
  369. return bs_shared_ptr_new<StandardPostProcessSettings>();
  370. }
  371. RendererCamera* RenderBeast::updateCameraData(const Camera* camera, bool forceRemove)
  372. {
  373. RendererCamera* output;
  374. SPtr<RenderTarget> renderTarget = camera->getViewport()->getTarget();
  375. auto iterFind = mCameras.find(camera);
  376. if(forceRemove)
  377. {
  378. if(iterFind != mCameras.end())
  379. {
  380. bs_delete(iterFind->second);
  381. mCameras.erase(iterFind);
  382. }
  383. renderTarget = nullptr;
  384. output = nullptr;
  385. }
  386. else
  387. {
  388. SPtr<Viewport> viewport = camera->getViewport();
  389. RENDERER_VIEW_DESC viewDesc;
  390. viewDesc.target.clearFlags = 0;
  391. if (viewport->getRequiresColorClear())
  392. viewDesc.target.clearFlags |= FBT_COLOR;
  393. if (viewport->getRequiresDepthClear())
  394. viewDesc.target.clearFlags |= FBT_DEPTH;
  395. if (viewport->getRequiresStencilClear())
  396. viewDesc.target.clearFlags |= FBT_STENCIL;
  397. viewDesc.target.clearColor = viewport->getClearColor();
  398. viewDesc.target.clearDepthValue = viewport->getClearDepthValue();
  399. viewDesc.target.clearStencilValue = viewport->getClearStencilValue();
  400. viewDesc.target.target = viewport->getTarget();
  401. viewDesc.target.nrmViewRect = viewport->getNormArea();
  402. viewDesc.target.viewRect = Rect2I(
  403. viewport->getX(),
  404. viewport->getY(),
  405. (UINT32)viewport->getWidth(),
  406. (UINT32)viewport->getHeight());
  407. if (viewDesc.target.target != nullptr)
  408. {
  409. viewDesc.target.targetWidth = viewDesc.target.target->getProperties().getWidth();
  410. viewDesc.target.targetHeight = viewDesc.target.target->getProperties().getHeight();
  411. }
  412. else
  413. {
  414. viewDesc.target.targetWidth = 0;
  415. viewDesc.target.targetHeight = 0;
  416. }
  417. viewDesc.target.numSamples = camera->getMSAACount();
  418. viewDesc.isOverlay = camera->getFlags().isSet(CameraFlag::Overlay);
  419. viewDesc.isHDR = camera->getFlags().isSet(CameraFlag::HDR);
  420. viewDesc.noLighting = camera->getFlags().isSet(CameraFlag::NoLighting);
  421. viewDesc.triggerCallbacks = true;
  422. viewDesc.runPostProcessing = true;
  423. viewDesc.cullFrustum = camera->getWorldFrustum();
  424. viewDesc.visibleLayers = camera->getLayers();
  425. viewDesc.nearPlane = camera->getNearClipDistance();
  426. viewDesc.farPlane = camera->getFarClipDistance();
  427. viewDesc.flipView = false;
  428. viewDesc.viewOrigin = camera->getPosition();
  429. viewDesc.viewDirection = camera->getForward();
  430. viewDesc.projTransform = camera->getProjectionMatrixRS();
  431. viewDesc.viewTransform = camera->getViewMatrix();
  432. viewDesc.stateReduction = mCoreOptions->stateReductionMode;
  433. viewDesc.skyboxTexture = camera->getSkybox();
  434. viewDesc.sceneCamera = camera;
  435. if (iterFind != mCameras.end())
  436. {
  437. output = iterFind->second;
  438. output->setView(viewDesc);
  439. }
  440. else
  441. {
  442. output = bs_new<RendererCamera>(viewDesc);
  443. mCameras[camera] = output;
  444. }
  445. output->setPostProcessSettings(camera->getPostProcessSettings());
  446. }
  447. // Remove from render target list
  448. int rtChanged = 0; // 0 - No RT, 1 - RT found, 2 - RT changed
  449. for (auto iterTarget = mRenderTargets.begin(); iterTarget != mRenderTargets.end(); ++iterTarget)
  450. {
  451. RendererRenderTarget& target = *iterTarget;
  452. for (auto iterCam = target.cameras.begin(); iterCam != target.cameras.end(); ++iterCam)
  453. {
  454. if (camera == *iterCam)
  455. {
  456. if (renderTarget != target.target)
  457. {
  458. target.cameras.erase(iterCam);
  459. rtChanged = 2;
  460. }
  461. else
  462. rtChanged = 1;
  463. break;
  464. }
  465. }
  466. if (target.cameras.empty())
  467. {
  468. mRenderTargets.erase(iterTarget);
  469. break;
  470. }
  471. }
  472. // Register in render target list
  473. if (renderTarget != nullptr && (rtChanged == 0 || rtChanged == 2))
  474. {
  475. auto findIter = std::find_if(mRenderTargets.begin(), mRenderTargets.end(),
  476. [&](const RendererRenderTarget& x) { return x.target == renderTarget; });
  477. if (findIter != mRenderTargets.end())
  478. {
  479. findIter->cameras.push_back(camera);
  480. }
  481. else
  482. {
  483. mRenderTargets.push_back(RendererRenderTarget());
  484. RendererRenderTarget& renderTargetData = mRenderTargets.back();
  485. renderTargetData.target = renderTarget;
  486. renderTargetData.cameras.push_back(camera);
  487. }
  488. // Sort render targets based on priority
  489. auto cameraComparer = [&](const Camera* a, const Camera* b) { return a->getPriority() > b->getPriority(); };
  490. auto renderTargetInfoComparer = [&](const RendererRenderTarget& a, const RendererRenderTarget& b)
  491. { return a.target->getProperties().getPriority() > b.target->getProperties().getPriority(); };
  492. std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
  493. for (auto& camerasPerTarget : mRenderTargets)
  494. {
  495. Vector<const Camera*>& cameras = camerasPerTarget.cameras;
  496. std::sort(begin(cameras), end(cameras), cameraComparer);
  497. }
  498. }
  499. return output;
  500. }
  501. void RenderBeast::setOptions(const SPtr<RendererOptions>& options)
  502. {
  503. mOptions = std::static_pointer_cast<RenderBeastOptions>(options);
  504. mOptionsDirty = true;
  505. }
  506. SPtr<RendererOptions> RenderBeast::getOptions() const
  507. {
  508. return mOptions;
  509. }
  510. void RenderBeast::syncOptions(const RenderBeastOptions& options)
  511. {
  512. bool filteringChanged = mCoreOptions->filtering != options.filtering;
  513. if (options.filtering == RenderBeastFiltering::Anisotropic)
  514. filteringChanged |= mCoreOptions->anisotropyMax != options.anisotropyMax;
  515. if (filteringChanged)
  516. refreshSamplerOverrides(true);
  517. *mCoreOptions = options;
  518. for (auto& entry : mCameras)
  519. {
  520. RendererCamera* rendererCam = entry.second;
  521. rendererCam->setStateReductionMode(mCoreOptions->stateReductionMode);
  522. }
  523. }
  524. void RenderBeast::renderAll()
  525. {
  526. // Sync all dirty sim thread CoreObject data to core thread
  527. CoreObjectManager::instance().syncToCore();
  528. if (mOptionsDirty)
  529. {
  530. gCoreThread().queueCommand(std::bind(&RenderBeast::syncOptions, this, *mOptions));
  531. mOptionsDirty = false;
  532. }
  533. gCoreThread().queueCommand(std::bind(&RenderBeast::renderAllCore, this, gTime().getTime(), gTime().getFrameDelta()));
  534. }
  535. static SPtr<Texture> dbgSkyTex;
  536. void RenderBeast::renderAllCore(float time, float delta)
  537. {
  538. THROW_IF_NOT_CORE_THREAD;
  539. gProfilerGPU().beginFrame();
  540. gProfilerCPU().beginSample("renderAllCore");
  541. // Note: I'm iterating over all sampler states every frame. If this ends up being a performance
  542. // issue consider handling this internally in ct::Material which can only do it when sampler states
  543. // are actually modified after sync
  544. refreshSamplerOverrides();
  545. // Update global per-frame hardware buffers
  546. mObjectRenderer->setParamFrameParams(time);
  547. // Retrieve animation data
  548. AnimationManager::instance().waitUntilComplete();
  549. const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
  550. FrameInfo frameInfo(delta, animData);
  551. //if (dbgSkyTex == nullptr)
  552. // dbgSkyTex = captureSceneCubeMap(Vector3(0, 2, 0), true, 1024, frameInfo);
  553. // Gather all views
  554. Vector<RendererCamera*> views;
  555. for (auto& rtInfo : mRenderTargets)
  556. {
  557. SPtr<RenderTarget> target = rtInfo.target;
  558. Vector<const Camera*>& cameras = rtInfo.cameras;
  559. UINT32 numCameras = (UINT32)cameras.size();
  560. for (UINT32 i = 0; i < numCameras; i++)
  561. {
  562. RendererCamera* viewInfo = mCameras[cameras[i]];
  563. views.push_back(viewInfo);
  564. }
  565. }
  566. // Render everything
  567. renderViews(views.data(), (UINT32)views.size(), frameInfo);
  568. gProfilerGPU().endFrame();
  569. // Present render targets with back buffers
  570. for (auto& rtInfo : mRenderTargets)
  571. {
  572. if(rtInfo.target->getProperties().isWindow())
  573. RenderAPI::instance().swapBuffers(rtInfo.target);
  574. }
  575. gProfilerCPU().endSample("renderAllCore");
  576. }
  577. void RenderBeast::renderViews(RendererCamera** views, UINT32 numViews, const FrameInfo& frameInfo)
  578. {
  579. // Generate render queues per camera
  580. mRenderableVisibility.assign(mRenderableVisibility.size(), false);
  581. for(UINT32 i = 0; i < numViews; i++)
  582. views[i]->determineVisible(mRenderables, mRenderableCullInfos, &mRenderableVisibility);
  583. // Generate a list of lights and their GPU buffers
  584. UINT32 numDirLights = (UINT32)mDirectionalLights.size();
  585. for (UINT32 i = 0; i < numDirLights; i++)
  586. {
  587. mLightDataTemp.push_back(LightData());
  588. mDirectionalLights[i].getParameters(mLightDataTemp.back());
  589. }
  590. UINT32 numRadialLights = (UINT32)mRadialLights.size();
  591. mLightVisibilityTemp.resize(numRadialLights, false);
  592. for (UINT32 i = 0; i < numViews; i++)
  593. views[i]->calculateVisibility(mPointLightWorldBounds, mLightVisibilityTemp);
  594. for(UINT32 i = 0; i < numRadialLights; i++)
  595. {
  596. if (!mLightVisibilityTemp[i])
  597. continue;
  598. mLightDataTemp.push_back(LightData());
  599. mRadialLights[i].getParameters(mLightDataTemp.back());
  600. }
  601. UINT32 numSpotLights = (UINT32)mSpotLights.size();
  602. mLightVisibilityTemp.resize(numSpotLights, false);
  603. for (UINT32 i = 0; i < numViews; i++)
  604. views[i]->calculateVisibility(mSpotLightWorldBounds, mLightVisibilityTemp);
  605. for (UINT32 i = 0; i < numSpotLights; i++)
  606. {
  607. if (!mLightVisibilityTemp[i])
  608. continue;
  609. mLightDataTemp.push_back(LightData());
  610. mSpotLights[i].getParameters(mLightDataTemp.back());
  611. }
  612. mGPULightData->setLights(mLightDataTemp, numDirLights, numRadialLights, numSpotLights);
  613. mLightDataTemp.clear();
  614. mLightVisibilityTemp.clear();
  615. // Update various buffers required by each renderable
  616. UINT32 numRenderables = (UINT32)mRenderables.size();
  617. for (UINT32 i = 0; i < numRenderables; i++)
  618. {
  619. if (!mRenderableVisibility[i])
  620. continue;
  621. // Note: Before uploading bone matrices perhaps check if they has actually been changed since last frame
  622. mRenderables[i]->renderable->updateAnimationBuffers(frameInfo.animData);
  623. // Note: Could this step be moved in notifyRenderableUpdated, so it only triggers when material actually gets
  624. // changed? Although it shouldn't matter much because if the internal versions keeping track of dirty params.
  625. for (auto& element : mRenderables[i]->elements)
  626. element.material->updateParamsSet(element.params);
  627. mRenderables[i]->perObjectParamBuffer->flushToGPU();
  628. }
  629. for (UINT32 i = 0; i < numViews; i++)
  630. {
  631. if (views[i]->isOverlay())
  632. renderOverlay(views[i]);
  633. else
  634. renderView(views[i], frameInfo.timeDelta);
  635. }
  636. }
  637. void RenderBeast::renderView(RendererCamera* viewInfo, float frameDelta)
  638. {
  639. gProfilerCPU().beginSample("Render");
  640. const Camera* sceneCamera = viewInfo->getSceneCamera();
  641. SPtr<GpuParamBlockBuffer> perCameraBuffer = viewInfo->getPerViewBuffer();
  642. perCameraBuffer->flushToGPU();
  643. Matrix4 viewProj = viewInfo->getViewProjMatrix();
  644. viewInfo->beginRendering(true);
  645. // Prepare light grid required for transparent object rendering
  646. mLightGrid->updateGrid(*viewInfo, *mGPULightData, viewInfo->renderWithNoLighting());
  647. SPtr<GpuParamBlockBuffer> gridParams;
  648. SPtr<GpuBuffer> gridOffsetsAndSize, gridLightIndices;
  649. mLightGrid->getOutputs(gridOffsetsAndSize, gridLightIndices, gridParams);
  650. // Assign camera and per-call data to all relevant renderables
  651. const VisibilityInfo& visibility = viewInfo->getVisibilityMasks();
  652. UINT32 numRenderables = (UINT32)mRenderables.size();
  653. for (UINT32 i = 0; i < numRenderables; i++)
  654. {
  655. if (!visibility.renderables[i])
  656. continue;
  657. RendererObject* rendererObject = mRenderables[i];
  658. rendererObject->updatePerCallBuffer(viewProj);
  659. for (auto& element : mRenderables[i]->elements)
  660. {
  661. if (element.perCameraBindingIdx != -1)
  662. element.params->setParamBlockBuffer(element.perCameraBindingIdx, perCameraBuffer, true);
  663. if (element.gridParamsBindingIdx != -1)
  664. element.params->setParamBlockBuffer(element.gridParamsBindingIdx, gridParams, true);
  665. element.gridOffsetsAndSizeParam.set(gridOffsetsAndSize);
  666. element.gridLightIndicesParam.set(gridLightIndices);
  667. element.lightsBufferParam.set(mGPULightData->getLightBuffer());
  668. }
  669. }
  670. SPtr<RenderTargets> renderTargets = viewInfo->getRenderTargets();
  671. renderTargets->bindGBuffer();
  672. // Trigger pre-base-pass callbacks
  673. auto iterRenderCallback = mCallbacks.begin();
  674. if (viewInfo->checkTriggerCallbacks())
  675. {
  676. while (iterRenderCallback != mCallbacks.end())
  677. {
  678. RendererExtension* extension = *iterRenderCallback;
  679. if (extension->getLocation() != RenderLocation::PreBasePass)
  680. break;
  681. if (extension->check(*sceneCamera))
  682. extension->render(*sceneCamera);
  683. ++iterRenderCallback;
  684. }
  685. }
  686. // Render base pass
  687. const Vector<RenderQueueElement>& opaqueElements = viewInfo->getOpaqueQueue()->getSortedElements();
  688. for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
  689. {
  690. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  691. renderElement(*renderElem, iter->passIdx, iter->applyPass, viewProj);
  692. }
  693. // Trigger post-base-pass callbacks
  694. if (viewInfo->checkTriggerCallbacks())
  695. {
  696. while (iterRenderCallback != mCallbacks.end())
  697. {
  698. RendererExtension* extension = *iterRenderCallback;
  699. if (extension->getLocation() != RenderLocation::PostBasePass)
  700. break;
  701. if (extension->check(*sceneCamera))
  702. extension->render(*sceneCamera);
  703. ++iterRenderCallback;
  704. }
  705. }
  706. RenderAPI& rapi = RenderAPI::instance();
  707. rapi.setRenderTarget(nullptr);
  708. // Render light pass
  709. ITiledDeferredLightingMat* lightingMat;
  710. UINT32 numSamples = viewInfo->getNumSamples();
  711. switch(numSamples)
  712. {
  713. case 0:
  714. case 1:
  715. lightingMat = mTiledDeferredLightingMats[0]; // No MSAA
  716. break;
  717. case 2:
  718. lightingMat = mTiledDeferredLightingMats[1]; // 2X MSAA
  719. break;
  720. case 4:
  721. lightingMat = mTiledDeferredLightingMats[2]; // 4X MSAA
  722. break;
  723. default:
  724. lightingMat = mTiledDeferredLightingMats[3]; // 8X MSAA or higher
  725. break;
  726. }
  727. lightingMat->setLights(*mGPULightData);
  728. lightingMat->execute(renderTargets, perCameraBuffer, viewInfo->renderWithNoLighting());
  729. const RenderAPIInfo& rapiInfo = RenderAPI::instance().getAPIInfo();
  730. bool usingFlattenedFB = numSamples > 1 && !rapiInfo.isFlagSet(RenderAPIFeatureFlag::MSAAImageStores);
  731. renderTargets->bindSceneColor(true);
  732. // If we're using flattened framebuffer for MSAA we need to copy its contents to the MSAA scene texture before
  733. // continuing
  734. if(usingFlattenedFB)
  735. {
  736. mFlatFramebufferToTextureMat->execute(renderTargets->getFlattenedSceneColorBuffer(),
  737. renderTargets->getSceneColor());
  738. }
  739. // Render skybox (if any)
  740. SPtr<Texture> skyTexture = viewInfo->getSkybox();
  741. if (skyTexture != nullptr && skyTexture->getProperties().getTextureType() == TEX_TYPE_CUBE_MAP)
  742. {
  743. mSkyboxMat->bind(perCameraBuffer);
  744. mSkyboxMat->setParams(skyTexture, Color::White);
  745. }
  746. else
  747. {
  748. Color clearColor = viewInfo->getClearColor();
  749. mSkyboxSolidColorMat->bind(perCameraBuffer);
  750. mSkyboxSolidColorMat->setParams(nullptr, clearColor);
  751. }
  752. SPtr<Mesh> mesh = gRendererUtility().getSkyBoxMesh();
  753. gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
  754. renderTargets->bindSceneColor(false);
  755. // Render transparent objects
  756. const Vector<RenderQueueElement>& transparentElements = viewInfo->getTransparentQueue()->getSortedElements();
  757. for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
  758. {
  759. BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
  760. renderElement(*renderElem, iter->passIdx, iter->applyPass, viewProj);
  761. }
  762. // Trigger post-light-pass callbacks
  763. if (viewInfo->checkTriggerCallbacks())
  764. {
  765. while (iterRenderCallback != mCallbacks.end())
  766. {
  767. RendererExtension* extension = *iterRenderCallback;
  768. if (extension->getLocation() != RenderLocation::PostLightPass)
  769. break;
  770. if (extension->check(*sceneCamera))
  771. extension->render(*sceneCamera);
  772. ++iterRenderCallback;
  773. }
  774. }
  775. // Post-processing and final resolve
  776. Rect2 viewportArea = viewInfo->getViewportRect();
  777. if (viewInfo->checkRunPostProcessing())
  778. {
  779. // If using MSAA, resolve into non-MSAA texture before post-processing
  780. if(numSamples > 1)
  781. {
  782. rapi.setRenderTarget(renderTargets->getSceneColorNonMSAART());
  783. rapi.setViewport(viewportArea);
  784. SPtr<Texture> sceneColor = renderTargets->getSceneColor();
  785. gRendererUtility().blit(sceneColor, Rect2I::EMPTY, viewInfo->getFlipView());
  786. }
  787. // Post-processing code also takes care of writting to the final output target
  788. PostProcessing::instance().postProcess(viewInfo, renderTargets->getSceneColorNonMSAA(), frameDelta);
  789. }
  790. else
  791. {
  792. // Just copy from scene color to output if no post-processing
  793. SPtr<RenderTarget> target = viewInfo->getFinalTarget();
  794. rapi.setRenderTarget(target);
  795. rapi.setViewport(viewportArea);
  796. SPtr<Texture> sceneColor = renderTargets->getSceneColor();
  797. gRendererUtility().blit(sceneColor, Rect2I::EMPTY, viewInfo->getFlipView());
  798. }
  799. // Trigger overlay callbacks
  800. if (viewInfo->checkTriggerCallbacks())
  801. {
  802. while (iterRenderCallback != mCallbacks.end())
  803. {
  804. RendererExtension* extension = *iterRenderCallback;
  805. if (extension->getLocation() != RenderLocation::Overlay)
  806. break;
  807. if (extension->check(*sceneCamera))
  808. extension->render(*sceneCamera);
  809. ++iterRenderCallback;
  810. }
  811. }
  812. viewInfo->endRendering();
  813. gProfilerCPU().endSample("Render");
  814. }
  815. void RenderBeast::renderOverlay(RendererCamera* viewInfo)
  816. {
  817. gProfilerCPU().beginSample("RenderOverlay");
  818. viewInfo->getPerViewBuffer()->flushToGPU();
  819. viewInfo->beginRendering(false);
  820. const Camera* camera = viewInfo->getSceneCamera();
  821. SPtr<RenderTarget> target = viewInfo->getFinalTarget();
  822. SPtr<Viewport> viewport = camera->getViewport();
  823. UINT32 clearBuffers = 0;
  824. if (viewport->getRequiresColorClear())
  825. clearBuffers |= FBT_COLOR;
  826. if (viewport->getRequiresDepthClear())
  827. clearBuffers |= FBT_DEPTH;
  828. if (viewport->getRequiresStencilClear())
  829. clearBuffers |= FBT_STENCIL;
  830. if (clearBuffers != 0)
  831. {
  832. RenderAPI::instance().setRenderTarget(target);
  833. RenderAPI::instance().clearViewport(clearBuffers, viewport->getClearColor(),
  834. viewport->getClearDepthValue(), viewport->getClearStencilValue());
  835. }
  836. else
  837. RenderAPI::instance().setRenderTarget(target, false, RT_COLOR0);
  838. RenderAPI::instance().setViewport(viewport->getNormArea());
  839. // Trigger overlay callbacks
  840. auto iterRenderCallback = mCallbacks.begin();
  841. while (iterRenderCallback != mCallbacks.end())
  842. {
  843. RendererExtension* extension = *iterRenderCallback;
  844. if (extension->getLocation() != RenderLocation::Overlay)
  845. {
  846. ++iterRenderCallback;
  847. continue;
  848. }
  849. if (extension->check(*camera))
  850. extension->render(*camera);
  851. ++iterRenderCallback;
  852. }
  853. viewInfo->endRendering();
  854. gProfilerCPU().endSample("RenderOverlay");
  855. }
  856. void RenderBeast::renderElement(const BeastRenderableElement& element, UINT32 passIdx, bool bindPass,
  857. const Matrix4& viewProj)
  858. {
  859. SPtr<Material> material = element.material;
  860. if (bindPass)
  861. gRendererUtility().setPass(material, passIdx, element.techniqueIdx);
  862. gRendererUtility().setPassParams(element.params, passIdx);
  863. if(element.morphVertexDeclaration == nullptr)
  864. gRendererUtility().draw(element.mesh, element.subMesh);
  865. else
  866. gRendererUtility().drawMorph(element.mesh, element.subMesh, element.morphShapeBuffer,
  867. element.morphVertexDeclaration);
  868. }
  869. SPtr<Texture> RenderBeast::captureSceneCubeMap(const Vector3& position, bool hdr, UINT32 size,
  870. const FrameInfo& frameInfo)
  871. {
  872. TEXTURE_DESC cubeMapDesc;
  873. cubeMapDesc.type = TEX_TYPE_CUBE_MAP;
  874. cubeMapDesc.format = hdr ? PF_FLOAT16_RGBA : PF_R8G8B8A8;
  875. cubeMapDesc.width = size;
  876. cubeMapDesc.height = size;
  877. cubeMapDesc.numMips = PixelUtil::getMaxMipmaps(size, size, 1, cubeMapDesc.format);
  878. cubeMapDesc.usage = TU_RENDERTARGET;
  879. SPtr<Texture> cubemap = Texture::create(cubeMapDesc);
  880. Matrix4 projTransform = Matrix4::projectionPerspective(Degree(90.0f), 1.0f, 0.05f, 1000.0f);
  881. ConvexVolume localFrustum(projTransform);
  882. RenderAPI::instance().convertProjectionMatrix(projTransform, projTransform);
  883. RENDERER_VIEW_DESC viewDesc;
  884. viewDesc.target.clearFlags = FBT_COLOR | FBT_DEPTH;
  885. viewDesc.target.clearColor = Color::Black;
  886. viewDesc.target.clearDepthValue = 1.0f;
  887. viewDesc.target.clearStencilValue = 0;
  888. viewDesc.target.nrmViewRect = Rect2(0, 0, 1.0f, 1.0f);
  889. viewDesc.target.viewRect = Rect2I(0, 0, size, size);
  890. viewDesc.target.targetWidth = size;
  891. viewDesc.target.targetHeight = size;
  892. viewDesc.target.numSamples = 1;
  893. viewDesc.isOverlay = false;
  894. viewDesc.isHDR = hdr;
  895. viewDesc.noLighting = false;
  896. viewDesc.triggerCallbacks = false;
  897. viewDesc.runPostProcessing = false;
  898. viewDesc.visibleLayers = 0xFFFFFFFFFFFFFFFF;
  899. viewDesc.nearPlane = 0.5f;
  900. viewDesc.farPlane = 1000.0f;
  901. viewDesc.flipView = RenderAPI::instance().getAPIInfo().isFlagSet(RenderAPIFeatureFlag::UVYAxisUp);
  902. viewDesc.viewOrigin = position;
  903. viewDesc.projTransform = projTransform;
  904. viewDesc.stateReduction = mCoreOptions->stateReductionMode;
  905. viewDesc.sceneCamera = nullptr;
  906. // Note: Find a camera to receive skybox from. Skybox should probably be a global property instead of a per-camera
  907. // one.
  908. for(auto& entry : mRenderTargets)
  909. {
  910. for(auto& camera : entry.cameras)
  911. {
  912. if (camera->getSkybox() != nullptr)
  913. {
  914. viewDesc.skyboxTexture = camera->getSkybox();
  915. break;
  916. }
  917. }
  918. }
  919. Matrix4 viewOffsetMat = Matrix4::translation(-position);
  920. RendererCamera views[6];
  921. for(UINT32 i = 0; i < 6; i++)
  922. {
  923. // Calculate view matrix
  924. Matrix3 viewRotationMat;
  925. Vector3 forward;
  926. Vector3 up = Vector3::UNIT_Y;
  927. switch (i)
  928. {
  929. case CF_PositiveX:
  930. forward = Vector3::UNIT_X;
  931. break;
  932. case CF_NegativeX:
  933. forward = -Vector3::UNIT_X;
  934. break;
  935. case CF_PositiveY:
  936. forward = Vector3::UNIT_Y;
  937. up = -Vector3::UNIT_Z;
  938. break;
  939. case CF_NegativeY:
  940. forward = Vector3::UNIT_X;
  941. up = Vector3::UNIT_Z;
  942. break;
  943. case CF_PositiveZ:
  944. forward = Vector3::UNIT_Z;
  945. break;
  946. case CF_NegativeZ:
  947. forward = -Vector3::UNIT_Z;
  948. break;
  949. }
  950. Vector3 right = Vector3::cross(up, forward);
  951. viewRotationMat = Matrix3(right, up, forward);
  952. viewDesc.viewDirection = forward;
  953. viewDesc.viewTransform = Matrix4(viewRotationMat) * viewOffsetMat;
  954. // Calculate world frustum for culling
  955. const Vector<Plane>& frustumPlanes = localFrustum.getPlanes();
  956. Matrix4 worldMatrix = viewDesc.viewTransform.transpose();
  957. Vector<Plane> worldPlanes(frustumPlanes.size());
  958. UINT32 j = 0;
  959. for (auto& plane : frustumPlanes)
  960. {
  961. worldPlanes[j] = worldMatrix.multiplyAffine(plane);
  962. j++;
  963. }
  964. viewDesc.cullFrustum = ConvexVolume(worldPlanes);
  965. // Set up face render target
  966. RENDER_TEXTURE_DESC cubeFaceRTDesc;
  967. cubeFaceRTDesc.colorSurfaces[0].texture = cubemap;
  968. cubeFaceRTDesc.colorSurfaces[0].face = i;
  969. cubeFaceRTDesc.colorSurfaces[0].numFaces = 1;
  970. viewDesc.target.target = RenderTexture::create(cubeFaceRTDesc);
  971. views[i].setView(viewDesc);
  972. views[i].updatePerViewBuffer();
  973. views[i].determineVisible(mRenderables, mRenderableCullInfos);
  974. }
  975. RendererCamera* viewPtrs[] = { &views[0], &views[1], &views[2], &views[3], &views[4], &views[5] };
  976. renderViews(viewPtrs, 6, frameInfo);
  977. ReflectionCubemap::filterCubemapForSpecular(cubemap);
  978. return cubemap;
  979. }
  980. void RenderBeast::refreshSamplerOverrides(bool force)
  981. {
  982. bool anyDirty = false;
  983. for (auto& entry : mSamplerOverrides)
  984. {
  985. SPtr<MaterialParams> materialParams = entry.first.material->_getInternalParams();
  986. MaterialSamplerOverrides* materialOverrides = entry.second;
  987. for(UINT32 i = 0; i < materialOverrides->numOverrides; i++)
  988. {
  989. SamplerOverride& override = materialOverrides->overrides[i];
  990. const MaterialParamsBase::ParamData* materialParamData = materialParams->getParamData(override.paramIdx);
  991. SPtr<SamplerState> samplerState;
  992. materialParams->getSamplerState(*materialParamData, samplerState);
  993. UINT64 hash = 0;
  994. if (samplerState != nullptr)
  995. hash = samplerState->getProperties().getHash();
  996. if (hash != override.originalStateHash || force)
  997. {
  998. if (samplerState != nullptr)
  999. override.state = SamplerOverrideUtility::generateSamplerOverride(samplerState, mCoreOptions);
  1000. else
  1001. override.state = SamplerOverrideUtility::generateSamplerOverride(SamplerState::getDefault(), mCoreOptions);
  1002. override.originalStateHash = override.state->getProperties().getHash();
  1003. materialOverrides->isDirty = true;
  1004. }
  1005. // Dirty flag can also be set externally, so check here even though we assign it above
  1006. if (materialOverrides->isDirty)
  1007. anyDirty = true;
  1008. }
  1009. }
  1010. // Early exit if possible
  1011. if (!anyDirty)
  1012. return;
  1013. UINT32 numRenderables = (UINT32)mRenderables.size();
  1014. for (UINT32 i = 0; i < numRenderables; i++)
  1015. {
  1016. for(auto& element : mRenderables[i]->elements)
  1017. {
  1018. MaterialSamplerOverrides* overrides = element.samplerOverrides;
  1019. if(overrides != nullptr && overrides->isDirty)
  1020. {
  1021. UINT32 numPasses = element.material->getNumPasses();
  1022. for(UINT32 j = 0; j < numPasses; j++)
  1023. {
  1024. SPtr<GpuParams> params = element.params->getGpuParams(j);
  1025. const UINT32 numStages = 6;
  1026. for (UINT32 k = 0; k < numStages; k++)
  1027. {
  1028. GpuProgramType type = (GpuProgramType)k;
  1029. SPtr<GpuParamDesc> paramDesc = params->getParamDesc(type);
  1030. if (paramDesc == nullptr)
  1031. continue;
  1032. for (auto& samplerDesc : paramDesc->samplers)
  1033. {
  1034. UINT32 set = samplerDesc.second.set;
  1035. UINT32 slot = samplerDesc.second.slot;
  1036. UINT32 overrideIndex = overrides->passes[j].stateOverrides[set][slot];
  1037. if (overrideIndex == (UINT32)-1)
  1038. continue;
  1039. params->setSamplerState(set, slot, overrides->overrides[overrideIndex].state);
  1040. }
  1041. }
  1042. }
  1043. }
  1044. }
  1045. }
  1046. for (auto& entry : mSamplerOverrides)
  1047. entry.second->isDirty = false;
  1048. }
  1049. }}