Copy link to clipboard
Copied
Hello,
I am using the Substance Plugin with Unreal Engine 5.3.
I have a USubstanceGraphInstance* with some input parameters that I customize at runtime before rendering the graph instance. Since I only want to read the pixel data from the generated output textures, I don't need to save the textures to disk.
I have two questions:
How do I register a callback function, or is there another way to get notified when the async rendering of a graph instance has finished?
Once the rendering has finished, how can I access the generated output textures as a UTexture2D*?
Thanks!
Copy link to clipboard
Copied
Hi Kontur,
You can access the textures using the USubstanceGraphInstance Pointer by the following codes below
for (const auto& output : USubstanceGraphInstancePointer->Instance->getOutputs())
{
if (output->mUserData != 0)
{
UTexture2D* texture = Cast<UTexture2D>(reinterpret_cast<USubstanceOutputData*>(output->mUserData)->GetData());
// Do something with the texture
}
}
Also, when the asynchronous rendering finishes for each texture, texture->PostEditChange() is called. Just listen to that event. That is the only event fired when the rendering is done from our own internal post render callback.
Copy link to clipboard
Copied
Thank you for your swift reply. I am just now getting around to following up.
Unfortunately, PostEditChange() is an editor-only function, and we need this to work in a shipping build.
To provide more context, the output textures are used as heightmaps for procedural terrain generation in a seed-based world. Currently, we extend the Substance plugin with a query manager that handles asynchronous render requests and calls back the game code when UpdateTexture() is eventually called in SubstanceCoreHelpers.cpp (which seems to occur in shipping builds too). However, this approach feels very hacky and fragile, so I wonder if there is an "official" or at least a better way of doing it.
Ideally, when a new level is generated in the game, we want to instantiate the Substance graph that represents the terrain type of the level (each terrain type is represented by a different Substance graph) and we want to asynchronously and simultaneously render the level's heightmap in multiple chunks. To do this, each Substance graph has X and Y input parameters, which are used in the graph to render the appropriate chunk of the global level heightmap. We would read the pixel data from the output textures and then discard them along with the graph instances. When a new level is needed, the cycle starts again.
However, we are generally unsure about the proper workflow for runtime generation, so any insights you could provide would be immensely helpful!
Thank you!
Copy link to clipboard
Copied
Hi @Kontur, we need to know a few more things about this particular workflow to provide guidance here. Could you let us know:
Best,
Aldo
Copy link to clipboard
Copied
Hi Aldo,
Thank you for getting back to me!
1. Our project includes hundreds of graphs (.sbsar files). Each graph represents a terrain type and has inputs for Seed and XY coordinates, producing a single channel-packed basecolor output.
2. The full heightmap resolution is 16384x16384. We plan to composite it from 4x4k texture chunks (refer to the screenshot). Our goal is to divide the workload, allowing us to start rendering the terrain around the player as quickly as possible.
3. Ideally, we would instantiate only one graph at a time—the one associated with the terrain type of the currently generated map, and we would use this single instance to asynchronously and simultaneously render four different versions (same Seed, different XY coordinates), one for each chunk. If this is (understandably) not feasible, we would then want to instantiate four separate graphs, one for each chunk, and render them simultaneously.
I hope this clarifies things. If you need any more information, please let me know!
Thank you!
Copy link to clipboard
Copied
Sorry about the screenshot, instead of 2x2, it shows a 4x4 grid, we are still experimenting with the best settings.
Copy link to clipboard
Copied
Hi @kontur, I took a look at our substance creation during Play in Editor and there is definitely an improvement that can be made. It's following the same process as importing in editor and causing a render of the substance, we have a task logged to work on seperating these workflows to reduce the delay when creating a graph through blueprints. In the meantime, can you try packaging the scene and testing, full runtime shouldn't have the same issue when not considered Play in Editor.
Thank you,
Josh