简单Shader实现刮刮乐效果
Unity Shader的测试题,类似刮刮乐那种。
下面是实现的一个效果(随便找的图片),是在一个plane中根据按钮来滑动鼠标来进行刮刮乐的操作,即plane上的一张图片上显示不同图片的某区域的颜色值。
首先是Shader部分,我们就根据纹理的a值来判断区域内该显示哪个图片的颜色值。
Shader "Unlit/changeC" { Properties { _ColorTex("Color Texture", 2D) = "white"{} //三张图片的纹理 _FirstTex("First Texture", 2D) = "white"{} _SecondTex("Second Texture", 2D) = "white"{} _ThirdTex("Third Texture", 2D) = "white"{} } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" sampler2D _ColorTex; sampler2D _FirstTex; sampler2D _SecondTex; sampler2D _ThirdTex; fixed4 frag(v2f_img i):SV_Target { //根据纹理的a值来判断显示哪个图片的纹理 float r = tex2D(_ColorTex, i.uv).a; if(r > 0.66) { return tex2D(_FirstTex, i.uv); } if (r > 0.33) { return tex2D(_SecondTex, i.uv); } return tex2D(_ThirdTex, i.uv); } ENDCG } } FallBack "Diffuse" }
在Unity场景中,创建一个plane(3D中的,因为要定位鼠标的位置,就直接用3D中的碰撞来检测),为其增加一个Tag
下面是c#代码,挂在创建的plane上
using System.Collections; using System.Collections.Generic; using UnityEngine; public class changeC : MonoBehaviour { //擦除的像素半径 public int radius = 20; //控制显示效果的纹理 Texture2D colorTint; //像素高度 public int picWidth, picHeight; //显示的图片 float picIndex; void Start() { picIndex = 0f; colorTint = new Texture2D(picWidth, picHeight, TextureFormat.Alpha8, false); for(int i = 0; i < picWidth; i++) { for(int j=0;j<picHeight;j++) { colorTint.SetPixel(i, j, new Color(0, 0, 0, 1)); } } colorTint.Apply(); GetComponent<MeshRenderer>().material.SetTexture("_ColorTex", colorTint); } private void Update() { if(Input.GetMouseButton(0)) { //print("a"); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if(Physics.Raycast(ray,out hit)) { if(hit.collider.tag == "TintTex") { print("b"); changeColor(hit.textureCoord); } } } } void changeColor(Vector2 uv) { Vector2Int o = new Vector2Int((int)(colorTint.width * uv.x), (int)(colorTint.height * uv.y)); print("color"); for (int x = -radius; x < radius; x++) { for (int y = -radius; y < radius; y++) { if (x * x + y * y < radius * radius) { colorTint.SetPixel(o.x + x, o.y + y, new Color(0,0,0,1)*picIndex); } } } colorTint.Apply(); GetComponent<MeshRenderer>().material.SetTexture("_ColorTex", colorTint); } public void SetPicIndex(float i) { picIndex = i; } }
再创建三个button,为其绑定事件(每个button直接调用c#代码中的setPicIndex,传入不同参数即可),把plane拖入其中就大功告成了。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class test3 : MonoBehaviour { public GameObject plane; private void Start() { Button btn = this.GetComponent<Button>(); btn.onClick.AddListener(OnClick); } void OnClick() { plane.GetComponent<changeC>().SetPicIndex(0); } }