Instancing will no longer be used under X instances
*Experimental* optimization Former-commit-id: 4dee4905d59739b3ec062ef283d4b7561160e21d
This commit is contained in:
parent
b969c24060
commit
28eff9af30
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
|
// À partir de combien d'instances d'un même mesh/matériau l'instancing doit-il être utilisé ?
|
||||||
|
#define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 100
|
||||||
|
|
||||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||||
#define NAZARA_GRAPHICS_MEMORYLEAKTRACKER 0
|
#define NAZARA_GRAPHICS_MEMORYLEAKTRACKER 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <Nazara/Math/Box.hpp>
|
#include <Nazara/Math/Box.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
class NzCamera;
|
class NzCamera;
|
||||||
class NzMaterial;
|
class NzMaterial;
|
||||||
|
|
@ -85,7 +86,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
||||||
|
|
||||||
typedef std::map<const NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
|
typedef std::map<const NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
|
||||||
typedef std::map<const NzStaticMesh*, std::vector<StaticData>, StaticMeshComparator> StaticMeshContainer;
|
typedef std::map<const NzStaticMesh*, std::vector<StaticData>, StaticMeshComparator> StaticMeshContainer;
|
||||||
typedef std::map<const NzMaterial*, std::pair<SkeletalMeshContainer, StaticMeshContainer>, ModelMaterialComparator> MeshContainer;
|
typedef std::map<const NzMaterial*, std::tuple<bool, SkeletalMeshContainer, StaticMeshContainer>, ModelMaterialComparator> MeshContainer;
|
||||||
|
|
||||||
MeshContainer opaqueModels;
|
MeshContainer opaqueModels;
|
||||||
std::vector<std::pair<unsigned int, bool>> transparentsModels;
|
std::vector<std::pair<unsigned int, bool>> transparentsModels;
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
||||||
if (pair.second)
|
if (pair.second)
|
||||||
material->AddResourceListener(this, ResourceType_Material);
|
material->AddResourceListener(this, ResourceType_Material);
|
||||||
|
|
||||||
auto& meshMap = pair.first->second.second;
|
auto& meshMap = std::get<2>(pair.first->second);
|
||||||
|
|
||||||
auto pair2 = meshMap.insert(std::make_pair(staticMesh, StaticMeshContainer::mapped_type()));
|
auto pair2 = meshMap.insert(std::make_pair(staticMesh, StaticMeshContainer::mapped_type()));
|
||||||
if (pair2.second)
|
if (pair2.second)
|
||||||
|
|
@ -144,7 +144,13 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
||||||
|
|
||||||
std::vector<StaticData>& staticDataContainer = pair2.first->second;
|
std::vector<StaticData>& staticDataContainer = pair2.first->second;
|
||||||
|
|
||||||
staticDataContainer.resize(staticDataContainer.size()+1);
|
unsigned int instanceCount = staticDataContainer.size() + 1;
|
||||||
|
|
||||||
|
// As-t-on suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
|
||||||
|
if (instanceCount >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
|
||||||
|
std::get<0>(pair.first->second) = true; // Apparemment oui, activons l'instancing avec ce matériau
|
||||||
|
|
||||||
|
staticDataContainer.resize(instanceCount);
|
||||||
StaticData& data = staticDataContainer.back();
|
StaticData& data = staticDataContainer.back();
|
||||||
|
|
||||||
data.aabb = staticMesh->GetAABB();
|
data.aabb = staticMesh->GetAABB();
|
||||||
|
|
@ -211,7 +217,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
|
||||||
case ResourceType_SkeletalMesh:
|
case ResourceType_SkeletalMesh:
|
||||||
{
|
{
|
||||||
for (auto& pair : opaqueModels)
|
for (auto& pair : opaqueModels)
|
||||||
pair.second.first.erase(static_cast<const NzSkeletalMesh*>(resource));
|
std::get<1>(pair.second).erase(static_cast<const NzSkeletalMesh*>(resource));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +225,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
|
||||||
case ResourceType_StaticMesh:
|
case ResourceType_StaticMesh:
|
||||||
{
|
{
|
||||||
for (auto& pair : opaqueModels)
|
for (auto& pair : opaqueModels)
|
||||||
pair.second.second.erase(static_cast<const NzStaticMesh*>(resource));
|
std::get<2>(pair.second).erase(static_cast<const NzStaticMesh*>(resource));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,20 +143,20 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||||
// Rendu des modèles opaques
|
// Rendu des modèles opaques
|
||||||
for (auto& matIt : m_renderQueue.opaqueModels)
|
for (auto& matIt : m_renderQueue.opaqueModels)
|
||||||
{
|
{
|
||||||
NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = matIt.second.first;
|
NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = std::get<1>(matIt.second);
|
||||||
NzForwardRenderQueue::StaticMeshContainer& staticContainer = matIt.second.second;
|
NzForwardRenderQueue::StaticMeshContainer& staticContainer = std::get<2>(matIt.second);
|
||||||
|
|
||||||
if (!skeletalContainer.empty() || !staticContainer.empty())
|
if (!skeletalContainer.empty() || !staticContainer.empty())
|
||||||
{
|
{
|
||||||
const NzMaterial* material = matIt.first;
|
const NzMaterial* material = matIt.first;
|
||||||
|
|
||||||
// Nous utilisons de l'instancing lorsqu'aucune lumière (autre que directionnelle) n'est active
|
// La RenderQueue active ou non l'instancing selon le nombre d'instances
|
||||||
|
bool renderQueueInstancing = std::get<0>(matIt.second);
|
||||||
|
|
||||||
|
// Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active
|
||||||
// Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches
|
// Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches
|
||||||
// (Le deferred shading n'a pas ce problème)
|
// (Le deferred shading n'a pas ce problème)
|
||||||
|
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty() && renderQueueInstancing;
|
||||||
///FIXME: l'instancing fait-il réellement gagner en performances ?
|
|
||||||
///TODO: Activer l'instancing uniquement si plusieurs instances sont à rendre ?
|
|
||||||
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty();
|
|
||||||
|
|
||||||
// On commence par récupérer le programme du matériau
|
// On commence par récupérer le programme du matériau
|
||||||
const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, (instancing) ? nzShaderFlags_Instancing : 0);
|
const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, (instancing) ? nzShaderFlags_Instancing : 0);
|
||||||
|
|
@ -284,6 +284,9 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Et on remet à zéro l'instancing
|
||||||
|
std::get<0>(matIt.second) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::pair<unsigned int, bool>& pair : m_renderQueue.transparentsModels)
|
for (const std::pair<unsigned int, bool>& pair : m_renderQueue.transparentsModels)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue