BsRenderBeast.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsRenderBeast.h"
  4. #include "Components/BsCCamera.h"
  5. #include "Components/BsCRenderable.h"
  6. #include "Material/BsMaterial.h"
  7. #include "Material/BsPass.h"
  8. #include "BsCoreApplication.h"
  9. #include "RenderAPI/BsViewport.h"
  10. #include "RenderAPI/BsRenderTarget.h"
  11. #include "CoreThread/BsCoreThread.h"
  12. #include "Profiling/BsProfilerCPU.h"
  13. #include "Profiling/BsProfilerGPU.h"
  14. #include "Material/BsShader.h"
  15. #include "RenderAPI/BsGpuParamBlockBuffer.h"
  16. #include "Utility/BsTime.h"
  17. #include "CoreThread/BsCoreObjectManager.h"
  18. #include "BsRenderBeastOptions.h"
  19. #include "Renderer/BsLight.h"
  20. #include "BsGpuResourcePool.h"
  21. #include "Renderer/BsRendererUtility.h"
  22. #include "Animation/BsAnimationManager.h"
  23. #include "Animation/BsSkeleton.h"
  24. #include "Renderer/BsRendererExtension.h"
  25. #include "Renderer/BsReflectionProbe.h"
  26. #include "Renderer/BsIBLUtility.h"
  27. #include "Renderer/BsSkybox.h"
  28. #include "BsStandardDeferredLighting.h"
  29. #include "BsShadowRendering.h"
  30. #include "BsRenderCompositor.h"
  31. #include "BsRendererTextures.h"
  32. #include "BsRenderBeastIBLUtility.h"
  33. #include "Renderer/BsRendererManager.h"
  34. using namespace std::placeholders;
  35. namespace bs { namespace ct
  36. {
  37. RenderBeast::RenderBeast()
  38. {
  39. mOptions = bs_shared_ptr_new<RenderBeastOptions>();
  40. }
  41. const StringID& RenderBeast::getName() const
  42. {
  43. static StringID name = "RenderBeast";
  44. return name;
  45. }
  46. void RenderBeast::initialize()
  47. {
  48. Renderer::initialize();
  49. gCoreThread().queueCommand(std::bind(&RenderBeast::initializeCore, this), CTQF_InternalQueue);
  50. }
  51. void RenderBeast::destroy()
  52. {
  53. Renderer::destroy();
  54. gCoreThread().queueCommand(std::bind(&RenderBeast::destroyCore, this));
  55. gCoreThread().submit(true);
  56. }
  57. void RenderBeast::initializeCore()
  58. {
  59. const RenderAPI& rapi = RenderAPI::instance();
  60. const RenderAPIInfo& rapiInfo = rapi.getAPIInfo();
  61. if(
  62. !rapiInfo.isFlagSet(RenderAPIFeatureFlag::Compute) ||
  63. !rapiInfo.isFlagSet(RenderAPIFeatureFlag::LoadStore) ||
  64. !rapiInfo.isFlagSet(RenderAPIFeatureFlag::TextureViews))
  65. {
  66. mFeatureSet = RenderBeastFeatureSet::DesktopMacOS;
  67. }
  68. RendererUtility::startUp();
  69. GpuResourcePool::startUp();
  70. IBLUtility::startUp<RenderBeastIBLUtility>();
  71. RendererTextures::startUp();
  72. mCoreOptions = bs_shared_ptr_new<RenderBeastOptions>();
  73. mScene = bs_shared_ptr_new<RendererScene>(mCoreOptions);
  74. mObjectRenderer = bs_new<ObjectRenderer>();
  75. mMainViewGroup = bs_new<RendererViewGroup>();
  76. StandardDeferred::startUp();
  77. RenderCompositor::registerNodeType<RCNodeSceneDepth>();
  78. RenderCompositor::registerNodeType<RCNodeGBuffer>();
  79. RenderCompositor::registerNodeType<RCNodeLightAccumulation>();
  80. RenderCompositor::registerNodeType<RCNodeSceneColor>();
  81. RenderCompositor::registerNodeType<RCNodeStandardDeferredLighting>();
  82. RenderCompositor::registerNodeType<RCNodeStandardDeferredIBL>();
  83. RenderCompositor::registerNodeType<RCNodeTiledDeferredLighting>();
  84. RenderCompositor::registerNodeType<RCNodeTiledDeferredIBL>();
  85. RenderCompositor::registerNodeType<RCNodeUnflattenLightAccum>();
  86. RenderCompositor::registerNodeType<RCNodeFinalResolve>();
  87. RenderCompositor::registerNodeType<RCNodeSkybox>();
  88. RenderCompositor::registerNodeType<RCNodeUnflattenSceneColor>();
  89. RenderCompositor::registerNodeType<RCNodePostProcess>();
  90. RenderCompositor::registerNodeType<RCNodeTonemapping>();
  91. RenderCompositor::registerNodeType<RCNodeGaussianDOF>();
  92. RenderCompositor::registerNodeType<RCNodeFXAA>();
  93. RenderCompositor::registerNodeType<RCNodeResolvedSceneDepth>();
  94. RenderCompositor::registerNodeType<RCNodeHiZ>();
  95. RenderCompositor::registerNodeType<RCNodeSSAO>();
  96. RenderCompositor::registerNodeType<RCNodeClusteredForward>();
  97. RenderCompositor::registerNodeType<RCNodeIndirectLighting>();
  98. RenderCompositor::registerNodeType<RCNodeSSR>();
  99. RenderCompositor::registerNodeType<RCNodeMSAACoverage>();
  100. }
  101. void RenderBeast::destroyCore()
  102. {
  103. // Make sure all tasks finish first
  104. processTasks(true);
  105. if (mObjectRenderer != nullptr)
  106. bs_delete(mObjectRenderer);
  107. mScene = nullptr;
  108. RenderCompositor::cleanUp();
  109. StandardDeferred::shutDown();
  110. bs_delete(mMainViewGroup);
  111. RendererTextures::shutDown();
  112. IBLUtility::shutDown();
  113. GpuResourcePool::shutDown();
  114. RendererUtility::shutDown();
  115. }
  116. void RenderBeast::notifyRenderableAdded(Renderable* renderable)
  117. {
  118. mScene->registerRenderable(renderable);
  119. const SceneInfo& sceneInfo = mScene->getSceneInfo();
  120. RendererObject* rendererObject = sceneInfo.renderables[renderable->getRendererId()];
  121. for(auto& entry : rendererObject->elements)
  122. mObjectRenderer->initElement(*rendererObject, entry);
  123. }
  124. void RenderBeast::notifyRenderableRemoved(Renderable* renderable)
  125. {
  126. mScene->unregisterRenderable(renderable);
  127. }
  128. void RenderBeast::notifyRenderableUpdated(Renderable* renderable)
  129. {
  130. mScene->updateRenderable(renderable);
  131. }
  132. void RenderBeast::notifyLightAdded(Light* light)
  133. {
  134. mScene->registerLight(light);
  135. }
  136. void RenderBeast::notifyLightUpdated(Light* light)
  137. {
  138. mScene->updateLight(light);
  139. }
  140. void RenderBeast::notifyLightRemoved(Light* light)
  141. {
  142. mScene->unregisterLight(light);
  143. }
  144. void RenderBeast::notifyCameraAdded(Camera* camera)
  145. {
  146. mScene->registerCamera(camera);
  147. }
  148. void RenderBeast::notifyCameraUpdated(Camera* camera, UINT32 updateFlag)
  149. {
  150. mScene->updateCamera(camera, updateFlag);
  151. }
  152. void RenderBeast::notifyCameraRemoved(Camera* camera)
  153. {
  154. mScene->unregisterCamera(camera);
  155. }
  156. void RenderBeast::notifyReflectionProbeAdded(ReflectionProbe* probe)
  157. {
  158. mScene->registerReflectionProbe(probe);
  159. }
  160. void RenderBeast::notifyReflectionProbeUpdated(ReflectionProbe* probe, bool texture)
  161. {
  162. mScene->updateReflectionProbe(probe, texture);
  163. }
  164. void RenderBeast::notifyReflectionProbeRemoved(ReflectionProbe* probe)
  165. {
  166. mScene->unregisterReflectionProbe(probe);
  167. }
  168. void RenderBeast::notifyLightProbeVolumeAdded(LightProbeVolume* volume)
  169. {
  170. mScene->registerLightProbeVolume(volume);
  171. }
  172. void RenderBeast::notifyLightProbeVolumeUpdated(LightProbeVolume* volume)
  173. {
  174. mScene->updateLightProbeVolume(volume);
  175. }
  176. void RenderBeast::notifyLightProbeVolumeRemoved(LightProbeVolume* volume)
  177. {
  178. mScene->unregisterLightProbeVolume(volume);
  179. }
  180. void RenderBeast::notifySkyboxAdded(Skybox* skybox)
  181. {
  182. mScene->registerSkybox(skybox);
  183. }
  184. void RenderBeast::notifySkyboxRemoved(Skybox* skybox)
  185. {
  186. mScene->unregisterSkybox(skybox);
  187. }
  188. void RenderBeast::setOptions(const SPtr<RendererOptions>& options)
  189. {
  190. mOptions = std::static_pointer_cast<RenderBeastOptions>(options);
  191. mOptionsDirty = true;
  192. }
  193. SPtr<RendererOptions> RenderBeast::getOptions() const
  194. {
  195. return mOptions;
  196. }
  197. void RenderBeast::syncOptions(const RenderBeastOptions& options)
  198. {
  199. bool filteringChanged = mCoreOptions->filtering != options.filtering;
  200. if (options.filtering == RenderBeastFiltering::Anisotropic)
  201. filteringChanged |= mCoreOptions->anisotropyMax != options.anisotropyMax;
  202. if (filteringChanged)
  203. mScene->refreshSamplerOverrides(true);
  204. *mCoreOptions = options;
  205. mScene->setOptions(mCoreOptions);
  206. ShadowRendering& shadowRenderer = mMainViewGroup->getShadowRenderer();
  207. shadowRenderer.setShadowMapSize(mCoreOptions->shadowMapSize);
  208. }
  209. void RenderBeast::renderAll(const EvaluatedAnimationData* animData)
  210. {
  211. // Sync all dirty sim thread CoreObject data to core thread
  212. CoreObjectManager::instance().syncToCore();
  213. if (mOptionsDirty)
  214. {
  215. gCoreThread().queueCommand(std::bind(&RenderBeast::syncOptions, this, *mOptions));
  216. mOptionsDirty = false;
  217. }
  218. FrameTimings timings;
  219. timings.time = gTime().getTime();
  220. timings.timeDelta = gTime().getFrameDelta();
  221. timings.frameIdx = gTime().getFrameIdx();
  222. gCoreThread().queueCommand(std::bind(&RenderBeast::renderAllCore, this, timings, animData));
  223. }
  224. void RenderBeast::renderAllCore(FrameTimings timings, const EvaluatedAnimationData* animData)
  225. {
  226. THROW_IF_NOT_CORE_THREAD;
  227. gProfilerGPU().beginFrame();
  228. gProfilerCPU().beginSample("renderAllCore");
  229. const SceneInfo& sceneInfo = mScene->getSceneInfo();
  230. // Note: I'm iterating over all sampler states every frame. If this ends up being a performance
  231. // issue consider handling this internally in ct::Material which can only do it when sampler states
  232. // are actually modified after sync
  233. mScene->refreshSamplerOverrides();
  234. // Update global per-frame hardware buffers
  235. mObjectRenderer->setParamFrameParams(timings.time);
  236. // Retrieve animation data
  237. sceneInfo.renderableReady.resize(sceneInfo.renderables.size(), false);
  238. sceneInfo.renderableReady.assign(sceneInfo.renderables.size(), false);
  239. FrameInfo frameInfo(timings, animData);
  240. // Make sure any renderer tasks finish first, as rendering might depend on them
  241. processTasks(false);
  242. // Gather all views
  243. Vector<RendererView*> views;
  244. for (auto& rtInfo : sceneInfo.renderTargets)
  245. {
  246. SPtr<RenderTarget> target = rtInfo.target;
  247. const Vector<Camera*>& cameras = rtInfo.cameras;
  248. UINT32 numCameras = (UINT32)cameras.size();
  249. for (UINT32 i = 0; i < numCameras; i++)
  250. {
  251. UINT32 viewIdx = sceneInfo.cameraToView.at(cameras[i]);
  252. RendererView* viewInfo = sceneInfo.views[viewIdx];
  253. views.push_back(viewInfo);
  254. }
  255. }
  256. mMainViewGroup->setViews(views.data(), (UINT32)views.size());
  257. mMainViewGroup->determineVisibility(sceneInfo);
  258. // Update reflection probe array if required
  259. updateReflProbeArray();
  260. // Render everything
  261. renderViews(*mMainViewGroup, frameInfo);
  262. gProfilerGPU().endFrame();
  263. // Present render targets with back buffers
  264. for (auto& rtInfo : sceneInfo.renderTargets)
  265. {
  266. if(rtInfo.target->getProperties().isWindow)
  267. RenderAPI::instance().swapBuffers(rtInfo.target);
  268. }
  269. gProfilerCPU().endSample("renderAllCore");
  270. }
  271. void RenderBeast::renderViews(RendererViewGroup& viewGroup, const FrameInfo& frameInfo)
  272. {
  273. const SceneInfo& sceneInfo = mScene->getSceneInfo();
  274. const VisibilityInfo& visibility = viewGroup.getVisibilityInfo();
  275. // Render shadow maps
  276. ShadowRendering& shadowRenderer = viewGroup.getShadowRenderer();
  277. shadowRenderer.renderShadowMaps(*mScene, viewGroup, frameInfo);
  278. // Update various buffers required by each renderable
  279. UINT32 numRenderables = (UINT32)sceneInfo.renderables.size();
  280. for (UINT32 i = 0; i < numRenderables; i++)
  281. {
  282. if (!visibility.renderables[i])
  283. continue;
  284. mScene->prepareRenderable(i, frameInfo);
  285. }
  286. UINT32 numViews = viewGroup.getNumViews();
  287. for (UINT32 i = 0; i < numViews; i++)
  288. {
  289. RendererView* view = viewGroup.getView(i);
  290. const RenderSettings& settings = view->getRenderSettings();
  291. if (settings.overlayOnly)
  292. renderOverlay(*view);
  293. else
  294. renderView(viewGroup, *view, frameInfo);
  295. }
  296. }
  297. void RenderBeast::renderView(const RendererViewGroup& viewGroup, RendererView& view, const FrameInfo& frameInfo)
  298. {
  299. gProfilerCPU().beginSample("Render");
  300. const SceneInfo& sceneInfo = mScene->getSceneInfo();
  301. auto& viewProps = view.getProperties();
  302. SPtr<GpuParamBlockBuffer> perCameraBuffer = view.getPerViewBuffer();
  303. perCameraBuffer->flushToGPU();
  304. // Make sure light probe data is up to date
  305. if(view.getRenderSettings().enableIndirectLighting)
  306. mScene->updateLightProbes();
  307. view.beginFrame();
  308. RenderCompositorNodeInputs inputs(viewGroup, view, sceneInfo, *mCoreOptions, frameInfo, mFeatureSet);
  309. // Register callbacks
  310. if (viewProps.triggerCallbacks)
  311. {
  312. for(auto& extension : mCallbacks)
  313. {
  314. RenderLocation location = extension->getLocation();
  315. switch(location)
  316. {
  317. case RenderLocation::Prepare:
  318. inputs.extPrepare.push_back(extension);
  319. break;
  320. case RenderLocation::PreBasePass:
  321. inputs.extPreBasePass.push_back(extension);
  322. break;
  323. case RenderLocation::PostBasePass:
  324. inputs.extPostBasePass.push_back(extension);
  325. break;
  326. case RenderLocation::PostLightPass:
  327. inputs.extPostLighting.push_back(extension);
  328. break;
  329. case RenderLocation::Overlay:
  330. inputs.extOverlay.push_back(extension);
  331. break;
  332. }
  333. }
  334. }
  335. const RenderCompositor& compositor = view.getCompositor();
  336. compositor.execute(inputs);
  337. view.endFrame();
  338. gProfilerCPU().endSample("Render");
  339. }
  340. void RenderBeast::renderOverlay(RendererView& view)
  341. {
  342. gProfilerCPU().beginSample("RenderOverlay");
  343. view.getPerViewBuffer()->flushToGPU();
  344. view.beginFrame();
  345. auto& viewProps = view.getProperties();
  346. const Camera* camera = view.getSceneCamera();
  347. SPtr<RenderTarget> target = viewProps.target;
  348. SPtr<Viewport> viewport = camera->getViewport();
  349. ClearFlags clearFlags = viewport->getClearFlags();
  350. UINT32 clearBuffers = 0;
  351. if (clearFlags.isSet(ClearFlagBits::Color))
  352. clearBuffers |= FBT_COLOR;
  353. if (clearFlags.isSet(ClearFlagBits::Depth))
  354. clearBuffers |= FBT_DEPTH;
  355. if (clearFlags.isSet(ClearFlagBits::Stencil))
  356. clearBuffers |= FBT_STENCIL;
  357. if (clearBuffers != 0)
  358. {
  359. RenderAPI::instance().setRenderTarget(target);
  360. RenderAPI::instance().clearViewport(clearBuffers, viewport->getClearColorValue(),
  361. viewport->getClearDepthValue(), viewport->getClearStencilValue());
  362. }
  363. else
  364. RenderAPI::instance().setRenderTarget(target, 0, RT_COLOR0);
  365. RenderAPI::instance().setViewport(viewport->getArea());
  366. // Trigger overlay callbacks
  367. auto iterRenderCallback = mCallbacks.begin();
  368. while (iterRenderCallback != mCallbacks.end())
  369. {
  370. RendererExtension* extension = *iterRenderCallback;
  371. if (extension->getLocation() != RenderLocation::Overlay)
  372. {
  373. ++iterRenderCallback;
  374. continue;
  375. }
  376. if (extension->check(*camera))
  377. extension->render(*camera);
  378. ++iterRenderCallback;
  379. }
  380. view.endFrame();
  381. gProfilerCPU().endSample("RenderOverlay");
  382. }
  383. void RenderBeast::updateReflProbeArray()
  384. {
  385. SceneInfo& sceneInfo = mScene->_getSceneInfo();
  386. UINT32 numProbes = (UINT32)sceneInfo.reflProbes.size();
  387. bs_frame_mark();
  388. {
  389. UINT32 currentCubeArraySize = 0;
  390. if(sceneInfo.reflProbeCubemapsTex != nullptr)
  391. currentCubeArraySize = sceneInfo.reflProbeCubemapsTex->getProperties().getNumArraySlices();
  392. bool forceArrayUpdate = false;
  393. if(sceneInfo.reflProbeCubemapsTex == nullptr || (currentCubeArraySize < numProbes && currentCubeArraySize != MaxReflectionCubemaps))
  394. {
  395. TEXTURE_DESC cubeMapDesc;
  396. cubeMapDesc.type = TEX_TYPE_CUBE_MAP;
  397. cubeMapDesc.format = PF_RG11B10F;
  398. cubeMapDesc.width = IBLUtility::REFLECTION_CUBEMAP_SIZE;
  399. cubeMapDesc.height = IBLUtility::REFLECTION_CUBEMAP_SIZE;
  400. cubeMapDesc.numMips = PixelUtil::getMaxMipmaps(cubeMapDesc.width, cubeMapDesc.height, 1, cubeMapDesc.format);
  401. cubeMapDesc.numArraySlices = std::min(MaxReflectionCubemaps, numProbes + 4); // Keep a few empty entries
  402. sceneInfo.reflProbeCubemapsTex = Texture::create(cubeMapDesc);
  403. forceArrayUpdate = true;
  404. }
  405. auto& cubemapArrayProps = sceneInfo.reflProbeCubemapsTex->getProperties();
  406. FrameQueue<UINT32> emptySlots;
  407. for (UINT32 i = 0; i < numProbes; i++)
  408. {
  409. const RendererReflectionProbe& probeInfo = sceneInfo.reflProbes[i];
  410. if (probeInfo.arrayIdx > MaxReflectionCubemaps)
  411. continue;
  412. if(probeInfo.arrayDirty || forceArrayUpdate)
  413. {
  414. SPtr<Texture> texture = probeInfo.probe->getFilteredTexture();
  415. if (texture == nullptr)
  416. continue;
  417. auto& srcProps = texture->getProperties();
  418. bool isValid = srcProps.getWidth() == IBLUtility::REFLECTION_CUBEMAP_SIZE &&
  419. srcProps.getHeight() == IBLUtility::REFLECTION_CUBEMAP_SIZE &&
  420. srcProps.getNumMipmaps() == cubemapArrayProps.getNumMipmaps() &&
  421. srcProps.getTextureType() == TEX_TYPE_CUBE_MAP;
  422. if(!isValid)
  423. {
  424. if (!probeInfo.errorFlagged)
  425. {
  426. String errMsg = StringUtil::format("Cubemap texture invalid to use as a reflection cubemap. "
  427. "Check texture size (must be {0}x{0}) and mip-map count",
  428. IBLUtility::REFLECTION_CUBEMAP_SIZE);
  429. LOGERR(errMsg);
  430. probeInfo.errorFlagged = true;
  431. }
  432. }
  433. else
  434. {
  435. for(UINT32 face = 0; face < 6; face++)
  436. {
  437. for(UINT32 mip = 0; mip <= srcProps.getNumMipmaps(); mip++)
  438. {
  439. TEXTURE_COPY_DESC copyDesc;
  440. copyDesc.srcFace = face;
  441. copyDesc.srcMip = mip;
  442. copyDesc.dstFace = probeInfo.arrayIdx * 6 + face;
  443. copyDesc.dstMip = mip;
  444. texture->copy(sceneInfo.reflProbeCubemapsTex, copyDesc);
  445. }
  446. }
  447. }
  448. mScene->setReflectionProbeArrayIndex(i, probeInfo.arrayIdx, true);
  449. }
  450. // Note: Consider pruning the reflection cubemap array if empty slot count becomes too high
  451. }
  452. }
  453. bs_frame_clear();
  454. }
  455. void RenderBeast::captureSceneCubeMap(const SPtr<Texture>& cubemap, const Vector3& position,
  456. const CaptureSettings& settings)
  457. {
  458. const SceneInfo& sceneInfo = mScene->getSceneInfo();
  459. auto& texProps = cubemap->getProperties();
  460. Matrix4 projTransform = Matrix4::projectionPerspective(Degree(90.0f), 1.0f, 0.05f, 1000.0f);
  461. ConvexVolume localFrustum(projTransform);
  462. RenderAPI::instance().convertProjectionMatrix(projTransform, projTransform);
  463. RENDERER_VIEW_DESC viewDesc;
  464. viewDesc.target.clearFlags = FBT_COLOR | FBT_DEPTH;
  465. viewDesc.target.clearColor = Color::Black;
  466. viewDesc.target.clearDepthValue = 1.0f;
  467. viewDesc.target.clearStencilValue = 0;
  468. viewDesc.target.nrmViewRect = Rect2(0, 0, 1.0f, 1.0f);
  469. viewDesc.target.viewRect = Rect2I(0, 0, texProps.getWidth(), texProps.getHeight());
  470. viewDesc.target.targetWidth = texProps.getWidth();
  471. viewDesc.target.targetHeight = texProps.getHeight();
  472. viewDesc.target.numSamples = 1;
  473. viewDesc.triggerCallbacks = false;
  474. viewDesc.runPostProcessing = false;
  475. viewDesc.capturingReflections = true;
  476. viewDesc.encodeDepth = settings.encodeDepth;
  477. viewDesc.depthEncodeNear = settings.depthEncodeNear;
  478. viewDesc.depthEncodeFar = settings.depthEncodeFar;
  479. viewDesc.visibleLayers = 0xFFFFFFFFFFFFFFFF;
  480. viewDesc.nearPlane = 0.5f;
  481. viewDesc.farPlane = 1000.0f;
  482. viewDesc.flipView = !RenderAPI::instance().getAPIInfo().isFlagSet(RenderAPIFeatureFlag::UVYAxisUp);
  483. viewDesc.viewOrigin = position;
  484. viewDesc.projTransform = projTransform;
  485. viewDesc.projType = PT_PERSPECTIVE;
  486. viewDesc.stateReduction = mCoreOptions->stateReductionMode;
  487. viewDesc.sceneCamera = nullptr;
  488. SPtr<RenderSettings> renderSettings = bs_shared_ptr_new<RenderSettings>();
  489. renderSettings->enableHDR = settings.hdr;
  490. renderSettings->enableShadows = true;
  491. renderSettings->enableIndirectLighting = false;
  492. renderSettings->screenSpaceReflections.enabled = false;
  493. renderSettings->ambientOcclusion.enabled = false;
  494. Matrix4 viewOffsetMat = Matrix4::translation(-position);
  495. // Note: We render upside down, then flip the image vertically, which results in a horizontal flip. The horizontal
  496. // flip is required due to the fact how cubemap faces are defined. Another option would be to change the view
  497. // orientation matrix, but that also requires a culling mode flip which is inconvenient to do globally.
  498. RendererView views[6];
  499. for(UINT32 i = 0; i < 6; i++)
  500. {
  501. // Calculate view matrix
  502. Vector3 forward;
  503. Vector3 up = Vector3::UNIT_Y;
  504. switch (i)
  505. {
  506. case CF_PositiveX:
  507. forward = -Vector3::UNIT_X;
  508. up = -Vector3::UNIT_Y;
  509. break;
  510. case CF_NegativeX:
  511. forward = Vector3::UNIT_X;
  512. up = -Vector3::UNIT_Y;
  513. break;
  514. case CF_PositiveY:
  515. forward = Vector3::UNIT_Y;
  516. up = -Vector3::UNIT_Z;
  517. break;
  518. case CF_NegativeY:
  519. forward = -Vector3::UNIT_Y;
  520. up = Vector3::UNIT_Z;
  521. break;
  522. case CF_PositiveZ:
  523. forward = -Vector3::UNIT_Z;
  524. up = -Vector3::UNIT_Y;
  525. break;
  526. case CF_NegativeZ:
  527. forward = Vector3::UNIT_Z;
  528. up = -Vector3::UNIT_Y;
  529. break;
  530. }
  531. Vector3 right = Vector3::cross(up, forward);
  532. Matrix3 viewRotationMat = Matrix3(right, up, forward);
  533. viewDesc.viewDirection = -forward;
  534. viewDesc.viewTransform = Matrix4(viewRotationMat) * viewOffsetMat;
  535. // Calculate world frustum for culling
  536. const Vector<Plane>& frustumPlanes = localFrustum.getPlanes();
  537. Matrix4 worldMatrix = viewDesc.viewTransform.transpose();
  538. Vector<Plane> worldPlanes(frustumPlanes.size());
  539. UINT32 j = 0;
  540. for (auto& plane : frustumPlanes)
  541. {
  542. worldPlanes[j] = worldMatrix.multiplyAffine(plane);
  543. j++;
  544. }
  545. viewDesc.cullFrustum = ConvexVolume(worldPlanes);
  546. // Set up face render target
  547. RENDER_TEXTURE_DESC cubeFaceRTDesc;
  548. cubeFaceRTDesc.colorSurfaces[0].texture = cubemap;
  549. cubeFaceRTDesc.colorSurfaces[0].face = i;
  550. cubeFaceRTDesc.colorSurfaces[0].numFaces = 1;
  551. viewDesc.target.target = RenderTexture::create(cubeFaceRTDesc);
  552. views[i].setView(viewDesc);
  553. views[i].setRenderSettings(renderSettings);
  554. views[i].updatePerViewBuffer();
  555. }
  556. RendererView* viewPtrs[] = { &views[0], &views[1], &views[2], &views[3], &views[4], &views[5] };
  557. RendererViewGroup viewGroup(viewPtrs, 6, mCoreOptions->shadowMapSize);
  558. viewGroup.determineVisibility(sceneInfo);
  559. FrameInfo frameInfo({ 0.0f, 1.0f / 60.0f, 0 });
  560. renderViews(viewGroup, frameInfo);
  561. // Make sure the render texture is available for reads
  562. RenderAPI::instance().setRenderTarget(nullptr);
  563. }
  564. SPtr<RenderBeast> gRenderBeast()
  565. {
  566. return std::static_pointer_cast<RenderBeast>(RendererManager::instance().getActive());
  567. }
  568. }}