mirror of
https://github.com/lubosz/overte.git
synced 2025-04-17 12:36:24 +02:00
one step closer
This commit is contained in:
parent
0b03012e5e
commit
a4b9ec50e9
6 changed files with 62 additions and 39 deletions
|
@ -436,7 +436,11 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
assert(lightStage);
|
||||
assert(lightStage->getNumLights() > 0);
|
||||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame);
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
//const auto& globalShadow = lightAndShadow.second;
|
||||
LightStage::ShadowPointer globalShadow;
|
||||
if (shadowFrame && !shadowFrame->_objects.empty()) {
|
||||
globalShadow = shadowFrame->_objects.front();
|
||||
}
|
||||
|
||||
// Bind the shadow buffers
|
||||
if (globalShadow) {
|
||||
|
@ -640,7 +644,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
|
|||
args->_batch = &batch;
|
||||
_gpuTimer->begin(batch);
|
||||
|
||||
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows);
|
||||
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, shadowFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows);
|
||||
|
||||
lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
|
||||
|
||||
|
|
|
@ -152,6 +152,11 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi
|
|||
setMaxDistance(maxDistance);
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setLight(graphics::LightPointer light) {
|
||||
_light = light;
|
||||
}
|
||||
|
||||
|
||||
void LightStage::Shadow::setMaxDistance(float value) {
|
||||
// This overlaping factor isn't really used directly for blending of shadow cascades. It
|
||||
// just there to be sure the cascades do overlap. The blending width used is relative
|
||||
|
|
|
@ -76,6 +76,8 @@ public:
|
|||
|
||||
Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount = 1);
|
||||
|
||||
void setLight(graphics::LightPointer light);
|
||||
|
||||
void setKeylightFrustum(const ViewFrustum& viewFrustum,
|
||||
float nearDepth = 1.0f, float farDepth = 1000.0f);
|
||||
void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum,
|
||||
|
|
|
@ -154,7 +154,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto shadowTaskOutputs = inputs.get2();
|
||||
|
||||
// Shadow Stage Frame
|
||||
const auto shadowFrame = shadowTaskOutputs.get1();
|
||||
const auto shadowFrame = shadowTaskOutputs[1];
|
||||
|
||||
fadeEffect->build(task, opaques);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
|
||||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", lightFrame);
|
||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
|
||||
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Outputs>(3);
|
||||
// Fetch and cull the items from the scene
|
||||
|
||||
static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask);
|
||||
|
@ -96,7 +97,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||
char jobName[64];
|
||||
sprintf(jobName, "ShadowCascadeSetup%d", i);
|
||||
const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, lightFrame, i, tagBits, tagMask);
|
||||
const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, shadowFrame, i, tagBits, tagMask);
|
||||
const auto shadowFilter = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(0);
|
||||
auto antiFrustum = render::Varying(ViewFrustumPointer());
|
||||
cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1);
|
||||
|
@ -359,31 +360,30 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
|||
*_cameraFrustum = args->getViewFrustum();
|
||||
output.edit2() = _cameraFrustum;
|
||||
|
||||
const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame);
|
||||
if (globalShadow) {
|
||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
|
||||
// Clear previous shadow frame
|
||||
if (!_globalShadowObject) {
|
||||
_globalShadowObject = std::make_shared<LightStage::Shadow>(graphics::LightPointer(), 100.0f);
|
||||
}
|
||||
_shadowFrameCache->_objects.clear();
|
||||
|
||||
const auto theGlobalShadow = lightStage->getCurrentKeyShadow(lightFrame);
|
||||
if (theGlobalShadow) {
|
||||
_globalShadowObject->setLight(theGlobalShadow->getLight());
|
||||
_globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
|
||||
|
||||
auto& firstCascade = globalShadow->getCascade(0);
|
||||
auto& firstCascade = _globalShadowObject->getCascade(0);
|
||||
auto& firstCascadeFrustum = firstCascade.getFrustum();
|
||||
unsigned int cascadeIndex;
|
||||
|
||||
// Adjust each cascade frustum
|
||||
for (cascadeIndex = 0; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
|
||||
for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
|
||||
auto& bias = _bias[cascadeIndex];
|
||||
globalShadow->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
|
||||
_globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
|
||||
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
|
||||
bias._constant, bias._slope);
|
||||
}
|
||||
|
||||
// copy paste the values for the shadow params:
|
||||
/* if (!_globalShadowObject) {
|
||||
LightStage::Shadow::Schema schema;
|
||||
_globalShadowObject = std::make_shared<gpu::Buffer>(sizeof(LightStage::Shadow::Schema), (const gpu::Byte*) &schema);
|
||||
}
|
||||
_globalShadowObject->getBuffersetData(globalShadow->getBuffer()._size, globalShadow->getBuffer()._buffer->getData());
|
||||
|
||||
|
||||
_shadowFrameCache->pushShadow(_globalShadowObject);*/
|
||||
_shadowFrameCache->pushShadow(_globalShadowObject);
|
||||
|
||||
// Now adjust coarse frustum bounds
|
||||
auto frustumPosition = firstCascadeFrustum->getPosition();
|
||||
|
@ -397,8 +397,8 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
|||
auto near = firstCascadeFrustum->getNearClip();
|
||||
auto far = firstCascadeFrustum->getFarClip();
|
||||
|
||||
for (cascadeIndex = 1; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
|
||||
auto& cascadeFrustum = globalShadow->getCascade(cascadeIndex).getFrustum();
|
||||
for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
|
||||
auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum();
|
||||
|
||||
farTopLeft = cascadeFrustum->getFarTopLeft() - frustumPosition;
|
||||
farBottomRight = cascadeFrustum->getFarBottomRight() - frustumPosition;
|
||||
|
@ -439,36 +439,48 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
|||
}
|
||||
|
||||
void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) {
|
||||
const auto shadowFrame = input;
|
||||
/*
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
const auto& lightFrame = *input;
|
||||
assert(lightStage);
|
||||
|
||||
*/
|
||||
// Cache old render args
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
RenderShadowTask::CullFunctor cullFunctor;
|
||||
|
||||
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)
|
||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
||||
|
||||
if (shadowFrame && !shadowFrame->_objects.empty() && shadowFrame->_objects[0]) {
|
||||
const auto globalShadow = shadowFrame->_objects[0]; //lightStage->getCurrentKeyShadow(lightFrame);
|
||||
|
||||
// Set the keylight render args
|
||||
auto& cascade = globalShadow->getCascade(_cascadeIndex);
|
||||
auto& cascadeFrustum = cascade.getFrustum();
|
||||
args->pushViewFrustum(*cascadeFrustum);
|
||||
auto texelSize = glm::min(cascadeFrustum->getHeight(), cascadeFrustum->getWidth()) / cascade.framebuffer->getSize().x;
|
||||
// Set the cull threshold to 24 shadow texels. This is totally arbitrary
|
||||
const auto minTexelCount = 24.0f;
|
||||
// TODO : maybe adapt that with LOD management system?
|
||||
texelSize *= minTexelCount;
|
||||
cullFunctor._minSquareSize = texelSize * texelSize;
|
||||
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)
|
||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
||||
|
||||
output.edit1() = cascadeFrustum;
|
||||
} else {
|
||||
// Set the keylight render args
|
||||
auto& cascade = globalShadow->getCascade(_cascadeIndex);
|
||||
auto& cascadeFrustum = cascade.getFrustum();
|
||||
args->pushViewFrustum(*cascadeFrustum);
|
||||
auto texelSize = glm::min(cascadeFrustum->getHeight(), cascadeFrustum->getWidth()) / cascade.framebuffer->getSize().x;
|
||||
// Set the cull threshold to 24 shadow texels. This is totally arbitrary
|
||||
const auto minTexelCount = 24.0f;
|
||||
// TODO : maybe adapt that with LOD management system?
|
||||
texelSize *= minTexelCount;
|
||||
cullFunctor._minSquareSize = texelSize * texelSize;
|
||||
|
||||
output.edit1() = cascadeFrustum;
|
||||
|
||||
} else {
|
||||
output.edit0() = ItemFilter::Builder::nothing();
|
||||
output.edit1() = ViewFrustumPointer();
|
||||
}
|
||||
}
|
||||
else {
|
||||
output.edit0() = ItemFilter::Builder::nothing();
|
||||
output.edit1() = ViewFrustumPointer();
|
||||
}
|
||||
|
||||
output.edit2() = cullFunctor;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ private:
|
|||
|
||||
class RenderShadowCascadeSetup {
|
||||
public:
|
||||
using Inputs = LightStage::FramePointer;
|
||||
using Inputs = LightStage::ShadowFramePointer;
|
||||
using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
|
||||
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
|
||||
|
||||
|
|
Loading…
Reference in a new issue