mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2025-12-31 00:10:44 -06:00
Some more cleanup of the PR
This commit is contained in:
@@ -5,7 +5,6 @@ local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
|
||||
|
||||
-- Model CC0 from https://sketchfab.com/3d-models/celestial-globe-341fa8a777e94883841409438756f747
|
||||
local celestial_globe_folder = asset.resource({
|
||||
Name = "Celestial Globe",
|
||||
@@ -14,8 +13,8 @@ local celestial_globe_folder = asset.resource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
-- These models are in the same shadow group, so will cast onto and receive
|
||||
-- shadows from each other, as well as the Mars surface
|
||||
-- These models are in the same shadow group, so will cast onto and receive shadows from
|
||||
-- each other, as well as the Mars surface
|
||||
local ModelMarsSmall = {
|
||||
Identifier = "celestial-globe-mars1",
|
||||
Parent = mars.Mars.Identifier,
|
||||
@@ -215,12 +214,16 @@ local ModelMoon = {
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(ModelMarsSmall)
|
||||
openspace.registerShadowcaster(sun.LightSource.Identifier, ModelMarsSmall.Identifier, mars.Mars.Identifier, "mars")
|
||||
openspace.addSceneGraphNode(ModelMarsLarge)
|
||||
|
||||
openspace.addSceneGraphNode(ModelMarsLarge)
|
||||
openspace.registerShadowcaster(sun.LightSource.Identifier, ModelMarsLarge.Identifier, mars.Mars.Identifier, "mars")
|
||||
|
||||
openspace.addSceneGraphNode(ModelMarsOtherGroup)
|
||||
openspace.registerShadowcaster(sun.LightSource.Identifier, ModelMarsOtherGroup.Identifier, mars.Mars.Identifier)
|
||||
|
||||
openspace.addSceneGraphNode(ModelEarth)
|
||||
openspace.registerShadowcaster(sun.LightSource.Identifier, ModelEarth.Identifier, earth.Earth.Identifier, "earth")
|
||||
|
||||
openspace.addSceneGraphNode(ModelMoon)
|
||||
openspace.registerShadowcaster(sun.LightSource.Identifier, ModelMoon.Identifier, moon.Moon.Identifier, "moon")
|
||||
end)
|
||||
|
||||
Submodule ext/ghoul updated: c748bc9d41...80947f9bbd
@@ -634,7 +634,7 @@ struct CustomEvent : public Event {
|
||||
*
|
||||
* \pre subtype_ must not be empty
|
||||
*/
|
||||
CustomEvent(std::string_view subtype_, std::string_view payload_ = "");
|
||||
CustomEvent(std::string_view subtype_, std::string_view payload_);
|
||||
|
||||
const tstring subtype;
|
||||
const tstring payload;
|
||||
|
||||
@@ -178,9 +178,11 @@ public:
|
||||
virtual void deferredcastersChanged(Deferredcaster& deferredcaster,
|
||||
DeferredcasterListener::IsAttached isAttached) override;
|
||||
|
||||
void registerShadowCaster(const std::string& shadowgroup, const SceneGraphNode* lightsource,
|
||||
const SceneGraphNode* target);
|
||||
std::pair<GLuint, glm::dmat4> shadowInformation(const SceneGraphNode* node, const std::string& shadowgroup) const;
|
||||
void registerShadowCaster(const std::string& shadowGroup,
|
||||
const SceneGraphNode* lightsource, const SceneGraphNode* target);
|
||||
void removeShadowCaster(const std::string& shadowGroup, const SceneGraphNode* target);
|
||||
|
||||
std::pair<GLuint, glm::dmat4> shadowInformation(const std::string& shadowgroup) const;
|
||||
|
||||
private:
|
||||
using RaycasterProgObjMap = std::map<
|
||||
@@ -251,7 +253,7 @@ private:
|
||||
|
||||
struct ShadowMap {
|
||||
const SceneGraphNode* lightsource = nullptr;
|
||||
std::vector<std::string> shadowGroups;
|
||||
std::vector<const SceneGraphNode*> targets;
|
||||
GLuint depthMap = 0;
|
||||
glm::ivec2 depthMapResolution = glm::ivec2(0);
|
||||
GLuint fbo = 0;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
@@ -59,6 +60,7 @@ class Camera;
|
||||
class DeferredcasterManager;
|
||||
class RaycasterManager;
|
||||
class Scene;
|
||||
class SceneGraphNode;
|
||||
class SceneManager;
|
||||
class ScreenLog;
|
||||
class ScreenSpaceRenderable;
|
||||
@@ -161,8 +163,12 @@ public:
|
||||
|
||||
uint64_t frameNumber() const;
|
||||
|
||||
void registerShadowCaster(const std::string& shadowgroup, const SceneGraphNode* lightsource, SceneGraphNode* shadower, SceneGraphNode* shadowee);
|
||||
std::pair<GLuint, glm::dmat4> shadowInformation(const SceneGraphNode* node, const std::string& shadowgroup) const;
|
||||
void registerShadowCaster(const std::string& shadowgroup,
|
||||
const SceneGraphNode* lightSource, SceneGraphNode* shadower,
|
||||
SceneGraphNode* shadowee);
|
||||
void removeShadowCaster(const std::string& shadowgroup, SceneGraphNode* shadower,
|
||||
SceneGraphNode* shadowee);
|
||||
std::pair<GLuint, glm::dmat4> shadowInformation(const std::string& shadowgroup) const;
|
||||
|
||||
private:
|
||||
void renderScreenLog();
|
||||
|
||||
@@ -50,11 +50,13 @@ public:
|
||||
const std::string& shadowGroup() const;
|
||||
double shadowFrustumSize() const;
|
||||
|
||||
virtual glm::dvec3 center() const = 0;
|
||||
|
||||
virtual void renderForDepthMap(const glm::dmat4& vp) const = 0;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
protected:
|
||||
virtual void renderForDepthMap(const glm::dmat4& vp) const = 0;
|
||||
|
||||
properties::BoolProperty _castShadow;
|
||||
const SceneGraphNode* _lightSource = nullptr;
|
||||
std::string _shadowGroup;
|
||||
@@ -68,6 +70,7 @@ protected:
|
||||
class Shadowee {
|
||||
public:
|
||||
void addShadower(const Shadower* shadower);
|
||||
void removeShadower(const Shadower* shadower);
|
||||
|
||||
protected:
|
||||
std::vector<const Shadower*> _shadowers;
|
||||
|
||||
@@ -102,10 +102,6 @@ float SceneGraphLightSource::intensity() const {
|
||||
return _intensity;
|
||||
}
|
||||
|
||||
glm::dvec3 SceneGraphLightSource::positionWorldSpace() const {
|
||||
return _sceneGraphNode->modelTransform() * glm::dvec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
glm::vec3 SceneGraphLightSource::directionViewSpace(const RenderData& renderData) const {
|
||||
if (!_sceneGraphNode) {
|
||||
return glm::vec3(0.f);
|
||||
|
||||
@@ -43,7 +43,6 @@ public:
|
||||
bool initialize() override;
|
||||
glm::vec3 directionViewSpace(const RenderData& renderData) const override;
|
||||
float intensity() const override;
|
||||
glm::dvec3 positionWorldSpace() const;
|
||||
|
||||
private:
|
||||
properties::FloatProperty _intensity;
|
||||
|
||||
@@ -25,12 +25,9 @@
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
|
||||
#include <modules/base/basemodule.h>
|
||||
#include <modules/base/lightsource/scenegraphlightsource.h>
|
||||
#include <openspace/documentation/documentation.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>
|
||||
@@ -365,9 +362,9 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
, _enableDepthTest(EnableDepthTestInfo, true)
|
||||
, _blendingFuncOption(BlendingOptionInfo)
|
||||
, _renderWireframe(RenderWireframeInfo, false)
|
||||
, _lightSourcePropertyOwner({ "LightSources", "Light Sources" })
|
||||
, _useOverrideColor(UseOverrideColorInfo, false)
|
||||
, _overrideColor(OverrideColorInfo, glm::vec4(0, 0, 0, 1))
|
||||
, _lightSourcePropertyOwner({ "LightSources", "Light Sources" })
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -526,10 +523,10 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
setInteractionSphere(boundingSphere() * 0.1);
|
||||
|
||||
if (_hasFrustumSize) {
|
||||
const float radius = _geometry->boundingRadius() * _modelScale;
|
||||
_frustumSize = radius;
|
||||
_frustumSize.setMinValue(radius * 0.1f);
|
||||
_frustumSize.setMaxValue(radius * 3.f);
|
||||
const float r = static_cast<float>(_geometry->boundingRadius() * _modelScale);
|
||||
_frustumSize = r;
|
||||
_frustumSize.setMinValue(r * 0.1f);
|
||||
_frustumSize.setMaxValue(r * 3.f);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -568,9 +565,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
else {
|
||||
releaseDepthMapResources();
|
||||
}
|
||||
|
||||
// To update list of shadowers for our parent
|
||||
global::eventEngine->publishEvent<events::CustomEvent>("Cast Shadow Changed");
|
||||
});
|
||||
|
||||
if (p.rotationVector.has_value()) {
|
||||
@@ -781,10 +775,10 @@ void RenderableModel::initializeGL() {
|
||||
setBoundingSphere(_geometry->boundingRadius() * _modelScale);
|
||||
|
||||
if (_hasFrustumSize) {
|
||||
const float radius = _geometry->boundingRadius() * _modelScale;
|
||||
_frustumSize = radius;
|
||||
_frustumSize.setMinValue(radius * 0.1f);
|
||||
_frustumSize.setMaxValue(radius * 3.f);
|
||||
const float r = static_cast<float>(_geometry->boundingRadius() * _modelScale);
|
||||
_frustumSize = r;
|
||||
_frustumSize.setMinValue(r * 0.1f);
|
||||
_frustumSize.setMaxValue(r * 3.f);
|
||||
}
|
||||
|
||||
// Set Interaction sphere size to be 10% of the bounding sphere
|
||||
@@ -986,10 +980,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
ghoul::opengl::TextureUnit shadowUnit;
|
||||
if (_castShadow && _lightSource) {
|
||||
auto [depthMap, vp] = global::renderEngine->shadowInformation(
|
||||
_lightSource,
|
||||
_shadowGroup
|
||||
);
|
||||
auto [depthMap, vp] = global::renderEngine->shadowInformation(_shadowGroup);
|
||||
|
||||
_program->setUniform("model", modelTransform);
|
||||
_program->setUniform("light_vp", vp);
|
||||
|
||||
@@ -60,9 +60,6 @@ public:
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
void renderForDepthMap(const glm::dmat4& vp) const override;
|
||||
|
||||
glm::dvec3 center() const;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
@@ -75,6 +72,9 @@ private:
|
||||
BounceInfinitely
|
||||
};
|
||||
|
||||
void renderForDepthMap(const glm::dmat4& vp) const override;
|
||||
glm::dvec3 center() const override;
|
||||
|
||||
std::filesystem::path _file;
|
||||
std::unique_ptr<ghoul::modelgeometry::ModelGeometry> _geometry;
|
||||
bool _invertModelScale = false;
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
#include <modules/debugging/rendering/debugrenderer.h>
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/gpulayergroup.h>
|
||||
@@ -35,8 +34,6 @@
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/events/event.h>
|
||||
#include <openspace/events/eventengine.h>
|
||||
#include <openspace/interaction/sessionrecordinghandler.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
@@ -59,7 +56,6 @@
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
|
||||
#include <ghoul/io/model/modelgeometry.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
@@ -73,6 +69,7 @@ namespace {
|
||||
|
||||
// Global flags to modify the RenderableGlobe
|
||||
constexpr bool LimitLevelByAvailableData = true;
|
||||
constexpr bool PreformHorizonCulling = true;
|
||||
|
||||
// Shadow structure
|
||||
struct ShadowRenderingStruct {
|
||||
@@ -133,18 +130,11 @@ namespace {
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PerformHorizonCullingInfo = {
|
||||
"PerformHorizonCulling",
|
||||
"Perform horizon culling",
|
||||
"If this value is set to 'true', renderables below the horizon will be culled.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ResetTileProviderInfo = {
|
||||
"ResetTileProviders",
|
||||
"Reset tile providers",
|
||||
"Reset all tile provides for the globe and reload the data.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
openspace::properties::Property::Visibility::Developer
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ModelSpaceRenderingInfo = {
|
||||
@@ -301,9 +291,6 @@ namespace {
|
||||
// [[codegen::verbatim(TargetLodScaleFactorInfo.description)]]
|
||||
std::optional<float> targetLodScaleFactor;
|
||||
|
||||
// [[codegen::verbatim(ModelSpaceRenderingInfo.description)]]
|
||||
std::optional<int> modelSpaceRenderingCutoffLevel;
|
||||
|
||||
// [[codegen::verbatim(OrenNayarRoughnessInfo.description)]]
|
||||
std::optional<float> orenNayarRoughness;
|
||||
|
||||
@@ -619,15 +606,14 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
BoolProperty(LevelProjectedAreaInfo, true),
|
||||
TriggerProperty(ResetTileProviderInfo),
|
||||
BoolProperty(PerformFrustumCullingInfo, true),
|
||||
BoolProperty(PerformHorizonCullingInfo, true),
|
||||
IntProperty(ModelSpaceRenderingInfo, 14, 1, 22),
|
||||
IntProperty(DynamicLodIterationCountInfo, 16, 4, 128)
|
||||
})
|
||||
, _debugPropertyOwner({ "Debug" })
|
||||
, _shadowMappingProperties({
|
||||
BoolProperty(ShadowMappingInfo, true),
|
||||
BoolProperty(ShadowMappingInfo, false),
|
||||
FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f),
|
||||
IntProperty(NumberShadowSamplesInfo, 4, 1, 256)
|
||||
IntProperty(NumberShadowSamplesInfo, 5, 1, 7)
|
||||
})
|
||||
, _shadowMappingPropertyOwner({ "ShadowMapping", "Shadow Mapping" })
|
||||
, _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments)
|
||||
@@ -748,9 +734,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.dynamicLodIterationCount);
|
||||
|
||||
_debugProperties.modelSpaceRenderingCutoffLevel =
|
||||
p.modelSpaceRenderingCutoffLevel.value_or(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
addPropertySubOwner(_debugPropertyOwner);
|
||||
|
||||
auto notifyShaderRecompilation = [this]() {
|
||||
@@ -1341,7 +1324,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly)
|
||||
std::vector<DepthMapData> depthMapData;
|
||||
for (const auto& [node, groups] : _shadowSpec) {
|
||||
for (const std::string& grp : groups) {
|
||||
auto [depthmap, vp] = global::renderEngine->shadowInformation(node, grp);
|
||||
auto [depthmap, vp] = global::renderEngine->shadowInformation(grp);
|
||||
depthMapData.emplace_back(depthmap, vp);
|
||||
}
|
||||
}
|
||||
@@ -1364,8 +1347,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly)
|
||||
traversalMemory.erase(traversalMemory.begin());
|
||||
|
||||
if (isLeaf(*n) && n->isVisible) {
|
||||
const bool useGlobalRendering = n->tileIndex.level < cutoff;
|
||||
if (useGlobalRendering) {
|
||||
if (n->tileIndex.level < cutoff) {
|
||||
global[iGlobal] = n;
|
||||
iGlobal++;
|
||||
}
|
||||
@@ -1692,7 +1674,6 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<glm::dmat4> lightViewProjections;
|
||||
std::vector<std::pair<ghoul::opengl::TextureUnit, GLuint>> depthmapTextureUnits;
|
||||
for (const DepthMapData& depthData : depthMapData) {
|
||||
@@ -2000,12 +1981,12 @@ void RenderableGlobe::recompileShaders() {
|
||||
|
||||
// Both shader programs use depthmap shadows
|
||||
shaderDictionary.setValue("useDepthmapShadows", 1);
|
||||
int nmaps = 0;
|
||||
int nDepthMaps = 0;
|
||||
for (const auto& [src, grps] : _shadowSpec) {
|
||||
nmaps += static_cast<int>(grps.size());
|
||||
nDepthMaps += static_cast<int>(grps.size());
|
||||
}
|
||||
|
||||
shaderDictionary.setValue("nDepthMaps", nmaps);
|
||||
shaderDictionary.setValue("nDepthMaps", nDepthMaps);
|
||||
//
|
||||
// Create local shader
|
||||
//
|
||||
@@ -2094,8 +2075,9 @@ bool RenderableGlobe::testIfCullable(const Chunk& chunk,
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
return (_debugProperties.performHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) ||
|
||||
(_debugProperties.performFrustumCulling && isCullableByFrustum(chunk, renderData, mvp));
|
||||
return (PreformHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) ||
|
||||
(_debugProperties.performFrustumCulling &&
|
||||
isCullableByFrustum(chunk, renderData, mvp));
|
||||
}
|
||||
|
||||
int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderData,
|
||||
|
||||
@@ -243,7 +243,6 @@ private:
|
||||
properties::BoolProperty levelByProjectedAreaElseDistance;
|
||||
properties::TriggerProperty resetTileProviders;
|
||||
properties::BoolProperty performFrustumCulling;
|
||||
properties::BoolProperty performHorizonCulling;
|
||||
properties::IntProperty modelSpaceRenderingCutoffLevel;
|
||||
properties::IntProperty dynamicLodIterationCount;
|
||||
} _debugProperties;
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/deferredcaster.h>
|
||||
@@ -34,6 +33,7 @@
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/shadowmapping.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
@@ -46,9 +46,11 @@
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -438,21 +440,25 @@ void FramebufferRenderer::deferredcastersChanged(Deferredcaster&,
|
||||
_dirtyDeferredcastData = true;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::registerShadowCaster(const std::string& shadowgroup,
|
||||
const SceneGraphNode* lightsource, const SceneGraphNode* target)
|
||||
void FramebufferRenderer::registerShadowCaster(const std::string& shadowGroup,
|
||||
const SceneGraphNode* lightsource,
|
||||
const SceneGraphNode* target)
|
||||
{
|
||||
constexpr int DepthMapResolutionMultiplier = 4;
|
||||
|
||||
if (!_shadowMaps.contains(shadowgroup)) {
|
||||
if (!_shadowMaps.contains(shadowGroup)) {
|
||||
_shadowMaps.insert({});
|
||||
}
|
||||
|
||||
ShadowMap& shadowMap = _shadowMaps[shadowgroup];
|
||||
ShadowMap& shadowMap = _shadowMaps[shadowGroup];
|
||||
|
||||
shadowMap.shadowGroups.push_back(target->identifier());
|
||||
shadowMap.targets.push_back(target);
|
||||
shadowMap.lightsource = lightsource;
|
||||
shadowMap.depthMapResolution = global::renderEngine->renderingResolution() * DepthMapResolutionMultiplier;
|
||||
shadowMap.depthMapResolution =
|
||||
global::renderEngine->renderingResolution() * DepthMapResolutionMultiplier;
|
||||
|
||||
shadowMap.depthMapResolution =
|
||||
glm::min(shadowMap.depthMapResolution, glm::ivec2(OpenGLCap.max2DTextureSize()));
|
||||
|
||||
GLint prevFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
|
||||
@@ -490,8 +496,39 @@ void FramebufferRenderer::registerShadowCaster(const std::string& shadowgroup,
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, prevFbo);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::removeShadowCaster(const std::string& shadowGroup,
|
||||
const SceneGraphNode* target)
|
||||
{
|
||||
if (!_shadowMaps.contains(shadowGroup)) {
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Could not find shadow group '{}'", shadowGroup
|
||||
));
|
||||
}
|
||||
ShadowMap& shadowMap = _shadowMaps[shadowGroup];
|
||||
|
||||
auto it = std::find(
|
||||
shadowMap.targets.begin(),
|
||||
shadowMap.targets.end(),
|
||||
target
|
||||
);
|
||||
if (it == shadowMap.targets.end()) {
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Could not find shadowing target '{}'", target->identifier()
|
||||
));
|
||||
}
|
||||
|
||||
shadowMap.targets.erase(it);
|
||||
|
||||
// If this was the last target we can destroy the depth map and the FBO
|
||||
if (shadowMap.targets.empty()) {
|
||||
glDeleteTextures(1, &shadowMap.depthMap);
|
||||
glDeleteFramebuffers(1, &shadowMap.fbo);
|
||||
_shadowMaps.erase(shadowGroup);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<GLuint, glm::dmat4> FramebufferRenderer::shadowInformation(
|
||||
const SceneGraphNode* node, const std::string& shadowgroup) const
|
||||
const std::string& shadowgroup) const
|
||||
{
|
||||
ghoul_assert(_shadowMaps.contains(shadowgroup), "Shadow group not registered");
|
||||
return {
|
||||
@@ -1178,26 +1215,30 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
RendererTasks tasks;
|
||||
|
||||
if (!_renderedDepthMapsThisFrame) {
|
||||
// We are using this flag to cover the cases where we have multiple draw calls per
|
||||
// frame (for example for fisheye rendering). We only need to generate the shadow
|
||||
// map once in these circumstances
|
||||
|
||||
renderDepthMaps();
|
||||
_renderedDepthMapsThisFrame = true;
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("Background");
|
||||
TracyGpuZone("Background")
|
||||
const ghoul::GLDebugGroup group("Background");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Background);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("Opaque");
|
||||
TracyGpuZone("Opaque")
|
||||
const ghoul::GLDebugGroup group("Opaque");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Opaque);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("PreDeferredTransparent");
|
||||
TracyGpuZone("PreDeferredTransparent")
|
||||
const ghoul::GLDebugGroup group("PreDeferredTransparent");
|
||||
data.renderBinMask = static_cast<int>(
|
||||
Renderable::RenderBin::PreDeferredTransparent
|
||||
@@ -1207,13 +1248,13 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
|
||||
// Run Volume Tasks
|
||||
{
|
||||
TracyGpuZone("Raycaster Tasks");
|
||||
TracyGpuZone("Raycaster Tasks")
|
||||
const ghoul::GLDebugGroup group("Raycaster Tasks");
|
||||
performRaycasterTasks(tasks.raycasterTasks, viewport);
|
||||
}
|
||||
|
||||
if (!tasks.deferredcasterTasks.empty()) {
|
||||
TracyGpuZone("Deferred Caster Tasks");
|
||||
TracyGpuZone("Deferred Caster Tasks")
|
||||
const ghoul::GLDebugGroup group("Deferred Caster Tasks");
|
||||
|
||||
// We use ping pong rendering in order to be able to render multiple deferred
|
||||
@@ -1229,14 +1270,14 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
glEnablei(GL_BLEND, 0);
|
||||
|
||||
{
|
||||
TracyGpuZone("Overlay");
|
||||
TracyGpuZone("Overlay")
|
||||
const ghoul::GLDebugGroup group("Overlay");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Overlay);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("PostDeferredTransparent");
|
||||
TracyGpuZone("PostDeferredTransparent")
|
||||
const ghoul::GLDebugGroup group("PostDeferredTransparent");
|
||||
data.renderBinMask = static_cast<int>(
|
||||
Renderable::RenderBin::PostDeferredTransparent
|
||||
@@ -1245,7 +1286,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("Sticker");
|
||||
TracyGpuZone("Sticker")
|
||||
const ghoul::GLDebugGroup group("Sticker");
|
||||
data.renderBinMask = static_cast<int>(
|
||||
Renderable::RenderBin::Sticker
|
||||
@@ -1297,24 +1338,24 @@ void FramebufferRenderer::renderDepthMaps() {
|
||||
glGetIntegerv(GL_VIEWPORT, prevVp);
|
||||
|
||||
for (std::pair<const std::string, ShadowMap>& shadowMap : _shadowMaps) {
|
||||
glm::dvec3 vmin = glm::dvec3(std::numeric_limits<double>::max()),
|
||||
vmax(-std::numeric_limits<double>::max());
|
||||
glm::dvec3 vmin = glm::dvec3(std::numeric_limits<double>::max());
|
||||
glm::dvec3 vmax = glm::dvec3(-std::numeric_limits<double>::max());
|
||||
|
||||
std::vector<RenderableModel*> torender;
|
||||
for (const std::string& identifier : shadowMap.second.shadowGroups) {
|
||||
SceneGraphNode* node =
|
||||
global::renderEngine->scene()->sceneGraphNode(identifier);
|
||||
if (node) {
|
||||
RenderableModel* model =
|
||||
dynamic_cast<RenderableModel*>(node->renderable());
|
||||
if (model && model->isEnabled() && model->isCastingShadow() && model->isReady()) {
|
||||
const double fsz = model->shadowFrustumSize();
|
||||
glm::dvec3 center = model->center();
|
||||
vmin = glm::min(vmin, center - fsz / 2);
|
||||
vmax = glm::max(vmax, center + fsz / 2);
|
||||
std::vector<const Shadower*> torender;
|
||||
for (const SceneGraphNode* node : shadowMap.second.targets) {
|
||||
ghoul_assert(node, "No SceneGraphNode");
|
||||
ghoul_assert(node->renderable(), "No Renderable");
|
||||
|
||||
torender.push_back(model);
|
||||
}
|
||||
const Shadower* model = dynamic_cast<const Shadower*>(node->renderable());
|
||||
if (model && node->renderable()->isEnabled() &&
|
||||
model->isCastingShadow() && node->renderable()->isReady())
|
||||
{
|
||||
const double fsz = model->shadowFrustumSize();
|
||||
glm::dvec3 center = model->center();
|
||||
vmin = glm::min(vmin, center - fsz / 2);
|
||||
vmax = glm::max(vmax, center + fsz / 2);
|
||||
|
||||
torender.push_back(model);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1342,10 +1383,9 @@ void FramebufferRenderer::renderDepthMaps() {
|
||||
shadowMap.second.depthMapResolution.y);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
for (const RenderableModel* model : torender) {
|
||||
for (const Shadower* model : torender) {
|
||||
model->renderForDepthMap(shadowMap.second.viewProjectionMatrix);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Restore previous FBO and viewport
|
||||
|
||||
@@ -687,37 +687,58 @@ uint64_t RenderEngine::frameNumber() const {
|
||||
return _frameNumber;
|
||||
}
|
||||
|
||||
void RenderEngine::registerShadowCaster(const std::string& shadowgroup,
|
||||
const SceneGraphNode* lightsource, SceneGraphNode* shadower,
|
||||
SceneGraphNode* shadowee)
|
||||
void RenderEngine::registerShadowCaster(const std::string& shadowGroup,
|
||||
const SceneGraphNode* lightsource,
|
||||
SceneGraphNode* shadower,
|
||||
SceneGraphNode* shadowee)
|
||||
{
|
||||
ghoul_assert(!shadowgroup.empty(), "No shadowgroup specified");
|
||||
ghoul_assert(!shadowGroup.empty(), "No shadowGroup specified");
|
||||
ghoul_assert(lightsource, "No light source specified");
|
||||
ghoul_assert(shadower, "No shadower specified");
|
||||
ghoul_assert(shadowee, "No shadowee specified");
|
||||
|
||||
_renderer.registerShadowCaster(shadowgroup, lightsource, shadower);
|
||||
_renderer.registerShadowCaster(shadowGroup, lightsource, shadower);
|
||||
|
||||
Shadower* sr = dynamic_cast<Shadower*>(shadower->renderable());
|
||||
if (!sr) {
|
||||
throw ghoul::RuntimeError("Provided shadower scene graph node is not a shadower");
|
||||
}
|
||||
sr->setLightSource(lightsource);
|
||||
sr->setShadowGroup(shadowgroup);
|
||||
|
||||
sr->setShadowGroup(shadowGroup);
|
||||
|
||||
Shadowee* se = dynamic_cast<Shadowee*>(shadowee->renderable());
|
||||
if (!se) {
|
||||
throw ghoul::RuntimeError("Provided shadowee scene graph node is not a shadowee");
|
||||
}
|
||||
se->addShadower(sr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::pair<GLuint, glm::dmat4> RenderEngine::shadowInformation(const SceneGraphNode* node,
|
||||
const std::string& shadowgroup) const
|
||||
void RenderEngine::removeShadowCaster(const std::string& shadowGroup,
|
||||
SceneGraphNode* shadower,
|
||||
SceneGraphNode* shadowee)
|
||||
{
|
||||
return _renderer.shadowInformation(node, shadowgroup);
|
||||
ghoul_assert(!shadowGroup.empty(), "No shadowGroup specified");
|
||||
ghoul_assert(shadower, "No shadower specified");
|
||||
ghoul_assert(shadowee, "No shadowee specified");
|
||||
|
||||
_renderer.removeShadowCaster(shadowGroup, shadower);
|
||||
|
||||
Shadower* sr = dynamic_cast<Shadower*>(shadower->renderable());
|
||||
if (!sr) {
|
||||
throw ghoul::RuntimeError("Provided shadower scene graph node is not a shadower");
|
||||
}
|
||||
|
||||
Shadowee* se = dynamic_cast<Shadowee*>(shadowee->renderable());
|
||||
if (!se) {
|
||||
throw ghoul::RuntimeError("Provided shadowee scene graph node is not a shadowee");
|
||||
}
|
||||
se->removeShadower(sr);
|
||||
}
|
||||
|
||||
std::pair<GLuint, glm::dmat4> RenderEngine::shadowInformation(
|
||||
const std::string& shadowgroup) const
|
||||
{
|
||||
return _renderer.shadowInformation(shadowgroup);
|
||||
}
|
||||
|
||||
void RenderEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& viewMatrix,
|
||||
|
||||
@@ -105,4 +105,13 @@ void Shadowee::addShadower(const Shadower* shadower) {
|
||||
}
|
||||
}
|
||||
|
||||
void Shadowee::removeShadower(const Shadower* shadower) {
|
||||
ghoul_precondition(shadower, "Shadower must not be nullptr");
|
||||
|
||||
auto it = std::find(_shadowers.begin(), _shadowers.end(), shadower);
|
||||
if (it != _shadowers.end()) {
|
||||
_shadowers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -1037,6 +1037,27 @@ namespace {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the pair of light source, shadower, shadowee, and shadowGroup to act together
|
||||
* in order to produce a depth image that is used for shadow calculations. The
|
||||
* lightSource, the shadower, and the shadowee must be existing scene graph nodes that are
|
||||
* used to calculate the positions of the light and to determine which object is rendered
|
||||
* to cast a shadow and which object should receive the shadow.
|
||||
* Shadowcasters registered using the same shadow group will have their shadows interact
|
||||
* with each other, whereas objects with different shadowGroups will not cast shadows on
|
||||
* objects other than the shadowee.
|
||||
*
|
||||
* \param lightSource The identifier of the scene graph node that should act as the source
|
||||
* of the light for shadowing purposes
|
||||
* \param shadower The identifier of the scene graph node that is the object that casts a
|
||||
* shadow on the shadowee and other shadowers in the tsame shadow group
|
||||
* \param shadowee The identifier of the scene graph node that is the object that receives
|
||||
* the shadow of the shadower
|
||||
* \param shadowGroup An arbitrary name that identifies a shadow group, meaning multiple
|
||||
* shadowcaster registrations that should act in unison. The name must
|
||||
* not start with a `_` character. If this parameter is omitted, a
|
||||
* suitable unique name will be automatically generated
|
||||
*/
|
||||
[[codegen::luawrap]] void registerShadowcaster(std::string lightSource,
|
||||
std::string shadower, std::string shadowee,
|
||||
std::optional<std::string> shadowGroup)
|
||||
@@ -1079,6 +1100,68 @@ namespace {
|
||||
global::renderEngine->registerShadowCaster(*shadowGroup, ls, shdr, shdee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing pairing of a shadowcaster group, consisting of a light source, a
|
||||
* shadower, a shadowee, and a shadow group. If the pairing exists, it will be removed,
|
||||
* causing the shadow calculations to cease. If the pairing does not exist, an error
|
||||
* message will be raised.
|
||||
*
|
||||
*
|
||||
* \param lightSource The identifier of the scene graph node that should act as the source
|
||||
* of the light for shadowing purposes
|
||||
* \param shadower The identifier of the scene graph node that is the object that casts a
|
||||
* shadow on the shadowee and other shadowers in the tsame shadow group
|
||||
* \param shadowee The identifier of the scene graph node that is the object that receives
|
||||
* the shadow of the shadower
|
||||
* \param shadowGroup An arbitrary name that identifies a shadow group, meaning multiple
|
||||
* shadowcaster registrations that should act in unison. The name must
|
||||
* not start with a `_` character. If this parameter is omitted, a
|
||||
* suitable unique name will be automatically generated. If the same
|
||||
* light source, shadower, and shadowee are provided as for a previous
|
||||
* register call, the generated name will be identical
|
||||
*/
|
||||
[[codegen::luawrap]] void removeShadowcaster(std::string lightSource,
|
||||
std::string shadower, std::string shadowee,
|
||||
std::optional<std::string> shadowGroup)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
if (shadowGroup.has_value() && !shadowGroup->empty() && shadowGroup->at(0) == '_') {
|
||||
throw ghoul::lua::LuaError(std::format(
|
||||
"The 'shadowGroup' parameter must not start with '_': {}", *shadowGroup
|
||||
));
|
||||
}
|
||||
|
||||
// Synthesize a unique name if none is provided
|
||||
if (!shadowGroup.has_value()) {
|
||||
static int Count = 0;
|
||||
shadowGroup = std::format("_{}|{}|{}|{}", lightSource, shadower, shadowee, Count);
|
||||
Count++;
|
||||
}
|
||||
ghoul_assert(shadowGroup.has_value(), "No shadowgroup specified");
|
||||
|
||||
const Scene* scene = global::renderEngine->scene();
|
||||
|
||||
const SceneGraphNode* ls = scene->sceneGraphNode(lightSource);
|
||||
if (!ls) {
|
||||
throw ghoul::lua::LuaError(std::format(
|
||||
"Could not find light source '{}'", lightSource
|
||||
));
|
||||
}
|
||||
|
||||
SceneGraphNode* shdr = scene->sceneGraphNode(shadower);
|
||||
if (!shdr) {
|
||||
throw ghoul::lua::LuaError(std::format("Could not find shadower '{}'", shadower));
|
||||
}
|
||||
|
||||
SceneGraphNode* shdee = scene->sceneGraphNode(shadowee);
|
||||
if (!shdee) {
|
||||
throw ghoul::lua::LuaError(std::format("Could not find shadowee '{}'", shadowee));
|
||||
}
|
||||
|
||||
global::renderEngine->removeShadowCaster(*shadowGroup, shdr, shdee);
|
||||
}
|
||||
|
||||
// Returns a list of all scene graph nodes in the scene that have a renderable of the
|
||||
// specific type
|
||||
[[codegen::luawrap]] std::vector<std::string> nodeByRenderableType(std::string type) {
|
||||
|
||||
Reference in New Issue
Block a user