mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 12:04:25 +02:00
Shadows are completely working with settings on both pipeline
This commit is contained in:
parent
5a6f30b458
commit
237fb4dc4c
18 changed files with 284 additions and 96 deletions
|
@ -1,16 +1,2 @@
|
|||
{
|
||||
"RenderMainView": {
|
||||
"RenderShadowTask": {
|
||||
"Enabled": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"RenderDeferredTask": {
|
||||
"AmbientOcclusion": {
|
||||
"Enabled": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "DeferredLightingEffect.h"
|
||||
#include "PickManager.h"
|
||||
|
||||
#include "LightingModel.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "RenderShadowTask.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
|
@ -393,14 +394,19 @@ Menu::Menu() {
|
|||
connect(action, &QAction::triggered, [action] {
|
||||
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
|
||||
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 (action->isChecked()) {
|
||||
mainViewShadowTaskConfig->setPreset("Enabled");
|
||||
} else {
|
||||
mainViewShadowTaskConfig->setPreset("None");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -408,14 +414,24 @@ Menu::Menu() {
|
|||
connect(action, &QAction::triggered, [action] {
|
||||
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
|
||||
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 (action->isChecked()) {
|
||||
mainViewAmbientOcclusionConfig->setPreset("Enabled");
|
||||
} else {
|
||||
mainViewAmbientOcclusionConfig->setPreset("None");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
const auto& frameTransform = inputs.get0();
|
||||
const auto& linearDepthFramebuffer = inputs.get2();
|
||||
const auto& lightingModel = input.get0();
|
||||
|
||||
if (!lightingModel->isAmbientOcclusionEnabled()) {
|
||||
output.edit0().reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& frameTransform = input.get1();
|
||||
const auto& linearDepthFramebuffer = input.get3();
|
||||
|
||||
const int resolutionLevel = _aoParametersBuffer->getResolutionLevel();
|
||||
const auto depthResolutionLevel = getDepthResolutionLevel();
|
||||
|
@ -629,8 +636,8 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
auto occlusionFBO = _framebuffer->getOcclusionFramebuffer();
|
||||
auto occlusionBlurredFBO = _framebuffer->getOcclusionBlurredFramebuffer();
|
||||
|
||||
outputs.edit0() = _framebuffer;
|
||||
outputs.edit1() = _aoParametersBuffer;
|
||||
output.edit0() = _framebuffer;
|
||||
output.edit1() = _aoParametersBuffer;
|
||||
|
||||
auto occlusionPipeline = getOcclusionPipeline();
|
||||
auto bilateralBlurPipeline = getBilateralBlurPipeline();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "render/DrawTask.h"
|
||||
|
||||
#include "LightingModel.h"
|
||||
#include "DeferredFrameTransform.h"
|
||||
#include "DeferredFramebuffer.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
|
@ -152,15 +153,15 @@ signals:
|
|||
|
||||
class AmbientOcclusionEffect {
|
||||
public:
|
||||
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
|
||||
using Outputs = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
|
||||
using Input = render::VaryingSet4<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
|
||||
using Output = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
|
||||
using Config = AmbientOcclusionEffectConfig;
|
||||
using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Inputs, Outputs, Config>;
|
||||
using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Input, Output, Config>;
|
||||
|
||||
AmbientOcclusionEffect();
|
||||
|
||||
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 AOParameters : public AmbientOcclusionParams {
|
||||
|
|
|
@ -378,8 +378,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
const HazeStage::FramePointer& hazeFrame,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource,
|
||||
bool renderShadows) {
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) {
|
||||
|
||||
auto args = renderContext->args;
|
||||
auto& batch = (*args->_batch);
|
||||
|
@ -596,9 +595,7 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex
|
|||
}
|
||||
}
|
||||
|
||||
RenderDeferred::RenderDeferred(bool renderShadows):
|
||||
_renderShadows(renderShadows)
|
||||
{
|
||||
RenderDeferred::RenderDeferred() {
|
||||
DependencyManager::get<DeferredLightingEffect>()->init();
|
||||
}
|
||||
|
||||
|
@ -629,7 +626,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
|
|||
args->_batch = &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);
|
||||
|
||||
|
|
|
@ -55,16 +55,9 @@ public:
|
|||
static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters);
|
||||
static void unsetLocalLightsBatch(gpu::Batch& batch);
|
||||
|
||||
// void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
// void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
// bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() = default;
|
||||
|
||||
// bool _shadowMapEnabled{ true }; // note that this value is overwritten in the ::configure method
|
||||
// bool _ambientOcclusionEnabled{ false };
|
||||
|
||||
graphics::MeshPointer _pointLightMesh;
|
||||
graphics::MeshPointer getPointLightMesh();
|
||||
graphics::MeshPointer _spotLightMesh;
|
||||
|
@ -150,8 +143,7 @@ public:
|
|||
const HazeStage::FramePointer& hazeFrame,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource,
|
||||
bool renderShadows);
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource);
|
||||
};
|
||||
|
||||
class RenderDeferredLocals {
|
||||
|
@ -168,7 +160,6 @@ public:
|
|||
gpu::BufferView _localLightsBuffer;
|
||||
|
||||
RenderDeferredLocals();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -190,7 +181,7 @@ public:
|
|||
using Config = RenderDeferredConfig;
|
||||
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;
|
||||
|
||||
RenderDeferred(bool renderShadows = false);
|
||||
RenderDeferred();
|
||||
|
||||
void configure(const Config& config);
|
||||
|
||||
|
@ -204,7 +195,6 @@ protected:
|
|||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
||||
private:
|
||||
bool _renderShadows { false };
|
||||
};
|
||||
|
||||
class DefaultLightingSetup {
|
||||
|
|
|
@ -163,8 +163,8 @@ class MakeLightingModelConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool enableSkinning MEMBER enableSkinning NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableBlendshape MEMBER enableBlendshape NOTIFY dirty)
|
||||
|
||||
Q_PROPERTY(bool enableAmbientOcclusion MEMBER enableAmbientOcclusion NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableShadow MEMBER enableShadow NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableAmbientOcclusion READ isAmbientOcclusionEnabled WRITE setAmbientOcclusion NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableShadow READ isShadowEnabled WRITE setShadow NOTIFY dirty)
|
||||
|
||||
|
||||
public:
|
||||
|
@ -199,6 +199,14 @@ public:
|
|||
bool enableAmbientOcclusion{ 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:
|
||||
void dirty();
|
||||
};
|
||||
|
|
|
@ -112,7 +112,7 @@ void RenderDeferredTask::configure(const Config& config) {
|
|||
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>();
|
||||
// Prepare the ShapePipelines
|
||||
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();
|
||||
|
||||
// Lighting model comes next, the big configuration of the view
|
||||
const auto& lightingModel = inputs[1];
|
||||
|
||||
// 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
|
||||
const auto currentStageFrames = lightingStageInputs.get0();
|
||||
const auto lightFrame = currentStageFrames[0];
|
||||
|
@ -151,11 +154,12 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto& zones = lightingStageInputs[1];
|
||||
|
||||
// Shadow Task Outputs
|
||||
const auto shadowTaskOutputs = inputs.get2();
|
||||
const auto& shadowTaskOutputs = inputs.get3();
|
||||
|
||||
// Shadow Stage Frame
|
||||
const auto shadowFrame = shadowTaskOutputs[1];
|
||||
|
||||
|
||||
fadeEffect->build(task, opaques);
|
||||
|
||||
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
|
||||
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform", jitter);
|
||||
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
||||
|
||||
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");
|
||||
|
||||
// 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 ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(0);
|
||||
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(1);
|
||||
const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(0);
|
||||
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(1);
|
||||
|
||||
// Velocity
|
||||
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
|
||||
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
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
|
||||
const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying();
|
||||
|
|
|
@ -137,14 +137,14 @@ signals:
|
|||
|
||||
class RenderDeferredTask {
|
||||
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 JobModel = render::Task::ModelI<RenderDeferredTask, Input, Config>;
|
||||
|
||||
RenderDeferredTask();
|
||||
|
||||
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:
|
||||
};
|
||||
|
|
|
@ -54,8 +54,10 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
|||
// const auto& items = fetchedItems[0];
|
||||
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
|
||||
const auto& currentStageFrames = lightingStageInputs.get0();
|
||||
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
|
||||
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
|
||||
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
||||
|
||||
// Filter zones from the general metas bucket
|
||||
// const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
class RenderForwardTask {
|
||||
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>;
|
||||
|
||||
RenderForwardTask() {}
|
||||
|
|
|
@ -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
|
||||
// Fetch the current frame stacks from all the stages
|
||||
// Starting with the Light Frame genreated in previous tasks
|
||||
const auto& lightFrame = input;
|
||||
|
||||
const auto& lightFrame = input.getN<Input>(0);
|
||||
|
||||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", lightFrame);
|
||||
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
|
||||
|
||||
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
|
||||
// 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 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);
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
auto lightFrame = *input;
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
@ -360,16 +370,12 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
|||
*_cameraFrustum = args->getViewFrustum();
|
||||
output.edit2() = _cameraFrustum;
|
||||
|
||||
// Clear previous shadow frame
|
||||
if (!_globalShadowObject) {
|
||||
_globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.f, 4);
|
||||
}
|
||||
_shadowFrameCache->_objects.clear();
|
||||
|
||||
const auto theGlobalLight = lightStage->getCurrentKeyLight(lightFrame);
|
||||
if (theGlobalLight && theGlobalLight->getCastShadows()) {
|
||||
//const auto theGlobalShadow = lightStage->getCurrentKeyShadow(lightFrame);
|
||||
//if (theGlobalShadow) {
|
||||
_globalShadowObject->setLight(theGlobalLight);
|
||||
_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.y = int(queryResolution.y * _coarseShadowFrustum->getHeight() / firstCascadeFrustum->getHeight());
|
||||
output.edit1() = queryResolution;
|
||||
|
||||
output.edit3() = _shadowFrameCache;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "Shadows_shared.slh"
|
||||
|
||||
#include "LightingModel.h"
|
||||
#include "LightStage.h"
|
||||
|
||||
class ViewFrustum;
|
||||
|
@ -36,10 +37,12 @@ protected:
|
|||
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
|
||||
public:
|
||||
RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", true) {}
|
||||
// RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", true) {}
|
||||
RenderShadowTaskConfig() {}
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -49,7 +52,7 @@ class RenderShadowTask {
|
|||
public:
|
||||
|
||||
// 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 Config = RenderShadowTaskConfig;
|
||||
using JobModel = render::Task::ModelIO<RenderShadowTask, Input, Output, Config>;
|
||||
|
@ -100,14 +103,14 @@ signals:
|
|||
|
||||
class RenderShadowSetup {
|
||||
public:
|
||||
using Inputs = LightStage::FramePointer;
|
||||
using Outputs = render::VaryingSet4<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer, LightStage::ShadowFramePointer>;
|
||||
using Input = RenderShadowTask::Input;
|
||||
using Output = render::VaryingSet4<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer, LightStage::ShadowFramePointer>;
|
||||
using Config = RenderShadowSetupConfig;
|
||||
using JobModel = render::Job::ModelIO<RenderShadowSetup, Inputs, Outputs, Config>;
|
||||
using JobModel = render::Job::ModelIO<RenderShadowSetup, Input, Output, Config>;
|
||||
|
||||
RenderShadowSetup();
|
||||
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:
|
||||
|
||||
|
@ -151,7 +154,7 @@ public:
|
|||
|
||||
class RenderShadowTeardown {
|
||||
public:
|
||||
using Input = RenderShadowSetup::Outputs;
|
||||
using Input = RenderShadowSetup::Output;
|
||||
using JobModel = render::Job::ModelI<RenderShadowTeardown, Input>;
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input);
|
||||
};
|
||||
|
|
|
@ -16,24 +16,25 @@
|
|||
#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) {
|
||||
// auto items = input.get<Input>();
|
||||
|
||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
|
||||
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);
|
||||
|
||||
if (isDeferred) {
|
||||
// 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.
|
||||
const auto& ligthStageFrame = lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0];
|
||||
const auto cascadeSceneBBoxes = task.addJob<RenderShadowTask>("RenderShadowTask", ligthStageFrame, cullFunctor, tagBits, tagMask);
|
||||
const auto shadowTaskIn = RenderShadowTask::Input(lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0], lightingModel).asVarying();
|
||||
const auto shadowTaskOut = task.addJob<RenderShadowTask>("RenderShadowTask", shadowTaskIn, cullFunctor, tagBits, tagMask);
|
||||
|
||||
const auto renderInput = RenderDeferredTask::Input(items, lightingStageFramesAndZones, cascadeSceneBBoxes).asVarying();
|
||||
task.addJob<RenderDeferredTask>("RenderDeferredTask", renderInput, true);
|
||||
const auto renderInput = RenderDeferredTask::Input(items, lightingModel, lightingStageFramesAndZones, shadowTaskOut).asVarying();
|
||||
task.addJob<RenderDeferredTask>("RenderDeferredTask", renderInput);
|
||||
} else {
|
||||
const auto renderInput = RenderForwardTask::Input(items, lightingStageFramesAndZones).asVarying();
|
||||
const auto renderInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
||||
task.addJob<RenderForwardTask>("Forward", renderInput);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ Rectangle {
|
|||
"Emissive:LightingModel:enableEmissive",
|
||||
"Lightmap:LightingModel:enableLightmap",
|
||||
"Background:LightingModel:enableBackground",
|
||||
"Haze:LightingModel:enableHaze",
|
||||
"ssao:AmbientOcclusion:enabled",
|
||||
"Haze:LightingModel:enableHaze",
|
||||
"ssao:LightingModel:enableAmbientOcclusion",
|
||||
"Textures:LightingModel:enableMaterialTexturing"
|
||||
]
|
||||
HifiControls.CheckBox {
|
||||
|
@ -93,9 +93,7 @@ Rectangle {
|
|||
"Spot:LightingModel:enableSpotLight",
|
||||
"Light Contour:LightingModel:showLightContour",
|
||||
"Zone Stack:DrawZoneStack:enabled",
|
||||
"Shadow:RenderShadowTask:enabled",
|
||||
"Shadowning:LightingModel:enableShadow",
|
||||
"AmbientOcclusioning:LightingModel:enableAmbientOcclusion"
|
||||
"Shadow:LightingModel:enableShadow"
|
||||
]
|
||||
HifiControls.CheckBox {
|
||||
boxSize: 20
|
||||
|
|
13
scripts/developer/utilities/render/engineList.js
Normal file
13
scripts/developer/utilities/render/engineList.js
Normal 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();
|
30
scripts/developer/utilities/render/engineList.qml
Normal file
30
scripts/developer/utilities/render/engineList.qml
Normal 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
|
||||
}
|
||||
}
|
130
scripts/developer/utilities/render/holo.js
Normal file
130
scripts/developer/utilities/render/holo.js
Normal 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);
|
||||
}());
|
Loading…
Reference in a new issue