I am writing a compute shader, that counts white pixels on the screen, and, in the future, calculates luminance. Right now counting white pixels works well, but problems arise when I try to connect second RWBuffer to read back luminance. It seems like buffer is created, passed to the shader, but cannot be read or modified, and seems to be zero for shader. When trying readback it just returns start values from AddClearUAVPass, without using or modifying them.
PassParams definition:
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, CameraTexture)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<int>, Output)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<int>, Luminance)
END_SHADER_PARAMETER_STRUCT()
Buffers creation (as you can see both buffers are declared the same, OutputBuffer works, while LuminanceBuffer - no)
FRDGBufferRef OutputBuffer = GraphBuilder.CreateBuffer(
FRDGBufferDesc::CreateBufferDesc(sizeof(int32), 1),
TEXT("OutputBuffer"));
FRDGBufferRef LuminanceBuffer = GraphBuilder.CreateBuffer(
FRDGBufferDesc::CreateBufferDesc(sizeof(int32), 2),
TEXT("LuminanceBuffer"));
PassParameters->Output = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputBuffer, PF_R32_SINT));
PassParameters->Luminance = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(LuminanceBuffer, PF_R32_SINT));
AddClearUAVPass(GraphBuilder, PassParameters->Output, 0);
AddClearUAVPass(GraphBuilder, PassParameters->Luminance, 13);
(13 in AddClearUAVPass for testing)
Readback (Output buffer returns correct values, LumBuffer returns 13)
FRHIGPUBufferReadback* GPUOutputBufferReadback = new FRHIGPUBufferReadback(TEXT("ExecuteTestOutput"));
FRHIGPUBufferReadback* GPULuminanceBufferReadback = new FRHIGPUBufferReadback(TEXT("ExecuteTestOutput1"));
AddEnqueueCopyPass(GraphBuilder, GPUOutputBufferReadback, OutputBuffer, 0u);
AddEnqueueCopyPass(GraphBuilder, GPULuminanceBufferReadback, LuminanceBuffer, 0u);
auto RunnerFunc = [GPUOutputBufferReadback, GPULuminanceBufferReadback, AsyncCallback](auto&& RunnerFunc) -> void {
if (GPUOutputBufferReadback->IsReady() && GPULuminanceBufferReadback->IsReady()) {
int32* Buffer = (int32*)GPUOutputBufferReadback->Lock(sizeof(int32));
int32 ObjectSize = Buffer[0];
GPUOutputBufferReadback->Unlock();
int32* LumBuffer = (int32*)(GPULuminanceBufferReadback->Lock(8));
UE_LOG(LogTemp, Log, TEXT("Luminance Buffer: %d, %d"), LumBuffer[0], LumBuffer[1]);
int32 ObjectLum = LumBuffer[0];
int32 OtherLum = LumBuffer[1];
GPULuminanceBufferReadback->Unlock();
AsyncTask(ENamedThreads::GameThread, [AsyncCallback, ObjectSize, ObjectLum, OtherLum]() {
AsyncCallback(ObjectSize, ObjectLum, OtherLum);
});
delete GPUOutputBufferReadback;
delete GPULuminanceBufferReadback;
} else {
AsyncTask(ENamedThreads::ActualRenderingThread, [RunnerFunc]() {
RunnerFunc(RunnerFunc);
});
}
};
Here is shader itself. In InterlockedAdd I add Luminance[0] to check if shader can access the buffer, and it seems empty. When trying to modify Luminance[0] and Luminance[1] it does nothing
#include "/Engine/Public/Platform.ush"
Texture2D<float4> InputTexture;
Texture2D<float4> CameraTexture;
RWBuffer<int> Output;
RWBuffer<int> Luminance;
[numthreads(32, 32, 1)]
void Test(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupIndex : SV_GroupIndex)
{
uint width, height;
InputTexture.GetDimensions(width, height);
if (DispatchThreadId.x >= width || DispatchThreadId.y >= height)
return;
float4 colorData = InputTexture.Load(int3(DispatchThreadId.xy, 0));
float3 color = colorData.rgb;
float threshold = 0.9;
bool isWhite = (color.r > threshold && color.g > threshold && color.b > threshold);
if (isWhite)
{
InterlockedAdd(Output[0], Luminance[0]);
}
if (DispatchThreadId.x == 0 && DispatchThreadId.y == 0)
{
Luminance[0] = 41;
Luminance[1] = 24;
}
}
Ive tried to replace float values from Luminance to int, and it didnt change anything.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744399119a4572297.html
评论列表(0条)