mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-14 21:16:42 +02:00
171 lines
5.9 KiB
C++
171 lines
5.9 KiB
C++
//
|
|
// RenderShadowTask.h
|
|
// render-utils/src/
|
|
//
|
|
// Created by Zach Pomerantz on 1/7/2016.
|
|
// Copyright 2016 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
|
|
//
|
|
|
|
#ifndef hifi_RenderShadowTask_h
|
|
#define hifi_RenderShadowTask_h
|
|
|
|
#include <gpu/Framebuffer.h>
|
|
#include <gpu/Pipeline.h>
|
|
|
|
#include <render/CullTask.h>
|
|
|
|
#include "Shadows_shared.slh"
|
|
|
|
#include "LightingModel.h"
|
|
#include "LightStage.h"
|
|
|
|
class ViewFrustum;
|
|
|
|
class RenderShadowMap {
|
|
public:
|
|
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 } {}
|
|
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
|
|
|
protected:
|
|
render::ShapePlumberPointer _shapePlumber;
|
|
unsigned int _cascadeIndex;
|
|
};
|
|
|
|
//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() {}
|
|
|
|
signals:
|
|
void dirty();
|
|
};
|
|
|
|
class RenderShadowTask {
|
|
public:
|
|
|
|
// There is one AABox per shadow cascade
|
|
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>;
|
|
|
|
RenderShadowTask() {}
|
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cameraCullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
|
|
|
void configure(const Config& configuration);
|
|
|
|
struct CullFunctor {
|
|
float _minSquareSize{ 0.0f };
|
|
|
|
bool operator()(const RenderArgs* args, const AABox& bounds) const {
|
|
// Cull only objects that are too small relatively to shadow frustum
|
|
const auto boundsSquareRadius = glm::dot(bounds.getDimensions(), bounds.getDimensions());
|
|
return boundsSquareRadius > _minSquareSize;
|
|
}
|
|
};
|
|
|
|
CullFunctor _cullFunctor;
|
|
|
|
};
|
|
|
|
class RenderShadowSetupConfig : public render::Job::Config {
|
|
Q_OBJECT
|
|
Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty)
|
|
Q_PROPERTY(float constantBias1 MEMBER constantBias1 NOTIFY dirty)
|
|
Q_PROPERTY(float constantBias2 MEMBER constantBias2 NOTIFY dirty)
|
|
Q_PROPERTY(float constantBias3 MEMBER constantBias3 NOTIFY dirty)
|
|
Q_PROPERTY(float slopeBias0 MEMBER slopeBias0 NOTIFY dirty)
|
|
Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty)
|
|
Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty)
|
|
Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty)
|
|
public:
|
|
|
|
float constantBias0{ 0.15f };
|
|
float constantBias1{ 0.15f };
|
|
float constantBias2{ 0.175f };
|
|
float constantBias3{ 0.2f };
|
|
float slopeBias0{ 0.6f };
|
|
float slopeBias1{ 0.6f };
|
|
float slopeBias2{ 0.7f };
|
|
float slopeBias3{ 0.82f };
|
|
|
|
signals:
|
|
void dirty();
|
|
};
|
|
|
|
class RenderShadowSetup {
|
|
public:
|
|
using Input = RenderShadowTask::Input;
|
|
using Output = render::VaryingSet5<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer, LightStage::ShadowFramePointer, graphics::LightPointer>;
|
|
using Config = RenderShadowSetupConfig;
|
|
using JobModel = render::Job::ModelIO<RenderShadowSetup, Input, Output, Config>;
|
|
|
|
RenderShadowSetup();
|
|
void configure(const Config& configuration);
|
|
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
|
|
|
private:
|
|
|
|
ViewFrustumPointer _cameraFrustum;
|
|
ViewFrustumPointer _coarseShadowFrustum;
|
|
struct {
|
|
float _constant;
|
|
float _slope;
|
|
} _bias[SHADOW_CASCADE_MAX_COUNT];
|
|
|
|
LightStage::ShadowFrame::Object _globalShadowObject;
|
|
LightStage::ShadowFramePointer _shadowFrameCache;
|
|
|
|
void setConstantBias(int cascadeIndex, float value);
|
|
void setSlopeBias(int cascadeIndex, float value);
|
|
};
|
|
|
|
class RenderShadowCascadeSetup {
|
|
public:
|
|
using Inputs = LightStage::ShadowFramePointer;
|
|
using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
|
|
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
|
|
|
|
RenderShadowCascadeSetup(unsigned int cascadeIndex, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) :
|
|
_cascadeIndex(cascadeIndex), _tagBits(tagBits), _tagMask(tagMask) {}
|
|
|
|
void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output);
|
|
|
|
private:
|
|
unsigned int _cascadeIndex;
|
|
uint8_t _tagBits { 0x00 };
|
|
uint8_t _tagMask { 0x00 };
|
|
};
|
|
|
|
class RenderShadowCascadeTeardown {
|
|
public:
|
|
using Input = render::ItemFilter;
|
|
using JobModel = render::Job::ModelI<RenderShadowCascadeTeardown, Input>;
|
|
void run(const render::RenderContextPointer& renderContext, const Input& input);
|
|
};
|
|
|
|
class RenderShadowTeardown {
|
|
public:
|
|
using Input = RenderShadowSetup::Output;
|
|
using JobModel = render::Job::ModelI<RenderShadowTeardown, Input>;
|
|
void run(const render::RenderContextPointer& renderContext, const Input& input);
|
|
};
|
|
|
|
class CullShadowBounds {
|
|
public:
|
|
using Inputs = render::VaryingSet5<render::ShapeBounds, render::ItemFilter, ViewFrustumPointer, graphics::LightPointer, RenderShadowTask::CullFunctor>;
|
|
using Outputs = render::VaryingSet2<render::ShapeBounds, AABox>;
|
|
using JobModel = render::Job::ModelIO<CullShadowBounds, Inputs, Outputs>;
|
|
|
|
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
|
};
|
|
|
|
#endif // hifi_RenderShadowTask_h
|