Shadow is working correctly in both pipelines

This commit is contained in:
Sam Gateau 2018-12-17 00:27:07 -08:00
parent a4b9ec50e9
commit 318bf20ede
9 changed files with 80 additions and 54 deletions

View file

@ -100,7 +100,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
// Do we need to allocate the light in the stage ?
if (LightStage::isIndexInvalid(_sunIndex)) {
_sunIndex = _stage->addLight(_sunLight);
_shadowIndex = _stage->addShadow(_sunIndex, SUN_SHADOW_MAX_DISTANCE, SUN_SHADOW_CASCADE_COUNT);
// _shadowIndex = _stage->addShadow(_sunIndex, SUN_SHADOW_MAX_DISTANCE, SUN_SHADOW_CASCADE_COUNT);
} else {
_stage->updateLightArrayBuffer(_sunIndex);
}

View file

@ -303,8 +303,6 @@ AmbientOcclusionEffect::AmbientOcclusionEffect() {
}
void AmbientOcclusionEffect::configure(const Config& config) {
DependencyManager::get<DeferredLightingEffect>()->setAmbientOcclusionEnabled(config.isEnabled());
bool shouldUpdateBlurs = false;
bool shouldUpdateTechnique = false;

View file

@ -405,7 +405,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch.setResourceTexture(ru::Texture::DeferredDepth, deferredFramebuffer->getPrimaryDepthTexture());
// FIXME: Different render modes should have different tasks
if (args->_renderMode == RenderArgs::DEFAULT_RENDER_MODE && deferredLightingEffect->isAmbientOcclusionEnabled() && ambientOcclusionFramebuffer) {
if (lightingModel->isAmbientOcclusionEnabled() && ambientOcclusionFramebuffer) {
batch.setResourceTexture(ru::Texture::DeferredObscurance, ambientOcclusionFramebuffer->getOcclusionTexture());
} else {
// need to assign the white texture if ao is off
@ -430,28 +430,23 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch.setResourceTexture(ru::Texture::SsscSpecularBeckmann, subsurfaceScatteringResource->getScatteringSpecular());
}
// Global directional light and ambient pass
// Global directional light, maybe shadow and ambient pass
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
assert(lightStage->getNumLights() > 0);
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame);
//const auto& globalShadow = lightAndShadow.second;
auto keyLight = lightStage->getCurrentKeyLight(*lightFrame);
// Check if keylight casts shadows
bool keyLightCastShadows{ false };
LightStage::ShadowPointer globalShadow;
if (shadowFrame && !shadowFrame->_objects.empty()) {
if (lightingModel->isShadowEnabled() && shadowFrame && !shadowFrame->_objects.empty()) {
globalShadow = shadowFrame->_objects.front();
if (globalShadow) {
keyLightCastShadows = true;
}
}
// Bind the shadow buffers
if (globalShadow) {
batch.setResourceTexture(ru::Texture::Shadow, globalShadow->map);
}
auto program = deferredLightingEffect->_directionalSkyboxLight;
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
auto keyLight = lightAndShadow.first;
// Global Ambient light
graphics::LightPointer ambientLight;
if (lightStage && lightFrame->_ambientLights.size()) {
ambientLight = lightStage->getLight(lightFrame->_ambientLights.front());
@ -459,18 +454,10 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
bool hasAmbientMap = (ambientLight != nullptr);
// Setup the global directional pass pipeline
auto program = deferredLightingEffect->_directionalSkyboxLight;
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
{
// Check if keylight casts shadows
bool keyLightCastShadows { false };
if (renderShadows && lightStage && lightFrame->_sunLights.size()) {
graphics::LightPointer keyLight = lightStage->getLight(lightFrame->_sunLights.front());
if (keyLight) {
keyLightCastShadows = keyLight->getCastShadows();
}
}
if (deferredLightingEffect->_shadowMapEnabled && keyLightCastShadows) {
if (keyLightCastShadows) {
// If the keylight has an ambient Map then use the Skybox version of the pass
// otherwise use the ambient sphere version
@ -493,7 +480,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
}
}
if (locations->shadowTransform && globalShadow) {
if (keyLightCastShadows && globalShadow) {
batch.setResourceTexture(ru::Texture::Shadow, globalShadow->map);
batch.setUniformBuffer(ru::Buffer::ShadowParams, globalShadow->getBuffer());
}
@ -515,10 +503,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch.draw(gpu::TRIANGLE_STRIP, 4);
deferredLightingEffect->unsetKeyLightBatch(batch);
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
batch.setResourceTexture(ru::Texture::Shadow +i, nullptr);
}
batch.setResourceTexture(ru::Texture::Shadow, nullptr);
}
}
@ -702,7 +687,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
// Add the global light to the light stage (for later shadow rendering)
// Set this light to be the default
_defaultLightID = lightStage->addLight(lp, true);
lightStage->addShadow(_defaultLightID);
// lightStage->addShadow(_defaultLightID);
}
auto backgroundStage = renderContext->_scene->getStage<BackgroundStage>();

View file

@ -55,15 +55,15 @@ 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; }
// 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 };
// bool _shadowMapEnabled{ true }; // note that this value is overwritten in the ::configure method
// bool _ambientOcclusionEnabled{ false };
graphics::MeshPointer _pointLightMesh;
graphics::MeshPointer getPointLightMesh();

View file

@ -187,6 +187,24 @@ bool LightingModel::isBlendshapeEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().enableBlendshape;
}
void LightingModel::setAmbientOcclusion(bool enable) {
if (enable != isAmbientOcclusionEnabled()) {
_parametersBuffer.edit<Parameters>().enableAmbientOcclusion = (float)enable;
}
}
bool LightingModel::isAmbientOcclusionEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().enableAmbientOcclusion;
}
void LightingModel::setShadow(bool enable) {
if (enable != isShadowEnabled()) {
_parametersBuffer.edit<Parameters>().enableShadow = (float)enable;
}
}
bool LightingModel::isShadowEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().enableShadow;
}
MakeLightingModel::MakeLightingModel() {
_lightingModel = std::make_shared<LightingModel>();
}
@ -218,6 +236,9 @@ void MakeLightingModel::configure(const Config& config) {
_lightingModel->setSkinning(config.enableSkinning);
_lightingModel->setBlendshape(config.enableBlendshape);
_lightingModel->setAmbientOcclusion(config.enableAmbientOcclusion);
_lightingModel->setShadow(config.enableShadow);
}
void MakeLightingModel::run(const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) {

View file

@ -76,6 +76,12 @@ public:
void setBlendshape(bool enable);
bool isBlendshapeEnabled() const;
void setAmbientOcclusion(bool enable);
bool isAmbientOcclusionEnabled() const;
void setShadow(bool enable);
bool isShadowEnabled() const;
UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
protected:
@ -112,6 +118,11 @@ protected:
float enableSkinning{ 1.0f };
float enableBlendshape{ 1.0f };
float enableAmbientOcclusion{ 0.0f };
float enableShadow{ 1.0f };
float spare1{ 1.0f };
float spare2{ 1.0f };
Parameters() {}
};
UniformBufferView _parametersBuffer;
@ -152,6 +163,10 @@ 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)
public:
MakeLightingModelConfig() : render::Job::Config() {} // Make Lighting Model is always on
@ -181,6 +196,9 @@ public:
bool enableSkinning{ true };
bool enableBlendshape{ true };
bool enableAmbientOcclusion{ true };
bool enableShadow{ true };
signals:
void dirty();
};

View file

@ -39,7 +39,7 @@ using namespace render;
extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
void RenderShadowTask::configure(const Config& configuration) {
DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.isEnabled());
//DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.isEnabled());
// This is a task, so must still propogate configure() to its Jobs
// Task::configure(configuration);
}
@ -112,7 +112,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
// GPU jobs: Render to shadow map
sprintf(jobName, "RenderShadowMap%d", i);
const auto shadowInputs = RenderShadowMap::Inputs(culledShadowItemsAndBounds.getN<CullShadowBounds::Outputs>(0),
culledShadowItemsAndBounds.getN<CullShadowBounds::Outputs>(1), lightFrame).asVarying();
culledShadowItemsAndBounds.getN<CullShadowBounds::Outputs>(1), shadowFrame).asVarying();
task.addJob<RenderShadowMap>(jobName, shadowInputs, shapePlumber, i);
sprintf(jobName, "ShadowCascadeTeardown%d", i);
task.addJob<RenderShadowCascadeTeardown>(jobName, shadowFilter);
@ -214,12 +214,12 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
const auto& inShapes = inputs.get0();
const auto& inShapeBounds = inputs.get1();
const auto& lightFrame = inputs.get2();
const auto& shadowFrame = inputs.get2();
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
auto shadow = lightStage->getCurrentKeyShadow(*lightFrame);
LightStage::ShadowPointer shadow;
if (shadowFrame && !shadowFrame->_objects.empty()) {
shadow = shadowFrame->_objects.front();
}
if (!shadow || _cascadeIndex >= shadow->getCascadeCount()) {
return;
}
@ -362,13 +362,15 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
// Clear previous shadow frame
if (!_globalShadowObject) {
_globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.0f);
_globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.f, 4);
}
_shadowFrameCache->_objects.clear();
const auto theGlobalShadow = lightStage->getCurrentKeyShadow(lightFrame);
if (theGlobalShadow) {
_globalShadowObject->setLight(theGlobalShadow->getLight());
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);
auto& firstCascade = _globalShadowObject->getCascade(0);

View file

@ -25,7 +25,7 @@ class ViewFrustum;
class RenderShadowMap {
public:
using Inputs = render::VaryingSet3<render::ShapeBounds, AABox, LightStage::FramePointer>;
using Inputs = render::VaryingSet3<render::ShapeBounds, AABox, LightStage::ShadowFramePointer>;
using JobModel = render::Job::ModelI<RenderShadowMap, Inputs>;
RenderShadowMap(render::ShapePlumberPointer shapePlumber, unsigned int cascadeIndex) : _shapePlumber{ shapePlumber }, _cascadeIndex{ cascadeIndex } {}

View file

@ -93,7 +93,9 @@ Rectangle {
"Spot:LightingModel:enableSpotLight",
"Light Contour:LightingModel:showLightContour",
"Zone Stack:DrawZoneStack:enabled",
"Shadow:RenderShadowTask:enabled"
"Shadow:RenderShadowTask:enabled",
"Shadowning:LightingModel:enableShadow",
"AmbientOcclusioning:LightingModel:enableAmbientOcclusion"
]
HifiControls.CheckBox {
boxSize: 20