Level of Detail

Discussion about everything. New games, 3d math, development tips...
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

I've created the basic framework of the class. You can tell it the beginning of the level of detail distance and the end, how many levels there are, and how many edge collapses will be used on the lowest level. It will modulate between the highest and lowest detail to get those in between. So here's another question I have: Would it be best to let the user define the method they want to use for level of detail, or spend less time and only finish edge collapse?
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

For what I'm making, I let the user change anything incase they have problems with one method.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Post by Mel »

Finish edge collapse, and leave open the chance to the user to suply its own function for mesh reduction, perhaps?

I'd suggest too that it worked in screen space, besides world space. I mean, you need more detail when the object is bigger in the screen, not only when it is close.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Hmm, a very good idea. I think I'll do that. There's just one thing that's bothering me. To test if it sped things up, I deleted half of the triangles in all the models I tested LOD on, trying to represent the triangles lost in LOD. So the triangle rendering went from about 200000 to 100000, but the frame rate only went up 10 frames per second.
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

well, if it was running at 20 or 10 FPS before that then it would definitely be a worthwhile improvement..! The difference between unplayable and playable.

Presumably with a lot of large models and triangles covering the whole screen and lots of overdraw the improvement would be better.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Well I tested it with 300 models with about 700 faces each. Would it be better to test it with only a few, more detailed meshes?
wITTus
Posts: 167
Joined: Tue Jun 24, 2008 7:41 pm
Location: Germany

Post by wITTus »

I'm also very interested in LOD SceneNodes, please put your code into an online SVN repository so that we can discuss it together. :wink:
Generated Documentation for BlindSide's irrNetLite.
"When I heard birds chirping, I knew I didn't have much time left before my mind would go." - clinko
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

wITTus wrote:I'm also very interested in LOD SceneNodes, please put your code into an online SVN repository so that we can discuss it together. :wink:
I plan on in, I just have to actually get something done on edge collapse. The basic frame work is done, but I'm working on a way of converting the irrlicht IMeshBuffer into just a list of indices and vertices, like the article posted by midnight. I also need a function to convert it back.

EDIT: Okay, here is the basic framework I have so far:

Code: Select all

class CLODSceneNode : public scene::ISceneNode
{




	IMesh* DefaultMesh;
	IMesh** LODMesh;
	IMesh* CurrentMesh;
	char CurrentLevel;
	char LevelCount;
	float LODBegin;
	float LODLast;
	bool LODOn;

public:

	CLODSceneNode(IMesh* mesh, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, int numOfCollapseOnLast, char numOfLevels = 4, float LODBeginDist = 10, float LODLastDist = 30)
		: scene::ISceneNode(parent, mgr, id)
	{
		DefaultMesh = mesh;
		CurrentMesh = mesh;
		CurrentMesh->getMeshBuffer(0)->getMaterial().Wireframe = true;
		LODBegin = LODBeginDist;
		LODLast = LODLastDist;
		LevelCount = numOfLevels;
		CurrentLevel = 0;
		LODMesh = new IMesh*[numOfLevels];
		LODOn = true;
		short icount = 0;

		array<u16> indices;
		for (int x = 0; x < mesh->getMeshBufferCount(); x++) {
			for (int y = 0; y < mesh->getMeshBuffer(x)->getIndexCount(); y++) {
				indices.push_back(mesh->getMeshBuffer(x)->getIndices()[y]);
				icount++;
			}
		
		}
		icount /= 3;

		

		

	}

	
	virtual void OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnRegisterSceneNode();
	}


	virtual void render()
	{
		if (LODOn) {
			vector3df cameraPos = SceneManager->getActiveCamera()->getPosition();
			f32 dist = AbsoluteTransformation.getTranslation().getDistanceFrom(cameraPos);
			CurrentLevel = 0;
			float increment = (LODLast-LODBegin)/LevelCount;
			for (int x = 0; x < LevelCount; x++) {
				if (dist >= (LODBegin+increment*x)*(LODBegin+increment*x))
					CurrentLevel = x;
			}
		}
		else
			CurrentMesh = DefaultMesh;
		IVideoDriver* driver = SceneManager->getVideoDriver();
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		for (int x = 0; x < CurrentMesh->getMeshBufferCount(); x++) {
			driver->setMaterial(CurrentMesh->getMeshBuffer(x)->getMaterial());
			driver->drawMeshBuffer(CurrentMesh->getMeshBuffer(x));
		}
	}
	
	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return CurrentMesh->getBoundingBox();
	}

	void setLODOn(bool on) { LODOn = on; };
	bool getLODOn() { return LODOn; };

};
Doesn't do any lod yet, but it determines the current level and so on. LODMesh array is of course going to be the array for level of detail, current mesh will be the one to currently display. Like how I named those? :lol:
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

Lonesome Ducky wrote:Well I was thinking with edge collapse, that for the new vertex I could just take the average u and v of the 2 vertices I combined. Would this be a good approach?
In my humble opinion I think that this idea is completely wrong for common mesh, it's will work for things like terrain node but not for custom mesh. The simple explanation is that sometime your mesh have tilling part like the one under. As you may know even if will not be able to render properly it using your method.

Image
Lonesome Ducky wrote:Well I tested it with 300 models with about 700 faces each. Would it be better to test it with only a few, more detailed meshes?
Absolutely, I think if your meshes are too small, you're algorithm will take aproximately (or more) the time to compute that drawing your mesh. So I would recommand you to start with 3K+ mesh.

And I would like to say do you wanna cooperate, this way we could work together on it.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Well, if it's tiling, the LOD won't pick a huge edge to collapse. Even if it did, what better way is there to do it? If I'm combining to vertices, shouldn't I find the uv that would best fit the combination? If I use the averages of the uv, it will be right in between them. If you have a better method, I'd love to know it. With the computing, I compute the levels of detail in the beginning and just switch them out at defined distances. And if you wanna cooperate, I'd be glad to have someone help me, but it may be a little difficult. Just tell me what you'd like to do.
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

I just thinked about it again a solution can be generate a uvw map for the lowest lod but it's will multiply the surface required to have the same level of detail for the texture. I think that the best way would require shader (but the things is how to make it good and fast)

Edit :
And I would say for you framework try to update LOD level each X ms depending of the camera speed per default or by user.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Well, for simplicity's sake, I'll just stick with averaging the uv in the beginning. Then, when I've finished the actual edge collapse code, I'll implement your method.
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

Well I tested it with 300 models with about 700 faces each. Would it be better to test it with only a few, more detailed meshes?
on reconsidering, I think what I said about overdraw was nonsense :D just ignore me...

but good luck with this project, it's very interesting!
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

I dont think you should alter vertexes in any way, make x arrays of arrays of irr::u16 for indices and each is going to hold an array for a LOD of the mesh. The indices get generated when loading the mesh, not in the render loop. Dead Efficient huh?
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

That's what I'm planning on doing.
Post Reply