Course: Neural Network Engine (NNE)

Hey @mattaimonetti,

The workflow to setup and initialize a RDG model should be pretty similar to the CPU and GPU case that you summarized above very nicely.

However, creating in- and outputs and EnqueueRDG is quite different, as the RDG API is for a completely different use case:
While CPU and GPU inference is done completely outside the render loop, the RDG API is meant to be used to embed a neural network into the render flow, e.g. to work on a resources that is used to render a frame (mesh, texture, rendertarget, …).
Or in other words, you can think of the RDG model as a set of compute shaders that are added to the render graph, before it is launched to render the next frame.

A “simple” use case would be post processing: You could create a class inheriting from FSceneViewExtensionBase and override the PrePostProcessPass_RenderThread function.
The engine will call your function from the render thread and give you the colored frame inside FPostProcessingInputs which you can then process and write back.
Instead of enqueueing here a classic compute shader to process the frame, you would just EnqueueRDG your neural network doing the processing for you.

A challenge is to convert the texture (which could have any pixel format) into a tensor of type float. So you need a compute shader to convert from texture to a FRDGBufferRef and the result back to a texture again.
You can create the intermediate buffers (in- and output for the network) with the following code

FRDGBufferDesc InputBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), NeuralNetworkInputSize.X * NeuralNetworkInputSize.Y * 3);
FRDGBufferRef InputBuffer = GraphBuilder.CreateBuffer(InputBufferDesc, *FString("NeuralPostProcessing::InputBuffer"));

To set it as an input to the compute shader you may need to create an UAV resource from it with

FRDGBufferUAVRef InputBufferUAV = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(InputBuffer, PF_R32_FLOAT));

It is possible to create your own graphbuilder from an RHI command list, but only between two frames. Then you could register your external buffers (or upload from CPU) and enqueue the neural network to be processed outside the frames.

It will probably also help to read in the UE docs about how the RDG pipeline works and how the resources behave.

I hope I could help, let me know if you have further questions.

2 Likes