Scratch Card Is not smooth using SetPixel()

Hi,

I want to implement a scratcher where user can scratch the foil to reveal the content on card. For the following I used unity SetPixel(). But it’s not smooth when user reveal vigorously.

My code is as follow :

public class Scratcher : MonoBehaviour
{
		public UITexture mTex;

		private Texture2D texture;
		private float erasedPixels;

		private int textureWidth = 28;
		private int textureHieght = 28;

		void  Start ()
		{
				// Create a new texture and assign it to the renderer's material
				texture = new Texture2D (textureWidth, textureHieght, TextureFormat.RGB24, true);

				GetComponent<UITexture> ().material.SetTexture ("_SliceGuide", texture);

				// Fill the texture with white (you could also paint it black, then draw with white)
				for (int y = 0; y < texture.height; ++y) {
						for (int x = 0; x < texture.width; ++x) {
								texture.SetPixel (x, y, Color.white);
						}
				}
				texture.Apply ();
		}

		void Update ()
		{
				if (Input.GetMouseButton (0) && UICamera.hoveredObject != null && UICamera.hoveredObject.tag == "ScratchFoil") {

						Vector3 localPos = transform.InverseTransformPoint (UICamera.lastHit.point);
						Vector2 uv;

						uv.x = localPos.x / (float)mTex.width;
						uv.y = localPos.y / (float)mTex.height;

						Texture2D tex = texture;

						Vector2 pixelUV = uv;

						pixelUV.x *= tex.width;
						pixelUV.y *= tex.height;

						// add black spot, which is then transparent in the shader
						tex.SetPixel ((int)pixelUV.x, (int)pixelUV.y, Color.black);
						tex.Apply ();
				}
		}
}

Now I applied this script on my NGUI UITexture which contains a material with a shader used to clip the current texture RGB value from _MainTex.

Shader As follow :

 Shader "mShaders/ScratchEffect" {
    Properties {
      _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
      _SliceGuide ("Slice Guide (RGB)", 2D) = "white" {}
      _SliceAmount ("Slice Amount", Range(0.0, 1.0)) = 0.9
    }

    SubShader {
      Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType" = "Transparent" }
      Cull Off

      CGPROGRAM
      #pragma surface surf Lambert alpha
      struct Input {
          float2 uv_MainTex;
          float2 uv_SliceGuide;
          float _SliceAmount;
      };

      sampler2D _MainTex;
      sampler2D _SliceGuide;
      float _SliceAmount;

      void surf (Input IN, inout SurfaceOutput o) {
          clip(tex2D (_SliceGuide, IN.uv_SliceGuide).rgb - _SliceAmount);
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          o.Emission = tex2D (_MainTex, IN.uv_MainTex).rgb;
          o.Alpha = tex2D (_MainTex, IN.uv_MainTex).a;
      }
      ENDCG

    }
    Fallback "Diffuse"

  }

Everything working fine to it just this SetPixel() is sucking a lot of frame per second and not giving smooth scratch effect.

Anybody help me out with this trouble.

Thanks in Advance.

You should avoid using SetPixel() so often. It is much more efficient to use SetPixels().

Perhaps in Update() you could maintain a list of pixels you need to set. Then, after a certain threshold, apply the pixels you were recording via SetPixels() as a batch. You could play with the threshold such that it is not very noticeable.