Open ChrisSchroeder01 opened 11 months ago
So if I'm understanding you correctly, you want a long-lived buffer on the GPU (one that persists through multiple frames)?
If so, the indirect instancing example has this setup, and the name of the relevant array is RWBaseInstanceBuffer
. But it is complicated as you mentioned, so I'll distill it here:
[!NOTE] This is crudely adapted from the indirect instancing example and can be simplified a bit
compute.usf
struct MeshItem {
float3 Position;
float3 Rotation;
float3 Scale;
};
// This is our buffer in the shader
RWStructuredBuffer<MeshItem> RWBaseInstanceBuffer;
main.h
- under the shader definition
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<FMeshItem>, RWBaseInstanceBuffer)
END_SHADER_PARAMETER_STRUCT()
main.cpp
/** Structure to carry RDG resources. */
struct FVolatileResources
{
FRDGBufferRef BaseInstanceBuffer;
FRDGBufferUAVRef BaseInstanceBufferUAV;
FRDGBufferSRVRef BaseInstanceBufferSRV;
};
main.cpp
- when you dispatch
// ...
PassParameters->RWBaseInstanceBuffer = InVolatileResources.BaseInstanceBufferUAV;
// ...
struct ShaderContext {
// Multi-frame buffers used to store the instance data.
// This is initialized in InitializeResources()
mutable TRefCountPtr<FRDGPooledBuffer> BaseInstanceBuffer;
}
main.cpp
- when we need to initialize stuff for our shader we call this and pass in a long-lived shader context and volatile resources
/** Initialize the volatile resources used in the render graph. */
void InitializeResources(FRDGBuilder &GraphBuilder, ShaderContext &Ctx, FVolatileResources &OutResources)
{
if (!Ctx.BaseInstanceBuffer.IsValid())
{
// We need to create the instance buffers.
OutResources.BaseInstanceBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(FMeshItem), MAX_RENDER_ITEMS), TEXT("Mesh.BaseInstanceBuffer"));
Ctx.BaseInstanceBuffer = GraphBuilder.ConvertToExternalBuffer(OutResources.BaseInstanceBuffer);
}
else
{
// Buffers already exist, we can use them.
OutResources.BaseInstanceBuffer = GraphBuilder.RegisterExternalBuffer(Ctx.BaseInstanceBuffer);
}
OutResources.BaseInstanceBufferUAV = GraphBuilder.CreateUAV(OutResources.BaseInstanceBuffer);
OutResources.BaseInstanceBufferSRV = GraphBuilder.CreateSRV(OutResources.BaseInstanceBuffer);
}
Hopefully that captures it correctly. Let me know if something's not working or if you need help finding where to put it
Hello,
I am currently trying to pass a Structured Buffer to the shader. The compute shader should also be able to change the values of the structs in this Structured Buffer over time (multiple executions).
I have a struct:
And my Execute RTComputeShader method:
I got the pass to shader working with the following in the DispatchRenderThread Method:
Unfortunately I could not figure out how to create an external buffer, which i assume will fix my issue that the computed data of my compute shader will not be overwritten. I tryied parameter, but I could not figure out how to get such a value.
RegisterExternalBuffer
but this Function is undefined. FRDGBuilder as a method called RegisterExternalBuffer but this method requires a TRefCountPtrI am using the following Shader Parameter Definition:
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<FAgent>, Agents)
because the pre-generated commented proposeSHADER_PARAMETER_UAV(RWStructuredBuffer<FMyCustomStruct>, MyCustomStructs) // On the shader side: RWStructuredBuffer<FMyCustomStruct> MyCustomStructs;
again I could not figure out how to get aFRHIUnorderedAccessView *
from the TArray.I came across several posts also trying to achieve what I want: https://forums.unrealengine.com/t/loading-data-to-from-structured-buffer-compute-shaders/470083 https://forums.unrealengine.com/t/rwbuffer-and-buffer-in-compute-shaders-when-they-binding-with-the-same-resource/508164
There are a few things I noticed, it seems that Epic Games changed things from for the 5.3 Version. For example FRHICommandListImmediate::LockStructuredBuffer does not exist anymore (see: https://docs.unrealengine.com/5.3/en-US/API/Runtime/RHI/FRHICommandListImmediate/LockStructuredBuffer/)
I also looked at the Indirect Instancing examples but they looked pretty complex on the first sight. It would generally be nice to have a single Compute Shader Example with every possible Shader Parameter (the 7 commented ones) to know what to do for each parameter type.