Showing the changes to libraries/render-utils/src/RenderCommonTask.cpp (1 of 81 files). Show all
Unified · Split
| @@ -13,7 +13,10 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | #include "render-utils/ShaderConstants.h" | 14 | #include "render-utils/ShaderConstants.h" |
| 15 | #include "DeferredLightingEffect.h" | 15 | #include "DeferredLightingEffect.h" |
| 16 | #include "FadeEffect.h" | ||
| 16 | #include "RenderUtilsLogging.h" | 17 | #include "RenderUtilsLogging.h" |
| 18 | #include "RenderViewTask.h" | ||
| 19 | #include "StencilMaskPass.h" | ||
| 17 | 20 | ||
| 18 | namespace ru { | 21 | namespace ru { |
| 19 | using render_utils::slot::texture::Texture; | 22 | using render_utils::slot::texture::Texture; |
| @@ -25,9 +28,11 @@ namespace gr { · 5 unmodified lines | |||
| 25 | using graphics::slot::buffer::Buffer; | 28 | using graphics::slot::buffer::Buffer; |
| 26 | } | 29 | } |
| 27 | 30 | ||
| 31 | using RenderArgsPointer = std::shared_ptr<RenderArgs>; | ||
| 28 | 32 | ||
| 29 | using namespace render; | 33 | using namespace render; |
| 30 | extern void initForwardPipelines(ShapePlumber& plumber); | 34 | extern void initForwardPipelines(ShapePlumber& plumber); |
| 35 | extern void initMirrorPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter, bool forward); | ||
| 31 | 36 | ||
| 32 | void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) { | 37 | void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) { |
| 33 | timer = _gpuTimer; | 38 | timer = _gpuTimer; |
| @@ -45,10 +50,14 @@ void EndGPURangeTimer::run(const render::RenderContextPointer& renderContext, co · 11 unmodified lines | |||
| 45 | config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage()); | 50 | config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage()); |
| 46 | } | 51 | } |
| 47 | 52 | ||
| 53 | render::ShapePlumberPointer DrawLayered3D::_shapePlumber = std::make_shared<ShapePlumber>(); | ||
| 54 | |||
| 48 | DrawLayered3D::DrawLayered3D(bool opaque) : | 55 | DrawLayered3D::DrawLayered3D(bool opaque) : |
| 49 | _shapePlumber(std::make_shared<ShapePlumber>()), | ||
| 50 | _opaquePass(opaque) { | 56 | _opaquePass(opaque) { |
| 51 | initForwardPipelines(*_shapePlumber); | 57 | static std::once_flag once; |
| 58 | std::call_once(once, [] { | ||
| 59 | initForwardPipelines(*_shapePlumber); | ||
| 60 | }); | ||
| 52 | } | 61 | } |
| 53 | 62 | ||
| 54 | void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) { | 63 | void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) { |
| @@ -262,3 +271,149 @@ void ResolveFramebuffer::run(const render::RenderContextPointer& renderContext, · 207 unmodified lines | |||
| 262 | } | 271 | } |
| 263 | } | 272 | } |
| 264 | 273 | ||
| 274 | class SetupMirrorTask { | ||
| 275 | public: | ||
| 276 | using Input = RenderMirrorTask::Inputs; | ||
| 277 | using Outputs = render::VaryingSet4<render::ItemBound, gpu::FramebufferPointer, RenderArgsPointer, glm::vec2>; | ||
| 278 | using JobModel = render::Job::ModelIO<SetupMirrorTask, Input, Outputs>; | ||
| 279 | |||
| 280 | SetupMirrorTask(size_t mirrorIndex, size_t depth) : _mirrorIndex(mirrorIndex), _depth(depth) {} | ||
| 281 | |||
| 282 | void run(const render::RenderContextPointer& renderContext, const Input& inputs, Outputs& outputs) { | ||
| 283 | auto args = renderContext->args; | ||
| 284 | auto items = inputs.get0(); | ||
| 285 | |||
| 286 | if (items.empty() || _mirrorIndex > items.size() - 1) { | ||
| 287 | renderContext->taskFlow.abortTask(); | ||
| 288 | return; | ||
| 289 | } | ||
| 290 | |||
| 291 | auto inputFramebuffer = inputs.get1(); | ||
| 292 | if (!_mirrorFramebuffer || _mirrorFramebuffer->getWidth() != inputFramebuffer->getWidth() || _mirrorFramebuffer->getHeight() != inputFramebuffer->getHeight()) { | ||
| 293 | _mirrorFramebuffer.reset(gpu::Framebuffer::create("mirror" + _mirrorIndex, gpu::Element::COLOR_SRGBA_32, inputFramebuffer->getWidth(), inputFramebuffer->getHeight())); | ||
| 294 | } | ||
| 295 | |||
| 296 | render::ItemBound mirror = items[_mirrorIndex]; | ||
| 297 | |||
| 298 | _cachedArgsPointer->_renderMode = args->_renderMode; | ||
| 299 | _cachedArgsPointer->_blitFramebuffer = args->_blitFramebuffer; | ||
| 300 | _cachedArgsPointer->_ignoreItem = args->_ignoreItem; | ||
| 301 | _cachedArgsPointer->_mirrorDepth = args->_mirrorDepth; | ||
| 302 | _cachedArgsPointer->_numMirrorFlips = args->_numMirrorFlips; | ||
| 303 | |||
| 304 | ViewFrustum srcViewFrustum = args->getViewFrustum(); | ||
| 305 | ItemID portalExitID = args->_scene->getItem(mirror.id).computeMirrorView(srcViewFrustum); | ||
| 306 | |||
| 307 | args->_blitFramebuffer = _mirrorFramebuffer; | ||
| 308 | args->_ignoreItem = portalExitID != Item::INVALID_ITEM_ID ? portalExitID : mirror.id; | ||
| 309 | args->_mirrorDepth = _depth; | ||
| 310 | args->_numMirrorFlips += portalExitID != Item::INVALID_ITEM_ID ? 0 : 1; | ||
| 311 | |||
| 312 | gpu::doInBatch("SetupMirrorTask::run", args->_context, [&](gpu::Batch& batch) { | ||
| 313 | bool shouldMirror = args->_numMirrorFlips % 2 == (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE); | ||
| 314 | batch.setContextMirrorViewCorrection(shouldMirror); | ||
| 315 | }); | ||
| 316 | |||
| 317 | // Without calculating the bound planes, the mirror will use the same culling frustum as the main camera, | ||
| 318 | // which is not what we want here. | ||
| 319 | srcViewFrustum.calculate(); | ||
| 320 | args->pushViewFrustum(srcViewFrustum); | ||
| 321 | |||
| 322 | outputs.edit0() = mirror; | ||
| 323 | outputs.edit1() = inputFramebuffer; | ||
| 324 | outputs.edit2() = _cachedArgsPointer; | ||
| 325 | outputs.edit3() = inputs.get2(); | ||
| 326 | } | ||
| 327 | |||
| 328 | protected: | ||
| 329 | gpu::FramebufferPointer _mirrorFramebuffer { nullptr }; | ||
| 330 | RenderArgsPointer _cachedArgsPointer { std::make_shared<RenderArgs>() }; | ||
| 331 | size_t _mirrorIndex; | ||
| 332 | size_t _depth; | ||
| 333 | |||
| 334 | }; | ||
| 335 | |||
| 336 | class DrawMirrorTask { | ||
| 337 | public: | ||
| 338 | using Inputs = SetupMirrorTask::Outputs; | ||
| 339 | using JobModel = render::Job::ModelI<DrawMirrorTask, Inputs>; | ||
| 340 | |||
| 341 | DrawMirrorTask() { | ||
| 342 | static std::once_flag once; | ||
| 343 | std::call_once(once, [this] { | ||
| 344 | auto state = std::make_shared<gpu::State>(); | ||
| 345 | state->setCullMode(gpu::State::CULL_BACK); | ||
| 346 | state->setDepthTest(true, true, gpu::LESS_EQUAL); | ||
| 347 | PrepareStencil::testMaskDrawShape(*state); | ||
| 348 | |||
| 349 | auto fadeEffect = DependencyManager::get<FadeEffect>(); | ||
| 350 | initMirrorPipelines(*_forwardPipelines, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter(), true); | ||
| 351 | initMirrorPipelines(*_deferredPipelines, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter(), false); | ||
| 352 | }); | ||
| 353 | } | ||
| 354 | |||
| 355 | void run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { | ||
| 356 | auto args = renderContext->args; | ||
| 357 | auto mirror = inputs.get0(); | ||
| 358 | auto framebuffer = inputs.get1(); | ||
| 359 | auto cachedArgs = inputs.get2(); | ||
| 360 | auto jitter = inputs.get3(); | ||
| 361 | |||
| 362 | if (cachedArgs) { | ||
| 363 | args->_renderMode = cachedArgs->_renderMode; | ||
| 364 | } | ||
| 365 | args->popViewFrustum(); | ||
| 366 | |||
| 367 | gpu::doInBatch("DrawMirrorTask::run", args->_context, [&](gpu::Batch& batch) { | ||
| 368 | args->_batch = &batch; | ||
| 369 | |||
| 370 | if (cachedArgs) { | ||
| 371 | bool shouldMirror = cachedArgs->_numMirrorFlips % 2 == (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE); | ||
| 372 | batch.setContextMirrorViewCorrection(shouldMirror); | ||
| 373 | } | ||
| 374 | |||
| 375 | batch.setFramebuffer(framebuffer); | ||
| 376 | batch.setViewportTransform(args->_viewport); | ||
| 377 | batch.setStateScissorRect(args->_viewport); | ||
| 378 | |||
| 379 | glm::mat4 projMat; | ||
| 380 | Transform viewMat; | ||
| 381 | args->getViewFrustum().evalProjectionMatrix(projMat); | ||
| 382 | args->getViewFrustum().evalViewTransform(viewMat); | ||
| 383 | |||
| 384 | batch.setProjectionTransform(projMat); | ||
| 385 | batch.setProjectionJitter(jitter.x, jitter.y); | ||
| 386 | batch.setViewTransform(viewMat); | ||
| 387 | |||
| 388 | batch.setResourceTexture(gr::Texture::MaterialMirror, args->_blitFramebuffer->getRenderBuffer(0)); | ||
| 389 | |||
| 390 | renderShapes(renderContext, args->_renderMethod == render::Args::RenderMethod::FORWARD ? _forwardPipelines : _deferredPipelines, { mirror }); | ||
| 391 | |||
| 392 | args->_batch = nullptr; | ||
| 393 | }); | ||
| 394 | |||
| 395 | if (cachedArgs) { | ||
| 396 | // Restore the blit framebuffer after we've sampled from it | ||
| 397 | args->_blitFramebuffer = cachedArgs->_blitFramebuffer; | ||
| 398 | args->_ignoreItem = cachedArgs->_ignoreItem; | ||
| 399 | args->_mirrorDepth = cachedArgs->_mirrorDepth; | ||
| 400 | args->_numMirrorFlips = cachedArgs->_numMirrorFlips; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | private: | ||
| 405 | static ShapePlumberPointer _forwardPipelines; | ||
| 406 | static ShapePlumberPointer _deferredPipelines; | ||
| 407 | }; | ||
| 408 | |||
| 409 | ShapePlumberPointer DrawMirrorTask::_forwardPipelines = std::make_shared<ShapePlumber>(); | ||
| 410 | ShapePlumberPointer DrawMirrorTask::_deferredPipelines = std::make_shared<ShapePlumber>(); | ||
| 411 | |||
| 412 | void RenderMirrorTask::build(JobModel& task, const render::Varying& inputs, render::Varying& output, size_t mirrorIndex, render::CullFunctor cullFunctor, size_t depth) { | ||
| 413 | size_t nextDepth = depth + 1; | ||
| 414 | const auto setupOutput = task.addJob<SetupMirrorTask>("SetupMirror" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), inputs, mirrorIndex, nextDepth); | ||
| 415 | |||
| 416 | task.addJob<RenderViewTask>("RenderMirrorView" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1, nextDepth); | ||
| 417 | |||
| 418 | task.addJob<DrawMirrorTask>("DrawMirrorTask" + std::to_string(mirrorIndex) + "Depth" + std::to_string(depth), setupOutput); | ||
| 419 | } | ||