SetPixel / Texture.Apply – terrible performance on iOS.

Hi!

I’m having some trouble with performance when I try to update a texture on every frame using Texture.Apply(). It runs smooth on a MacBook Pro and on an iPhone 6, but when I test it on older devices, I get around 2-5 fps.

I’m trying to create a scratch card thing, which loops over some brush pixels and applies them to a texture on given x and y coordinates. Check this video to get an idea of the effect I’m looking for: https://drive.google.com/file/d/0B0aaXCyLab3sd1hmZFpJcmFGR0U/view

The texture painting code looks like this:

for (int x = 0; x < brush.width; x++) {
	for (int y = 0; y < brush.height; y++) {
		Color sourceColor = brush.GetPixel(x, y);
		Color maskColor = maskTexture.GetPixel(xPos + x, yPos + y);
		if (sourceColor.a < 1 && maskColor.a > 0) {
			maskTexture.SetPixel(xPos + x, yPos + y, sourceColor);
		}
	}
}
		
maskTexture.Apply();

Is it any alternative method I can use to achieve a similar effect? Doing this inside a shader would probably be much better performance, but I have very limited experience with shaders in Unity.

I have also looked at the RenderTexture class, but I’m not really sure how to use it for this particular task.

Yes this sounds like a thing for shaders. You will have to research this on your own but ideally you want to make a shader with:

  1. Base unscratched texture
  2. Completely revealed scratched texture
  3. Buffer A
  4. Buffer B

Pass 1:
Write to buffer A’s red channel all of buffer B’s red channel plus the new scratchy effects on the red channel.

Pass 2:
Write to buffer B all of buffer A

Pass 3:
Lerp between base and reveal textures using Buffer B’s red channel.

This isn’t something particularly easy to do but this is what you would do.