mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 10:40:09 -06:00
calculate view frustum for shadow mapping automatically
based on model extents as defined by its bounding-radius
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/events/event.h>
|
||||
#include <openspace/events/eventengine.h>
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
@@ -177,8 +179,15 @@ namespace {
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CastShadowInfo = {
|
||||
"CastShadow",
|
||||
"Enable model to cast shadow",
|
||||
"Cast shadow",
|
||||
"Enable model to cast shadow on its parent renderable",
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FrustumSizeInfo = {
|
||||
"FrustumSize",
|
||||
"Size of the depth-pass view frustum",
|
||||
"Sets the width & height (effectively left/right & top/bottom)"
|
||||
" of the depth-pass view frustum, z-near & z-far are calculated.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
@@ -296,6 +305,9 @@ namespace {
|
||||
// [[codegen::verbatim(RenderWireframeInfo.description)]]
|
||||
std::optional<bool> renderWireframe;
|
||||
|
||||
// [[codegen::verbatim(FrustumSizeInfo.description)]]
|
||||
std::optional<float> frustumSize;
|
||||
|
||||
// [[codegen::verbatim(BlendingOptionInfo.description)]]
|
||||
std::optional<std::string> blendingOption;
|
||||
|
||||
@@ -344,6 +356,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
, _rotationVec(RotationVecInfo, glm::dvec3(0.0), glm::dvec3(0.0), glm::dvec3(360.0))
|
||||
, _enableDepthTest(EnableDepthTestInfo, true)
|
||||
, _renderWireframe(RenderWireframeInfo, false)
|
||||
, _frustumSize(FrustumSizeInfo, 1.f)
|
||||
, _useCache(UseCacheInfo, true)
|
||||
, _castShadow(CastShadowInfo, false)
|
||||
, _blendingFuncOption(
|
||||
@@ -476,6 +489,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_enableFaceCulling);
|
||||
addProperty(_enableDepthTest);
|
||||
addProperty(_renderWireframe);
|
||||
addProperty(_castShadow);
|
||||
addProperty(_frustumSize);
|
||||
addProperty(_modelTransform);
|
||||
addProperty(_pivot);
|
||||
addProperty(_rotationVec);
|
||||
@@ -484,6 +499,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_modelScale);
|
||||
_modelScale.setExponent(20.f);
|
||||
|
||||
_autoSizeFrustum = !p.frustumSize.has_value();
|
||||
|
||||
_modelScale.onChange([this]() {
|
||||
if (!_geometry) {
|
||||
LWARNING(std::format(
|
||||
@@ -496,6 +513,13 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
|
||||
// Set Interaction sphere size to be 10% of the bounding sphere
|
||||
setInteractionSphere(boundingSphere() * 0.1);
|
||||
|
||||
if (_autoSizeFrustum) {
|
||||
const float radius = _geometry->boundingRadius() * _modelScale;
|
||||
_frustumSize = radius;
|
||||
_frustumSize.setMinValue(radius * .1f);
|
||||
_frustumSize.setMaxValue(radius * 3.f);
|
||||
}
|
||||
});
|
||||
|
||||
_rotationVec.onChange([this]() {
|
||||
@@ -526,6 +550,11 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
});
|
||||
|
||||
_castShadow.onChange([]() {
|
||||
// To update list of shadowers for our parent
|
||||
global::eventEngine->publishEvent<events::CustomEvent>("Cast Shadow Changed", "nada");
|
||||
});
|
||||
|
||||
if (p.rotationVector.has_value()) {
|
||||
_rotationVec = *p.rotationVector;
|
||||
}
|
||||
@@ -733,6 +762,13 @@ void RenderableModel::initializeGL() {
|
||||
_geometry->calculateBoundingRadius();
|
||||
setBoundingSphere(_geometry->boundingRadius() * _modelScale);
|
||||
|
||||
if (_autoSizeFrustum) {
|
||||
const float radius = _geometry->boundingRadius() * _modelScale;
|
||||
_frustumSize = radius;
|
||||
_frustumSize.setMinValue(radius * .1f);
|
||||
_frustumSize.setMaxValue(radius * 3.f);
|
||||
}
|
||||
|
||||
// Set Interaction sphere size to be 10% of the bounding sphere
|
||||
setInteractionSphere(boundingSphere() * 0.1);
|
||||
|
||||
@@ -1220,8 +1256,8 @@ RenderableModel::DepthMapData RenderableModel::renderDepthMap() const {
|
||||
|
||||
_depthMapProgram->activate();
|
||||
|
||||
const double size = boundingSphere();
|
||||
const double dist = size * 10000.;
|
||||
const double frustumSize = static_cast<double>(_frustumSize);
|
||||
const double distance = frustumSize * 10000.;
|
||||
|
||||
// Model
|
||||
glm::dmat4 transform = glm::translate(glm::dmat4(1), glm::dvec3(_pivot.value()));
|
||||
@@ -1229,21 +1265,21 @@ RenderableModel::DepthMapData RenderableModel::renderDepthMap() const {
|
||||
glm::dmat4 model = this->parent()->modelTransform() * transform;
|
||||
|
||||
// View
|
||||
glm::dvec3 center = this->parent()->worldPosition();
|
||||
glm::dvec3 center = model * glm::dvec4(_geometry->center(), 1.);
|
||||
glm::dvec3 light_dir = glm::normalize(center - light->positionWorldSpace());
|
||||
glm::dvec3 right = glm::normalize(glm::cross(glm::dvec3(0, 1, 0), -light_dir));
|
||||
glm::dvec3 eye = center + light_dir * dist;
|
||||
glm::dvec3 eye = center + light_dir * distance;
|
||||
glm::dvec3 up = glm::cross(right, light_dir);
|
||||
glm::dmat4 view = glm::lookAt(eye, center, up);
|
||||
|
||||
// Projection
|
||||
glm::dmat4 projection = glm::ortho(
|
||||
-size,
|
||||
size,
|
||||
-size,
|
||||
size,
|
||||
dist * 0.1,
|
||||
dist * 1.1
|
||||
-frustumSize,
|
||||
frustumSize,
|
||||
-frustumSize,
|
||||
frustumSize,
|
||||
distance * 0.1,
|
||||
distance * 1.1
|
||||
);
|
||||
|
||||
glm::dmat4 viewProjection = projection * view;
|
||||
|
||||
Reference in New Issue
Block a user