x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Customise UVs per instance with Instanced Static Meshes

All instances of an Instanced Static Mesh Component must share the same material and mesh. Is it possible, however, to customise the rendering of the material on the instance in any way other than using the PerInstanceRandom and PerInstanceFadeAmountconstants?

To be more specific, I have a texture map that contains a number of different textures. I'd like to access the UV attributes applied to the instanced mesh so that I could render different textures on different instances through the same material. Is this possible at all?

For reference, and to clarify what I'm after, it seems that Unity supports something called MaterialPropertyBlocks, which allows you to pass custom data to the instances and access that data in the shader.

Thanks in advance for any information!

Product Version: UE 4.12
Tags:
more ▼

asked Oct 07 '16 at 08:54 AM in Rendering

avatar image

nnevala
26 1 3 3

avatar image Terzalo Mar 22 '17 at 02:52 PM

I was able to achieve this by modifying InstancedStaticMesh source code to accept user-defined float instead of random float.

My modifications are described here: https://markdownshare.com/view/a4b04e89-83bc-48bd-8ec5-229ab407f275

Add Instance blueprint node now accepts an additional parameter:

alt text

And you can access this parameter in the material with PerInstanceRandom:

alt text

You can use any float value, but I noticed heavy glitches when the fractional component is zero. I am not sure why this happens, but I seemingly solved this by adding 0.5 to the integer before passing it to the instance and using floor operation to get the integer back in the material.

I used this to generate Minecraft-like voxel terrain. Here, grass, dirt, tree trunks and leaves all use the same quad mesh in a single Instanced Static Mesh for each 8x8 chunk of voxels (tall grass uses a separate mesh).

alt text

avatar image nnevala Mar 22 '17 at 03:23 PM

Thank you so much for this, it looks amazing! Will have a closer look ASAP :)

avatar image Althaen Jul 03 '18 at 11:33 AM

Hey, I couldn't manage to implement what you're suggesting, would you be able to show what the code is supposed to look like?

avatar image nonchip Dec 15 '18 at 04:14 AM

do you think this could be done in a plugin instead? that way it would more easily survive engine updates and multiple people in a team (especially the artsy types) won't have to make sure they get the same changes etc, but i can't figure out how to inherit from the ISMC stuff in a plugin and then e.g. use that functionality both directly and in a HISMC (since that depends on the original code) :/

avatar image J.Kimberley Dec 19 '18 at 01:34 AM

This would great as a plugin if not a new feature of ISMC. I managed to get it working by editing modifying 4.20 source. But will need to get latest version at some point.

avatar image vle07 Feb 17 '19 at 04:50 AM

Would you have any instructions on how to modify the source? I think Terzalo's instructions are outdated and don't apply to the latest engine versions. Thanks!

avatar image vle07 Feb 18 '19 at 06:55 AM

Actually, I've managed to get it to work in 4.21 by modifying the source code as well. I had to pad the structure containing the instance data or I'd get serialization errors, but everything else was fairly straight-forward.

I took a stab at creating a plugin, but from what I can tell, it's actually impossible with the way Epic has designed the UInstancedStaticMeshComponent class and its interaction with other parts of the engine. You need to extend UInstancedStaticMeshComponent to get it correctly work with lightmaps, physics, etc, but then you can't override necessary functions like BuildRenderData (since it's not a virtual function).

avatar image nonchip Feb 20 '19 at 11:38 AM

yeah i looked at the source and tried to figure out if/how it could be made a plugin but it seems so lowlevel intertwined with the rendering code etc you can't just copy it (also horrible idea because upgradeability) but i also saw no way to extend it in a plugin and have the engine actually use that then. which is a bit sad, i mean it's such a straightforward feature, why isn't it in the engine already, they literally only need to add a single boolean per instance to turn the PRNG off and expose the "random" value (probably better to also rename it then :P).

avatar image J.Kimberley Aug 03 '18 at 01:06 AM

Did you find that you still had performance benefits of instanced static meshes?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

I don't think you can add your own data to Per Instance parameters without modifying the engine, however, it should be relatively trivial to do, You should take a look at LocalVertexFactory.usf and InstancedStaticMesh.cpp.

However, if you do not want to dive into the code, you could describe the effect, you are trying to achieve. There might be a simple workaround for that.

more ▼

answered Oct 07 '16 at 10:15 AM

avatar image

Deathrey
7.9k 130 31 293

avatar image nnevala Oct 07 '16 at 10:42 AM

This is a bit simplified, but still a more detailed explanation of what I'm after:

I'm building a turn based strategy game (not totally unlike the example project), and I want to procedurally generate the environment. The game world will consist of objects, most of which will have a very simple mesh (e.g. a piece of wall). For these I'd like to re-use the mesh and simply render a different texture based on the type of wall to get the performance I need. To give you a ballpark figure I expect that a single level might include tens or even hundreds of thousands of these objects.

I can't use different materials for different instances, but I think it should be possible to create a texture atlas and simply sample different parts of that per instance to achieve the same effect. The problem is that I can't pass any custom information to the instance that I could then reference in the material to determine which part of the atlas to sample.

The Turn Based Strategy example project also uses a texture atlas to render different floor tiles, but uses the PerInstanceRandom constant to simply pick a random one. This isn't really good enough for me.

I think you've already answered this pointing me to the engine code that I might have to customise to achieve this, but surely there has to be another way?

avatar image nnevala Oct 07 '16 at 12:08 PM

Ah, after some time trying to wrap my head around this, I think I finally understand why UE works the way it does: because of the different LOD models. Because of this the vertex buffers have to be dynamically created, which makes them directly inaccessible.

I wonder if there is a solution that involves just extending the ISMC rather than having to change the engine core itself...

avatar image Deathrey Oct 07 '16 at 06:19 PM

Passing unique UVs for every instance to get textures from atlas is probably good way to go. Yeah, for your purpose you should be able to create new class, extending ISMC, but sadly that is outside of what I can help with. I did not do much coding for UE4.

Perhaps, you would get more qualified assistance by posting in programming section of the forums or answerhub.

avatar image nnevala Oct 10 '16 at 12:57 PM
avatar image Deathrey Oct 10 '16 at 01:45 PM

I'll keep an eye on the thread. Quite interested myself. Thanks.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

For making unique instances I admit it's very interesting way. I also want to make many instances to move or change slightly but in current implementation of ISM I cannot.

Even if for unique shapes it's great idea I would rather stay with custom static mesh when generating voxels. It is possible to pass custom vertex value for each triangle which makes material setup very easy and flexible. I can read unique RGBA values for all faces I create.

https://www.youtube.com/watch?v=WXJw1pswLRM

So yeah in the end I am not even using all values but only A: FColor color = FColor(255, 255, 255, i); and only values 0-6 from it so 249 values are unused :D

more ▼

answered Mar 03 '19 at 09:51 PM

avatar image

Tefel
24 3 8 13

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question