#1 

26-06-2009 22:40:06

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 86.215.145.207
Courriel

Hello sa fait un baille que j'ai pas poster une ressource x), donc j'ai mit au point mon système de frustrum culling en me basant sur celui de tmyke concrètement cela sert a masquer les node non visible et donc de gagner du frame rate





FrustrumCulling.hppFrustrumCulling.cppPlane.hppPlane.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
///--------------------------------------------------------------------------------
/// @file FrustrumCulling.hpp
/// @brief Technique de culling par masquage d'objet non visible
///--------------------------------------------------------------------------------
#ifndef __FRUSTRUMCULLING_HPP_INCLUDED__
#define __FRUSTRUMCULLING_HPP_INCLUDED__

#include "Plane.hpp"
#include <irrlicht.h>

namespace App { namespace Engine { namespace Culling {

	///--------------------------------------------------------------------------------
	/// Technique de culling par masquage d'objet non visible
	///--------------------------------------------------------------------------------
	class FrustrumCulling
	{
		public:
			///--------------------------------------------------------------------------------
			/// Constructeur
			///
			/// @param _SceneManager : Gestionnaire de scene
			///--------------------------------------------------------------------------------
			FrustrumCulling(irr::scene::ISceneManager * _SceneManager);
			///--------------------------------------------------------------------------------
			/// Destructeur
			///--------------------------------------------------------------------------------
			~FrustrumCulling();

			///--------------------------------------------------------------------------------
			/// Pour crée le culling
			///--------------------------------------------------------------------------------
			void Create();
			///--------------------------------------------------------------------------------
			/// Pour recrée le culling
			///--------------------------------------------------------------------------------
			void Recreate();

			///--------------------------------------------------------------------------------
			/// Pour mettre a jour le culling
			///--------------------------------------------------------------------------------
			void Update();

			///--------------------------------------------------------------------------------
			/// Pour ajouter un scene node
			///
			/// @param _SceneNode : Pointeur vers le scene node
			///--------------------------------------------------------------------------------
			void AddSceneNode(const irr::scene::ISceneNode * _SceneNode);
			///--------------------------------------------------------------------------------
			/// Pour supprimer un scene node
			///
			/// @param _SceneNode : Pointeur vers le scene node
			///--------------------------------------------------------------------------------
			void RemoveSceneNode(const irr::scene::ISceneNode * _SceneNode);

			///--------------------------------------------------------------------------------
			/// Pour tester si une box et visible
			///
			/// @param _Box : Box a tester
			///--------------------------------------------------------------------------------
			bool IsVisible(const irr::core::aabbox3d<irr::f32>& box);

		private:
			///--------------------------------------------------------------------------------
			/// Gestionnaire de scene
			///--------------------------------------------------------------------------------
			irr::scene::ISceneManager * m_SceneManager;
			///--------------------------------------------------------------------------------
			/// Pour stocker les nodes
			///--------------------------------------------------------------------------------
			irr::core::array<irr::scene::ISceneNode *> m_Nodes;
			///--------------------------------------------------------------------------------
			/// Pour tester si un node est visible
			///--------------------------------------------------------------------------------
			App::Core::Plane m_FrustumPlane[6];
			///--------------------------------------------------------------------------------
			/// Dernier / derniere position et cible de la camera
			///--------------------------------------------------------------------------------
			irr::core::vector3df m_LastPosition, m_LastTarget;
	};

}	// Culling
}	// Engine
}	// App

#endif	// __FRUSTRUMCULLING_HPP_INCLUDED__

Donc voila alors pour l'utilisation ajouter juste avant la boucle de rendu

Code c++ :

App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);
m_FrustrumCulling->Create();

et dans le boucle de rendu

Code c++ :

m_FrustrumCulling->Update();
m_Driver->beginScene(.........

=========================================

Exemple complet :

Code c++ :

#include <irrlicht.h>
#include "FrustrumCulling.hpp"

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
	irr::SIrrlichtCreationParameters m_IrrlichtCreationParameters;
	m_IrrlichtCreationParameters.AntiAlias			= true;
	m_IrrlichtCreationParameters.Bits				= 32;
	m_IrrlichtCreationParameters.DriverType			= irr::video::EDT_DIRECT3D9;
	m_IrrlichtCreationParameters.Fullscreen			= false;
	m_IrrlichtCreationParameters.HighPrecisionFPU	= true;
	m_IrrlichtCreationParameters.Stencilbuffer		= true;
	m_IrrlichtCreationParameters.WindowSize			= irr::core::dimension2di(800,600);

	irr::IrrlichtDevice			* m_Device			= irr::createDeviceEx(m_IrrlichtCreationParameters);
	irr::video::IVideoDriver	* m_Driver			= m_Device->getVideoDriver();
	irr::scene::ISceneManager	* m_SceneManager	= m_Device->getSceneManager();

	for( int x = 0 ; x != 10 ; x++)
		for( int y = 0 ; y != 10 ; y++)
			for( int z = 0 ; z != 10 ; z++)
				m_SceneManager->addCubeSceneNode(1, 0 , -1, irr::core::vector3df(x * 10 ,y* 10, z* 10));

	irr::scene::ICameraSceneNode * m_Camera = m_SceneManager->addCameraSceneNodeFPS(0, 40.f, 0.01f);
	m_Camera->setPosition(m_Camera->getPosition() + irr::core::vector3df(0,20,0));
   
	App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);

	m_FrustrumCulling->Create();
	int __LastFPS = -1;

	while(m_Device->run())
	{
		if (m_Device->isWindowActive())
		{
			m_FrustrumCulling->Update();
			m_Driver->beginScene(true, true, irr::video::SColor(0,200,200,200));
			m_SceneManager->drawAll();
			m_Driver->endScene();
			
			int __Fps = m_Driver->getFPS();
			if (__LastFPS != __Fps)
			{
				core::stringw __Str;
				__Str += "FPS:";
				__Str += __Fps;
				m_Device->setWindowCaption(__Str.c_str());
				__LastFPS = __Fps;
			}

		}
	}
	delete m_FrustrumCulling;
	m_Device->drop();

	return 0;
}


Hors ligne


#2 

27-06-2009 07:07:25

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.21.77
Courriel

Merci pour le partage de ces codes wink et cool de te voir passer dans le coin.

Irrlicht a bien besoin de ce genre de code pour améliorer ses performances wink

Merci.


Force et sagesse...

Hors ligne


#3 

27-06-2009 12:17:54

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 86.215.145.207
Courriel

^^


Hors ligne


#4 

29-06-2009 17:53:55

Copland
Modérateurs
Date d'inscription:
Messages: 657
IP: 92.136.78.41
Courriel  Site web

Je croyais qu'irrlicht avait déjà son propre frustum culling, je comprends plus là :s


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#5 

29-06-2009 19:06:12

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 86.215.144.87
Courriel

oui ca peut paraitre enbicieu mais mon system et plus performent environ 34fps sur une scene avec 1000 cube , celui de irrlicht bug un peu il faut carement que le node soit derriere la camera pour qui soit detecter comme non visible


Hors ligne


#6 

29-06-2009 19:47:29

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.70.37
Courriel

Je confirme.


Force et sagesse...

Hors ligne


#7 

30-06-2009 09:56:40

Metallizer
Membres
Avatar de Metallizer
Date d'inscription:
Messages: 100
IP: 80.14.49.68
Courriel  Site web

J'ai pas encore testé ton code mais justement, si Irrlicht attend qu'un node soit bien derrière la caméra pour le cacher, ça doit être pour éviter le cas où le node est très grand.

Moi aussi en tout cas je suis interloqué, je croyais que le frustrum culling de Irrlicht agissait sur les triangles (et non les nodes) grâce à un octree... ou alors j'ai vraiment rien pigé.


Hors ligne


#8 

30-06-2009 15:05:17

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 86.215.144.87
Courriel

il y a plusieur type de culling : frustrum, ambient, oclusion...


Hors ligne


#9 

14-08-2011 20:36:31

thoced
Membres
Date d'inscription:
Messages: 65
IP: 91.179.204.204
Courriel

Allais je relance ce topic.

Et dans la version actuel d'Irrlicht. Ce probleme de Frustum est-t-il corrigé ?.

Car effectivement j'ai l'impression qu'avec la version 1.7.2, effectivement les nodes de l'octree ne sont pas visibile si seulement ils sont derrière la caméra.

Si je ne me trompe pas, ce probleme sera-t-il corrigé dans la version futur ?

merci

a+, thoced


Hors ligne


#10 

15-08-2011 03:04:50

Magun
Administrateurs
Avatar de Magun
Date d'inscription:
Messages: 910
IP: 188.93.45.30
Courriel  Site web

le probleme est corriger sur le svn (1.8)
enfin sa bug encore un peut

Hors ligne


#11 

15-08-2011 07:32:36

thoced
Membres
Date d'inscription:
Messages: 65
IP: 91.179.204.204
Courriel

Justement je viens juste de de compiler la version 1.8 (SVN) et j'ai toujours le meme probleme.

Mais bon pour être sur de ne pas dire de bètise: voici exactement comment je procède

1) je charge un mesh (petit terrain au format b3d)
2) je crée une node avec smgr->addOctreeSceneNode(...);
3) je spécifie le type culling node->setAutomaticCulling(EAC_FRUSTUM_BOX);

4) j'affiche le nombre de polygones qui s'affichent.

Et la je constate que lorsque je positionne ma camera sur le terrain, effectivement le nombre de poly diminue lorsque les nodes crée par l'octree se trouvent derrière la camera mais par contre lorsque je positionne la camera en hauteur en regardant vers le bas (un peu à la façon d'un jeu RTS), je constate que dés que qu'un node de l'octree se trouve dans le cone de visibilité, c'est l'ensemble du mesh qui est affiché parceque justement tous les nodes de l'octree se trouvent devant la camera.

merci de m'indiquer si je me trompe

a+, thoced


Hors ligne


#12 

16-08-2011 09:01:50

Magun
Administrateurs
Avatar de Magun
Date d'inscription:
Messages: 910
IP: 188.93.45.30
Courriel  Site web

non c'est sa, mais dans ce cas intéresse toi a l'oclusion culling, en gros tu fait un raytest entre la camera et les tout nodes pour déterminer leur visibiliter
par contre c'est lent, mais facil a interfacer dans un thread séparé

Hors ligne


#13 

17-08-2011 21:38:04

thoced
Membres
Date d'inscription:
Messages: 65
IP: 91.179.6.79
Courriel

Je trouve franchement dommage que dans un moteur graphique, le Frustum culling ne soit pas encore complètement correctement implémenté.
C'est quand même les bases je pense surtout si l'on veut que le moteur perdure dans le temps.

Attention je n'ai pas dit que c'était facile a développer mais je trouve que les choix pris pour l'amélioration du moteur sont parfois étrange.


Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
119 invités en ligne
membre en ligne: -
RSS Feed