move stage frames to varyings

This commit is contained in:
SamGondelman 2018-10-01 11:26:02 -07:00
parent 70c7ffcc71
commit de90ce5f2b
30 changed files with 328 additions and 561 deletions

View file

@ -55,85 +55,46 @@ BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index
void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
const auto& lightingModel = inputs; const auto& lightingModel = inputs.get0();
if (!lightingModel->isBackgroundEnabled()) { if (!lightingModel->isBackgroundEnabled()) {
return; return;
} }
// Background rendering decision // Background rendering decision
auto backgroundStage = renderContext->_scene->getStage<BackgroundStage>(); const auto& backgroundStage = renderContext->_scene->getStage<BackgroundStage>();
assert(backgroundStage); const auto& backgroundFrame = inputs.get1();
graphics::SunSkyStagePointer background;
graphics::SkyboxPointer skybox; graphics::SkyboxPointer skybox;
if (backgroundStage->_currentFrame._backgrounds.size()) { if (backgroundStage && backgroundFrame._backgrounds.size()) {
auto backgroundId = backgroundStage->_currentFrame._backgrounds.front(); const auto& background = backgroundStage->getBackground(backgroundFrame._backgrounds.front());
auto background = backgroundStage->getBackground(backgroundId);
if (background) { if (background) {
skybox = background->getSkybox(); skybox = background->getSkybox();
} }
} }
/* auto backgroundMode = skyStage->getBackgroundMode();
switch (backgroundMode) {
case graphics::SunSkyStage::SKY_DEFAULT: {
auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage();
auto sceneKeyLight = scene->getKeyLight();
scene->setSunModelEnable(false);
sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR));
sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY);
sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY);
sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION);
// fall through: render a skybox (if available), or the defaults (if requested)
}
case graphics::SunSkyStage::SKY_BOX: {*/
if (skybox && !skybox->empty()) { if (skybox && !skybox->empty()) {
PerformanceTimer perfTimer("skybox"); PerformanceTimer perfTimer("skybox");
auto args = renderContext->args; auto args = renderContext->args;
gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch; args->_batch = &batch;
batch.enableSkybox(true); batch.enableSkybox(true);
batch.setViewportTransform(args->_viewport); batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport); batch.setStateScissorRect(args->_viewport);
glm::mat4 projMat; glm::mat4 projMat;
Transform viewMat; Transform viewMat;
args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalProjectionMatrix(projMat);
args->getViewFrustum().evalViewTransform(viewMat); args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat); batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat); batch.setViewTransform(viewMat);
skybox->render(batch, args->getViewFrustum()); skybox->render(batch, args->getViewFrustum());
}); });
args->_batch = nullptr; args->_batch = nullptr;
// break;
}
// fall through: render defaults (if requested)
// }
/*
case graphics::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: {
if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) {
auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage();
auto sceneKeyLight = scene->getKeyLight();
auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture();
if (defaultSkyboxAmbientTexture) {
sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance());
sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture);
}
// fall through: render defaults skybox
} else {
break;
}
} }
*/
} }
BackgroundStageSetup::BackgroundStageSetup() { BackgroundStageSetup::BackgroundStageSetup() {

View file

@ -76,18 +76,16 @@ public:
BackgroundStageSetup(); BackgroundStageSetup();
void run(const render::RenderContextPointer& renderContext); void run(const render::RenderContextPointer& renderContext);
protected:
}; };
class DrawBackgroundStage { class DrawBackgroundStage {
public: public:
using Inputs = LightingModelPointer; using Inputs = render::VaryingSet2<LightingModelPointer, BackgroundStage::Frame>;
using JobModel = render::Job::ModelI<DrawBackgroundStage, Inputs>; using JobModel = render::Job::ModelI<DrawBackgroundStage, Inputs>;
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); DrawBackgroundStage() {}
protected: void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
}; };
#endif #endif

View file

@ -35,7 +35,16 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
const auto frameTransform = inputs.get0(); const auto frameTransform = inputs.get0();
const auto inputFrameBuffer = inputs.get1(); const auto inputFrameBuffer = inputs.get1();
const auto bloom = inputs.get2(); const auto bloomFrame = inputs.get2();
const auto& bloomStage = renderContext->_scene->getStage<BloomStage>();
graphics::BloomPointer bloom;
if (bloomStage && bloomFrame._blooms.size()) {
bloom = bloomStage->getBloom(bloomFrame._blooms.front());
}
if (!bloom) {
renderContext->taskFlow.abortTask();
return;
}
assert(inputFrameBuffer->hasColor()); assert(inputFrameBuffer->hasColor());
@ -65,11 +74,6 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y }; glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y };
if (!bloom) {
renderContext->taskFlow.abortTask();
return;
}
_parameters.edit()._threshold = bloom->getBloomThreshold(); _parameters.edit()._threshold = bloom->getBloomThreshold();
gpu::doInBatch("BloomThreshold::run", args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("BloomThreshold::run", args->_context, [&](gpu::Batch& batch) {
@ -89,6 +93,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
outputs.edit0() = _outputBuffer; outputs.edit0() = _outputBuffer;
outputs.edit1() = 0.5f + bloom->getBloomSize() * 3.5f; outputs.edit1() = 0.5f + bloom->getBloomSize() * 3.5f;
outputs.edit2() = bloom;
} }
BloomApply::BloomApply() { BloomApply::BloomApply() {
@ -296,9 +301,9 @@ void BloomEffect::build(JobModel& task, const render::Varying& inputs, render::V
const auto blurFB2 = task.addJob<render::BlurGaussian>("BloomBlur2", blurInput2); const auto blurFB2 = task.addJob<render::BlurGaussian>("BloomBlur2", blurInput2);
const auto& frameBuffer = inputs.getN<Inputs>(1); const auto& frameBuffer = inputs.getN<Inputs>(1);
const auto& bloom = inputs.getN<Inputs>(2);
// Mix all blur levels at quarter resolution // Mix all blur levels at quarter resolution
const auto bloom = bloomOutputs.getN<BloomThreshold::Outputs>(2);
const auto applyInput = BloomApply::Inputs(blurInputBuffer, blurFB0, blurFB1, blurFB2, bloom).asVarying(); const auto applyInput = BloomApply::Inputs(blurInputBuffer, blurFB0, blurFB1, blurFB2, bloom).asVarying();
task.addJob<BloomApply>("BloomApply", applyInput); task.addJob<BloomApply>("BloomApply", applyInput);
// And then blend result in additive manner on top of final color buffer // And then blend result in additive manner on top of final color buffer

View file

@ -14,7 +14,7 @@
#include <render/Engine.h> #include <render/Engine.h>
#include "graphics/Bloom.h" #include "BloomStage.h"
#include "DeferredFrameTransform.h" #include "DeferredFrameTransform.h"
@ -28,8 +28,8 @@ class BloomThresholdConfig : public render::Job::Config {
class BloomThreshold { class BloomThreshold {
public: public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, gpu::FramebufferPointer, graphics::BloomPointer>; using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, gpu::FramebufferPointer, BloomStage::Frame>;
using Outputs = render::VaryingSet2<gpu::FramebufferPointer, float>; using Outputs = render::VaryingSet3<gpu::FramebufferPointer, float, graphics::BloomPointer>;
using Config = BloomThresholdConfig; using Config = BloomThresholdConfig;
using JobModel = render::Job::ModelIO<BloomThreshold, Inputs, Outputs, Config>; using JobModel = render::Job::ModelIO<BloomThreshold, Inputs, Outputs, Config>;
@ -127,7 +127,7 @@ private:
class BloomEffect { class BloomEffect {
public: public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, gpu::FramebufferPointer, graphics::BloomPointer>; using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, gpu::FramebufferPointer, BloomStage::Frame>;
using Config = BloomConfig; using Config = BloomConfig;
using JobModel = render::Task::ModelI<BloomEffect, Inputs, Config>; using JobModel = render::Task::ModelI<BloomEffect, Inputs, Config>;

View file

@ -16,16 +16,6 @@
std::string BloomStage::_stageName { "BLOOM_STAGE"}; std::string BloomStage::_stageName { "BLOOM_STAGE"};
const BloomStage::Index BloomStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; const BloomStage::Index BloomStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
FetchBloomStage::FetchBloomStage() {
_bloom = std::make_shared<graphics::Bloom>();
}
void FetchBloomStage::configure(const Config& config) {
_bloom->setBloomIntensity(config.bloomIntensity);
_bloom->setBloomThreshold(config.bloomThreshold);
_bloom->setBloomSize(config.bloomSize);
}
BloomStage::Index BloomStage::findBloom(const BloomPointer& bloom) const { BloomStage::Index BloomStage::findBloom(const BloomPointer& bloom) const {
auto found = _bloomMap.find(bloom); auto found = _bloomMap.find(bloom);
if (found != _bloomMap.end()) { if (found != _bloomMap.end()) {
@ -66,14 +56,3 @@ void BloomStageSetup::run(const render::RenderContextPointer& renderContext) {
renderContext->_scene->resetStage(BloomStage::getName(), std::make_shared<BloomStage>()); renderContext->_scene->resetStage(BloomStage::getName(), std::make_shared<BloomStage>());
} }
} }
void FetchBloomStage::run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom) {
auto bloomStage = renderContext->_scene->getStage<BloomStage>();
assert(bloomStage);
bloom = nullptr;
if (bloomStage->_currentFrame._blooms.size() != 0) {
auto bloomId = bloomStage->_currentFrame._blooms.front();
bloom = bloomStage->getBloom(bloomId);
}
}

View file

@ -102,17 +102,4 @@ signals:
void dirty(); void dirty();
}; };
class FetchBloomStage {
public:
using Config = FetchBloomConfig;
using JobModel = render::Job::ModelO<FetchBloomStage, graphics::BloomPointer, Config>;
FetchBloomStage();
void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom);
private:
graphics::BloomPointer _bloom;
};
#endif #endif

View file

@ -405,6 +405,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
auto& ambientOcclusionFramebuffer = inputs.get3(); auto& ambientOcclusionFramebuffer = inputs.get3();
auto& velocityFramebuffer = inputs.get4(); auto& velocityFramebuffer = inputs.get4();
auto& frameTransform = inputs.get5(); auto& frameTransform = inputs.get5();
auto& lightFrame = inputs.get6();
gpu::doInBatch("DebugDeferredBuffer::run", args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("DebugDeferredBuffer::run", args->_context, [&](gpu::Batch& batch) {
batch.enableStereo(false); batch.enableStereo(false);
@ -443,7 +444,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
assert(lightStage->getNumLights() > 0); assert(lightStage->getNumLights() > 0);
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(lightFrame);
const auto& globalShadow = lightAndShadow.second; const auto& globalShadow = lightAndShadow.second;
if (globalShadow) { if (globalShadow) {
batch.setResourceTexture(Textures::Shadow, globalShadow->map); batch.setResourceTexture(Textures::Shadow, globalShadow->map);

View file

@ -21,6 +21,8 @@
#include "AmbientOcclusionEffect.h" #include "AmbientOcclusionEffect.h"
#include "VelocityBufferPass.h" #include "VelocityBufferPass.h"
#include "LightStage.h"
class DebugDeferredBufferConfig : public render::Job::Config { class DebugDeferredBufferConfig : public render::Job::Config {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled) Q_PROPERTY(bool enabled MEMBER enabled)
@ -39,12 +41,13 @@ signals:
class DebugDeferredBuffer { class DebugDeferredBuffer {
public: public:
using Inputs = render::VaryingSet6<DeferredFramebufferPointer, using Inputs = render::VaryingSet7<DeferredFramebufferPointer,
LinearDepthFramebufferPointer, LinearDepthFramebufferPointer,
SurfaceGeometryFramebufferPointer, SurfaceGeometryFramebufferPointer,
AmbientOcclusionFramebufferPointer, AmbientOcclusionFramebufferPointer,
VelocityFramebufferPointer, VelocityFramebufferPointer,
DeferredFrameTransformPointer>; DeferredFrameTransformPointer,
LightStage::Frame>;
using Config = DebugDeferredBufferConfig; using Config = DebugDeferredBufferConfig;
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>; using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;

View file

@ -70,17 +70,22 @@ void DeferredLightingEffect::init() {
loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations); loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations);
} }
// FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines
void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch) { void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch) {
setupKeyLightBatch(args, batch, args->_scene->getStage<LightStage>()->_currentFrame);
}
void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame) {
PerformanceTimer perfTimer("DLE->setupBatch()"); PerformanceTimer perfTimer("DLE->setupBatch()");
graphics::LightPointer keySunLight; graphics::LightPointer keySunLight;
auto lightStage = args->_scene->getStage<LightStage>(); auto lightStage = args->_scene->getStage<LightStage>();
if (lightStage) { if (lightStage) {
keySunLight = lightStage->getCurrentKeyLight(); keySunLight = lightStage->getCurrentKeyLight(lightFrame);
} }
graphics::LightPointer keyAmbiLight; graphics::LightPointer keyAmbiLight;
if (lightStage) { if (lightStage) {
keyAmbiLight = lightStage->getCurrentAmbientLight(); keyAmbiLight = lightStage->getCurrentAmbientLight(lightFrame);
} }
if (keySunLight) { if (keySunLight) {
@ -361,12 +366,6 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input
// For the rest of the rendering, bind the lighting model // For the rest of the rendering, bind the lighting model
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());
}); });
// Prepare a fresh Light Frame
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
lightStage->_currentFrame.clear();
} }
@ -374,7 +373,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
const DeferredFrameTransformPointer& frameTransform, const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer, const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel, const LightingModelPointer& lightingModel,
const graphics::HazePointer& haze, const LightStage::Frame& lightFrame,
const HazeStage::Frame& hazeFrame,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource,
@ -434,7 +434,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
assert(lightStage->getNumLights() > 0); assert(lightStage->getNumLights() > 0);
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(lightFrame);
const auto& globalShadow = lightAndShadow.second; const auto& globalShadow = lightAndShadow.second;
// Bind the shadow buffers // Bind the shadow buffers
@ -448,8 +448,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
auto keyLight = lightAndShadow.first; auto keyLight = lightAndShadow.first;
graphics::LightPointer ambientLight; graphics::LightPointer ambientLight;
if (lightStage && lightStage->_currentFrame._ambientLights.size()) { if (lightStage && lightFrame._ambientLights.size()) {
ambientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); ambientLight = lightStage->getLight(lightFrame._ambientLights.front());
} }
bool hasAmbientMap = (ambientLight != nullptr); bool hasAmbientMap = (ambientLight != nullptr);
@ -458,8 +458,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// Check if keylight casts shadows // Check if keylight casts shadows
bool keyLightCastShadows { false }; bool keyLightCastShadows { false };
if (renderShadows && lightStage && lightStage->_currentFrame._sunLights.size()) { if (renderShadows && lightStage && lightFrame._sunLights.size()) {
graphics::LightPointer keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); graphics::LightPointer keyLight = lightStage->getLight(lightFrame._sunLights.front());
if (keyLight) { if (keyLight) {
keyLightCastShadows = keyLight->getCastShadows(); keyLightCastShadows = keyLight->getCastShadows();
} }
@ -496,13 +496,17 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
} }
// Setup the global lighting // Setup the global lighting
deferredLightingEffect->setupKeyLightBatch(args, batch); deferredLightingEffect->setupKeyLightBatch(args, batch, lightFrame);
// Haze // Haze
if (haze) { const auto& hazeStage = args->_scene->getStage<HazeStage>();
batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); if (hazeStage && hazeFrame._hazes.size() > 0) {
const auto& hazePointer = hazeStage->getHaze(hazeFrame._hazes.front());
if (hazePointer) {
batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
}
} }
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
deferredLightingEffect->unsetKeyLightBatch(batch); deferredLightingEffect->unsetKeyLightBatch(batch);
@ -617,7 +621,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
auto lightClusters = inputs.get6(); auto lightClusters = inputs.get6();
auto args = renderContext->args; auto args = renderContext->args;
const auto haze = inputs.get7(); const auto& lightFrame = inputs.get7();
const auto& hazeFrame = inputs.get8();
if (!_gpuTimer) { if (!_gpuTimer) {
_gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__);
@ -626,10 +631,10 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
auto previousBatch = args->_batch; auto previousBatch = args->_batch;
gpu::doInBatch(nullptr, args->_context, [&](gpu::Batch& batch) { gpu::doInBatch(nullptr, args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch; args->_batch = &batch;
_gpuTimer->begin(batch); _gpuTimer->begin(batch);
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows);
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, haze, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows);
lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
cleanupJob.run(renderContext); cleanupJob.run(renderContext);

View file

@ -49,6 +49,7 @@ public:
void init(); void init();
static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch); static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch);
static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame);
static void unsetKeyLightBatch(gpu::Batch& batch); static void unsetKeyLightBatch(gpu::Batch& batch);
static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters); static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters);
@ -139,13 +140,13 @@ public:
class RenderDeferredSetup { class RenderDeferredSetup {
public: public:
// using JobModel = render::Job::ModelI<RenderDeferredSetup, DeferredFrameTransformPointer>;
void run(const render::RenderContextPointer& renderContext, void run(const render::RenderContextPointer& renderContext,
const DeferredFrameTransformPointer& frameTransform, const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer, const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel, const LightingModelPointer& lightingModel,
const graphics::HazePointer& haze, const LightStage::Frame& lightFrame,
const HazeStage::Frame& hazeFrame,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource,
@ -181,9 +182,9 @@ using RenderDeferredConfig = render::GPUJobConfig;
class RenderDeferred { class RenderDeferred {
public: public:
using Inputs = render::VaryingSet8 < using Inputs = render::VaryingSet9<
DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer,
AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, graphics::HazePointer>; AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, LightStage::Frame, HazeStage::Frame>;
using Config = RenderDeferredConfig; using Config = RenderDeferredConfig;
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>; using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;

View file

@ -19,7 +19,6 @@
#include "StencilMaskPass.h" #include "StencilMaskPass.h"
#include "FramebufferCache.h" #include "FramebufferCache.h"
#include "HazeStage.h"
#include "LightStage.h" #include "LightStage.h"
namespace ru { namespace ru {
@ -32,98 +31,15 @@ namespace gr {
using graphics::slot::buffer::Buffer; using graphics::slot::buffer::Buffer;
} }
void HazeConfig::setHazeColor(const glm::vec3 value) {
hazeColor = value;
}
void HazeConfig::setHazeGlareAngle(const float value) {
hazeGlareAngle = value;
}
void HazeConfig::setHazeGlareColor(const glm::vec3 value) {
hazeGlareColor = value;
}
void HazeConfig::setHazeBaseReference(const float value) {
hazeBaseReference = value;
}
void HazeConfig::setHazeActive(const bool active) {
isHazeActive = active;
}
void HazeConfig::setAltitudeBased(const bool active) {
isAltitudeBased = active;
}
void HazeConfig::setHazeAttenuateKeyLight(const bool active) {
isHazeAttenuateKeyLight = active;
}
void HazeConfig::setModulateColorActive(const bool active) {
isModulateColorActive = active;
}
void HazeConfig::setHazeEnableGlare(const bool active) {
isHazeEnableGlare = active;
}
void HazeConfig::setHazeRange(const float value) {
hazeRange = value;
}
void HazeConfig::setHazeAltitude(const float value) {
hazeHeight = value;
}
void HazeConfig::setHazeKeyLightRange(const float value) {
hazeKeyLightRange = value;
}
void HazeConfig::setHazeKeyLightAltitude(const float value) {
hazeKeyLightAltitude = value;
}
void HazeConfig::setHazeBackgroundBlend(const float value) {
hazeBackgroundBlend = value;
}
MakeHaze::MakeHaze() {
_haze = std::make_shared<graphics::Haze>();
}
void MakeHaze::configure(const Config& config) {
_haze->setHazeColor(config.hazeColor);
_haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle));
_haze->setHazeGlareColor(config.hazeGlareColor);
_haze->setHazeBaseReference(config.hazeBaseReference);
_haze->setHazeActive(config.isHazeActive);
_haze->setAltitudeBased(config.isAltitudeBased);
_haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight);
_haze->setModulateColorActive(config.isModulateColorActive);
_haze->setHazeEnableGlare(config.isHazeEnableGlare);
_haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange));
_haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight));
_haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange));
_haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude));
_haze->setHazeBackgroundBlend(config.hazeBackgroundBlend);
}
void MakeHaze::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) {
haze = _haze;
}
void DrawHaze::configure(const Config& config) {
}
void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
const auto haze = inputs.get0(); const auto hazeFrame = inputs.get0();
if (haze == nullptr) { const auto& hazeStage = renderContext->args->_scene->getStage<HazeStage>();
graphics::HazePointer haze;
if (hazeStage && hazeFrame._hazes.size() > 0) {
haze = hazeStage->getHaze(hazeFrame._hazes.front());
}
if (!haze) {
return; return;
} }
@ -131,6 +47,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
const auto framebuffer = inputs.get2(); const auto framebuffer = inputs.get2();
const auto transformBuffer = inputs.get3(); const auto transformBuffer = inputs.get3();
const auto lightingModel = inputs.get4(); const auto lightingModel = inputs.get4();
const auto lightFrame = inputs.get5();
auto depthBuffer = framebuffer->getLinearDepthTexture(); auto depthBuffer = framebuffer->getLinearDepthTexture();
@ -161,17 +78,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport)); batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport));
batch.setPipeline(_hazePipeline); batch.setPipeline(_hazePipeline);
batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer());
auto hazeStage = args->_scene->getStage<HazeStage>();
if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) {
graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front());
if (hazePointer) {
batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
} else {
// Something is wrong, so just quit Haze
return;
}
}
batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer()); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer());
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());
@ -179,13 +86,12 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
auto lightStage = args->_scene->getStage<LightStage>(); auto lightStage = args->_scene->getStage<LightStage>();
if (lightStage) { if (lightStage) {
graphics::LightPointer keyLight; graphics::LightPointer keyLight;
keyLight = lightStage->getCurrentKeyLight(); keyLight = lightStage->getCurrentKeyLight(lightFrame);
if (keyLight) { if (keyLight) {
batch.setUniformBuffer(gr::Buffer::KeyLight, keyLight->getLightSchemaBuffer()); batch.setUniformBuffer(gr::Buffer::KeyLight, keyLight->getLightSchemaBuffer());
} }
} }
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
} }

View file

@ -19,152 +19,20 @@
#include <gpu/Pipeline.h> #include <gpu/Pipeline.h>
#include <render/Forward.h> #include <render/Forward.h>
#include <render/DrawTask.h> #include <render/DrawTask.h>
#include <graphics/Haze.h>
#include "SurfaceGeometryPass.h" #include "SurfaceGeometryPass.h"
#include "LightingModel.h" #include "LightingModel.h"
#include "HazeStage.h"
#include "LightStage.h"
using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>; using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
class MakeHazeConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(glm::vec3 hazeColor MEMBER hazeColor WRITE setHazeColor NOTIFY dirty);
Q_PROPERTY(float hazeGlareAngle MEMBER hazeGlareAngle WRITE setHazeGlareAngle NOTIFY dirty);
Q_PROPERTY(glm::vec3 hazeGlareColor MEMBER hazeGlareColor WRITE setHazeGlareColor NOTIFY dirty);
Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty);
Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty);
Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty);
Q_PROPERTY(bool isHazeAttenuateKeyLight MEMBER isHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight NOTIFY dirty);
Q_PROPERTY(bool isModulateColorActive MEMBER isModulateColorActive WRITE setModulateColorActive NOTIFY dirty);
Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty);
Q_PROPERTY(float hazeRange MEMBER hazeRange WRITE setHazeRange NOTIFY dirty);
Q_PROPERTY(float hazeHeight MEMBER hazeHeight WRITE setHazeAltitude NOTIFY dirty);
Q_PROPERTY(float hazeKeyLightRange MEMBER hazeKeyLightRange WRITE setHazeKeyLightRange NOTIFY dirty);
Q_PROPERTY(float hazeKeyLightAltitude MEMBER hazeKeyLightAltitude WRITE setHazeKeyLightAltitude NOTIFY dirty);
Q_PROPERTY(float hazeBackgroundBlend MEMBER hazeBackgroundBlend WRITE setHazeBackgroundBlend NOTIFY dirty);
public:
MakeHazeConfig() : render::Job::Config() {}
glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR };
float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE };
glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR };
float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE };
bool isHazeActive{ false };
bool isAltitudeBased{ false };
bool isHazeAttenuateKeyLight{ false };
bool isModulateColorActive{ false };
bool isHazeEnableGlare{ false };
float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE };
float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT };
float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE };
float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE };
float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND };
public slots:
void setHazeColor(const glm::vec3 value) { hazeColor = value; emit dirty(); }
void setHazeGlareAngle(const float value) { hazeGlareAngle = value; emit dirty(); }
void setHazeGlareColor(const glm::vec3 value) { hazeGlareColor = value; emit dirty(); }
void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); }
void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); }
void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); }
void setHazeAttenuateKeyLight(const bool active) { isHazeAttenuateKeyLight = active; emit dirty(); }
void setModulateColorActive(const bool active) { isModulateColorActive = active; emit dirty(); }
void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); }
void setHazeRange(const float value) { hazeRange = value; emit dirty(); }
void setHazeAltitude(const float value) { hazeHeight = value; emit dirty(); }
void setHazeKeyLightRange(const float value) { hazeKeyLightRange = value; emit dirty(); }
void setHazeKeyLightAltitude(const float value) { hazeKeyLightAltitude = value; emit dirty(); }
void setHazeBackgroundBlend(const float value) { hazeBackgroundBlend = value; ; emit dirty(); }
signals:
void dirty();
};
class MakeHaze {
public:
using Config = MakeHazeConfig;
using JobModel = render::Job::ModelO<MakeHaze, graphics::HazePointer, Config>;
MakeHaze();
void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze);
private:
graphics::HazePointer _haze;
};
class HazeConfig : public render::Job::Config {
public:
HazeConfig() : render::Job::Config(true) {}
// attributes
glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR };
float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE };
glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR };
float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE };
bool isHazeActive{ false }; // Setting this to true will set haze to on
bool isAltitudeBased{ false };
bool isHazeAttenuateKeyLight{ false };
bool isModulateColorActive{ false };
bool isHazeEnableGlare{ false };
float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE };
float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT };
float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE };
float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE };
float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND };
// methods
void setHazeColor(const glm::vec3 value);
void setHazeGlareAngle(const float value);
void setHazeGlareColor(const glm::vec3 value);
void setHazeBaseReference(const float value);
void setHazeActive(const bool active);
void setAltitudeBased(const bool active);
void setHazeAttenuateKeyLight(const bool active);
void setModulateColorActive(const bool active);
void setHazeEnableGlare(const bool active);
void setHazeRange(const float value);
void setHazeAltitude(const float value);
void setHazeKeyLightRange(const float value);
void setHazeKeyLightAltitude(const float value);
void setHazeBackgroundBlend(const float value);
};
class DrawHaze { class DrawHaze {
public: public:
using Inputs = render::VaryingSet5<graphics::HazePointer, gpu::FramebufferPointer, LinearDepthFramebufferPointer, DeferredFrameTransformPointer, LightingModelPointer>; using Inputs = render::VaryingSet6<HazeStage::Frame, gpu::FramebufferPointer, LinearDepthFramebufferPointer, DeferredFrameTransformPointer, LightingModelPointer, LightStage::Frame>;
using Config = HazeConfig; using JobModel = render::Job::ModelI<DrawHaze, Inputs>;
using JobModel = render::Job::ModelI<DrawHaze, Inputs, Config>;
void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
private: private:

View file

@ -16,32 +16,6 @@
std::string HazeStage::_stageName { "HAZE_STAGE"}; std::string HazeStage::_stageName { "HAZE_STAGE"};
const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
FetchHazeStage::FetchHazeStage() {
_haze = std::make_shared<graphics::Haze>();
}
void FetchHazeStage::configure(const Config& config) {
_haze->setHazeColor(config.hazeColor);
_haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle));
_haze->setHazeGlareColor(config.hazeGlareColor);
_haze->setHazeBaseReference(config.hazeBaseReference);
_haze->setHazeActive(config.isHazeActive);
_haze->setAltitudeBased(config.isAltitudeBased);
_haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight);
_haze->setModulateColorActive(config.isModulateColorActive);
_haze->setHazeEnableGlare(config.isHazeEnableGlare);
_haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange));
_haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight));
_haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange));
_haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude));
_haze->setHazeBackgroundBlend(config.hazeBackgroundBlend);
}
HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const { HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const {
auto found = _hazeMap.find(haze); auto found = _hazeMap.find(haze);
if (found != _hazeMap.end()) { if (found != _hazeMap.end()) {
@ -84,15 +58,4 @@ void HazeStageSetup::run(const render::RenderContextPointer& renderContext) {
if (!stage) { if (!stage) {
renderContext->_scene->resetStage(HazeStage::getName(), std::make_shared<HazeStage>()); renderContext->_scene->resetStage(HazeStage::getName(), std::make_shared<HazeStage>());
} }
} }
void FetchHazeStage::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) {
auto hazeStage = renderContext->_scene->getStage<HazeStage>();
assert(hazeStage);
haze = nullptr;
if (hazeStage->_currentFrame._hazes.size() != 0) {
auto hazeId = hazeStage->_currentFrame._hazes.front();
haze = hazeStage->getHaze(hazeId);
}
}

View file

@ -150,18 +150,4 @@ public slots:
signals: signals:
void dirty(); void dirty();
}; };
class FetchHazeStage {
public:
using Config = FetchHazeConfig;
using JobModel = render::Job::ModelO<FetchHazeStage, graphics::HazePointer, Config>;
FetchHazeStage();
void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze);
private:
graphics::HazePointer _haze;
};
#endif #endif

View file

@ -548,7 +548,8 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext,
auto deferredTransform = inputs.get0(); auto deferredTransform = inputs.get0();
auto lightingModel = inputs.get1(); auto lightingModel = inputs.get1();
auto surfaceGeometryFramebuffer = inputs.get2(); auto lightFrame = inputs.get2();
auto surfaceGeometryFramebuffer = inputs.get3();
// first update the Grid with the new frustum // first update the Grid with the new frustum
if (!_freeze) { if (!_freeze) {
@ -559,7 +560,7 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext,
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
_lightClusters->updateLightStage(lightStage); _lightClusters->updateLightStage(lightStage);
_lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); _lightClusters->updateLightFrame(lightFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled());
auto clusteringStats = _lightClusters->updateClusters(); auto clusteringStats = _lightClusters->updateClusters();

View file

@ -167,7 +167,7 @@ protected:
class LightClusteringPass { class LightClusteringPass {
public: public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, LightingModelPointer, LinearDepthFramebufferPointer>; using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, LightingModelPointer, LightStage::Frame, LinearDepthFramebufferPointer>;
using Outputs = LightClustersPointer; using Outputs = LightClustersPointer;
using Config = LightClusteringPassConfig; using Config = LightClusteringPassConfig;
using JobModel = render::Job::ModelIO<LightClusteringPass, Inputs, Outputs, Config>; using JobModel = render::Job::ModelIO<LightClusteringPass, Inputs, Outputs, Config>;

View file

@ -372,36 +372,36 @@ LightStage::LightPointer LightStage::removeLight(Index index) {
return removedLight; return removedLight;
} }
LightStage::LightPointer LightStage::getCurrentKeyLight() const { LightStage::LightPointer LightStage::getCurrentKeyLight(const LightStage::Frame& frame) const {
Index keyLightId{ _defaultLightId }; Index keyLightId { _defaultLightId };
if (!_currentFrame._sunLights.empty()) { if (!frame._sunLights.empty()) {
keyLightId = _currentFrame._sunLights.front(); keyLightId = frame._sunLights.front();
} }
return _lights.get(keyLightId); return _lights.get(keyLightId);
} }
LightStage::LightPointer LightStage::getCurrentAmbientLight() const { LightStage::LightPointer LightStage::getCurrentAmbientLight(const LightStage::Frame& frame) const {
Index keyLightId { _defaultLightId }; Index keyLightId { _defaultLightId };
if (!_currentFrame._ambientLights.empty()) { if (!frame._ambientLights.empty()) {
keyLightId = _currentFrame._ambientLights.front(); keyLightId = frame._ambientLights.front();
} }
return _lights.get(keyLightId); return _lights.get(keyLightId);
} }
LightStage::ShadowPointer LightStage::getCurrentKeyShadow() const { LightStage::ShadowPointer LightStage::getCurrentKeyShadow(const LightStage::Frame& frame) const {
Index keyLightId { _defaultLightId }; Index keyLightId { _defaultLightId };
if (!_currentFrame._sunLights.empty()) { if (!frame._sunLights.empty()) {
keyLightId = _currentFrame._sunLights.front(); keyLightId = frame._sunLights.front();
} }
auto shadow = getShadow(keyLightId); auto shadow = getShadow(keyLightId);
assert(shadow == nullptr || shadow->getLight() == getLight(keyLightId)); assert(shadow == nullptr || shadow->getLight() == getLight(keyLightId));
return shadow; return shadow;
} }
LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow() const { LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const {
Index keyLightId { _defaultLightId }; Index keyLightId { _defaultLightId };
if (!_currentFrame._sunLights.empty()) { if (!frame._sunLights.empty()) {
keyLightId = _currentFrame._sunLights.front(); keyLightId = frame._sunLights.front();
} }
auto shadow = getShadow(keyLightId); auto shadow = getShadow(keyLightId);
auto light = getLight(keyLightId); auto light = getLight(keyLightId);

View file

@ -151,11 +151,6 @@ public:
return LightAndShadow(light, shadow); return LightAndShadow(light, shadow);
} }
LightPointer getCurrentKeyLight() const;
LightPointer getCurrentAmbientLight() const;
ShadowPointer getCurrentKeyShadow() const;
LightAndShadow getCurrentKeyLightAndShadow() const;
LightStage(); LightStage();
gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; } gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; }
@ -193,6 +188,11 @@ public:
Index getSpotOffLight() { return _spotOffLightId; } Index getSpotOffLight() { return _spotOffLightId; }
Index getSunOffLight() { return _sunOffLightId; } Index getSunOffLight() { return _sunOffLightId; }
LightPointer getCurrentKeyLight(const LightStage::Frame& frame) const;
LightPointer getCurrentAmbientLight(const LightStage::Frame& frame) const;
ShadowPointer getCurrentKeyShadow(const LightStage::Frame& frame) const;
LightAndShadow getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const;
protected: protected:
struct Desc { struct Desc {

View file

@ -197,12 +197,14 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer
}); });
} }
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) { void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) {
assert(renderContext->args); assert(renderContext->args);
assert(renderContext->args->_context); assert(renderContext->args->_context);
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
const auto& lightFrame = inputs;
// Return view frustum // Return view frustum
auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>(); auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
if (!viewFrustum) { if (!viewFrustum) {
@ -216,7 +218,7 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out
for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) { for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>(); auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>();
if (lightStage) { if (lightStage) {
auto globalShadow = lightStage->getCurrentKeyShadow(); auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame);
if (globalShadow && i<(int)globalShadow->getCascadeCount()) { if (globalShadow && i<(int)globalShadow->getCascadeCount()) {
auto& cascade = globalShadow->getCascade(i); auto& cascade = globalShadow->getCascade(i);
@ -229,3 +231,21 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out
} }
} }
} }
void FetchCurrentFrames::run(const render::RenderContextPointer& renderContext, Outputs& outputs) {
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
outputs.edit0() = lightStage->_currentFrame;
auto backgroundStage = renderContext->_scene->getStage<BackgroundStage>();
assert(backgroundStage);
outputs.edit1() = backgroundStage->_currentFrame;
auto hazeStage = renderContext->_scene->getStage<HazeStage>();
assert(hazeStage);
outputs.edit2() = hazeStage->_currentFrame;
auto bloomStage = renderContext->_scene->getStage<BloomStage>();
assert(bloomStage);
outputs.edit3() = bloomStage->_currentFrame;
}

View file

@ -13,6 +13,11 @@
#include <render/RenderFetchCullSortTask.h> #include <render/RenderFetchCullSortTask.h>
#include "LightingModel.h" #include "LightingModel.h"
#include "LightStage.h"
#include "BackgroundStage.h"
#include "HazeStage.h"
#include "BloomStage.h"
class BeginGPURangeTimer { class BeginGPURangeTimer {
public: public:
using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>; using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
@ -106,10 +111,22 @@ public:
FRUSTUM_COUNT FRUSTUM_COUNT
}; };
using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>; using Inputs = LightStage::Frame;
using JobModel = render::Job::ModelO<ExtractFrustums, Output>; using Outputs = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
using JobModel = render::Job::ModelIO<ExtractFrustums, Inputs, Outputs>;
void run(const render::RenderContextPointer& renderContext, Output& output); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output);
};
class FetchCurrentFrames {
public:
using Outputs = render::VaryingSet4<LightStage::Frame, BackgroundStage::Frame, HazeStage::Frame, BloomStage::Frame>;
using JobModel = render::Job::ModelO<FetchCurrentFrames, Outputs>;
FetchCurrentFrames() {}
void run(const render::RenderContextPointer& renderContext, Outputs& outputs);
}; };
#endif // hifi_RenderDeferredTask_h #endif // hifi_RenderDeferredTask_h

View file

@ -180,29 +180,32 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
task.addJob<DrawLight>("DrawLight", lights); task.addJob<DrawLight>("DrawLight", lights);
// Fetch the current frame stacks from all the stages
const auto currentFrames = task.addJob<FetchCurrentFrames>("FetchCurrentFrames");
const auto lightFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(0);
const auto backgroundFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(1);
const auto hazeFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(2);
const auto bloomFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(3);
// Light Clustering // Light Clustering
// Create the cluster grid of lights, cpu job for now // Create the cluster grid of lights, cpu job for now
const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).asVarying(); const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, lightFrame, linearDepthTarget).asVarying();
const auto lightClusters = task.addJob<LightClusteringPass>("LightClustering", lightClusteringPassInputs); const auto lightClusters = task.addJob<LightClusteringPass>("LightClustering", lightClusteringPassInputs);
// Add haze model
const auto hazeModel = task.addJob<FetchHazeStage>("HazeModel");
// DeferredBuffer is complete, now let's shade it into the LightingBuffer // DeferredBuffer is complete, now let's shade it into the LightingBuffer
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying(); surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, lightFrame, hazeFrame).asVarying();
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs, renderShadows); task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs, renderShadows);
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel); const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying();
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", backgroundInputs);
const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeModel, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel)); const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeFrame, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel, lightFrame));
task.addJob<DrawHaze>("DrawHazeDeferred", drawHazeInputs); task.addJob<DrawHaze>("DrawHazeDeferred", drawHazeInputs);
// Render transparent objects forward in LightingBuffer // Render transparent objects forward in LightingBuffer
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters, jitter).asVarying(); const auto transparentsInputs = DrawDeferred::Inputs(transparents, hazeFrame, lightFrame, lightingModel, lightClusters, jitter).asVarying();
task.addJob<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber); task.addJob<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber);
// Light Cluster Grid Debuging job // Light Cluster Grid Debuging job
@ -246,8 +249,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<Antialiasing>("Antialiasing", antialiasingInputs); task.addJob<Antialiasing>("Antialiasing", antialiasingInputs);
// Add bloom // Add bloom
const auto bloomModel = task.addJob<FetchBloomStage>("BloomModel"); const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomFrame).asVarying();
const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomModel).asVarying();
task.addJob<BloomEffect>("Bloom", bloomInputs); task.addJob<BloomEffect>("Bloom", bloomInputs);
// Lighting Buffer ready for tone mapping // Lighting Buffer ready for tone mapping
@ -261,11 +263,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<DrawBounds>("DrawLightBounds", lights); task.addJob<DrawBounds>("DrawLightBounds", lights);
task.addJob<DrawBounds>("DrawZones", zones); task.addJob<DrawBounds>("DrawZones", zones);
const auto frustums = task.addJob<ExtractFrustums>("ExtractFrustums"); const auto frustums = task.addJob<ExtractFrustums>("ExtractFrustums", lightFrame);
const auto viewFrustum = frustums.getN<ExtractFrustums::Output>(ExtractFrustums::VIEW_FRUSTUM); const auto viewFrustum = frustums.getN<ExtractFrustums::Outputs>(ExtractFrustums::VIEW_FRUSTUM);
task.addJob<DrawFrustum>("DrawViewFrustum", viewFrustum, glm::vec3(0.0f, 1.0f, 0.0f)); task.addJob<DrawFrustum>("DrawViewFrustum", viewFrustum, glm::vec3(0.0f, 1.0f, 0.0f));
for (auto i = 0; i < ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT; i++) { for (auto i = 0; i < ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
const auto shadowFrustum = frustums.getN<ExtractFrustums::Output>(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i); const auto shadowFrustum = frustums.getN<ExtractFrustums::Outputs>(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i);
float tint = 1.0f - i / float(ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT - 1); float tint = 1.0f - i / float(ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT - 1);
char jobName[64]; char jobName[64];
sprintf(jobName, "DrawShadowFrustum%d", i); sprintf(jobName, "DrawShadowFrustum%d", i);
@ -290,7 +292,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// Debugging stages // Debugging stages
{ {
// Debugging Deferred buffer job // Debugging Deferred buffer job
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform)); const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform, lightFrame));
task.addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers); task.addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers);
const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
@ -315,7 +317,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<DrawStatus>("DrawStatus", drawStatusInputs, DrawStatus(statusIconMap)); task.addJob<DrawStatus>("DrawStatus", drawStatusInputs, DrawStatus(statusIconMap));
} }
task.addJob<DebugZoneLighting>("DrawZoneStack", deferredFrameTransform); const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying();
task.addJob<DebugZoneLighting>("DrawZoneStack", debugZoneInputs);
} }
// Upscale to finale resolution // Upscale to finale resolution
@ -351,9 +354,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
const auto& inItems = inputs.get0(); const auto& inItems = inputs.get0();
const auto& lightingModel = inputs.get1(); const auto& hazeFrame = inputs.get1();
const auto& lightClusters = inputs.get2(); const auto& lightFrame = inputs.get2();
const auto jitter = inputs.get3(); const auto& lightingModel = inputs.get3();
const auto& lightClusters = inputs.get4();
const auto jitter = inputs.get5();
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>(); auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
@ -378,13 +383,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer());
// Set the light // Set the light
deferredLightingEffect->setupKeyLightBatch(args, batch); deferredLightingEffect->setupKeyLightBatch(args, batch, lightFrame);
deferredLightingEffect->setupLocalLightsBatch(batch, lightClusters); deferredLightingEffect->setupLocalLightsBatch(batch, lightClusters);
// Setup haze if current zone has haze // Setup haze if current zone has haze
auto hazeStage = args->_scene->getStage<HazeStage>(); const auto& hazeStage = args->_scene->getStage<HazeStage>();
if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { if (hazeStage && hazeFrame._hazes.size() > 0) {
graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); const auto& hazePointer = hazeStage->getHaze(hazeFrame._hazes.front());
if (hazePointer) { if (hazePointer) {
batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer());
} }

View file

@ -17,6 +17,7 @@
#include "LightingModel.h" #include "LightingModel.h"
#include "LightClusters.h" #include "LightClusters.h"
#include "RenderShadowTask.h" #include "RenderShadowTask.h"
#include "HazeStage.h"
class DrawDeferredConfig : public render::Job::Config { class DrawDeferredConfig : public render::Job::Config {
Q_OBJECT Q_OBJECT
@ -42,7 +43,7 @@ protected:
class DrawDeferred { class DrawDeferred {
public: public:
using Inputs = render::VaryingSet4<render::ItemBounds, LightingModelPointer, LightClustersPointer, glm::vec2>; using Inputs = render::VaryingSet6<render::ItemBounds, HazeStage::Frame, LightStage::Frame, LightingModelPointer, LightClustersPointer, glm::vec2>;
using Config = DrawDeferredConfig; using Config = DrawDeferredConfig;
using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>; using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>;

View file

@ -32,7 +32,6 @@
#include "FramebufferCache.h" #include "FramebufferCache.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "RenderCommonTask.h" #include "RenderCommonTask.h"
#include "LightStage.h"
namespace ru { namespace ru {
using render_utils::slot::texture::Texture; using render_utils::slot::texture::Texture;
@ -59,13 +58,13 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
// Extract opaques / transparents / lights / metas / overlays / background // Extract opaques / transparents / lights / metas / overlays / background
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE]; const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE]; const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
// const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; //const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
const auto& metas = items.get0()[RenderFetchCullSortTask::META]; const auto& metas = items.get0()[RenderFetchCullSortTask::META];
const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
//const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND]; //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
// const auto& spatialSelection = items[1]; //const auto& spatialSelection = items[1];
fadeEffect->build(task, opaques); fadeEffect->build(task, opaques);
@ -76,10 +75,17 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
// Filter zones from the general metas bucket // Filter zones from the general metas bucket
const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas); const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas);
// Fetch the current frame stacks from all the stages
const auto currentFrames = task.addJob<FetchCurrentFrames>("FetchCurrentFrames");
const auto lightFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(0);
const auto backgroundFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(1);
//const auto hazeFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(2);
//const auto bloomFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(3);
// GPU jobs: Start preparing the main framebuffer // GPU jobs: Start preparing the main framebuffer
const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer"); const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer");
task.addJob<PrepareForward>("PrepareForward", lightingModel); task.addJob<PrepareForward>("PrepareForward", lightFrame);
// draw a stencil mask in hidden regions of the framebuffer. // draw a stencil mask in hidden regions of the framebuffer.
task.addJob<PrepareStencil>("PrepareStencil", framebuffer); task.addJob<PrepareStencil>("PrepareStencil", framebuffer);
@ -101,7 +107,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
task.addJob<DrawForward>("DrawOpaques", opaqueInputs, shapePlumber); task.addJob<DrawForward>("DrawOpaques", opaqueInputs, shapePlumber);
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel); const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying();
task.addJob<DrawBackgroundStage>("DrawBackgroundForward", backgroundInputs);
// Draw transparent objects forward // Draw transparent objects forward
const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying();
@ -114,8 +121,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
task.addJob<DrawBounds>("DrawTransparentBounds", transparents); task.addJob<DrawBounds>("DrawTransparentBounds", transparents);
task.addJob<DrawBounds>("DrawZones", zones); task.addJob<DrawBounds>("DrawZones", zones);
task.addJob<DebugZoneLighting>("DrawZoneStack", deferredFrameTransform); const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying();
task.addJob<DebugZoneLighting>("DrawZoneStack", debugZoneInputs);
} }
// Lighting Buffer ready for tone mapping // Lighting Buffer ready for tone mapping
@ -180,12 +187,12 @@ void PrepareForward::run(const RenderContextPointer& renderContext, const Inputs
graphics::LightPointer keySunLight; graphics::LightPointer keySunLight;
auto lightStage = args->_scene->getStage<LightStage>(); auto lightStage = args->_scene->getStage<LightStage>();
if (lightStage) { if (lightStage) {
keySunLight = lightStage->getCurrentKeyLight(); keySunLight = lightStage->getCurrentKeyLight(inputs);
} }
graphics::LightPointer keyAmbiLight; graphics::LightPointer keyAmbiLight;
if (lightStage) { if (lightStage) {
keyAmbiLight = lightStage->getCurrentAmbientLight(); keyAmbiLight = lightStage->getCurrentAmbientLight(inputs);
} }
if (keySunLight) { if (keySunLight) {

View file

@ -15,6 +15,7 @@
#include <gpu/Pipeline.h> #include <gpu/Pipeline.h>
#include <render/RenderFetchCullSortTask.h> #include <render/RenderFetchCullSortTask.h>
#include "LightingModel.h" #include "LightingModel.h"
#include "LightStage.h"
class RenderForwardTask { class RenderForwardTask {
public: public:
@ -40,7 +41,7 @@ private:
class PrepareForward { class PrepareForward {
public: public:
using Inputs = LightingModelPointer; using Inputs = LightStage::Frame;
using JobModel = render::Job::ModelI<PrepareForward, Inputs>; using JobModel = render::Job::ModelI<PrepareForward, Inputs>;
void run(const render::RenderContextPointer& renderContext, void run(const render::RenderContextPointer& renderContext,

View file

@ -24,6 +24,8 @@
#include "RenderUtilsLogging.h" #include "RenderUtilsLogging.h"
#include "RenderCommonTask.h"
// These values are used for culling the objects rendered in the shadow map // These values are used for culling the objects rendered in the shadow map
// but are readjusted afterwards // but are readjusted afterwards
#define SHADOW_FRUSTUM_NEAR 1.0f #define SHADOW_FRUSTUM_NEAR 1.0f
@ -40,10 +42,6 @@ void RenderShadowTask::configure(const Config& configuration) {
} }
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) {
::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) {
return _cullFunctor(args, bounds);
};
// Prepare the ShapePipeline // Prepare the ShapePipeline
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>(); ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
{ {
@ -54,7 +52,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
initZPassPipelines(*shapePlumber, state); initZPassPipelines(*shapePlumber, state);
} }
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup"); // FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw
// Fetch the current frame stacks from all the stages
const auto currentFrames = task.addJob<FetchCurrentFrames>("FetchCurrentFrames");
const auto lightFrame = currentFrames.getN<FetchCurrentFrames::Outputs>(0);
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", lightFrame);
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1); const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
// Fetch and cull the items from the scene // Fetch and cull the items from the scene
@ -89,7 +92,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
char jobName[64]; char jobName[64];
sprintf(jobName, "ShadowCascadeSetup%d", i); sprintf(jobName, "ShadowCascadeSetup%d", i);
const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, i, _cullFunctor, tagBits, tagMask); const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, lightFrame, i, tagBits, tagMask);
const auto shadowFilter = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(0); const auto shadowFilter = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(0);
auto antiFrustum = render::Varying(ViewFrustumPointer()); auto antiFrustum = render::Varying(ViewFrustumPointer());
cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1); cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1);
@ -97,14 +100,15 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
antiFrustum = cascadeFrustums[i - 2]; antiFrustum = cascadeFrustums[i - 2];
} }
// CPU jobs: finer grained culling const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum, lightFrame, cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(2)).asVarying();
const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying();
sprintf(jobName, "CullShadowCascade%d", i); sprintf(jobName, "CullShadowCascade%d", i);
const auto culledShadowItemsAndBounds = task.addJob<CullShadowBounds>(jobName, cullInputs, shadowCullFunctor); const auto culledShadowItemsAndBounds = task.addJob<CullShadowBounds>(jobName, cullInputs);
// GPU jobs: Render to shadow map // GPU jobs: Render to shadow map
sprintf(jobName, "RenderShadowMap%d", i); sprintf(jobName, "RenderShadowMap%d", i);
task.addJob<RenderShadowMap>(jobName, culledShadowItemsAndBounds, shapePlumber, i); const auto shadowInputs = RenderShadowMap::Inputs(culledShadowItemsAndBounds.getN<CullShadowBounds::Outputs>(0),
culledShadowItemsAndBounds.getN<CullShadowBounds::Outputs>(1), lightFrame).asVarying();
task.addJob<RenderShadowMap>(jobName, shadowInputs, shapePlumber, i);
sprintf(jobName, "ShadowCascadeTeardown%d", i); sprintf(jobName, "ShadowCascadeTeardown%d", i);
task.addJob<RenderShadowCascadeTeardown>(jobName, shadowFilter); task.addJob<RenderShadowCascadeTeardown>(jobName, shadowFilter);
@ -204,11 +208,12 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
const auto& inShapes = inputs.get0(); const auto& inShapes = inputs.get0();
const auto& inShapeBounds = inputs.get1(); const auto& inShapeBounds = inputs.get1();
const auto& lightFrame = inputs.get2();
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
auto shadow = lightStage->getCurrentKeyShadow(); auto shadow = lightStage->getCurrentKeyShadow(lightFrame);
if (!shadow || _cascadeIndex >= shadow->getCascadeCount()) { if (!shadow || _cascadeIndex >= shadow->getCascadeCount()) {
return; return;
} }
@ -328,11 +333,11 @@ void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) {
_bias[cascadeIndex]._slope = value * value * value * 0.01f; _bias[cascadeIndex]._slope = value * value * value * 0.01f;
} }
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) {
// Abort all jobs if not casting shadows // Abort all jobs if not casting shadows
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
if (!lightStage->getCurrentKeyLight() || !lightStage->getCurrentKeyLight()->getCastShadows()) { if (!lightStage->getCurrentKeyLight(input) || !lightStage->getCurrentKeyLight(input)->getCastShadows()) {
renderContext->taskFlow.abortTask(); renderContext->taskFlow.abortTask();
return; return;
} }
@ -346,7 +351,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
*_cameraFrustum = args->getViewFrustum(); *_cameraFrustum = args->getViewFrustum();
output.edit2() = _cameraFrustum; output.edit2() = _cameraFrustum;
const auto globalShadow = lightStage->getCurrentKeyShadow(); const auto globalShadow = lightStage->getCurrentKeyShadow(input);
if (globalShadow) { if (globalShadow) {
globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
@ -413,15 +418,18 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
} }
} }
void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) {
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
const auto& lightFrame = input;
assert(lightStage); assert(lightStage);
// Cache old render args // Cache old render args
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
const auto globalShadow = lightStage->getCurrentKeyShadow(); RenderShadowTask::CullFunctor cullFunctor;
if (globalShadow && _cascadeIndex<globalShadow->getCascadeCount()) {
const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame);
if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) {
// Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers)
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
@ -434,13 +442,14 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon
const auto minTexelCount = 24.0f; const auto minTexelCount = 24.0f;
// TODO : maybe adapt that with LOD management system? // TODO : maybe adapt that with LOD management system?
texelSize *= minTexelCount; texelSize *= minTexelCount;
_cullFunctor._minSquareSize = texelSize * texelSize; cullFunctor._minSquareSize = texelSize * texelSize;
output.edit1() = cascadeFrustum; output.edit1() = cascadeFrustum;
} else { } else {
output.edit0() = ItemFilter::Builder::nothing(); output.edit0() = ItemFilter::Builder::nothing();
output.edit1() = ViewFrustumPointer(); output.edit1() = ViewFrustumPointer();
} }
output.edit2() = cullFunctor;
} }
void RenderShadowCascadeTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) { void RenderShadowCascadeTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) {
@ -498,13 +507,20 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co
outShapes.clear(); outShapes.clear();
outBounds = AABox(); outBounds = AABox();
const auto& lightFrame = inputs.get3();
auto cullFunctor = inputs.get4();
render::CullFunctor shadowCullFunctor = [cullFunctor](const RenderArgs* args, const AABox& bounds) {
return cullFunctor(args, bounds);
};
if (!filter.selectsNothing()) { if (!filter.selectsNothing()) {
auto& details = args->_details.edit(RenderDetails::SHADOW); auto& details = args->_details.edit(RenderDetails::SHADOW);
render::CullTest test(_cullFunctor, args, details, antiFrustum); render::CullTest test(shadowCullFunctor, args, details, antiFrustum);
auto scene = args->_scene; auto scene = args->_scene;
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage); assert(lightStage);
const auto globalLightDir = lightStage->getCurrentKeyLight()->getDirection(); const auto globalLightDir = lightStage->getCurrentKeyLight(lightFrame)->getDirection();
auto castersFilter = render::ItemFilter::Builder(filter).withShadowCaster().build(); auto castersFilter = render::ItemFilter::Builder(filter).withShadowCaster().build();
const auto& receiversFilter = filter; const auto& receiversFilter = filter;

View file

@ -19,11 +19,13 @@
#include "Shadows_shared.slh" #include "Shadows_shared.slh"
#include "LightStage.h"
class ViewFrustum; class ViewFrustum;
class RenderShadowMap { class RenderShadowMap {
public: public:
using Inputs = render::VaryingSet2<render::ShapeBounds, AABox>; using Inputs = render::VaryingSet3<render::ShapeBounds, AABox, LightStage::Frame>;
using JobModel = render::Job::ModelI<RenderShadowMap, Inputs>; using JobModel = render::Job::ModelI<RenderShadowMap, Inputs>;
RenderShadowMap(render::ShapePlumberPointer shapePlumber, unsigned int cascadeIndex) : _shapePlumber{ shapePlumber }, _cascadeIndex{ cascadeIndex } {} RenderShadowMap(render::ShapePlumberPointer shapePlumber, unsigned int cascadeIndex) : _shapePlumber{ shapePlumber }, _cascadeIndex{ cascadeIndex } {}
@ -98,13 +100,14 @@ signals:
class RenderShadowSetup { class RenderShadowSetup {
public: public:
using Inputs = LightStage::Frame;
using Outputs = render::VaryingSet3<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer>; using Outputs = render::VaryingSet3<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer>;
using Config = RenderShadowSetupConfig; using Config = RenderShadowSetupConfig;
using JobModel = render::Job::ModelO<RenderShadowSetup, Outputs, Config>; using JobModel = render::Job::ModelIO<RenderShadowSetup, Inputs, Outputs, Config>;
RenderShadowSetup(); RenderShadowSetup();
void configure(const Config& configuration); void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, Outputs& output); void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output);
private: private:
@ -121,19 +124,19 @@ private:
class RenderShadowCascadeSetup { class RenderShadowCascadeSetup {
public: public:
using Outputs = render::VaryingSet2<render::ItemFilter, ViewFrustumPointer>; using Inputs = LightStage::Frame;
using JobModel = render::Job::ModelO<RenderShadowCascadeSetup, Outputs>; using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
RenderShadowCascadeSetup(unsigned int cascadeIndex, RenderShadowTask::CullFunctor& cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : RenderShadowCascadeSetup(unsigned int cascadeIndex, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) :
_cascadeIndex{ cascadeIndex }, _cullFunctor{ cullFunctor }, _tagBits(tagBits), _tagMask(tagMask) {} _cascadeIndex(cascadeIndex), _tagBits(tagBits), _tagMask(tagMask) {}
void run(const render::RenderContextPointer& renderContext, Outputs& output);
void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output);
private: private:
unsigned int _cascadeIndex; unsigned int _cascadeIndex;
RenderShadowTask::CullFunctor& _cullFunctor; uint8_t _tagBits { 0x00 };
uint8_t _tagBits{ 0x00 }; uint8_t _tagMask { 0x00 };
uint8_t _tagMask{ 0x00 };
}; };
class RenderShadowCascadeTeardown { class RenderShadowCascadeTeardown {
@ -152,20 +155,11 @@ public:
class CullShadowBounds { class CullShadowBounds {
public: public:
using Inputs = render::VaryingSet3<render::ShapeBounds, render::ItemFilter, ViewFrustumPointer>; using Inputs = render::VaryingSet5<render::ShapeBounds, render::ItemFilter, ViewFrustumPointer, LightStage::Frame, RenderShadowTask::CullFunctor>;
using Outputs = render::VaryingSet2<render::ShapeBounds, AABox>; using Outputs = render::VaryingSet2<render::ShapeBounds, AABox>;
using JobModel = render::Job::ModelIO<CullShadowBounds, Inputs, Outputs>; using JobModel = render::Job::ModelIO<CullShadowBounds, Inputs, Outputs>;
CullShadowBounds(render::CullFunctor cullFunctor) :
_cullFunctor{ cullFunctor } {
}
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
private:
render::CullFunctor _cullFunctor;
}; };
#endif // hifi_RenderShadowTask_h #endif // hifi_RenderShadowTask_h

View file

@ -39,28 +39,16 @@ namespace gr {
using namespace render; using namespace render;
class SetupZones {
public:
using Inputs = render::ItemBounds;
using JobModel = render::Job::ModelI<SetupZones, Inputs>;
SetupZones() {}
void run(const RenderContextPointer& context, const Inputs& inputs);
protected:
};
const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) {
// Filter out the sorted list of zones // Filter out the sorted list of zones
const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str()); const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str());
// just setup the current zone env // just setup the current zone env
task.addJob<SetupZones>("SetupZones", zoneItems); task.addJob<SetupZones>("SetupZones", zoneItems);
ouput = zoneItems; output = zoneItems;
} }
void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) { void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) {
@ -130,27 +118,29 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() {
void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) { void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) {
RenderArgs* args = context->args; RenderArgs* args = context->args;
auto deferredTransform = inputs; auto deferredTransform = inputs.get0();
auto lightFrame = inputs.get1();
auto backgroundFrame = inputs.get2();
auto lightStage = context->_scene->getStage<LightStage>(LightStage::getName()); auto lightStage = context->_scene->getStage<LightStage>(LightStage::getName());
std::vector<graphics::LightPointer> keyLightStack; std::vector<graphics::LightPointer> keyLightStack;
if (lightStage && lightStage->_currentFrame._sunLights.size()) { if (lightStage && lightFrame._sunLights.size()) {
for (auto index : lightStage->_currentFrame._sunLights) { for (auto index : lightFrame._sunLights) {
keyLightStack.push_back(lightStage->getLight(index)); keyLightStack.push_back(lightStage->getLight(index));
} }
} }
std::vector<graphics::LightPointer> ambientLightStack; std::vector<graphics::LightPointer> ambientLightStack;
if (lightStage && lightStage->_currentFrame._ambientLights.size()) { if (lightStage && lightFrame._ambientLights.size()) {
for (auto index : lightStage->_currentFrame._ambientLights) { for (auto index : lightFrame._ambientLights) {
ambientLightStack.push_back(lightStage->getLight(index)); ambientLightStack.push_back(lightStage->getLight(index));
} }
} }
auto backgroundStage = context->_scene->getStage<BackgroundStage>(BackgroundStage::getName()); auto backgroundStage = context->_scene->getStage<BackgroundStage>(BackgroundStage::getName());
std::vector<graphics::SkyboxPointer> skyboxStack; std::vector<graphics::SkyboxPointer> skyboxStack;
if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { if (backgroundStage && backgroundFrame._backgrounds.size()) {
for (auto index : backgroundStage->_currentFrame._backgrounds) { for (auto index : backgroundFrame._backgrounds) {
auto background = backgroundStage->getBackground(index); auto background = backgroundStage->getBackground(index);
if (background) { if (background) {
skyboxStack.push_back(background->getSkybox()); skyboxStack.push_back(background->getSkybox());
@ -158,7 +148,6 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I
} }
} }
gpu::doInBatch("DebugZoneLighting::run", args->_context, [=](gpu::Batch& batch) { gpu::doInBatch("DebugZoneLighting::run", args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport); batch.setViewportTransform(args->_viewport);

View file

@ -16,6 +16,19 @@
#include "DeferredFrameTransform.h" #include "DeferredFrameTransform.h"
#include "LightStage.h"
#include "BackgroundStage.h"
class SetupZones {
public:
using Inputs = render::ItemBounds;
using JobModel = render::Job::ModelI<SetupZones, Inputs>;
SetupZones() {}
void run(const render::RenderContextPointer& context, const Inputs& inputs);
};
class ZoneRendererConfig : public render::Task::Config { class ZoneRendererConfig : public render::Task::Config {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
@ -44,7 +57,7 @@ public:
ZoneRendererTask() {} ZoneRendererTask() {}
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs); void build(JobModel& task, const render::Varying& inputs, render::Varying& output);
void configure(const Config& config) { _maxDrawn = config.maxDrawn; } void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
@ -59,7 +72,7 @@ public:
Config(bool enabled = false) : JobConfig(enabled) {} Config(bool enabled = false) : JobConfig(enabled) {}
}; };
using Inputs = DeferredFrameTransformPointer; using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, LightStage::Frame, BackgroundStage::Frame>;
using JobModel = render::Job::ModelI<DebugZoneLighting, Inputs, Config>; using JobModel = render::Job::ModelI<DebugZoneLighting, Inputs, Config>;
DebugZoneLighting() {} DebugZoneLighting() {}

View file

@ -417,6 +417,7 @@ protected:
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6<T0, T1, T2, T3, T4, T5>; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6<T0, T1, T2, T3, T4, T5>; \
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7<T0, T1, T2, T3, T4, T5, T6>; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7<T0, T1, T2, T3, T4, T5, T6>; \
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8<T0, T1, T2, T3, T4, T5, T6, T7>; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8<T0, T1, T2, T3, T4, T5, T6, T7>; \
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8 > using VaryingSet9 = task::VaryingSet9<T0, T1, T2, T3, T4, T5, T6, T7, T8>; \
template < class T, int NUM > using VaryingArray = task::VaryingArray<T, NUM>; template < class T, int NUM > using VaryingArray = task::VaryingArray<T, NUM>;

View file

@ -328,6 +328,45 @@ public:
Varying asVarying() const { return Varying((*this)); } Varying asVarying() const { return Varying((*this)); }
}; };
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
class VaryingSet9 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying> {
public:
using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
VaryingSet9() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7()), Varying(T8())) {}
VaryingSet9(const VaryingSet9& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src), std::get<8>(src)) {}
VaryingSet9(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth, const Varying& nine) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth, nine) {}
const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
const T7& get7() const { return std::get<7>((*this)).template get<T7>(); }
T7& edit7() { return std::get<7>((*this)).template edit<T7>(); }
const T8& get8() const { return std::get<8>((*this)).template get<T8>(); }
T8& edit8() { return std::get<8>((*this)).template edit<T8>(); }
Varying asVarying() const { return Varying((*this)); }
};
template < class T, int NUM > template < class T, int NUM >
class VaryingArray : public std::array<Varying, NUM> { class VaryingArray : public std::array<Varying, NUM> {
public: public: