Author Topic: Blueprints & creating Substance graphs at runtime  (Read 4519 times)

Hello Allegorithmic community!

First, Thank you Allegorithmic for the amazing software!

I would like some more information on Blueprint nodes regarding the creation of graphs at runtime. I can't get it to work.


I've created a cube, and in the Level Blueprint I'm creating a Dynamic Material Instance. Then, I create a new Substance Graph, and generate its outputs (a simple base color).
Then, I get that substance graph first texture, which i suppose is the base color created before, and edit the Dynamic Material texture parameter to use that texture. Finally, I use the Async render to update the substance. I've used Sync too, and it yielded the same results:






So, what did I do wrong? I'm probably missing something quite basic here :P

Some other questions:
-In the "Create Graph Instance" what is the "Graph Desc Index" Input?
-In the same node, Instance Name is supposed to be the Graph identifier, right?
-I suppose it's a bug, but if you create a "Create Instance Outputs" by dragging from a substance graph pin, it connects to an "World Context Object" input that does not exist if you create the node manually.
-Is the async/sync node needed in this case?
-If in the "Create Instance Outputs" node I use an array like [0,1,6,7] (that is, I generate the textures of those indices), when I use "Get Substance Textures" will its resulting array be [0,1,2,3] or [0,1,2,3,4,5,6,7], 2-5 being "vacant"?


Any help is appreciated! Thank you!

Hey everyone!

Today I worked a bit more on this, and noticed that the "Duplicate Graph Instance" worked!
Still, would like some more info on what the "Create Graph Instance" node does. I probably put some wrong input there :)


Now to the following question:

I'm developing a space game, and my plan is to use substance to create the textures of Habitable planets at runtime. Obviously, creating hundreds of graph instances and materials would probably be quite expensive, so my idea was to use a system where there are only 20 graphs at any time, and these are being updated/replaced with new parameters (my game will use a fixed "hyperlane" system between systems, so I always know there are 5 stars with at most 4 habitable planets where the player can go ;)  )

I've already implemented it, and it almost works.
The way I set up, the system the player travels to will update its planets using a Sync node, so as to guarantee that the player will see everything correctly. the neighboring systems, on the other hand, are updated with the Async node, so as to not interrupt gameplay too much, but still processing in the background.

The Synced system works 100%, but the Async ones don't seem to load, even after quite some time (definitely enough to load 64x64 test textures). I plugged the node that shows the loading progress of the substances, and it doesn't increase. If I use Sync on all systems, they all work, but then load times would get really long if I increased resolution.

All the logic is in a lot of For loops. I assume the Async node gets called to update another substance before it manages to load the first, and so on. Could that be the problem?

Hi jacksonmpinheiro,

This is definitely interesting and definitely sounds like we have a bug in the async processing. Would you be able to copy the relevant blueprint into a separate project with some test assets and email it to josh.coyne@allegorithmic.com ? I would like to see why it's not working :)

Hey Josh!


I've created another project to test whether this was really a bug with the Substance Plugin or something on my end, and it seems that the problem isn't in the Async per se, rather it's something to do with rendering a 64x64 texture.
I'll send you the project via email. In order to replicate this bug:

First, play note that the 5 tables all get their textures correctly(One is synced, while the others are Asynced). The substance graph (Rings_INST) is creating 256x256 textures.
Now, change it to generate 64x64 outputs, and play again.
You will notice that while the table that uses Sync does load, the others do not (Tested for around 10 minutes).
Interestingly, changing them back to 256x256 will not work unless the editor is restarted.

Everything is done on the Level Blueprint.

I'll do some more testing on my main project, as that may be related (Since I was creating 64x64 textures in order to speed up and see if everything was working correctly).
If you need anything else to test, please let me know!
Thanks! :)

So, I've tested my main project a little bit, and it's working now!  ;D
I think I got a little impatient waiting for the 1K textures to render, and changed the graph to 64x64, triggering the bug I described earlier.
(By the way, the Substance Loading Progress node seems to get stuck, leading to me feeling that the Substance Engine is not processing, even if it actually is. Does it only update when a substance finishes loading, or is it more "fine-grained"? In any case, it never changed to me beyond the substances loaded with the Sync node, even if later the Async ones updated.)
After testing without changing resolution, right upon opening the project, it worked!

So the workaround for now is to reopen the editor whenever changing the resolution of a Graph that is duplicated at runtime.

Also, If anyone could answer the other questions on the OP, please do! :)

So, I've tested my main project a little bit, and it's working now!  ;D
I think I got a little impatient waiting for the 1K textures to render, and changed the graph to 64x64, triggering the bug I described earlier.
(By the way, the Substance Loading Progress node seems to get stuck, leading to me feeling that the Substance Engine is not processing, even if it actually is. Does it only update when a substance finishes loading, or is it more "fine-grained"? In any case, it never changed to me beyond the substances loaded with the Sync node, even if later the Async ones updated.)
After testing without changing resolution, right upon opening the project, it worked!

So the workaround for now is to reopen the editor whenever changing the resolution of a Graph that is duplicated at runtime.

Also, If anyone could answer the other questions on the OP, please do! :)

Hi Jack,

What is the question on the OP? I'm sorry, I think I missed it above.

Cheers,
Wes
Head of Substance Demo Art Team
the3dninja@adobe.com
Twitter: The3DNinja

These:

-In the "Create Graph Instance" what is the "Graph Desc Index" Input?

-In that same node, Instance Name is supposed to be the Graph identifier, right?

-If in the "Create Instance Outputs" node I use an array like [0,1,6,7] (that is, I generate the textures of those indices), when I use "Get Substance Textures" will its resulting array be [0,1,2,3] or [0,1,2,3,4,5,6,7], 2-5 being "vacant"?

Also, one more i had now:

-When to use Duplicate Substance Graph vs. Create Graph Instance?

Thanks! :)

These:

-In the "Create Graph Instance" what is the "Graph Desc Index" Input?

-In that same node, Instance Name is supposed to be the Graph identifier, right?

-If in the "Create Instance Outputs" node I use an array like [0,1,6,7] (that is, I generate the textures of those indices), when I use "Get Substance Textures" will its resulting array be [0,1,2,3] or [0,1,2,3,4,5,6,7], 2-5 being "vacant"?

Also, one more i had now:

-When to use Duplicate Substance Graph vs. Create Graph Instance?

Thanks! :)

Hi,

The graph desc index is index of the graph in the package description. Basically, if you have a sbsar with more than one graph, you can use this index to target a specific graph. It's something I think we will change.

Instead of using the create graph instance, I create a variable of graph instance which is then set to the substance inst and use that variable in my blueprint. However, I could use duplicate to make a copy of this graph if needed. That is when I would use duplicate.

Cheers,
Wes

Head of Substance Demo Art Team
the3dninja@adobe.com
Twitter: The3DNinja