History

Revert "Revert "Mirrors + Portals""

Dale Glass committed 2 years ago

Commit e7591d61 parent b33d35c81 files · +1047 −263Browse files

Showing the changes to libraries/render-utils/src/RenderCommonTask.cpp (1 of 81 files). Show all

Unified · Split

libraries/render-utils/src/RenderCommonTask.cpp+157−2
@@ -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
18namespace ru {21namespace 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
31using RenderArgsPointer = std::shared_ptr<RenderArgs>;
28 32
29using namespace render;33using namespace render;
30extern void initForwardPipelines(ShapePlumber& plumber);34extern void initForwardPipelines(ShapePlumber& plumber);
35extern void initMirrorPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter, bool forward);
31 36
32void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) {37void 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
53render::ShapePlumberPointer DrawLayered3D::_shapePlumber = std::make_shared<ShapePlumber>();
54
48DrawLayered3D::DrawLayered3D(bool opaque) :55DrawLayered3D::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
54void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) {63void 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
274class SetupMirrorTask {
275public:
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
328protected:
329 gpu::FramebufferPointer _mirrorFramebuffer { nullptr };
330 RenderArgsPointer _cachedArgsPointer { std::make_shared<RenderArgs>() };
331 size_t _mirrorIndex;
332 size_t _depth;
333
334};
335
336class DrawMirrorTask {
337public:
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
404private:
405 static ShapePlumberPointer _forwardPipelines;
406 static ShapePlumberPointer _deferredPipelines;
407};
408
409ShapePlumberPointer DrawMirrorTask::_forwardPipelines = std::make_shared<ShapePlumber>();
410ShapePlumberPointer 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 }