From 5288314d02c16bae5cd4e477b3e1637cdf6ae1a5 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 13 Jun 2019 17:42:32 -0700 Subject: [PATCH] Drafting ways to rescale in forward --- .../scripting/RenderScriptingInterface.cpp | 52 ++++++++++- .../src/scripting/RenderScriptingInterface.h | 17 ++-- .../src/DeferredLightingEffect.cpp | 2 +- .../render-utils/src/DeferredLightingEffect.h | 11 ++- libraries/render-utils/src/RenderCommonTask.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 2 +- .../render-utils/src/RenderForwardTask.cpp | 90 ++++++++++++------- .../render-utils/src/RenderForwardTask.h | 39 ++++++-- .../utilities/render/luci/RenderSettings.qml | 7 ++ 9 files changed, 166 insertions(+), 56 deletions(-) diff --git a/interface/src/scripting/RenderScriptingInterface.cpp b/interface/src/scripting/RenderScriptingInterface.cpp index 608f1d30e9..4e07d77c0b 100644 --- a/interface/src/scripting/RenderScriptingInterface.cpp +++ b/interface/src/scripting/RenderScriptingInterface.cpp @@ -37,7 +37,7 @@ void RenderScriptingInterface::loadSettings() { forceAntialiasingEnabled(_antialiasingEnabled); } -RenderScriptingInterface::RenderMethod RenderScriptingInterface::getRenderMethod() { +RenderScriptingInterface::RenderMethod RenderScriptingInterface::getRenderMethod() const { return (RenderMethod) _renderMethod; } @@ -64,7 +64,7 @@ QStringList RenderScriptingInterface::getRenderMethodNames() const { return refrenderMethodNames; } -bool RenderScriptingInterface::getShadowsEnabled() { +bool RenderScriptingInterface::getShadowsEnabled() const { return _shadowsEnabled; } @@ -88,7 +88,7 @@ void RenderScriptingInterface::forceShadowsEnabled(bool enabled) { }); } -bool RenderScriptingInterface::getAmbientOcclusionEnabled() { +bool RenderScriptingInterface::getAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; } @@ -112,7 +112,7 @@ void RenderScriptingInterface::forceAmbientOcclusionEnabled(bool enabled) { }); } -bool RenderScriptingInterface::getAntialiasingEnabled() { +bool RenderScriptingInterface::getAntialiasingEnabled() const { return _antialiasingEnabled; } @@ -145,3 +145,47 @@ void RenderScriptingInterface::forceAntialiasingEnabled(bool enabled) { } +float RenderScriptingInterface::getViewportResolutionScale() const { + return _viewportResolutionScale; +} + +void RenderScriptingInterface::setViewportResolutionScale(float scale) { + if (_viewportResolutionScale != scale) { + forceViewportResolutionScale(scale); + emit settingsChanged(); + } +} + +void RenderScriptingInterface::forceViewportResolutionScale(float scale) { + _renderSettingLock.withWriteLock([&] { + _viewportResolutionScale = (scale); + // _antialiasingEnabledSetting.set(enabled); + + auto renderConfig = qApp->getRenderEngine()->getConfiguration(); + assert(renderConfig); + auto deferredView = renderConfig->getConfig("RenderMainView.RenderDeferredTask"); + // mainView can be null if we're rendering in forward mode + if (deferredView) { + deferredView->setProperty("resolutionScale", _viewportResolutionScale); + } + auto forwardView = renderConfig->getConfig("RenderMainView.RenderForwardTask"); + // mainView can be null if we're rendering in forward mode + if (forwardView) { + forwardView->setProperty("resolutionScale", _viewportResolutionScale); + } +/* + auto mainViewJitterCamConfig = qApp->getRenderEngine()->getConfiguration()->getConfig("RenderMainView.JitterCam"); + auto mainViewAntialiasingConfig = qApp->getRenderEngine()->getConfiguration()->getConfig("RenderMainView.Antialiasing"); + if (mainViewJitterCamConfig && mainViewAntialiasingConfig) { + Menu::getInstance()->setIsOptionChecked(MenuOption::AntiAliasing, enabled); + if (enabled) { + mainViewJitterCamConfig->play(); + mainViewAntialiasingConfig->setDebugFXAA(false); + } + else { + mainViewJitterCamConfig->none(); + mainViewAntialiasingConfig->setDebugFXAA(true); + } + }*/ + }); +} diff --git a/interface/src/scripting/RenderScriptingInterface.h b/interface/src/scripting/RenderScriptingInterface.h index 39a88d4aad..11a071c86a 100644 --- a/interface/src/scripting/RenderScriptingInterface.h +++ b/interface/src/scripting/RenderScriptingInterface.h @@ -29,6 +29,7 @@ class RenderScriptingInterface : public QObject { Q_PROPERTY(bool shadowsEnabled READ getShadowsEnabled WRITE setShadowsEnabled NOTIFY settingsChanged) Q_PROPERTY(bool ambientOcclusionEnabled READ getAmbientOcclusionEnabled WRITE setAmbientOcclusionEnabled NOTIFY settingsChanged) Q_PROPERTY(bool antialiasingEnabled READ getAntialiasingEnabled WRITE setAntialiasingEnabled NOTIFY settingsChanged) + Q_PROPERTY(float viewportResolutionScale READ getViewportResolutionScale WRITE setViewportResolutionScale NOTIFY settingsChanged) public: RenderScriptingInterface(); @@ -66,7 +67,7 @@ public slots: * @function Render.getRenderMethod * @returns {number} "DEFERRED" or "FORWARD" */ - RenderMethod getRenderMethod(); + RenderMethod getRenderMethod() const; /**jsdoc * Sets the current render method @@ -88,7 +89,7 @@ public slots: * @function Render.getShadowsEnabled * @returns {bool} true if shadows are enabled, otherwise false */ - bool getShadowsEnabled(); + bool getShadowsEnabled() const; /**jsdoc * Enables or disables shadows @@ -102,7 +103,7 @@ public slots: * @function Render.getAmbientOcclusionEnabled * @returns {bool} true if ambient occlusion is enabled, otherwise false */ - bool getAmbientOcclusionEnabled(); + bool getAmbientOcclusionEnabled() const; /**jsdoc * Enables or disables ambient occlusion @@ -116,7 +117,7 @@ public slots: * @function Render.getAntialiasingEnabled * @returns {bool} true if anti-aliasing is enabled, otherwise false */ - bool getAntialiasingEnabled(); + bool getAntialiasingEnabled() const; /**jsdoc * Enables or disables anti-aliasing @@ -130,14 +131,14 @@ public slots: * @function Render.getViewportResolutionScale * @returns {number} */ - // float getViewportResolutionScale(); + float getViewportResolutionScale() const; /**jsdoc * Sets the current viewport resolution scale * @function Render.setViewportResolutionScale * @param {number} resolutionScale - between epsilon and 1.0 */ - // void setViewportResolutionScale(float resolutionScale); + void setViewportResolutionScale(float resolutionScale); signals: void settingsChanged(); @@ -150,7 +151,8 @@ private: int _renderMethod{ RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; bool _shadowsEnabled{ true }; bool _ambientOcclusionEnabled{ false }; - bool _antialiasingEnabled { true }; + bool _antialiasingEnabled{ true }; + float _viewportResolutionScale{ 1.0f }; // Actual settings saved on disk Setting::Handle _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; @@ -163,6 +165,7 @@ private: void forceShadowsEnabled(bool enabled); void forceAmbientOcclusionEnabled(bool enabled); void forceAntialiasingEnabled(bool enabled); + void forceViewportResolutionScale(float scale); static std::once_flag registry_flag; }; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 82b7f3102a..94c9dccfdd 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -313,7 +313,7 @@ gpu::FramebufferPointer PreparePrimaryFramebuffer::createFramebuffer(const char* } void PreparePrimaryFramebuffer::configure(const Config& config) { - _resolutionScale = config.resolutionScale; + _resolutionScale = config.getResolutionScale(); } void PreparePrimaryFramebuffer::run(const RenderContextPointer& renderContext, Output& primaryFramebuffer) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 1cc6ca4767..314d6fd4f6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -89,13 +89,18 @@ private: class PreparePrimaryFramebufferConfig : public render::Job::Config { Q_OBJECT - Q_PROPERTY(float resolutionScale MEMBER resolutionScale NOTIFY dirty) + Q_PROPERTY(float resolutionScale WRITE setResolutionScale READ getResolutionScale) public: - - float resolutionScale{ 1.0f }; + float getResolutionScale() const { return resolutionScale; } + void setResolutionScale(float scale) { + resolutionScale = std::max(0.1f, std::min(1.0f, resolutionScale)); + } signals: void dirty(); + +protected: + float resolutionScale{ 1.0f }; }; class PreparePrimaryFramebuffer { diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h index 4f72600d34..8fd7f22a21 100644 --- a/libraries/render-utils/src/RenderCommonTask.h +++ b/libraries/render-utils/src/RenderCommonTask.h @@ -13,6 +13,8 @@ #include "LightStage.h" #include "LightingModel.h" + + class BeginGPURangeTimer { public: using JobModel = render::Job::ModelO; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 624869bbf5..deafce0419 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -99,7 +99,7 @@ void RenderDeferredTask::configure(const Config& config) { auto upsamplePrimaryBufferConfig = config.getConfig("PrimaryBufferUpscale"); assert(preparePrimaryBufferConfig); assert(upsamplePrimaryBufferConfig); - preparePrimaryBufferConfig->setProperty("resolutionScale", config.resolutionScale); + preparePrimaryBufferConfig->setResolutionScale(config.resolutionScale); upsamplePrimaryBufferConfig->setProperty("factor", 1.0f / config.resolutionScale); } diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index de55f3f4ff..a53b480b9f 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -47,6 +47,16 @@ using namespace render; extern void initForwardPipelines(ShapePlumber& plumber); +void RenderForwardTask::configure(const Config& config) { + // Propagate resolution scale to sub jobs who need it + auto preparePrimaryBufferConfig = config.getConfig("PreparePrimaryBuffer"); +// auto upsamplePrimaryBufferConfig = config.getConfig("PrimaryBufferUpscale"); + assert(preparePrimaryBufferConfig); +// assert(upsamplePrimaryBufferConfig); + preparePrimaryBufferConfig->setResolutionScale(config.resolutionScale); + // upsamplePrimaryBufferConfig->setProperty("factor", 1.0f / config.resolutionScale); +} + void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { task.addJob("SetRenderMethodTask", render::Args::FORWARD); @@ -87,16 +97,19 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // First job, alter faded fadeEffect->build(task, opaques); - // Prepare objects shared by several jobs - const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); // GPU jobs: Start preparing the main framebuffer - const auto framebuffer = task.addJob("PrepareFramebuffer"); + const auto scaledPrimaryFramebuffer = task.addJob("PreparePrimaryBuffer"); - task.addJob("PrepareForward", lightFrame); + // Prepare deferred, generate the shared Deferred Frame Transform. Only valid with the scaled frame buffer + const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); + + // Prepare Forward Framebuffer pass + const auto prepareForwardInputs = PrepareForward::Inputs(scaledPrimaryFramebuffer, lightFrame).asVarying(); + task.addJob("PrepareForward", prepareForwardInputs); // draw a stencil mask in hidden regions of the framebuffer. - task.addJob("PrepareStencil", framebuffer); + task.addJob("PrepareStencil", scaledPrimaryFramebuffer); // Draw opaques forward const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel).asVarying(); @@ -130,7 +143,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Just resolve the msaa const auto resolveInputs = - ResolveFramebuffer::Inputs(framebuffer, static_cast(nullptr)).asVarying(); + ResolveFramebuffer::Inputs(scaledPrimaryFramebuffer, static_cast(nullptr)).asVarying(); const auto resolvedFramebuffer = task.addJob("Resolve", resolveInputs); //auto resolvedFramebuffer = task.addJob("Resolve", framebuffer); @@ -157,35 +170,38 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // task.addJob("Blit", framebuffer); } -void PrepareFramebuffer::configure(const Config& config) { +gpu::FramebufferPointer PreparePrimaryFramebufferMSAA::createFramebuffer(const char* name, const glm::uvec2& frameSize, int numSamples) { + gpu::FramebufferPointer framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(name)); + + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); + + auto colorFormat = gpu::Element::COLOR_SRGBA_32; + auto colorTexture = + gpu::Texture::createRenderBufferMultisample(colorFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); + framebuffer->setRenderBuffer(0, colorTexture); + + auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format + auto depthTexture = + gpu::Texture::createRenderBufferMultisample(depthFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); + framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); + + return framebuffer; +} + +void PreparePrimaryFramebufferMSAA::configure(const Config& config) { + _resolutionScale = config.getResolutionScale(); _numSamples = config.getNumSamples(); } -void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) { +void PreparePrimaryFramebufferMSAA::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) { glm::uvec2 frameSize(renderContext->args->_viewport.z, renderContext->args->_viewport.w); + glm::uvec2 scaledFrameSize(glm::vec2(frameSize) * _resolutionScale); // Resizing framebuffers instead of re-building them seems to cause issues with threaded rendering - if (_framebuffer && (_framebuffer->getSize() != frameSize || _framebuffer->getNumSamples() != _numSamples)) { - _framebuffer.reset(); + if (!_framebuffer || (_framebuffer->getSize() != scaledFrameSize) || (_framebuffer->getNumSamples() != _numSamples)) { + _framebuffer = createFramebuffer("forward", scaledFrameSize, _numSamples); } - - if (!_framebuffer) { - _framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("forward")); - - int numSamples = _numSamples; - - auto colorFormat = gpu::Element::COLOR_SRGBA_32; - auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); - auto colorTexture = - gpu::Texture::createRenderBufferMultisample(colorFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); - _framebuffer->setRenderBuffer(0, colorTexture); - - auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - auto depthTexture = - gpu::Texture::createRenderBufferMultisample(depthFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); - _framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); - } - +/* auto args = renderContext->args; gpu::doInBatch("PrepareFramebuffer::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -196,7 +212,7 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::Fra batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH | gpu::Framebuffer::BUFFER_STENCIL, vec4(vec3(0), 0), 1.0, 0, true); - }); + });*/ framebuffer = _framebuffer; } @@ -204,18 +220,30 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::Fra void PrepareForward::run(const RenderContextPointer& renderContext, const Inputs& inputs) { RenderArgs* args = renderContext->args; + auto primaryFramebuffer = inputs.get0(); + auto lightStageFrame = inputs.get1(); + gpu::doInBatch("RenderForward::Draw::run", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; + batch.enableStereo(false); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + batch.setFramebuffer(primaryFramebuffer); + batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH | + gpu::Framebuffer::BUFFER_STENCIL, + vec4(vec3(0), 0), 1.0, 0, true); + graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { - keySunLight = lightStage->getCurrentKeyLight(*inputs); + keySunLight = lightStage->getCurrentKeyLight(*lightStageFrame); } graphics::LightPointer keyAmbiLight; if (lightStage) { - keyAmbiLight = lightStage->getCurrentAmbientLight(*inputs); + keyAmbiLight = lightStage->getCurrentAmbientLight(*lightStageFrame); } if (keySunLight) { diff --git a/libraries/render-utils/src/RenderForwardTask.h b/libraries/render-utils/src/RenderForwardTask.h index 40d004ddb2..d4eb96d1e9 100755 --- a/libraries/render-utils/src/RenderForwardTask.h +++ b/libraries/render-utils/src/RenderForwardTask.h @@ -17,39 +17,57 @@ #include "AssembleLightingStageTask.h" #include "LightingModel.h" +class RenderForwardTaskConfig : public render::Task::Config { + Q_OBJECT + Q_PROPERTY(float resolutionScale MEMBER resolutionScale NOTIFY dirty) +public: + float resolutionScale{ 1.f }; + +signals: + void dirty(); +}; + class RenderForwardTask { public: using Input = render::VaryingSet3; - using JobModel = render::Task::ModelI; + using Config = RenderForwardTaskConfig; + using JobModel = render::Task::ModelI; RenderForwardTask() {} + void configure(const Config& config); void build(JobModel& task, const render::Varying& input, render::Varying& output); }; -class PrepareFramebufferConfig : public render::Job::Config { +class PreparePrimaryFramebufferMSAAConfig : public render::Job::Config { Q_OBJECT - Q_PROPERTY(int numSamples WRITE setNumSamples READ getNumSamples NOTIFY dirty) + Q_PROPERTY(float resolutionScale WRITE setResolutionScale READ getResolutionScale) + Q_PROPERTY(int numSamples WRITE setNumSamples READ getNumSamples) public: + float getResolutionScale() const { return resolutionScale; } + void setResolutionScale(float scale) { + resolutionScale = std::max(0.1f, std::min(1.0f, resolutionScale)); + } + int getNumSamples() const { return numSamples; } void setNumSamples(int num) { numSamples = std::max(1, std::min(32, num)); - emit dirty(); } signals: void dirty(); protected: + float resolutionScale{ 1.0f }; int numSamples{ 4 }; }; -class PrepareFramebuffer { +class PreparePrimaryFramebufferMSAA { public: - using Inputs = gpu::FramebufferPointer; - using Config = PrepareFramebufferConfig; - using JobModel = render::Job::ModelO; + using Output = gpu::FramebufferPointer; + using Config = PreparePrimaryFramebufferMSAAConfig; + using JobModel = render::Job::ModelO; void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, @@ -57,12 +75,15 @@ public: private: gpu::FramebufferPointer _framebuffer; + float _resolutionScale{ 1.0f }; int _numSamples; + + static gpu::FramebufferPointer createFramebuffer(const char* name, const glm::uvec2& frameSize, int numSamples); }; class PrepareForward { public: - using Inputs = LightStage::FramePointer; + using Inputs = render::VaryingSet2 ; using JobModel = render::Job::ModelI; void run(const render::RenderContextPointer& renderContext, diff --git a/scripts/developer/utilities/render/luci/RenderSettings.qml b/scripts/developer/utilities/render/luci/RenderSettings.qml index 906c117b3a..4da63bbcd1 100644 --- a/scripts/developer/utilities/render/luci/RenderSettings.qml +++ b/scripts/developer/utilities/render/luci/RenderSettings.qml @@ -30,5 +30,12 @@ Column { object: Render property: "shadowsEnabled" } + Prop.PropScalar { + label: "Viewport Resolution Scale" + object: Render + property: "viewportResolutionScale" + min: 0.1 + max: 1.0 + } }