New InstanceManager: Instancing done the right way

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Post Reply
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Added a new technique!!! It's already in trunk.

HWInstancingBasic.
It's REALLY FAST, but main downside is that it doesn't support skeletal animation. Great for physics-based particles, exploding debris, vegetation.
Also fixed a few bugs, including the D3D9 rendersystem setting the flag RSC_VERTEX_BUFFER_INSTANCE_DATA even for those cards that don't support it.
Also this technique supports much better culling, saving vertex shader power.

There's also a new function (which only works with this new technique) InstanceManager::setBatchesAsStaticAndUpdate( true ) which makes everything static. I get a 2x performance boost with it enabled. Great for vegetation I guess (you could use StaticGeometry for plants and such, but this instancing has the advantage of consuming very little VRAM and bandwidth). I will add it around these days to the NewInstancing sample to show it in action.

Thanks goes to Assaf Raman who did half the work by implementing instancing in both rendersystems.

Note for Linux users:
You will need OpenGL 3.3 to run the new technique, which requires very recent drivers. Otherwise it will show as "Unsupported" in the NewInstancing sample.

I'm thinking of making a section in the manual for Instancing (i.e. section 9), explaining how to set it up, what the demo shows, were are all the material files located, how it works, etc. What do you guys think?

Enjoy the release. By the way, I'm getting 24FPS (worst case) with 10.000 entities in the NewInstancing sample. (vs 3-5 fps from the other techniques, moving, non-animated, shadows enabled)
Apparently, VTF outperforms this technique only when everything is stationary.

Edit: The effectiveness of the "static" flag depends a lot on culling and whether the GPU is a bottleneck. In some cases, you may actually see a drop in performance (as one of my recent tests is showing)
Last edited by dark_sylinc on Thu Jan 20, 2011 8:41 pm, edited 1 time in total.
LBDude
Gnome
Posts: 389
Joined: Mon Jul 26, 2010 10:53 pm
x 22

Re: New InstanceManager: Instancing done the right way

Post by LBDude »

cool. That's awesome. I will have to check this out.
My blog here.
Game twitter here
cyrfer
Orc
Posts: 424
Joined: Wed Aug 01, 2007 8:13 pm
Location: Venice, CA, USA
x 7

Re: New InstanceManager: Instancing done the right way

Post by cyrfer »

dark_sylinc wrote:Apparently, VTF outperforms this technique only when everything is stationary.
Could you elaborate on what you mean by this and explain what is the reason for the performance differences?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

cyrfer wrote:
dark_sylinc wrote:Apparently, VTF outperforms this technique only when everything is stationary.
Could you elaborate on what you mean by this and explain what is the reason for the performance differences?
Ooops sorry.
Well, while everything is stationary, VTF technique is not updating the vertex texture nor it's InstancedEntities, so there is little CPU processing and the GPU can use the same vertex texture in all frames. This would, at first glance, mean that the VTF is more friendly to the GPU than using vertex attributes for passing matrices. However when updating the VTF, there are more matrices being updated (due to skeletal animation, which is not supported on HWInstancingBasic) and the vertex texture needs to be transferred each frame to the GPU. I guess that causes more overhead than updating the vertex buffers with the vertex attributes.

More than that, I would be guessing. It's too GPU-specific and I don't have access to trade-secret information (and if I were, probably I wouldn't be legally able to explain it)

I am now working in a hybrid between VTF and HW instancing. I wonder what the performance results will be..... may be it will shed some light
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Yet another instancing technique! HWInstancingVTF.

It's a hybrid between HWInstancingBasic & TextureVTF.

I was slightly disappointed, expecting it to be a lot faster than existing TextureVTF, but performance only really improves when per-entity culling kicks in. I guess I would have noted a speed up if the demo were memory bandwidth limited, which isn't.
Still the VRAM and CPU-side culling savings are really worth it :)

This is probably going to be the last technique I add. I consider this pretty much done.

Still missing using multiple submeshes, but I see really little benefit in that area and a lot of effort to support it.

Otherwise I'll be documenting it (adding to the manual) and fixing bugs that may be reported. I'll be using this in my personal projects, so if I see something that doesn't fit or is missing for a real-world application, I'll add it. But for the moment, I see this Instancing project nearly completed.

It's been fun! (admittedly, I've been coding to death, I see one more line of code in the morning and I'll cry :P)

Cheers
Dark Sylinc

Edit: Forgot to add some details:
The new technique is a hybrid. It uses HW instancing to repeat the same vertex buffers over and over, while sampling matrices from a texture. It supports a lot more instances per batch since there's no 16-bit vertices limitation, has per-entity culling on the CPU (which really saves performance when you're not looking at all entities).
Note the culling doesn't use the OctreeSceneManager (or whatever manager is active). So if you really would benefit from it, you may not want to put all your instances in the same batch, but rather select a smaller instancesPerBatch value.
User avatar
iloseall
Gremlin
Posts: 156
Joined: Sun Sep 14, 2003 3:54 am
Location: Beijing China
Contact:

Re: New InstanceManager: Instancing done the right way

Post by iloseall »

Great!!!!!!!!!!!!!!!!!!!!!!!!
I like this feature.

In my project ,I use Renderable::setCustomParameter to provider custom data for each entity.

and a patch to enhancement this. https://sourceforge.net/tracker/?func=d ... tid=302997

How can I get the custom parameter from Instance's shader?

thanks.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

iloseall wrote:How can I get the custom parameter from Instance's shader?
Hmmm, I suppose I could add a function "InstancedEntity::setCustomInstanceData" or something. To be passed to the shader, but not all instancing techniques may support it.

I'll add this when I get time for it (not soon I'm afraid)
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New InstanceManager: Instancing done the right way

Post by sparkprime »

If you need that you're probably better off hacking the code to choose the vertex format directly?
cyrfer
Orc
Posts: 424
Joined: Wed Aug 01, 2007 8:13 pm
Location: Venice, CA, USA
x 7

Re: New InstanceManager: Instancing done the right way

Post by cyrfer »

I also require per-instance data that is more than just the transform values. Is the custom parameter really the right way to do it? If you won't be working on this feature yourself, could you propose an attack plan to support "custom" per-instance data in case I get crazy enough to try to add support for it myself? Thanks for all the explanations and benchmarks, the instancing support is going to really help OGRE!
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

sparkprime wrote:If you need that you're probably better off hacking the code to choose the vertex format directly?
I thought so too, initially. But hacking isn't nice due to the ability of this manager to clean the batches, which needs proper care. Furthermore per instance extra data is very used in RTS (i.e. to colour units belonging to different teams)
cyrfer wrote:I also require per-instance data that is more than just the transform values. Is the custom parameter really the right way to do it? If you won't be working on this feature yourself, could you propose an attack plan to support "custom" per-instance data in case I get crazy enough to try to add support for it myself? Thanks for all the explanations and benchmarks, the instancing support is going to really help OGRE!
Well, it would work similiar to Renderable::setCustomParameter; but without the index number, and limited to 4 float values. But first you'd had to tell the manager you will be using a custom parameter.
How it is passed to the entities will vary. In HWBasic it is just another TEXCOORD in the instanced vertex buffer, in VTF it would be an additional tex fetch; for HW_VTF it is dubious whether another TEXCOORD or another tex fetch would be more efficient. For ShaderBased it is another TEXCOORD.

BTW I worked on an experimental way to use multiple submeshes, it's not very pretty, but it's the best shot so far, I will comment on it as I see how it goes.
delphenium
Gnoblar
Posts: 15
Joined: Fri Sep 24, 2010 6:51 pm
x 7

Re: New InstanceManager: Instancing done the right way

Post by delphenium »

Hi,

I have implemented my own instancing system that works similar to the approach discussed in this thread, with a couple of differences, notably how per-instance data is encoded and how animations are processed. Note that my implementation REQUIRES VTF and bypasses the Ogre::Animation system, it is a custom solution to a specific problem and not nearly as general as the solution discussed in this thread, however, the information may be useful to others trying to accomplish similar things. I did this for the following reasons.

1) Ability to encode an arbitrary amount of per-instance data
2) Ability to update animations on GPU (This is done because it is simply too slow to update 10000 skeletons with significant numbers of bones on CPU. When you turn on animations in the implementation discussed in this thread, you will note that the vast majority of the time is spent computing the updated bone matrices). This approach is discussed here: http://http.developer.nvidia.com/GPUGem ... _ch02.html The article uses DX10 features, noteably SV_InstanceID, but I found performance to be very good using just an instancing vertex buffer on DX9.
3) Ability to use LOD features, automatically use low LOD meshes/materials/shaders as instances get further away. When rendering enough instances, this rapidly becomes a problem, since I do not want to run complex shaders on far away instances, nor do I need very high resolution meshes for them.

I take the following approach:

I have three classes:
- InstanceBatch (Implements Ogre::MovableObject)
- LODInstanceBatch (Implements Ogre::Renderable)
- InstancedEntity (Implements Ogre::MovableObject)

Setup:

- Each InstanceBatch creates one LODInstanceBatch per LOD level in the mesh that is to be instanced.
- The number of entities to be instanced is pre-determined, this will determine the size of the instancing vertex buffer (this is the same as the code discussed in this thread).
-- If fewer instances are to be drawn at any time, it is far quicker to just hide them instead of rebuilding all of the data structures.
- Each LODInstanceBatch builds an instancing vertex buffer large enough to hold ALL instanced entities. (this is the same as the code discussed in this thread, with the difference that it does it per LOD level. The amount of space wasted in the vertex buffer is acceptble to me.)
- Each LODInstanceBatch pre-allocates space for a texture that can hold per-instance data for ALL instanced entities (this is similar, but not identical to code discussed thread. This texture holds far less data, only a world transform and indicies into other textures that may contain additional data)
- The InstanceBatch encodes animations that can be played by the instances similar to how it is discussed in the GPU gems article. The upside of this is that animating instances is VERY fast, the downside
is that you do not get the features that the Ogre animation system supports (blending between different animations for example). I find this an acceptable trade off, since the animations used by the instances are not very complex and do not require a complex blend tree to evaluate.

On each frame:
- Cull InstancedEntities
- Determine LOD of InstancedEntities, assign each InstancedEntity to the correct LODInstanceBatch
- LODInstanceBatch populates per-instance texture with world matrices, animation indicies and any other per-instance data that is required to draw the instance at this LOD level.
- LODInstanceBatch adjusts mRenderOperation.numberOfInstances to draw the correct number of instances at this LOD level (same as implementation discussed here)

The data:

Instancing Vertex buffer (one per LOD level): (computed once when the batch is constructed)
- Stores U,V coordinates into texture that stores per-instance data

Per-Instance Texture (updated once per frame)
- Stores world-transform of instance
- Stores animation/keyframe information per-instance
- CAN store any additional per-instance data that may be required

Animation Texture (computed once when the batch is constructed)
- Stores bone-matrices for each frame of animation for all animations that can be used by InstancedEntities in this InstanceBatch.

Shaders:
The vertex shader implementation is virtually identical to the one discussed in the GPU gems article. It uses the instance u,v coordinates to look up per-instance data, then uses per-instance data to locate the object in world space and computes additional indices to fetch the correct bone-matrices for animation. There is of course no limit on how much data you can encode per instance in this texture (colours, indicies into an atlased texture etc etc)

The step that you are interested in is the data encoded in the per-instance texture. The implementation discussed in this thread hides the per-instance texture it computes from you. I think the most natural way to pass additional per-instance data to the vertex shader is to encode it in the per-instance texture. This allows the instancing vertex buffer to only contain u,v coordinates to index into the per-instance texture, and the shader to fetch any data it needs from there. As dark_synlic has pointed out of course, this method only works for the VTF approaches. In my case, I am only targeting hardware that has good VTF support, so this is acceptable.

dark_synlic: Thanks a lot for your work on the instancing system, although I can't use your exact implementation due to shortcomings discussed above, it certainly proved to be a great help in implementing my own.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

@delphenium:
Thanks for your in depth explanation! And I'm glad my code served you as a basis/example. Each one may have his own needs when it comes to instancing, so yeah it's ok if you don't use mine :P :P

I like your LODInstanceBatch approach, not putting LOD is something that I slightly regret now, but I didn't come with many solutions anyway, I think that's the problem of doing it the first time; I didn't have everything figured out, so it was hard to think of a way.

The other element I find completely different is the animation of course, which is GPU based solution. I won't be implementing it for the very reasons you cited. It's a solution very specific to a particular problem. Besides I think the problem lies not in the CPU, but rather the way Ogre animations work now, which is not completely cache friendly, the SSE implementation could be revised, and most importantly, doesn't allow multi threaded update.

The way you store per instance data doesn't seem much different from what I'm thinking, unless I got it completely wrong.

Cheers and thanks for sharing!
Dark Sylinc
starry
Gnoblar
Posts: 6
Joined: Fri Feb 18, 2011 3:54 pm

Re: New InstanceManager: Instancing done the right way

Post by starry »

Firstly, nice job with the Instance Manager! Unfortunately, I think I found a small bug in one of the newer features of this new feature. :) I hope this is the correct forum & thread to discuss it.

The problem is with InstancedEntity::shareTransformWith(). I have found that slave entity's batch's bounding boxes do not update as slave entities move around (using their master's transforms, of course). I expect it's because the batch's bounding box extents are calculated using its entity's derived positions, but a slave doesn't need to update its position independently of the master. They don't even need to be attached to a scene node, because the master's transforms are sufficient.

I found this last night and haven't had a chance to look for a solution, or bug fix, but will do so soon. Any pointers and suggestions on solving the problem are welcome.

Thanks,
Steve
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Wow! Someone using an experimental feature I didn't even mention yet. I'm happy you worked on your own how to make it work :)

The shareTransformWith is experimental so I'm not surprised a few bugs are out. I checked in the code to the repository because it didn't hurt, I kept rev. control, a few guys could try it out if it worked for them; and most importantly, it didn't make the implementation less stable/buggy unless you actually use this piece of code (by the way, so far I've been using it without stability issues).
starry wrote:They don't even need to be attached to a scene node, because the master's transforms are sufficient.
May be that's the problem? Be sure the slaves have a scene node too.
Also note that the slaves have an independent InstanceManager & bounding box, thus you need to call their manager's showBoundingBoxes too.

To avoid creating needless SceneNodes, you can attach all your slaves and master to the same SceneNode:

Code: Select all

SceneNode *sceneNode; //Assumes this is a valid scene node
InstancedEntity *instEnt0 = mSceneMgr->createInstancedEntity( "MyMgr/Submesh0", "MyInstanceMat" );
InstancedEntity *instEnt1 = mSceneMgr->createInstancedEntity( "MyMgr/Submesh0", "MyInstanceMat" );
InstancedEntity *instEnt2 = mSceneMgr->createInstancedEntity( "MyMgr/Submesh1", "MyInstanceMat" );

instEnt1->shareTransformWith( instEnt0 );
instEnt2->shareTransformWith( instEnt0 );

sceneNode->attachObject( instEnt0 );
sceneNode->attachObject( instEnt1 );
sceneNode->attachObject( instEnt2 );
Try it that way and tell me how it goes. Also please tell which instancing technique are you using

Cheers
Dark Sylinc
starry
Gnoblar
Posts: 6
Joined: Fri Feb 18, 2011 3:54 pm

Re: New InstanceManager: Instancing done the right way

Post by starry »

dark_sylinc wrote:Wow! Someone using an experimental feature I didn't even mention yet. I'm happy you worked on your own how to make it work :)
I was looking for some way to emulate the behaviour of Entity::shareSkeletonInstanceWith(), so I was pleased to find InstancedEntity::shareTransformWith(). Although the different name surprised me, I had no problems figuring out the basic operation from the comments and code. :)
starry wrote:They don't even need to be attached to a scene node, because the master's transforms are sufficient.
May be that's the problem? Be sure the slaves have a scene node too.
I tried attaching to the parent's scene node yesterday and saw asserts from Ogre that lead me to believe I couldn't attach to the parent's scene node if the entity was sharing the transform and the erronous conclusion that the bounding box must be updated some other way. I tried it again today, since you wrote that it should be possible, and it appears to work perfectly. So, I'm not sure what was going on, but the good news is that it must be (or have been) a bug in my code, perhaps a linker problem that went away with a full re-build. :?

I'm using the HWInstancingVTF technique. I have a GeForce 8800 GT and it works nicely. :D

The only thing I can add is that it would be nice to have a SceneManager::hasInstanceManager (or getInstanceManager) function, because I don't know of any other way to find out if an InstanceManager has already been created short of trying to create another one and handling the exception.

Thanks,
Steve
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

starry wrote:I was looking for some way to emulate the behaviour of Entity::shareSkeletonInstanceWith(), so I was pleased to find InstancedEntity::shareTransformWith(). Although the different name surprised me, I had no problems figuring out the basic operation from the comments and code. :)
I'm glad it worked for you :)
The name is different because the main intention was different: InstancedEntities have no notion of SubEntities, so sharing their transform is an elegant way to workaround the problem with multiple instanced entities. Not the prettiest way, I know, but instancing is already hard enough to have to be managing multiple subentities.
starry wrote: The only thing I can add is that it would be nice to have a SceneManager::hasInstanceManager (or getInstanceManager) function, because I don't know of any other way to find out if an InstanceManager has already been created short of trying to create another one and handling the exception.
Oh, I thought I've had already checked that function in trunk. It will be soon then.
starry
Gnoblar
Posts: 6
Joined: Fri Feb 18, 2011 3:54 pm

Re: New InstanceManager: Instancing done the right way

Post by starry »

Oh, I thought I've had already checked that function in trunk. It will be soon then.
Excellent! Thanks for all the hard work.

Steve
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Thanks. I've pushed my changes to the main repository.

Note that the bounding box call is now slightly different. You'll see how it works in the NewInstancing sample. Just a tiny change.

Cheers
Dark Sylinc
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Re: New InstanceManager: Instancing done the right way

Post by spookyboo »

@dark_sylinc: I am hooking in halfway and haven't read all the posts, but if you intend to write an article (in the manual or a Wiki page), it would be nice to have some kind of decision tree when to use a particular technique (entities, static geometry, instanced geometry, instancing, ...). It is a question that regularly pops-up.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Thanks for the suggestion, will be certainly taken into consideration.

For the time being I suggest you to look at the headers of InstanceManager, InstanceBatchVTF, InstanceBatchShader, InstanceBatchHW & InstanceBatchHW_VTF.

The comments are doxygen friendly so if you're able to regenerate the API documentation, read it as a manual :)
starry
Gnoblar
Posts: 6
Joined: Fri Feb 18, 2011 3:54 pm

Re: New InstanceManager: Instancing done the right way

Post by starry »

Dark Sylinc,

I believe I have found the cause of the strange 'asserts' that have continued to plague me when trying to attach a slave to the master's scene node. I noticed that

Code: Select all

void SceneManager::updateDirtyInstanceManagers(void)
{
	InstanceManagerVec::const_iterator itor = mDirtyInstanceManagers.begin();
	InstanceManagerVec::const_iterator end  = mDirtyInstanceManagers.end();

	while( itor != end )
	{
		(*itor)->_updateDirtyBatches();
		++itor;
	}

	mDirtyInstanceManagers.clear();
}
can result in a call to

Code: Select all

void SceneManager::_addDirtyInstanceManager( InstanceManager *dirtyManager )
{
	mDirtyInstanceManagers.push_back( dirtyManager );
}
The problem I see is when I add a second instance manager. What happens is that push_back re-sizes mDirtyInstanceManagers and invalidates the iterator, which is caught in debug and results in an assert. The stack might be useful, so here it is.

Code: Select all

 	OgreMain_d.dll!Ogre::SceneManager::_addDirtyInstanceManager(Ogre::InstanceManager * dirtyManager=0x026c3958)  Line 6541	C++
 	OgreMain_d.dll!Ogre::InstanceManager::_addDirtyBatch(Ogre::InstanceBatch * dirtyBatch=0x08ca3ca8)  Line 408	C++
 	OgreMain_d.dll!Ogre::InstanceBatchHW_VTF::_boundsDirty()  Line 300	C++
 	OgreMain_d.dll!Ogre::InstancedEntity::_notifyMoved()  Line 343 + 0x1d bytes	C++
 	OgreMain_d.dll!Ogre::SceneNode::updateFromParentImpl()  Line 368 + 0xf bytes	C++
 	OgreMain_d.dll!Ogre::Node::_updateFromParent()  Line 231 + 0xf bytes	C++
 	OgreMain_d.dll!Ogre::Node::_getDerivedOrientation()  Line 562 + 0xf bytes	C++
 	OgreMain_d.dll!Ogre::Node::_getFullTransform()  Line 173 + 0x12 bytes	C++
 	OgreMain_d.dll!Ogre::MovableObject::_getParentNodeFullTransform()  Line 310 + 0x18 bytes	C++
 	OgreMain_d.dll!Ogre::MovableObject::getWorldBoundingBox(bool derive=true)  Line 321 + 0x12 bytes	C++
 	OgreMain_d.dll!Ogre::InstanceBatch::_updateBounds()  Line 115 + 0x1e bytes	C++
 	OgreMain_d.dll!Ogre::InstanceManager::_updateDirtyBatches()  Line 419	C++
	 OgreMain_d.dll!Ogre::SceneManager::updateDirtyInstanceManagers()  Line 6551	C++
I'll try to find a work around in my code, or a fix, tomorrow.

I hope this is useful to you.

Regards,
Steve
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: New InstanceManager: Instancing done the right way

Post by dark_sylinc »

Mmmm, interesting bug.
As a workaround, you can call SceneNode::_update( true, true ); before rendering the frame.

This bug happens because the SceneNode is dirty for some reason; and when it recalculates it's internal structs it notifies us we've changed.

Probably I'll add a "m_isUpdating" flag in the batch which will prevent calling addDirtyBatch

Edit: Odd. When _updateDirtyBatches is called, InstanceBatch::m_boundsDirty should be true already, and it's only set to false at the end of the call. This means when InstanceBatchHW_VTF::_boundsDirty is called, _addDirtyBatch shouldn't be getting called because of the "if" statement, so the question is what causes the InstanceBatch to get dirty with m_boundsDirty = false.
I'll look into it

Edit 2: Now I see it, the iterator that gets invalidated belongs to the SceneManager, not the InstanceManager!; well, SceneNode::_update( true, true ) after you've set all positions and orientations should do the trick. Meanwhile I'll think of a more permanent solution. Thanks for reporting this.
starry
Gnoblar
Posts: 6
Joined: Fri Feb 18, 2011 3:54 pm

Re: New InstanceManager: Instancing done the right way

Post by starry »

Edit 2: Now I see it, the iterator that gets invalidated belongs to the SceneManager, not the InstanceManager!; well, SceneNode::_update( true, true ) after you've set all positions and orientations should do the trick. Meanwhile I'll think of a more permanent solution. Thanks for reporting this.
No problem and thanks for the work around.

Steve
jonim8or
Goblin
Posts: 287
Joined: Mon Dec 08, 2008 4:49 pm
x 10

Re: New InstanceManager: Instancing done the right way

Post by jonim8or »

Is there a way to check whether an InstanceManager is already created?
I added the following as a quickfix in scenemanager:

Code: Select all

//---------------------------------------------------------------------
bool SceneManager::hasInstanceManager(const String &name)
{
	return mInstanceManagerMap.find(name) != mInstanceManagerMap.end();
}
but is there an other way to make sure you don 't attempt to create duplicate instancemanagers?
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New InstanceManager: Instancing done the right way

Post by sparkprime »

I noticed this documentation appears to be copy/pasted from something unrelated:

Code: Select all

                /** Returns whether the specified RenderTarget is compatible with this DepthBuffer
                        That is, this DepthBuffer can be attached to that RenderTarget
            @remarks
                Most APIs impose the following restrictions:
                                Width & height must be equal or higher than the render target's
                                They must be of the same bit depth.
                                They need to have the same FSAA setting
                        @param renderTarget The render target to test against
        */
                InstancedEntity* createInstancedEntity( const String &materialName );
Post Reply