- Home /
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.
Answer by rageingnonsense · Feb 26, 2015 at 11:39 PM
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.
Tried SetPixels() also. Still if I scratch vigorously, it still lagged. No so smooth. will appreciate if you provide any example.
thanks.
@Nikz_89 : tex.Apply (); is the culprit. if you want to use it in Update( ) ,just call it say , only 30 times or less per second . I hope this shall solve your lagging. You can even try this in retina devices. Just remember , less calls to tex.apply , means less lag. And yes , better to use SetPixels or SetPixels32 ins$$anonymous$$d of setpixel :D
Your answer
Follow this Question
Related Questions
Performance issue. Optimize or change SetPixel to allow for painting specific areas of a texture. 1 Answer
Lagspike when using instantiate in coorutine 0 Answers
Reduce Poly Count Within Unity? Higher FPS? 1 Answer
Android lag 1 Answer
Android game lags when using transform.RotateAround to rotate an object with many children 2 Answers