mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 04:08:13 +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);
|
||||||
assert(lightStage->getNumLights() > 0);
|
assert(lightStage->getNumLights() > 0);
|
||||||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame);
|
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
|
// Bind the shadow buffers
|
||||||
if (globalShadow) {
|
if (globalShadow) {
|
||||||
|
@ -640,7 +644,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, 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);
|
lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,11 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi
|
||||||
setMaxDistance(maxDistance);
|
setMaxDistance(maxDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightStage::Shadow::setLight(graphics::LightPointer light) {
|
||||||
|
_light = light;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LightStage::Shadow::setMaxDistance(float value) {
|
void LightStage::Shadow::setMaxDistance(float value) {
|
||||||
// This overlaping factor isn't really used directly for blending of shadow cascades. It
|
// 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
|
// 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);
|
Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount = 1);
|
||||||
|
|
||||||
|
void setLight(graphics::LightPointer light);
|
||||||
|
|
||||||
void setKeylightFrustum(const ViewFrustum& viewFrustum,
|
void setKeylightFrustum(const ViewFrustum& viewFrustum,
|
||||||
float nearDepth = 1.0f, float farDepth = 1000.0f);
|
float nearDepth = 1.0f, float farDepth = 1000.0f);
|
||||||
void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum,
|
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();
|
const auto shadowTaskOutputs = inputs.get2();
|
||||||
|
|
||||||
// Shadow Stage Frame
|
// Shadow Stage Frame
|
||||||
const auto shadowFrame = shadowTaskOutputs.get1();
|
const auto shadowFrame = shadowTaskOutputs[1];
|
||||||
|
|
||||||
fadeEffect->build(task, opaques);
|
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 setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", lightFrame);
|
||||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
|
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
|
||||||
|
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Outputs>(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);
|
||||||
|
@ -96,7 +97,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||||
char jobName[64];
|
char jobName[64];
|
||||||
sprintf(jobName, "ShadowCascadeSetup%d", i);
|
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);
|
const auto shadowFilter = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(0);
|
||||||
auto antiFrustum = render::Varying(ViewFrustumPointer());
|
auto antiFrustum = render::Varying(ViewFrustumPointer());
|
||||||
cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1);
|
cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1);
|
||||||
|
@ -359,31 +360,30 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
||||||
*_cameraFrustum = args->getViewFrustum();
|
*_cameraFrustum = args->getViewFrustum();
|
||||||
output.edit2() = _cameraFrustum;
|
output.edit2() = _cameraFrustum;
|
||||||
|
|
||||||
const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame);
|
// Clear previous shadow frame
|
||||||
if (globalShadow) {
|
if (!_globalShadowObject) {
|
||||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
|
_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();
|
auto& firstCascadeFrustum = firstCascade.getFrustum();
|
||||||
unsigned int cascadeIndex;
|
unsigned int cascadeIndex;
|
||||||
|
|
||||||
// Adjust each cascade frustum
|
// Adjust each cascade frustum
|
||||||
for (cascadeIndex = 0; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
|
for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
|
||||||
auto& bias = _bias[cascadeIndex];
|
auto& bias = _bias[cascadeIndex];
|
||||||
globalShadow->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
|
_globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
|
||||||
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
|
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
|
||||||
bias._constant, bias._slope);
|
bias._constant, bias._slope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy paste the values for the shadow params:
|
_shadowFrameCache->pushShadow(_globalShadowObject);
|
||||||
/* 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);*/
|
|
||||||
|
|
||||||
// Now adjust coarse frustum bounds
|
// Now adjust coarse frustum bounds
|
||||||
auto frustumPosition = firstCascadeFrustum->getPosition();
|
auto frustumPosition = firstCascadeFrustum->getPosition();
|
||||||
|
@ -397,8 +397,8 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
||||||
auto near = firstCascadeFrustum->getNearClip();
|
auto near = firstCascadeFrustum->getNearClip();
|
||||||
auto far = firstCascadeFrustum->getFarClip();
|
auto far = firstCascadeFrustum->getFarClip();
|
||||||
|
|
||||||
for (cascadeIndex = 1; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
|
for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
|
||||||
auto& cascadeFrustum = globalShadow->getCascade(cascadeIndex).getFrustum();
|
auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum();
|
||||||
|
|
||||||
farTopLeft = cascadeFrustum->getFarTopLeft() - frustumPosition;
|
farTopLeft = cascadeFrustum->getFarTopLeft() - frustumPosition;
|
||||||
farBottomRight = cascadeFrustum->getFarBottomRight() - 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) {
|
void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) {
|
||||||
|
const auto shadowFrame = input;
|
||||||
|
/*
|
||||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||||
const auto& lightFrame = *input;
|
const auto& lightFrame = *input;
|
||||||
assert(lightStage);
|
assert(lightStage);
|
||||||
|
*/
|
||||||
// Cache old render args
|
// Cache old render args
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
RenderShadowTask::CullFunctor cullFunctor;
|
RenderShadowTask::CullFunctor cullFunctor;
|
||||||
|
|
||||||
const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame);
|
|
||||||
if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) {
|
if (shadowFrame && !shadowFrame->_objects.empty() && shadowFrame->_objects[0]) {
|
||||||
// Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers)
|
const auto globalShadow = shadowFrame->_objects[0]; //lightStage->getCurrentKeyShadow(lightFrame);
|
||||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
|
||||||
|
|
||||||
// Set the keylight render args
|
if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) {
|
||||||
auto& cascade = globalShadow->getCascade(_cascadeIndex);
|
// Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers)
|
||||||
auto& cascadeFrustum = cascade.getFrustum();
|
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
||||||
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;
|
// Set the keylight render args
|
||||||
} else {
|
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.edit0() = ItemFilter::Builder::nothing();
|
||||||
output.edit1() = ViewFrustumPointer();
|
output.edit1() = ViewFrustumPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
output.edit2() = cullFunctor;
|
output.edit2() = cullFunctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ private:
|
||||||
|
|
||||||
class RenderShadowCascadeSetup {
|
class RenderShadowCascadeSetup {
|
||||||
public:
|
public:
|
||||||
using Inputs = LightStage::FramePointer;
|
using Inputs = LightStage::ShadowFramePointer;
|
||||||
using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
|
using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
|
||||||
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
|
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue