Instancing will no longer be used under X instances

*Experimental* optimization


Former-commit-id: 4dee4905d59739b3ec062ef283d4b7561160e21d
This commit is contained in:
Lynix 2013-08-09 00:33:18 +02:00
parent b969c24060
commit 28eff9af30
4 changed files with 25 additions and 12 deletions

View File

@ -29,6 +29,9 @@
/// 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)
#define NAZARA_GRAPHICS_MEMORYLEAKTRACKER 0

View File

@ -14,6 +14,7 @@
#include <Nazara/Math/Box.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <map>
#include <tuple>
class NzCamera;
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 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;
std::vector<std::pair<unsigned int, bool>> transparentsModels;

View File

@ -136,7 +136,7 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
if (pair.second)
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()));
if (pair2.second)
@ -144,7 +144,13 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
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();
data.aabb = staticMesh->GetAABB();
@ -211,7 +217,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
case ResourceType_SkeletalMesh:
{
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;
}
@ -219,7 +225,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
case ResourceType_StaticMesh:
{
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;
}

View File

@ -143,20 +143,20 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
// Rendu des modèles opaques
for (auto& matIt : m_renderQueue.opaqueModels)
{
NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = matIt.second.first;
NzForwardRenderQueue::StaticMeshContainer& staticContainer = matIt.second.second;
NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = std::get<1>(matIt.second);
NzForwardRenderQueue::StaticMeshContainer& staticContainer = std::get<2>(matIt.second);
if (!skeletalContainer.empty() || !staticContainer.empty())
{
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
// (Le deferred shading n'a pas ce problème)
///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();
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty() && renderQueueInstancing;
// On commence par récupérer le programme du matériau
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)