mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:24:07 +02:00
Fixed weird bug with objects suddenly poping out of the shadow map. Was due to objects with own pipeline corrupting the render state. Don't know why though
This commit is contained in:
parent
89b1ef2e19
commit
c9c93370da
5 changed files with 31 additions and 9 deletions
|
@ -119,7 +119,7 @@ void LightStage::Shadow::setMaxDistance(float value) {
|
|||
|
||||
// The max cascade distance is computed by multiplying the previous cascade's max distance by a certain
|
||||
// factor. There is a "user" factor that is computed from a desired max resolution loss in the shadow
|
||||
// and an optimal own based on the global min and max shadow distance, all cascades considered. The final
|
||||
// and an optimal one based on the global min and max shadow distance, all cascades considered. The final
|
||||
// distance is a gradual blend between the two
|
||||
const auto userDistanceScale = 1.0f / (1.0f - MAX_RESOLUTION_LOSS);
|
||||
const auto optimalDistanceScale = powf(_maxDistance / LOW_MAX_DISTANCE, 1.0f / (_cascades.size() - 1));
|
||||
|
@ -229,7 +229,7 @@ void LightStage::Shadow::setKeylightFrustum(unsigned int cascadeIndex, const Vie
|
|||
schema.cascades[cascadeIndex].reprojection = _biasMatrix * ortho * shadowViewInverse.getMatrix();
|
||||
// Adapt shadow bias to shadow resolution with a totally empirical formula
|
||||
const auto maxShadowFrustumDim = std::max(fabsf(min.x - max.x), fabsf(min.y - max.y));
|
||||
const auto REFERENCE_TEXEL_DENSITY = 10.0f;
|
||||
const auto REFERENCE_TEXEL_DENSITY = 12.0f;
|
||||
const auto cascadeTexelDensity = MAP_SIZE / maxShadowFrustumDim;
|
||||
schema.cascades[cascadeIndex].bias = MAX_BIAS * std::min(1.0f, REFERENCE_TEXEL_DENSITY / cascadeTexelDensity);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
Index findLight(const LightPointer& light) const;
|
||||
Index addLight(const LightPointer& light);
|
||||
|
||||
Index addShadow(Index lightIndex, float maxDistance = 16.0f, unsigned int cascadeCount = 1U);
|
||||
Index addShadow(Index lightIndex, float maxDistance = 20.0f, unsigned int cascadeCount = 1U);
|
||||
|
||||
LightPointer removeLight(Index index);
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "DeferredLightingEffect.h"
|
||||
#include "FramebufferCache.h"
|
||||
|
||||
#include "RenderUtilsLogging.h"
|
||||
|
||||
// These values are used for culling the objects rendered in the shadow map
|
||||
// but are readjusted afterwards
|
||||
#define SHADOW_FRUSTUM_NEAR 1.0f
|
||||
|
@ -123,7 +125,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
return;
|
||||
}
|
||||
|
||||
const auto& fbo = shadow->getCascade(_cascadeIndex).framebuffer;
|
||||
auto& cascade = shadow->getCascade(_cascadeIndex);
|
||||
auto& fbo = cascade.framebuffer;
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
ShapeKey::Builder defaultKeyBuilder;
|
||||
|
@ -162,6 +165,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned());
|
||||
|
||||
std::vector<ShapeKey> skinnedShapeKeys{};
|
||||
std::vector<ShapeKey> ownPipelineShapeKeys{};
|
||||
|
||||
// Iterate through all inShapes and render the unskinned
|
||||
args->_shapePipeline = shadowPipeline;
|
||||
|
@ -169,8 +173,10 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
for (auto items : inShapes) {
|
||||
if (items.first.isSkinned()) {
|
||||
skinnedShapeKeys.push_back(items.first);
|
||||
} else {
|
||||
} else if (!items.first.hasOwnPipeline()) {
|
||||
renderItems(renderContext, items.second);
|
||||
} else {
|
||||
ownPipelineShapeKeys.push_back(items.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +187,15 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
|
||||
// Finally render the items with their own pipeline last to prevent them from breaking the
|
||||
// render state. This is probably a temporary code as there is probably something better
|
||||
// to do in the render call of objects that have their own pipeline.
|
||||
args->_shapePipeline = nullptr;
|
||||
for (const auto& key : ownPipelineShapeKeys) {
|
||||
args->_itemShapeKey = key._flags.to_ulong();
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
|
||||
args->_batch = nullptr;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,15 +14,21 @@
|
|||
#include "RenderDeferredTask.h"
|
||||
#include "RenderForwardTask.h"
|
||||
|
||||
|
||||
|
||||
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred) {
|
||||
// auto items = input.get<Input>();
|
||||
|
||||
// Shadows use an orthographic projection because they are linked to sunlights
|
||||
// but the cullFunctor passed is probably tailored for perspective projection and culls too much.
|
||||
// TODO : create a special cull functor for this.
|
||||
task.addJob<RenderShadowTask>("RenderShadowTask", nullptr);
|
||||
task.addJob<RenderShadowTask>("RenderShadowTask", [](const RenderArgs* args, const AABox& bounds) {
|
||||
// Cull only objects that are too small relatively to shadow frustum
|
||||
auto& frustum = args->getViewFrustum();
|
||||
auto frustumSize = std::max(frustum.getHeight(), frustum.getWidth());
|
||||
const auto boundsRadius = bounds.getDimensions().length();
|
||||
const auto relativeBoundRadius = boundsRadius / frustumSize;
|
||||
const auto threshold = 1e-3f;
|
||||
return relativeBoundRadius > threshold;
|
||||
return true;
|
||||
});
|
||||
|
||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor);
|
||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||
|
|
|
@ -71,6 +71,8 @@ void ViewFrustum::setProjection(const glm::mat4& projection) {
|
|||
glm::vec4 top = inverseProjection * vec4(0.0f, 1.0f, -1.0f, 1.0f);
|
||||
top /= top.w;
|
||||
_fieldOfView = abs(glm::degrees(2.0f * abs(glm::angle(vec3(0.0f, 0.0f, -1.0f), glm::normalize(vec3(top))))));
|
||||
_height = _corners[TOP_RIGHT_NEAR].y - _corners[BOTTOM_RIGHT_NEAR].y;
|
||||
_width = _corners[TOP_RIGHT_NEAR].x - _corners[TOP_LEFT_NEAR].x;
|
||||
}
|
||||
|
||||
// ViewFrustum::calculate()
|
||||
|
|
Loading…
Reference in a new issue