Select lights closest to the reference node, not per model
This makes dynamic lighting slighly more performant and improves area lighting.
This commit is contained in:
parent
563238fd92
commit
200b1ad6d8
6 changed files with 22 additions and 70 deletions
|
@ -725,15 +725,17 @@ void Game::updateSceneGraph(float dt) {
|
|||
const Camera *camera = getActiveCamera();
|
||||
if (!camera) return;
|
||||
|
||||
shared_ptr<SceneNode> shadowReference;
|
||||
// Select a reference node for dynamic lighting
|
||||
shared_ptr<SceneNode> lightingRefNode;
|
||||
shared_ptr<Creature> partyLeader(_party.getLeader());
|
||||
if (partyLeader && _cameraType == CameraType::ThirdPerson) {
|
||||
shadowReference = partyLeader->getModelSceneNode();
|
||||
lightingRefNode = partyLeader->getModelSceneNode();
|
||||
} else {
|
||||
shadowReference = camera->sceneNode();
|
||||
lightingRefNode = camera->sceneNode();
|
||||
}
|
||||
|
||||
_sceneGraph.setActiveCamera(camera->sceneNode());
|
||||
_sceneGraph.setShadowReference(shadowReference);
|
||||
_sceneGraph.setLightingRefNode(lightingRefNode);
|
||||
_sceneGraph.setUpdateRoots(!_paused);
|
||||
_sceneGraph.update(dt);
|
||||
}
|
||||
|
|
|
@ -304,7 +304,7 @@ void ModelNodeSceneNode::drawSingle(bool shadowPass) {
|
|||
uniforms.combined.general.selfIllumColor = glm::vec4(_selfIllumColor, 1.0f);
|
||||
}
|
||||
if (isLightingEnabled()) {
|
||||
const vector<LightSceneNode *> &lights = _modelSceneNode->lightsAffectedBy();
|
||||
const vector<LightSceneNode *> &lights = _sceneGraph->closestLights();
|
||||
|
||||
uniforms.combined.featureMask |= UniformFeatureFlags::lighting;
|
||||
if (_material.custom) {
|
||||
|
|
|
@ -246,34 +246,6 @@ void ModelSceneNode::attach(const string &parent, const shared_ptr<SceneNode> &n
|
|||
}
|
||||
}
|
||||
|
||||
void ModelSceneNode::updateAbsoluteTransform() {
|
||||
SceneNode::updateAbsoluteTransform();
|
||||
_lightingDirty = true;
|
||||
}
|
||||
|
||||
void ModelSceneNode::updateLighting() {
|
||||
if (!_lightingDirty) return;
|
||||
|
||||
_lightsAffectedBy.clear();
|
||||
_sceneGraph->getLightsAt(*this, _lightsAffectedBy, kMaxLights, bind(&ModelSceneNode::isAffectableByLight, this, _1));
|
||||
_lightingDirty = false;
|
||||
|
||||
for (auto &attached : _attachedModels) {
|
||||
attached.second->setLightsAffectedBy(_lightsAffectedBy);
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelSceneNode::isAffectableByLight(const LightSceneNode &light) const {
|
||||
if (light.isAmbientOnly()) {
|
||||
return _usage == ModelUsage::Room;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelSceneNode::setLightingIsDirty() {
|
||||
_lightingDirty = true;
|
||||
}
|
||||
|
||||
bool ModelSceneNode::getNodeAbsolutePosition(const string &name, glm::vec3 &position) const {
|
||||
shared_ptr<ModelNode> node(_model->findNodeByName(name));
|
||||
if (!node) {
|
||||
|
@ -313,9 +285,6 @@ void ModelSceneNode::setVisible(bool visible) {
|
|||
for (auto &attached : _attachedModels) {
|
||||
attached.second->setVisible(visible);
|
||||
}
|
||||
if (visible) {
|
||||
_lightingDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelSceneNode::setAlpha(float alpha) {
|
||||
|
@ -330,10 +299,6 @@ void ModelSceneNode::setProjectileSpeed(float speed) {
|
|||
_projectileSpeed = speed;
|
||||
}
|
||||
|
||||
void ModelSceneNode::setLightsAffectedBy(const vector<LightSceneNode *> &lights) {
|
||||
_lightsAffectedBy = lights;
|
||||
}
|
||||
|
||||
void ModelSceneNode::setWalkmesh(shared_ptr<Walkmesh> walkmesh) {
|
||||
_walkmesh = move(walkmesh);
|
||||
}
|
||||
|
|
|
@ -83,17 +83,6 @@ public:
|
|||
|
||||
// END Attachments
|
||||
|
||||
// Dynamic lighting
|
||||
|
||||
void updateLighting();
|
||||
void setLightingIsDirty();
|
||||
|
||||
const std::vector<LightSceneNode *> &lightsAffectedBy() const { return _lightsAffectedBy; }
|
||||
|
||||
void setLightsAffectedBy(const std::vector<LightSceneNode *> &lights);
|
||||
|
||||
// END Dynamic lighting
|
||||
|
||||
private:
|
||||
IAnimationEventListener *_animEventListener;
|
||||
|
||||
|
@ -109,14 +98,9 @@ private:
|
|||
std::unordered_map<uint16_t, std::shared_ptr<ModelSceneNode>> _attachedModels;
|
||||
bool _visible { true };
|
||||
float _alpha { 1.0f };
|
||||
std::vector<LightSceneNode *> _lightsAffectedBy;
|
||||
bool _lightingDirty { true };
|
||||
float _projectileSpeed { 0.0f };
|
||||
|
||||
void initModelNodes();
|
||||
void updateAbsoluteTransform() override;
|
||||
|
||||
bool isAffectableByLight(const LightSceneNode &light) const;
|
||||
|
||||
std::unique_ptr<ModelNodeSceneNode> getModelNodeSceneNode(graphics::ModelNode &node) const;
|
||||
};
|
||||
|
|
|
@ -86,11 +86,10 @@ void SceneGraph::cullRoots() {
|
|||
}
|
||||
|
||||
void SceneGraph::updateLighting() {
|
||||
// Associate each model node with light sources
|
||||
for (auto &root : _roots) {
|
||||
if (root->type() == SceneNodeType::Model) {
|
||||
static_pointer_cast<ModelSceneNode>(root)->updateLighting();
|
||||
}
|
||||
_closestLights.clear();
|
||||
|
||||
if (_lightingRefNode) {
|
||||
getLightsAt(*_lightingRefNode, _closestLights, kMaxLights, [](auto &light) { return !light.isAmbientOnly(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,9 +166,9 @@ void SceneGraph::refreshFromSceneNode(const std::shared_ptr<SceneNode> &node) {
|
|||
void SceneGraph::refreshShadowLight() {
|
||||
const LightSceneNode *nextShadowLight = nullptr;
|
||||
|
||||
if (_shadowReference) {
|
||||
if (_lightingRefNode) {
|
||||
vector<LightSceneNode *> lights;
|
||||
getLightsAt(*_shadowReference, lights, 1, [](auto &light) { return light.isShadow(); });
|
||||
getLightsAt(*_lightingRefNode, lights, 1, [](auto &light) { return light.isShadow(); });
|
||||
|
||||
if (!lights.empty()) {
|
||||
nextShadowLight = lights.front();
|
||||
|
|
|
@ -66,7 +66,6 @@ public:
|
|||
|
||||
void setUpdateRoots(bool update) { _updateRoots = update; }
|
||||
void setActiveCamera(std::shared_ptr<CameraSceneNode> camera) { _activeCamera = std::move(camera); }
|
||||
void setShadowReference(std::shared_ptr<SceneNode> reference) { _shadowReference = std::move(reference); }
|
||||
void setUniformsPrototype(graphics::ShaderUniforms &&uniforms) { _uniformsPrototype = uniforms; }
|
||||
|
||||
// Roots
|
||||
|
@ -77,7 +76,7 @@ public:
|
|||
|
||||
// END Roots
|
||||
|
||||
// Lights and shadows
|
||||
// Lighting and shadows
|
||||
|
||||
/**
|
||||
* Fill lights vector with up to count lights, sorted by priority and
|
||||
|
@ -90,12 +89,14 @@ public:
|
|||
std::function<bool(const LightSceneNode &)> predicate = [](auto &light) { return true; }) const;
|
||||
|
||||
const glm::vec3 &ambientLightColor() const { return _ambientLightColor; }
|
||||
const std::vector<LightSceneNode *> closestLights() const { return _closestLights; }
|
||||
const LightSceneNode *shadowLight() const { return _shadowLight; }
|
||||
float shadowStrength() const { return _shadowStrength; }
|
||||
|
||||
void setAmbientLightColor(glm::vec3 color) { _ambientLightColor = std::move(color); }
|
||||
void setLightingRefNode(std::shared_ptr<SceneNode> node) { _lightingRefNode = std::move(node); }
|
||||
|
||||
// END Lights and shadows
|
||||
// END Lighting and shadows
|
||||
|
||||
// Fog
|
||||
|
||||
|
@ -127,19 +128,20 @@ private:
|
|||
std::vector<std::pair<EmitterSceneNode *, std::vector<Particle *>>> _particles;
|
||||
std::vector<std::pair<GrassSceneNode *, std::vector<GrassCluster>>> _grassClusters;
|
||||
|
||||
glm::vec3 _ambientLightColor { 0.5f };
|
||||
uint32_t _textureId { 0 };
|
||||
bool _updateRoots { true };
|
||||
graphics::ShaderUniforms _uniformsPrototype;
|
||||
|
||||
// Shadows
|
||||
// Lighting and shadows
|
||||
|
||||
glm::vec3 _ambientLightColor { 0.5f };
|
||||
std::shared_ptr<SceneNode> _lightingRefNode; /**< reference node to use when selecting closest light sources */
|
||||
std::vector<LightSceneNode *> _closestLights;
|
||||
const LightSceneNode *_shadowLight { nullptr };
|
||||
std::shared_ptr<SceneNode> _shadowReference;
|
||||
float _shadowStrength { 1.0f };
|
||||
bool _shadowFading { false };
|
||||
|
||||
// END Shadows
|
||||
// END Lighting and shadows
|
||||
|
||||
// Fog
|
||||
|
||||
|
|
Loading…
Reference in a new issue