Hello everyone.
I’m trying to findout what is going wrong with my code. The thing i want to do is set texture to ComputeShader,
save all pixels to array of struct:
struct MapDataStruct
{
int x;
int y;
float a;
};
and here is whole code of compute shader:
struct MapDataStruct
{
int x;
int y;
float a;
};
int Width;
RWTexture2D<float4> Input;
RWStructuredBuffer<MapDataStruct> Output;
[numthreads(8, 8, 1)]
void MapToStructs(uint3 id : SV_DispatchThreadID)
{
int index = Width * id.y + id.x;
Output[index].x = id.x;
Output[index].y = id.y;
Output[index].a = Input[id.xy].a;
}
Next in C# script it looks like this:
ComputeBuffer result = new ComputeBuffer ( tex.width * tex.height, this.GetMapStructStride ( ), ComputeBufferType.Structured );
int kernel = this.MapComputationsShader.FindKernel ( "MapToStructs" );
this.MapComputationsShader.SetInt ( "Width", tex.width );
this.MapComputationsShader.SetTexture ( kernel, "Input", ghelp.GetMiniMapScript ( ).renderTexture_Fow );
this.MapComputationsShader.SetBuffer ( kernel, "Output", result );
this.MapComputationsShader.Dispatch ( kernel, tex.width / 8, tex.height / 8, 1 );
int dataLength = tex.width * tex.height;
int oneReadSize = dataLength / 64;
auroraSurfaceFowMap.MapPixelsData = new List<MapDataStruct> ( );
for ( int currentLine = 0; currentLine < dataLength / oneReadSize; currentLine++ )
{
AsyncGPUReadbackRequest request = AsyncGPUReadback.Request ( result, oneReadSize, oneReadSize * currentLine );
while ( !request.done )
{
yield return null;
}
List<MapDataStruct> part = new List<MapDataStruct> ( request.GetData<MapDataStruct> ( ).Where ( s => s.a < 1f ).ToArray ( ) );
if ( part.Count > 0 )
{
auroraSurfaceFowMap.MapPixelsData.AddRange ( part );
Debug.Log ( $"Added {part.Count} pixels." );
}
yield return null;
}
result.Dispose ( );
Everything was okay when i was using just AsyncGPUReadback.Request ( result ) - without specifying size and offset parameters, but the issue was that there was about 200ms screen freeze when request.GetData<MapDataStruct> ( )
was invoked. Then i just found out that i can tell how big part of data i want to get from the buffer from AsyncGPUReadback.Request()
. In my opinion, this just should work but instead of this im getting always the same amount of pixels from ComputeBuffer Debug.Log ( $"Added {part.Count} pixels." );