mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 20:44:14 +02:00
Added Cascade subclass in LightStage Shadow
This commit is contained in:
parent
7fd03bed7e
commit
e0b36b800f
6 changed files with 64 additions and 37 deletions
|
@ -438,7 +438,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
|
|||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow();
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
if (globalShadow) {
|
||||
batch.setResourceTexture(Shadow, globalShadow->map);
|
||||
batch.setResourceTexture(Shadow, globalShadow->getCascade(0).map);
|
||||
}
|
||||
|
||||
if (linearDepthTarget) {
|
||||
|
|
|
@ -503,7 +503,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
// Bind the shadow buffer
|
||||
if (globalShadow) {
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map);
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->getCascade(0).map);
|
||||
}
|
||||
|
||||
auto& program = deferredLightingEffect->_directionalSkyboxLight;
|
||||
|
|
|
@ -28,20 +28,34 @@ LightStage::Shadow::Schema::Schema() {
|
|||
defaultTransform.bias = 0.005f;
|
||||
std::fill(cascades, cascades + SHADOW_CASCADE_MAX_COUNT, defaultTransform);
|
||||
invMapSize = 1.0f / MAP_SIZE;
|
||||
cascadeCount = 1;
|
||||
}
|
||||
|
||||
LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum{ std::make_shared<ViewFrustum>() } {
|
||||
LightStage::Shadow::Cascade::Cascade() : _frustum{ std::make_shared<ViewFrustum>() } {
|
||||
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
|
||||
map = framebuffer->getDepthStencilBuffer();
|
||||
Schema schema;
|
||||
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum,
|
||||
const glm::mat4& LightStage::Shadow::Cascade::getView() const {
|
||||
return _frustum->getView();
|
||||
}
|
||||
|
||||
const glm::mat4& LightStage::Shadow::Cascade::getProjection() const {
|
||||
return _frustum->getProjection();
|
||||
}
|
||||
|
||||
LightStage::Shadow::Shadow(model::LightPointer light, unsigned int cascadeCount) : _light{ light } {
|
||||
Schema schema;
|
||||
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
|
||||
_cascades.resize(cascadeCount);
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setKeylightFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum,
|
||||
float viewMinShadowDistance, float viewMaxShadowDistance,
|
||||
float nearDepth, float farDepth) {
|
||||
assert(viewMinShadowDistance < viewMaxShadowDistance);
|
||||
assert(nearDepth < farDepth);
|
||||
assert(cascadeIndex < _cascades.size());
|
||||
|
||||
// Orient the keylight frustum
|
||||
const auto& direction = glm::normalize(_light->getDirection());
|
||||
|
@ -55,12 +69,15 @@ void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum,
|
|||
auto up = glm::normalize(glm::cross(side, direction));
|
||||
orientation = glm::quat_cast(glm::mat3(side, up, -direction));
|
||||
}
|
||||
_frustum->setOrientation(orientation);
|
||||
|
||||
auto& cascade = _cascades[cascadeIndex];
|
||||
|
||||
cascade._frustum->setOrientation(orientation);
|
||||
|
||||
// Position the keylight frustum
|
||||
_frustum->setPosition(viewFrustum.getPosition() - (nearDepth + farDepth)*direction);
|
||||
cascade._frustum->setPosition(viewFrustum.getPosition() - (nearDepth + farDepth)*direction);
|
||||
|
||||
const Transform view{ _frustum->getView()};
|
||||
const Transform view{ cascade._frustum->getView()};
|
||||
const Transform viewInverse{ view.getInverseMatrix() };
|
||||
|
||||
auto nearCorners = viewFrustum.getCorners(viewMinShadowDistance);
|
||||
|
@ -92,30 +109,24 @@ void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum,
|
|||
auto near = glm::max(max.z, -nearDepth);
|
||||
auto far = -min.z;
|
||||
glm::mat4 ortho = glm::ortho<float>(min.x, max.x, min.y, max.y, near, far);
|
||||
_frustum->setProjection(ortho);
|
||||
cascade._frustum->setProjection(ortho);
|
||||
|
||||
// Calculate the frustum's internal state
|
||||
_frustum->calculate();
|
||||
cascade._frustum->calculate();
|
||||
|
||||
// Update the buffer
|
||||
_schemaBuffer.edit<Schema>().cascades[0].reprojection = _biasMatrix * ortho * viewInverse.getMatrix();
|
||||
_schemaBuffer.edit<Schema>().cascades[cascadeIndex].reprojection = _biasMatrix * ortho * viewInverse.getMatrix();
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setFrustum(const ViewFrustum& shadowFrustum) {
|
||||
void LightStage::Shadow::setFrustum(unsigned int cascadeIndex, const ViewFrustum& shadowFrustum) {
|
||||
assert(cascadeIndex < _cascades.size());
|
||||
const Transform view{ shadowFrustum.getView() };
|
||||
const Transform viewInverse{ view.getInverseMatrix() };
|
||||
auto& cascade = _cascades[cascadeIndex];
|
||||
|
||||
*_frustum = shadowFrustum;
|
||||
*cascade._frustum = shadowFrustum;
|
||||
// Update the buffer
|
||||
_schemaBuffer.edit<Schema>().cascades[0].reprojection = _biasMatrix * shadowFrustum.getProjection() * viewInverse.getMatrix();
|
||||
}
|
||||
|
||||
const glm::mat4& LightStage::Shadow::getView() const {
|
||||
return _frustum->getView();
|
||||
}
|
||||
|
||||
const glm::mat4& LightStage::Shadow::getProjection() const {
|
||||
return _frustum->getProjection();
|
||||
_schemaBuffer.edit<Schema>().cascades[cascadeIndex].reprojection = _biasMatrix * shadowFrustum.getProjection() * viewInverse.getMatrix();
|
||||
}
|
||||
|
||||
LightStage::Index LightStage::findLight(const LightPointer& light) const {
|
||||
|
|
|
@ -46,27 +46,43 @@ public:
|
|||
using UniformBufferView = gpu::BufferView;
|
||||
static const int MAP_SIZE = 1024;
|
||||
|
||||
Shadow(model::LightPointer light);
|
||||
class Cascade {
|
||||
friend Shadow;
|
||||
public:
|
||||
|
||||
void setKeylightFrustum(const ViewFrustum& viewFrustum, float viewMinShadowDistance, float viewMaxShadowDistance, float nearDepth = 1.0f, float farDepth = 1000.0f);
|
||||
Cascade();
|
||||
|
||||
void setFrustum(const ViewFrustum& shadowFrustum);
|
||||
const std::shared_ptr<ViewFrustum> getFrustum() const { return _frustum; }
|
||||
gpu::FramebufferPointer framebuffer;
|
||||
gpu::TexturePointer map;
|
||||
|
||||
const glm::mat4& getView() const;
|
||||
const glm::mat4& getProjection() const;
|
||||
const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
|
||||
|
||||
const glm::mat4& getView() const;
|
||||
const glm::mat4& getProjection() const;
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<ViewFrustum> _frustum;
|
||||
};
|
||||
|
||||
Shadow(model::LightPointer light, unsigned int cascadeCount = 1);
|
||||
|
||||
void setKeylightFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum, float viewMinShadowDistance, float viewMaxShadowDistance, float nearDepth = 1.0f, float farDepth = 1000.0f);
|
||||
void setFrustum(unsigned int cascadeIndex, const ViewFrustum& shadowFrustum);
|
||||
|
||||
const UniformBufferView& getBuffer() const { return _schemaBuffer; }
|
||||
|
||||
gpu::FramebufferPointer framebuffer;
|
||||
gpu::TexturePointer map;
|
||||
unsigned int getCascadeCount() const { return (unsigned int)_cascades.size(); }
|
||||
const Cascade& getCascade(unsigned int index) const { return _cascades[index]; }
|
||||
|
||||
protected:
|
||||
|
||||
using Cascades = std::vector<Cascade>;
|
||||
|
||||
static const glm::mat4 _biasMatrix;
|
||||
|
||||
model::LightPointer _light;
|
||||
std::shared_ptr<ViewFrustum> _frustum;
|
||||
Cascades _cascades;
|
||||
|
||||
#include "Shadows_shared.slh"
|
||||
|
||||
|
|
|
@ -545,7 +545,7 @@ void DrawFrustums::run(const render::RenderContextPointer& renderContext) {
|
|||
|
||||
const auto globalShadow = lightStage->getCurrentKeyShadow();
|
||||
if (globalShadow) {
|
||||
updateFrustum(*globalShadow->getFrustum(), _shadowFrustumMeshVertices);
|
||||
updateFrustum(*globalShadow->getCascade(0).getFrustum(), _shadowFrustumMeshVertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
auto shadow = lightStage->getCurrentKeyShadow();
|
||||
if (!shadow) return;
|
||||
|
||||
const auto& fbo = shadow->framebuffer;
|
||||
const auto& fbo = shadow->getCascade(0).framebuffer;
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
ShapeKey::Builder defaultKeyBuilder;
|
||||
|
@ -149,7 +149,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
// the minimal Z range.
|
||||
adjustNearFar(inShapeBounds, adjustedShadowFrustum);
|
||||
// Reapply the frustum as it has been adjusted
|
||||
shadow->setFrustum(adjustedShadowFrustum);
|
||||
shadow->setFrustum(0, adjustedShadowFrustum);
|
||||
args->popViewFrustum();
|
||||
args->pushViewFrustum(adjustedShadowFrustum);
|
||||
|
||||
|
@ -252,10 +252,10 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
|
|||
auto nearClip = args->getViewFrustum().getNearClip();
|
||||
float nearDepth = -args->_boomOffset.z;
|
||||
const float SHADOW_MAX_DISTANCE = 20.0f;
|
||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_MAX_DISTANCE, SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
|
||||
globalShadow->setKeylightFrustum(0, args->getViewFrustum(), nearDepth, nearClip + SHADOW_MAX_DISTANCE, SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
|
||||
|
||||
// Set the keylight render args
|
||||
args->pushViewFrustum(*(globalShadow->getFrustum()));
|
||||
args->pushViewFrustum(*(globalShadow->getCascade(0).getFrustum()));
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue