Question about instancing and associated memory costs

Hi folks,

I am rendering a rather large mangrove forest that consists of four unique trees, and observing a linear increase in memory consumption as I add more trees. My assumption was that memory consumption would barely change, since I am just adding instances of the original geometry -but apparently that reasoning is flawed.

Here is the simple node tree I’m using for instancing. It lives on an object that’s just a bunch of points scattered throughout my environment; with some randomized transforms. I did check with the spreadsheet those were indeed instances, and not realized geometry.

And here are three renders for illustration (see memory numbers) :

50 tree instances :

100 tree instances :

150 tree instances :

I observe that each batch of 50 trees add another 900MiB to the total memory consumption.

The entire mangrove consists of 2567 trees, I tried to render it all but my 4070Ti 12GiB quickly runs out of memory -actually even my 32GiB RAM doesn’t cut it with CPU/hybrid rendering (I tried).

What I haven’t tried yet, is aggressively working around it. For the moment, I’m wondering if this is normal? or if I am doing something wrong?

I have bought Higgsas’ toolset and I believe he has a frustum culling node in there, will try that. Will also try generating lowdef versions of these trees to scatter in the distance. Those are my two main leads right now.

Cheers,

Hadrien

1 Like

one thing to double check, even with your geometry instanced, have you checked that you’re not getting duplicates of any image textures used?

Thanks for the suggestion, how do I check for that ? I use only two textures, one for the bark and one for the leaves

there’s probably a far easier way, but how i do it is look at the file contents. where you have your scene editor, there’s a display mode dropdown, change that to ‘Blender File’ and it’ll show you all the contents. you’re mainly interested in what’s showing under Materials.

alternately, if you can click on the mangroves individually, you can check each ones material to make sure you don’t have Bark.001 Bark.042 Bark.27387 etc. :smiley:

Ok I see, no that’s not the cause… Since the trees are instanced through geonodes, there’s really only one object. I did check the material list, and it looks normal, no duplicates.

1 Like

Building of the Bounding Volume Hierarchy is independent of instancing… Check here for tips on improving performance…

Edit and correction: Instancing should bring down memory costs regardless.

This is the reality of 3d rendering unfortunately. Cull, LOD, fake banners, rendering the background elements once and then comping them in… etc. all techniques on top of the above linked tips especially needed for foliage/geometry dense scenes…

Another thing I repeat here often is that the illusion of detail is indistinguishable from actual detail and you should always strive for the former.

Check out ThomasKole’s stuff for inspiration.

Good luck!

6 Likes

1). For the viewport you could use convexhull or just a triangle or disable it - this way you have more memory for your final render .
2). You could make a LOD system .
3). Enable render region .
4). You could bake your texture to .exr use less memory with the same final result https://github.com/oscurart/Blender-30-Addons
5). Proxy but i think you can not do this with Blender …

6). Maybe linked append not sure iff this makes a difference …
https://docs.blender.org/manual/en/latest/files/linked_libraries/library_overrides.html

2 Likes

Something funky is going on here. I was able to reproduce this with a tree model I had laying around, but a highly subdivided suzanne does not cause the memory rise. After a bit of trial and error, I think I have a theory: geometry nodes doesn’t like nested instances. The tree model I tested scattering with had its own geometry nodes system to distribute leaves/blossoms/twigs.

Try this little demo file: It exhibits the problem, as you add more and more monkeys, memory useage steadily climbs. But if you hide the geometry nodes modifier on the monkey (so it’s not comprised of instanced cubes) you can render a nearly arbitrarily large number of monkeys with barely more memory than an empty scene.

geonodes_instance_memory_bug.blend (937.4 KB)

Here’s the memory usage on my machine (optix backend)

Empty scene: 663.64MB
131 regular suzannes: 663.81MB
13100 regular suzannes: 675.53MB

but…

131 cubic suzannes: 737.11MB
261 cubic suzannes: 810MB
523 cubic suzannes: 956MB

EDIT: went ahead and reported it https://projects.blender.org/blender/blender/issues/111459

8 Likes

Nice experiment and good observation!

Seems like you can improve performance drastically by realizing the “nested” instances… weird.

EDIT: Included test file so you can see difference with and without realizing nested instances
Realized nested instances test.blend (227.4 KB)

4 Likes

Actually I think that makes sense. If you realize the nested instance, Blender basically makes a real ‘copy’ of that object. So when you then reference that branch or leaf again and again and again, Blender just points to that same single realized copy of the object.

However, if it isn’t realized, Blender treats each reference to a branch or leaf as a new object (it calculates the node group again and makes a new reference to it each time).

1 Like

I want to quickly acknowledge the response here, many thanks folks !

@zeroskilz @Benny_G @J_the_Ninja @thetony20

In light of the information on nested instances, I have done a few more tests by realizing all leaves, strangely enough it cuts rendertime in half but the memory is the same. I haven’t done all tests, so I’ll get back to you with more numbers soon. Thanks again !!

This is the wisdom I needed… even when you know it, there’s a reluctance to cut down on your hard work so to say. I went and turned down the leaf definition, the amount of leaves itself, removed subsurf on the whole thing, and it’s already much more manageable.

3 Likes

Another cause could be materials linked to object instead of data : https://projects.blender.org/blender/blender/issues/109978

If each batch of 50 trees adds another 900MiB, then instancing clearly doesn’t work.

1 Like

So I’m back with some, uh… confounding data.

Thanks, but that’s not it. Both materials are linked to data.

You got me thinking and I tried the same scene but this time, instead of scattering my tree instances with geometry nodes, I just did it manually, by duplicating and hand-placing the collection instances.

213 trees :

426 trees :

Exact same memory footprint ! Instancing is working as expected.

@J_the_Ninja So there’s indeed something funky with geonodes,… and it’s not nested instances because I don’t have any of them : the leaves being realized, each one of the four trees is now completely unique geometry.

@HooglyBoogly what do you make of this ?

Cheers,

Hadrien

@Benny_G thanks for the advice, I forgot to mention I already have lower resolution standins in the viewport, and the navigation performance is just fine with them.

2 Likes

This seems wrong to me too! I think it would be worthy of a bug report if you have the time to simplify things a bit.

1 Like

Which was pretty much what I was guessing at, in that realizing the data isn’t just making a reference to all the same data, it’s basically making a copy.
Weather or not geonodes should work that way is another question.

Technically the manually placed trees isn’t the same memory footprint, the extra trees uses 0.03M more, which is of course the basic data used to store the position of all those extra duplicates. But yeah, working just as expected.

Have you tested or is it possible to use geonodes but without realizing any of the data?

Alright ! I’ll prepare a file for report. :+1:

Yes, I have tested without realizing the leaves (the rest of the tree is already unique geometry), this is how I encountered the issue originally.

1 Like

Forget what I said previously : realizing the leaves does solve the issue. I probably got confused, having so many scenes open and ticking/unticking thing after thing. Not sure where exactly I made a mistake, but I tested everything with a clear mind, and it works.

@J_the_Ninja you were correct from the start. Thanks again ! …What a gotcha !
@HooglyBoogly honestly my bad for the false alarm. Looks like it is indeed the issue with nested instances linked above.

Thanks all, I can resume reforesting.

Cheers !!

3 Likes

Glad that you got it to work! And realizing the leaves might even make it faster. But nested instancing is still meant to work as far as I know, so it still seems like a bug.

3 Likes

Oh yes, me too, you have no idea…!

That’s what it is, leaves are realized. That’s the only reason it works at all. For clarity, I had a few thousand leaves instanced on each tree, so ultimately, once the trees themselves were instanced on the terrain, the leaves were level-two instances (if I understand this all correctly). That’s what was bogging the thing down, apparently. Now each tree is effectively unique, so it’s a bit heavier in itself, but uncomparably lighter once there are thousands of them.

Thanks again for the support everyone. <3

Hadrien

1 Like