Texture2D looks blank in after using ReadPixels, but it's not when saved

I am trying to replace a texture in a GameObject with a custom one.
The new texture looks blank, but if I save it to disk and load that image into the GameObject, then it works fine.
I want to avoid that saving step, because I’m not sure I’m allowed to do that in mobile platforms…

Here’s what I did:

  • I created a class that it does not inherit from MonoBehaviour.
  • The class has a Texture2D member _texture.
  • The class has a method that uses a custom shader to draw something on a RenderTexture.
  • I use ReadPixels to copy the contents of this RenderTexture to _texture.

The method does something like this:

public void myFunction() {
   WWW _texLoader = new WWW("file://"+Application.dataPath+"sometexture.png");
   Texture2D source = new Texture2D(W, H, TextureFormat.ARGB32, false);
   _texLoader.LoadImageIntoTexture(source);
   RenderTexture rTexture = RenderTexture.GetTemporary(W, H, 0, RenderTextureFormat.ARGB32 );
   Material material = new Material(Shader.Find("MyMaterial"));
   Graphics.Blit(source, rTexture, material);
   // activate rTexture as current render target, so ReadPixels reads from it
   RenderTexture.active = rTexture ;
   Rect sourceRect = new Rect(0,0,W,H);
   _texture.ReadPixels(sourceRect, 0, 0);
   // go back to main context
   RenderTexture.active = null ;
   RenderTexture.ReleaseTemporary(rTexture);  
}
public Texture2D GetTexture() {
   return _texture;
}

After that, the image is set somewhere else to a GameObject using GetTexture(), but it looks blank. However, if I apply the function below, then it works.

public Texture2D GetAnotherTexture() {
	Texture2D texture = new Texture2D(W, H, TextureFormat.ARGB32, false);
	texture.LoadImage(File.ReadAllBytes(GetMyPath()));
	return texture ;
}

I have tried the things below, but nothing seems to work:

  • Making _texture static
  • Waiting 1 frame before setting the texture to the GameObject

Do I have to WaitForEndOfFrame()? I am writing to my own RenderTarget with RenderTexture.active, right? So I guess it should work (it actually works, since the saved image is fine…)
I guess it has something to do with the state of the Texture2D image, but I can’t find any help in the documentation. Any suggestions?
Thanks in advance.

I just realized that the problem is that I should call _texture.Apply() after reading the pixels… orz.
I thought that the default behavior of ReadPixels is that automatically calls Apply. Also, since saving works, I was convinced that the pixels “were there”…