Async version of Texture2D.GetPixel()

So, in my project i use textures for my terrain generator, e.g. to determine how much a procedural generation algorithm should blend with others, to create smooth terrain transitions (e.g. 2 different types of Perlin noise algorithms, one for hills and one for mountains).

The only problem is that i like my terrain generator to compute asynchronously to the main thread. Unfortunately the Texture2D.GetPixel() function can only be used on the main thread;


In the current workaround creating a frame drop each time a set of textures is loaded and converted to a Color[ , ] array for the async mesh builder to use.

I was wondering if there would be a alternate method to Texture2D.GetPixel() that could retrieve pixel information from a texture asynchronously.

use GPUAsyncReadbacks instead…

Oh, I see, you’re already in CPU land. You can use Native Arrays/GetRawTextureData a to copy the data into a native array and back into textures bypassing the slow Get/SetPixels APIs.

So i tried this function;

private Color32[,] textureData;
private async void ConvertTexture(Texture2D texture2D, Vector2Int textureSize) {
        await Task.Run(() => {
            var data = texture2D.GetRawTextureData<Color32>();
            var output = new Color32[textureSize.x, textureSize.y];
            for (int i = 0, x = 0; x < textureSize.x; i++, x++)
            {
                for (int y = 0; y < textureSize.y; y++)
                {
                    if (y != 0) i++;
                    output[x, y] = data[i];
                }
            }
            textureData = output;
        });
    }

And i yet, this function is also, only able to be called from the main thread, getting the exact same error as with GetPixel();

UnityException: get_isReadable can only be called from the main thread.

No, you need to use jobs (with burst) and native arrays here, not this. IJobParellelFor is likely what you want…

1 Like

The jobs and burst systems are both very new to unity (Jobs having been marked ‘stable’ since only a couple months). For this reason i avoided learning and working with any of the systems rumored to become part of the future unity DOTS, until DOTS gets a stable release out there. (cause why not start learning DOTS when DOTS is actually released). However if using unity jobs is the appropriate way of achieving this, i will read into using it when i get back to my terrain generator.

In any case, thanks for the help ^.^