Shadows are completely working with settings on both pipeline

This commit is contained in:
sam gateau 2018-12-17 17:34:47 -08:00
parent 5a6f30b458
commit 237fb4dc4c
18 changed files with 284 additions and 96 deletions

View file

@ -1,16 +1,2 @@
{ {
"RenderMainView": {
"RenderShadowTask": {
"Enabled": {
"enabled": true
}
},
"RenderDeferredTask": {
"AmbientOcclusion": {
"Enabled": {
"enabled": true
}
}
}
}
} }

View file

@ -48,6 +48,7 @@
#include "DeferredLightingEffect.h" #include "DeferredLightingEffect.h"
#include "PickManager.h" #include "PickManager.h"
#include "LightingModel.h"
#include "AmbientOcclusionEffect.h" #include "AmbientOcclusionEffect.h"
#include "RenderShadowTask.h" #include "RenderShadowTask.h"
#include "AntialiasingEffect.h" #include "AntialiasingEffect.h"
@ -393,14 +394,19 @@ Menu::Menu() {
connect(action, &QAction::triggered, [action] { connect(action, &QAction::triggered, [action] {
auto renderConfig = qApp->getRenderEngine()->getConfiguration(); auto renderConfig = qApp->getRenderEngine()->getConfiguration();
if (renderConfig) { if (renderConfig) {
auto mainViewShadowTaskConfig = renderConfig->getConfig<RenderShadowTask>("RenderMainView.RenderShadowTask"); auto lightingModelConfig = renderConfig->getConfig<MakeLightingModel>("RenderMainView.LightingModel");
if (lightingModelConfig) {
lightingModelConfig->setShadow(action->isChecked());
}
/* auto mainViewShadowTaskConfig = renderConfig->getConfig<RenderShadowTask>("RenderMainView.RenderShadowTask");
if (mainViewShadowTaskConfig) { if (mainViewShadowTaskConfig) {
if (action->isChecked()) { if (action->isChecked()) {
mainViewShadowTaskConfig->setPreset("Enabled"); mainViewShadowTaskConfig->setPreset("Enabled");
} else { } else {
mainViewShadowTaskConfig->setPreset("None"); mainViewShadowTaskConfig->setPreset("None");
} }
} }*/
} }
}); });
@ -408,14 +414,24 @@ Menu::Menu() {
connect(action, &QAction::triggered, [action] { connect(action, &QAction::triggered, [action] {
auto renderConfig = qApp->getRenderEngine()->getConfiguration(); auto renderConfig = qApp->getRenderEngine()->getConfiguration();
if (renderConfig) { if (renderConfig) {
auto mainViewAmbientOcclusionConfig = renderConfig->getConfig<AmbientOcclusionEffect>("RenderMainView.AmbientOcclusion"); auto lightingModelConfig = renderConfig->getConfig<MakeLightingModel>("RenderMainView.LightingModel");
if (lightingModelConfig) {
lightingModelConfig->setAmbientOcclusion(action->isChecked());
/* if (action->isChecked()) {
lightingModelConfig->setPreset("Enabled");
}
else {
mainViewAmbientOcclusionConfig->setPreset("None");
}*/
}
/* auto mainViewAmbientOcclusionConfig = renderConfig->getConfig<AmbientOcclusionEffect>("RenderMainView.AmbientOcclusion");
if (mainViewAmbientOcclusionConfig) { if (mainViewAmbientOcclusionConfig) {
if (action->isChecked()) { if (action->isChecked()) {
mainViewAmbientOcclusionConfig->setPreset("Enabled"); mainViewAmbientOcclusionConfig->setPreset("Enabled");
} else { } else {
mainViewAmbientOcclusionConfig->setPreset("None"); mainViewAmbientOcclusionConfig->setPreset("None");
} }
} }*/
} }
}); });

View file

@ -589,14 +589,21 @@ void AmbientOcclusionEffect::updateJitterSamples() {
} }
} }
void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) {
assert(renderContext->args); assert(renderContext->args);
assert(renderContext->args->hasViewFrustum()); assert(renderContext->args->hasViewFrustum());
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
const auto& frameTransform = inputs.get0(); const auto& lightingModel = input.get0();
const auto& linearDepthFramebuffer = inputs.get2();
if (!lightingModel->isAmbientOcclusionEnabled()) {
output.edit0().reset();
return;
}
const auto& frameTransform = input.get1();
const auto& linearDepthFramebuffer = input.get3();
const int resolutionLevel = _aoParametersBuffer->getResolutionLevel(); const int resolutionLevel = _aoParametersBuffer->getResolutionLevel();
const auto depthResolutionLevel = getDepthResolutionLevel(); const auto depthResolutionLevel = getDepthResolutionLevel();
@ -629,8 +636,8 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
auto occlusionFBO = _framebuffer->getOcclusionFramebuffer(); auto occlusionFBO = _framebuffer->getOcclusionFramebuffer();
auto occlusionBlurredFBO = _framebuffer->getOcclusionBlurredFramebuffer(); auto occlusionBlurredFBO = _framebuffer->getOcclusionBlurredFramebuffer();
outputs.edit0() = _framebuffer; output.edit0() = _framebuffer;
outputs.edit1() = _aoParametersBuffer; output.edit1() = _aoParametersBuffer;
auto occlusionPipeline = getOcclusionPipeline(); auto occlusionPipeline = getOcclusionPipeline();
auto bilateralBlurPipeline = getBilateralBlurPipeline(); auto bilateralBlurPipeline = getBilateralBlurPipeline();

View file

@ -17,6 +17,7 @@
#include "render/DrawTask.h" #include "render/DrawTask.h"
#include "LightingModel.h"
#include "DeferredFrameTransform.h" #include "DeferredFrameTransform.h"
#include "DeferredFramebuffer.h" #include "DeferredFramebuffer.h"
#include "SurfaceGeometryPass.h" #include "SurfaceGeometryPass.h"
@ -152,15 +153,15 @@ signals:
class AmbientOcclusionEffect { class AmbientOcclusionEffect {
public: public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>; using Input = render::VaryingSet4<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
using Outputs = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>; using Output = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
using Config = AmbientOcclusionEffectConfig; using Config = AmbientOcclusionEffectConfig;
using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Inputs, Outputs, Config>; using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Input, Output, Config>;
AmbientOcclusionEffect(); AmbientOcclusionEffect();
void configure(const Config& config); void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
// Class describing the uniform buffer with all the parameters common to the AO shaders // Class describing the uniform buffer with all the parameters common to the AO shaders
class AOParameters : public AmbientOcclusionParams { class AOParameters : public AmbientOcclusionParams {

View file

@ -378,8 +378,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
const HazeStage::FramePointer& hazeFrame, const HazeStage::FramePointer& hazeFrame,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) {
bool renderShadows) {
auto args = renderContext->args; auto args = renderContext->args;
auto& batch = (*args->_batch); auto& batch = (*args->_batch);
@ -596,9 +595,7 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex
} }
} }
RenderDeferred::RenderDeferred(bool renderShadows): RenderDeferred::RenderDeferred() {
_renderShadows(renderShadows)
{
DependencyManager::get<DeferredLightingEffect>()->init(); DependencyManager::get<DeferredLightingEffect>()->init();
} }
@ -629,7 +626,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
args->_batch = &batch; args->_batch = &batch;
_gpuTimer->begin(batch); _gpuTimer->begin(batch);
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, shadowFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, shadowFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);

View file

@ -55,16 +55,9 @@ public:
static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters); static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters);
static void unsetLocalLightsBatch(gpu::Batch& batch); static void unsetLocalLightsBatch(gpu::Batch& batch);
// void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
// void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
// bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
private: private:
DeferredLightingEffect() = default; DeferredLightingEffect() = default;
// bool _shadowMapEnabled{ true }; // note that this value is overwritten in the ::configure method
// bool _ambientOcclusionEnabled{ false };
graphics::MeshPointer _pointLightMesh; graphics::MeshPointer _pointLightMesh;
graphics::MeshPointer getPointLightMesh(); graphics::MeshPointer getPointLightMesh();
graphics::MeshPointer _spotLightMesh; graphics::MeshPointer _spotLightMesh;
@ -150,8 +143,7 @@ public:
const HazeStage::FramePointer& hazeFrame, const HazeStage::FramePointer& hazeFrame,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource);
bool renderShadows);
}; };
class RenderDeferredLocals { class RenderDeferredLocals {
@ -168,7 +160,6 @@ public:
gpu::BufferView _localLightsBuffer; gpu::BufferView _localLightsBuffer;
RenderDeferredLocals(); RenderDeferredLocals();
}; };
@ -190,7 +181,7 @@ public:
using Config = RenderDeferredConfig; using Config = RenderDeferredConfig;
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>; using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;
RenderDeferred(bool renderShadows = false); RenderDeferred();
void configure(const Config& config); void configure(const Config& config);
@ -204,7 +195,6 @@ protected:
gpu::RangeTimerPointer _gpuTimer; gpu::RangeTimerPointer _gpuTimer;
private: private:
bool _renderShadows { false };
}; };
class DefaultLightingSetup { class DefaultLightingSetup {

View file

@ -163,8 +163,8 @@ class MakeLightingModelConfig : public render::Job::Config {
Q_PROPERTY(bool enableSkinning MEMBER enableSkinning NOTIFY dirty) Q_PROPERTY(bool enableSkinning MEMBER enableSkinning NOTIFY dirty)
Q_PROPERTY(bool enableBlendshape MEMBER enableBlendshape NOTIFY dirty) Q_PROPERTY(bool enableBlendshape MEMBER enableBlendshape NOTIFY dirty)
Q_PROPERTY(bool enableAmbientOcclusion MEMBER enableAmbientOcclusion NOTIFY dirty) Q_PROPERTY(bool enableAmbientOcclusion READ isAmbientOcclusionEnabled WRITE setAmbientOcclusion NOTIFY dirty)
Q_PROPERTY(bool enableShadow MEMBER enableShadow NOTIFY dirty) Q_PROPERTY(bool enableShadow READ isShadowEnabled WRITE setShadow NOTIFY dirty)
public: public:
@ -199,6 +199,14 @@ public:
bool enableAmbientOcclusion{ true }; bool enableAmbientOcclusion{ true };
bool enableShadow{ true }; bool enableShadow{ true };
void setAmbientOcclusion(bool enable) { enableAmbientOcclusion = enable; emit dirty();}
bool isAmbientOcclusionEnabled() const { return enableAmbientOcclusion; }
void setShadow(bool enable) {
enableShadow = enable; emit dirty();
}
bool isShadowEnabled() const { return enableShadow; }
signals: signals:
void dirty(); void dirty();
}; };

View file

@ -112,7 +112,7 @@ void RenderDeferredTask::configure(const Config& config) {
upsamplePrimaryBufferConfig->setProperty("factor", 1.0f / config.resolutionScale); upsamplePrimaryBufferConfig->setProperty("factor", 1.0f / config.resolutionScale);
} }
void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output, bool renderShadows) { void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
auto fadeEffect = DependencyManager::get<FadeEffect>(); auto fadeEffect = DependencyManager::get<FadeEffect>();
// Prepare the ShapePipelines // Prepare the ShapePipelines
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>(); ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
@ -139,8 +139,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto& spatialSelection = fetchedItems.get1(); const auto& spatialSelection = fetchedItems.get1();
// Lighting model comes next, the big configuration of the view
const auto& lightingModel = inputs[1];
// Extract the Lighting Stages Current frame ( and zones) // Extract the Lighting Stages Current frame ( and zones)
const auto lightingStageInputs = inputs.get1(); const auto& lightingStageInputs = inputs.get2();
// Fetch the current frame stacks from all the stages // Fetch the current frame stacks from all the stages
const auto currentStageFrames = lightingStageInputs.get0(); const auto currentStageFrames = lightingStageInputs.get0();
const auto lightFrame = currentStageFrames[0]; const auto lightFrame = currentStageFrames[0];
@ -151,11 +154,12 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto& zones = lightingStageInputs[1]; const auto& zones = lightingStageInputs[1];
// Shadow Task Outputs // Shadow Task Outputs
const auto shadowTaskOutputs = inputs.get2(); const auto& shadowTaskOutputs = inputs.get3();
// Shadow Stage Frame // Shadow Stage Frame
const auto shadowFrame = shadowTaskOutputs[1]; const auto shadowFrame = shadowTaskOutputs[1];
fadeEffect->build(task, opaques); fadeEffect->build(task, opaques);
const auto jitter = task.addJob<JitterSample>("JitterCam"); const auto jitter = task.addJob<JitterSample>("JitterCam");
@ -165,7 +169,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// Prepare deferred, generate the shared Deferred Frame Transform. Only valid with the scaled frame buffer // Prepare deferred, generate the shared Deferred Frame Transform. Only valid with the scaled frame buffer
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform", jitter); const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform", jitter);
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
const auto opaqueRangeTimer = task.addJob<BeginGPURangeTimer>("BeginOpaqueRangeTimer", "DrawOpaques"); const auto opaqueRangeTimer = task.addJob<BeginGPURangeTimer>("BeginOpaqueRangeTimer", "DrawOpaques");
@ -202,10 +205,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto scatteringResource = task.addJob<SubsurfaceScattering>("Scattering"); const auto scatteringResource = task.addJob<SubsurfaceScattering>("Scattering");
// AO job // AO job
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).asVarying(); const auto ambientOcclusionInputs = AmbientOcclusionEffect::Input(lightingModel, deferredFrameTransform, deferredFramebuffer, linearDepthTarget).asVarying();
const auto ambientOcclusionOutputs = task.addJob<AmbientOcclusionEffect>("AmbientOcclusion", ambientOcclusionInputs); const auto ambientOcclusionOutputs = task.addJob<AmbientOcclusionEffect>("AmbientOcclusion", ambientOcclusionInputs);
const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(0); const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(0);
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(1); const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(1);
// Velocity // Velocity
const auto velocityBufferInputs = VelocityBufferPass::Inputs(deferredFrameTransform, deferredFramebuffer).asVarying(); const auto velocityBufferInputs = VelocityBufferPass::Inputs(deferredFrameTransform, deferredFramebuffer).asVarying();
@ -220,7 +223,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// 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, lightFrame, shadowFrame, hazeFrame).asVarying(); surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, lightFrame, shadowFrame, hazeFrame).asVarying();
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs, renderShadows); task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
// 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
const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying();

View file

@ -137,14 +137,14 @@ signals:
class RenderDeferredTask { class RenderDeferredTask {
public: public:
using Input = render::VaryingSet3<RenderFetchCullSortTask::Output, AssembleLightingStageTask::Output, RenderShadowTask::Output>; using Input = render::VaryingSet4<RenderFetchCullSortTask::Output, LightingModelPointer, AssembleLightingStageTask::Output, RenderShadowTask::Output>;
using Config = RenderDeferredTaskConfig; using Config = RenderDeferredTaskConfig;
using JobModel = render::Task::ModelI<RenderDeferredTask, Input, Config>; using JobModel = render::Task::ModelI<RenderDeferredTask, Input, Config>;
RenderDeferredTask(); RenderDeferredTask();
void configure(const Config& config); void configure(const Config& config);
void build(JobModel& task, const render::Varying& input, render::Varying& output, bool renderShadows); void build(JobModel& task, const render::Varying& input, render::Varying& output);
private: private:
}; };

View file

@ -54,8 +54,10 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
// const auto& items = fetchedItems[0]; // const auto& items = fetchedItems[0];
const auto& items = fetchedItems.get0(); const auto& items = fetchedItems.get0();
// Lighting model comes next, the big configuration of the view
const auto& lightingModel = inputs.get1();
const auto& lightingStageInputs = inputs.get1(); const auto& lightingStageInputs = inputs.get2();
// Fetch the current frame stacks from all the stages // Fetch the current frame stacks from all the stages
const auto& currentStageFrames = lightingStageInputs.get0(); const auto& currentStageFrames = lightingStageInputs.get0();
const auto& lightFrame = currentStageFrames[0]; const auto& lightFrame = currentStageFrames[0];
@ -91,7 +93,6 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
// Prepare objects shared by several jobs // Prepare objects shared by several jobs
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform"); const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
// 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);

View file

@ -19,7 +19,7 @@
class RenderForwardTask { class RenderForwardTask {
public: public:
using Input = render::VaryingSet2<RenderFetchCullSortTask::Output, AssembleLightingStageTask::Output>; using Input = render::VaryingSet3<RenderFetchCullSortTask::Output, LightingModelPointer, AssembleLightingStageTask::Output>;
using JobModel = render::Task::ModelI<RenderForwardTask, Input>; using JobModel = render::Task::ModelI<RenderForwardTask, Input>;
RenderForwardTask() {} RenderForwardTask() {}

View file

@ -59,11 +59,14 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
// 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 // 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 // Fetch the current frame stacks from all the stages
// Starting with the Light Frame genreated in previous tasks // Starting with the Light Frame genreated in previous tasks
const auto& lightFrame = input;
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", lightFrame); const auto& lightFrame = input.getN<Input>(0);
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Outputs>(3); const auto& lightingModel = input.getN<Input>(1);
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", input);
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Output>(1);
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Output>(3);
// Fetch and cull the items from the scene // Fetch and cull the items from the scene
static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask); static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask);
@ -75,7 +78,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
// Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not // Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not
// frustum culling or this will make shadow casters out of the camera frustum disappear. // frustum culling or this will make shadow casters out of the camera frustum disappear.
const auto cameraFrustum = setupOutput.getN<RenderShadowSetup::Outputs>(2); const auto cameraFrustum = setupOutput.getN<RenderShadowSetup::Output>(2);
const auto applyFunctorInputs = ApplyCullFunctorOnItemBounds::Inputs(shadowItems, cameraFrustum).asVarying(); const auto applyFunctorInputs = ApplyCullFunctorOnItemBounds::Inputs(shadowItems, cameraFrustum).asVarying();
const auto culledShadowItems = task.addJob<ApplyCullFunctorOnItemBounds>("ShadowCullCamera", applyFunctorInputs, cameraCullFunctor); const auto culledShadowItems = task.addJob<ApplyCullFunctorOnItemBounds>("ShadowCullCamera", applyFunctorInputs, cameraCullFunctor);
@ -122,7 +125,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
task.addJob<RenderShadowTeardown>("ShadowTeardown", setupOutput); task.addJob<RenderShadowTeardown>("ShadowTeardown", setupOutput);
output = Output(cascadeSceneBBoxes, setupOutput.getN<RenderShadowSetup::Outputs>(3)); output = Output(cascadeSceneBBoxes, setupOutput.getN<RenderShadowSetup::Output>(3));
} }
@ -341,12 +344,19 @@ 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, const Inputs& input, Outputs& output) { void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Input& input, Output& 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>();
auto lightFrame = *input;
assert(lightStage); assert(lightStage);
if (!lightStage->getCurrentKeyLight(lightFrame) || !lightStage->getCurrentKeyLight(lightFrame)->getCastShadows()) {
const auto lightFrame = *input.get0();
const auto lightingModel = input.get1();
// Clear previous shadow frame always
_shadowFrameCache->_objects.clear();
output.edit3() = _shadowFrameCache;
if (!lightingModel->isShadowEnabled() || !lightStage->getCurrentKeyLight(lightFrame) || !lightStage->getCurrentKeyLight(lightFrame)->getCastShadows()) {
renderContext->taskFlow.abortTask(); renderContext->taskFlow.abortTask();
return; return;
} }
@ -360,16 +370,12 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
*_cameraFrustum = args->getViewFrustum(); *_cameraFrustum = args->getViewFrustum();
output.edit2() = _cameraFrustum; output.edit2() = _cameraFrustum;
// Clear previous shadow frame
if (!_globalShadowObject) { if (!_globalShadowObject) {
_globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.f, 4); _globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.f, 4);
} }
_shadowFrameCache->_objects.clear();
const auto theGlobalLight = lightStage->getCurrentKeyLight(lightFrame); const auto theGlobalLight = lightStage->getCurrentKeyLight(lightFrame);
if (theGlobalLight && theGlobalLight->getCastShadows()) { if (theGlobalLight && theGlobalLight->getCastShadows()) {
//const auto theGlobalShadow = lightStage->getCurrentKeyShadow(lightFrame);
//if (theGlobalShadow) {
_globalShadowObject->setLight(theGlobalLight); _globalShadowObject->setLight(theGlobalLight);
_globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); _globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
@ -435,8 +441,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
queryResolution.x = int(queryResolution.x * _coarseShadowFrustum->getWidth() / firstCascadeFrustum->getWidth()); queryResolution.x = int(queryResolution.x * _coarseShadowFrustum->getWidth() / firstCascadeFrustum->getWidth());
queryResolution.y = int(queryResolution.y * _coarseShadowFrustum->getHeight() / firstCascadeFrustum->getHeight()); queryResolution.y = int(queryResolution.y * _coarseShadowFrustum->getHeight() / firstCascadeFrustum->getHeight());
output.edit1() = queryResolution; output.edit1() = queryResolution;
output.edit3() = _shadowFrameCache;
} }
} }

View file

@ -19,6 +19,7 @@
#include "Shadows_shared.slh" #include "Shadows_shared.slh"
#include "LightingModel.h"
#include "LightStage.h" #include "LightStage.h"
class ViewFrustum; class ViewFrustum;
@ -36,10 +37,12 @@ protected:
unsigned int _cascadeIndex; unsigned int _cascadeIndex;
}; };
class RenderShadowTaskConfig : public render::Task::Config::Persistent { //class RenderShadowTaskConfig : public render::Task::Config::Persistent {
class RenderShadowTaskConfig : public render::Task::Config {
Q_OBJECT Q_OBJECT
public: public:
RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", true) {} // RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", true) {}
RenderShadowTaskConfig() {}
signals: signals:
void dirty(); void dirty();
@ -49,7 +52,7 @@ class RenderShadowTask {
public: public:
// There is one AABox per shadow cascade // There is one AABox per shadow cascade
using Input = LightStage::FramePointer; using Input = render::VaryingSet2<LightStage::FramePointer, LightingModelPointer>;
using Output = render::VaryingSet2<render::VaryingArray<AABox, SHADOW_CASCADE_MAX_COUNT>, LightStage::ShadowFramePointer>; using Output = render::VaryingSet2<render::VaryingArray<AABox, SHADOW_CASCADE_MAX_COUNT>, LightStage::ShadowFramePointer>;
using Config = RenderShadowTaskConfig; using Config = RenderShadowTaskConfig;
using JobModel = render::Task::ModelIO<RenderShadowTask, Input, Output, Config>; using JobModel = render::Task::ModelIO<RenderShadowTask, Input, Output, Config>;
@ -100,14 +103,14 @@ signals:
class RenderShadowSetup { class RenderShadowSetup {
public: public:
using Inputs = LightStage::FramePointer; using Input = RenderShadowTask::Input;
using Outputs = render::VaryingSet4<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer, LightStage::ShadowFramePointer>; using Output = render::VaryingSet4<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer, LightStage::ShadowFramePointer>;
using Config = RenderShadowSetupConfig; using Config = RenderShadowSetupConfig;
using JobModel = render::Job::ModelIO<RenderShadowSetup, Inputs, Outputs, Config>; using JobModel = render::Job::ModelIO<RenderShadowSetup, Input, Output, Config>;
RenderShadowSetup(); RenderShadowSetup();
void configure(const Config& configuration); void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output); void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
private: private:
@ -151,7 +154,7 @@ public:
class RenderShadowTeardown { class RenderShadowTeardown {
public: public:
using Input = RenderShadowSetup::Outputs; using Input = RenderShadowSetup::Output;
using JobModel = render::Job::ModelI<RenderShadowTeardown, Input>; using JobModel = render::Job::ModelI<RenderShadowTeardown, Input>;
void run(const render::RenderContextPointer& renderContext, const Input& input); void run(const render::RenderContextPointer& renderContext, const Input& input);
}; };

View file

@ -16,24 +16,25 @@
#include "RenderForwardTask.h" #include "RenderForwardTask.h"
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) { void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) {
// auto items = input.get<Input>();
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask); const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
assert(items.canCast<RenderFetchCullSortTask::Output>()); assert(items.canCast<RenderFetchCullSortTask::Output>());
// const auto lightingStageFramesAndZones = task.addJob<AssembleLightingStageTask>("AssembleStages", items[0]); // Issue the lighting model, aka the big global settings for the view
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
// Assemble the lighting stages current frames
const auto lightingStageFramesAndZones = task.addJob<AssembleLightingStageTask>("AssembleStages", items); const auto lightingStageFramesAndZones = task.addJob<AssembleLightingStageTask>("AssembleStages", items);
if (isDeferred) { if (isDeferred) {
// Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling // Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling
// is performed, then casters not in the view frustum will be removed, which is not what we wish. // is performed, then casters not in the view frustum will be removed, which is not what we wish.
const auto& ligthStageFrame = lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0]; const auto shadowTaskIn = RenderShadowTask::Input(lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0], lightingModel).asVarying();
const auto cascadeSceneBBoxes = task.addJob<RenderShadowTask>("RenderShadowTask", ligthStageFrame, cullFunctor, tagBits, tagMask); const auto shadowTaskOut = task.addJob<RenderShadowTask>("RenderShadowTask", shadowTaskIn, cullFunctor, tagBits, tagMask);
const auto renderInput = RenderDeferredTask::Input(items, lightingStageFramesAndZones, cascadeSceneBBoxes).asVarying(); const auto renderInput = RenderDeferredTask::Input(items, lightingModel, lightingStageFramesAndZones, shadowTaskOut).asVarying();
task.addJob<RenderDeferredTask>("RenderDeferredTask", renderInput, true); task.addJob<RenderDeferredTask>("RenderDeferredTask", renderInput);
} else { } else {
const auto renderInput = RenderForwardTask::Input(items, lightingStageFramesAndZones).asVarying(); const auto renderInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
task.addJob<RenderForwardTask>("Forward", renderInput); task.addJob<RenderForwardTask>("Forward", renderInput);
} }
} }

View file

@ -48,7 +48,7 @@ Rectangle {
"Lightmap:LightingModel:enableLightmap", "Lightmap:LightingModel:enableLightmap",
"Background:LightingModel:enableBackground", "Background:LightingModel:enableBackground",
"Haze:LightingModel:enableHaze", "Haze:LightingModel:enableHaze",
"ssao:AmbientOcclusion:enabled", "ssao:LightingModel:enableAmbientOcclusion",
"Textures:LightingModel:enableMaterialTexturing" "Textures:LightingModel:enableMaterialTexturing"
] ]
HifiControls.CheckBox { HifiControls.CheckBox {
@ -93,9 +93,7 @@ Rectangle {
"Spot:LightingModel:enableSpotLight", "Spot:LightingModel:enableSpotLight",
"Light Contour:LightingModel:showLightContour", "Light Contour:LightingModel:showLightContour",
"Zone Stack:DrawZoneStack:enabled", "Zone Stack:DrawZoneStack:enabled",
"Shadow:RenderShadowTask:enabled", "Shadow:LightingModel:enableShadow"
"Shadowning:LightingModel:enableShadow",
"AmbientOcclusioning:LightingModel:enableAmbientOcclusion"
] ]
HifiControls.CheckBox { HifiControls.CheckBox {
boxSize: 20 boxSize: 20

View file

@ -0,0 +1,13 @@
function openEngineTaskView() {
// Set up the qml ui
var qml = Script.resolvePath('engineList.qml');
var window = new OverlayWindow({
title: 'Render Engine',
source: qml,
width: 300,
height: 400
});
window.setPosition(200, 50);
//window.closed.connect(function() { Script.stop(); });
}
openEngineTaskView();

View file

@ -0,0 +1,30 @@
//
// engineList.qml
//
// Created by Sam Gateau on 12/3/2018
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import stylesUit 1.0
import controlsUit 1.0 as HifiControls
import "../lib/jet/qml" as Jet
Item {
HifiConstants { id: hifi;}
id: render;
anchors.fill: parent
property var mainViewTask: Render.getConfig("RenderMainView")
Jet.TaskList {
rootConfig: Render
anchors.fill: render
}
}

View file

@ -0,0 +1,130 @@
"use strict";
//
// holo.js
//
// Created by Sam Gateau on 2018-12-17
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
// Function Name: inFrontOf()
//
// Description:
// -Returns the position in front of the given "position" argument, where the forward vector is based off
// the "orientation" argument and the amount in front is based off the "distance" argument.
function inFrontOf(distance, position, orientation) {
return Vec3.sum(position || MyAvatar.position,
Vec3.multiply(distance, Quat.getForward(orientation || MyAvatar.orientation)));
}
//*****************************************************
// Holo
//*****************************************************
function Holo(config) {
this.baseEntityProperties = {
name: "Holo-base",
//"collisionless": false,
"color": {
"blue": 239,
"green": 180,
"red": 0
},
"dimensions": {
"x": 10,
"y": 0.1,
"z": 10,
},
"grab": {
"grabbable": false,
},
// "ignoreForCollisions": false,
type: "Shape",
shape: "Cylinder",
shapeType:"box",
"position": inFrontOf(8, Vec3.sum(MyAvatar.position, { x: 0, y: -1, z: 0 })),
"rotation": Quat.multiply(MyAvatar.orientation, { w: 0, x: 0, y: 1, z: 0 }),
lifetime: config.lifetime,
}
this.baseEntity = Entities.addEntity( this.baseEntityProperties );
this.baseEntityProperties = Entities.getEntityProperties(this.baseEntity);
this.screenEntityProperties = {
name: "Holo-screen",
"collisionless": true,
"color": {
"blue": 239,
"red": 180,
"green": 0
},
"dimensions": {
"x": 5,
"y": 0.1,
"z": 5,
},
"grab": {
"grabbable": false,
},
"ignoreForCollisions": true,
type: "Shape",
shape: "Cylinder",
"position": inFrontOf(8, Vec3.sum(MyAvatar.position, { x: 0, y: -0.9, z: 0 })),
"rotation": Quat.multiply(MyAvatar.orientation, { w: 0, x: 0, y: 1, z: 0 }),
lifetime: config.lifetime,
}
this.screenEntity = Entities.addEntity( this.screenEntityProperties );
this.screenEntityProperties = Entities.getEntityProperties(this.screenEntity);
var DIM = {x: 5.0, y: 5.0, z: 0.0};
this.screen = Overlays.addOverlay("image3d", {
url: "resource://spectatorCameraFrame",
emissive: true,
parentID: this.screenEntity,
alpha: 1,
localRotation: { w: 1, x: 0, y: 0, z: 0 },
localPosition: { x: 0, y: 4.0, z: 0.0 },
dimensions: DIM,
lifetime: config.lifetime,
});
}
Holo.prototype.kill = function () {
if (this.baseEntity) {
Entities.deleteEntity(this.baseEntity);
// this.entity = null
}
if (this.screenEntity) {
Entities.deleteEntity(this.screenEntity);
// this.entity = null
}
if (this.screen) {
Overlays.deleteOverlay(this.view);
}
};
//*****************************************************
// Exe
//*****************************************************
var holo;
function shutdown() {
if (holo) {
holo.kill();
}
}
function startup() {
holo = new Holo({ lifetime: 60});
}
startup();
Script.scriptEnding.connect(shutdown);
}());