Jump to content

Level Construction Set Part 3: An Instancing Issue

Road Kill Kenny

1,260 views

Instancing is great! It improves performance drastically and it's almost like getting 100 pizza's for the same price as 1. However, there is one instance (excuse the pun) in which instancing is not ideal and that is when you want to have the same mesh to have different materials applied. Basically the problem occurs when you apply a material to one mesh in a set of instanced meshes all of those instanced meshes change material.

 

In my Level construction set I have multiple pre-fabricated pieces and materials. As you may have seen I can apply materials to those pieces individually in the editor. Say for example I want to have a room floor with material 'A' but then I have a corridor as well using material 'B' but some of the same meshes... How do I solve this? I few thoughts came to mind and they are as follows.

 

1. Have Multiple GMF Files for Each Piece

 

2. Use Some LE Commands To Try Make An Un-Instanced Mesh

 

Now I hope you figured it out for yourself that option 2 is the way to go without me having to tell you. Option 1 is a rather outrageous work around which is a bit like the epitome of ugly!

 

So the next question is how do you carry out step two. Well I fished around in the LE wiki for commands that may help that I have never used before and I found just the right code for it. The algorithm is as follows:

 

1. Load the mesh from the file path - LE::LoadMesh()

2. Create an empty mesh - LE::CreateMesh()

3. Add the mesh from the 1st mesh to the empty mesh - LE::AddMesh()

4. Update the new mesh - LE::UpdateMesh()

5. Delete the first mesh - LE::FreeEntity()

 

Although this takes a lot more than simply loading a mesh it is the quickest and cleanest workaround I could find for this problem. See below the function:

 

LE::TMesh LoadMeshNoInstance(std::string meshPath){

LE::TMesh instMesh = LE::LoadMesh(meshPath.c_str());
LE::TMesh noInstMesh = LE::CreateMesh();

LE::AddMesh(instMesh, noInstMesh);
LE::UpdateMesh(noInstMesh);
LE::FreeEntity(instMesh);

return noInstMesh;
}

 

PROBLEM:

 

Now we have solved the problem of not being able to load un-instanced meshes but the global problem isn't solved just yet right....... right?

 

Well no its not solved. You may recall the first line of this blog, "Instancing is great". We don't want to apply this non instancing loading functions to everything in the scene otherwise we will get horrible performance in run time and no body wants that!

 

Basically the ideal outcome would be that every "same" object with the "same" material utilize instancing. For example, if you had 10 2X1m blocks with Material 'A' and 15 2X1m blocks with Material 'B', 9 of the blocks with material 'A' would be instances of the first block with material A and 14 of the 2X1m blocks with Material 'B' would be instances of the first block with material B.

 

To solve this I will organize all of my blocks in a list. Each object has a type ID and a material ID which is inherent from my DDD system prior this problem. When a piece is to be loaded into the game it will look for a piece with a matching type ID and material ID from the list. If there is a match it will load the piece with instancing and if there is no match it will load the piece without instancing using the above function.

 

This will add a fair bit of overhead but fortunately it is overhead in the load time of the game rather than game play time and, therefore, it is less crucial.

 

The below image shows the result in my editor. 4 of the same piece with 4 different materials applied.

blogentry-3220-0-01769400-1349177635_thumb.jpg

 

Thanks for reading. Hope you enjoyed



6 Comments


Recommended Comments

Below is option 3. It's a bit to read through but at the end of the day it's a shader that Niosop created which gives you the benefits of instancing while still being able to "apply" different textures to your instances. It does have limitations (like everything else in life huh smile.png ) but those limitations might not be reached depending on your texture resolution and required variations.

 

Bottom of 2nd page is the actual shader file.

 

http://www.leadwerks..._hl__instancing

Share this comment


Link to comment

Below is option 3. It's a bit to read through but at the end of the day it's a shader that Niosop created which gives you the benefits of instancing while still being able to "apply" different textures to your instances. It does have limitations (like everything else in life huh smile.png ) but those limitations might not be reached depending on your texture resolution and required variations.

 

Bottom of 2nd page is the actual shader file.

 

http://www.leadwerks..._hl__instancing

 

Hmmm that must have been just before my time here. Though, I'll stick to my method for now.

Share this comment


Link to comment

I'm sat here in my lunch hour reading this nodding, "yes, yes, yes. Totally ugly yes, spot on."

 

I like your workaround so much I'm going to use it in my next bit of code and owe you a virtual pizza. I'll send you a real one when I get the chance.

 

Too bad there isn't an easy way to instance the materials. One of the problems we have for squads of armor is how to deal with vehicle damage and animating tank tracks.

 

Tank tracks we managed to do by having a material for the tracks that scrolls the UV offset of the track based on the object colour (Maclebee did the leg-work on that). Colour can be different for instanced entities.

 

But since players can fly (up to 4) hero ships in different skins, duplicating materials is expensive. Since a hero ship has multiple 4096x4096 textures having duplicates should be avoided.

 

One of the solutions I'm consider is a damage texture that is blended in splats according to RGB model colour. (Haven't the faintest idea how to do it yet.)

 

This is consistent with how we already apply damage to other objects where intensity relates to damage%. (Destroyed vehicles are left with a dark smokey/burned appearance).

Share this comment


Link to comment

We also have the opposite problem.

 

Models which have many similar child objects but not instanced. Cockpit interiors have 30+ toggle switches, 30+ rotary controls and cockpits can be duplicated.

Share this comment


Link to comment

One of the things I liked in UDK was material instances . You can make material and from it you can make as much as you wish material instances. In those instances you can expose public properties ,which you can change and make variations,you can change textures, colors, switch glow or illumination on/off from script etc. You can bind those materials to any mesh . Very powerful .

 

Leadwerks + material instances like that = ( AWESOME )

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...