赞
踩
先上成品效果
功能介绍:
1.笔刷形状(在预制体里面可以更改)
2.笔刷压力
3.百分判断
进度1代表区域1 1代表100% 进度2代表区域2,依次类推!
shader代码如下:
- // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
-
- Shader "Custom/MaskShader" {
- Properties{
- _Color("Color", Color) = (1,1,1,1)
- //_MainTex ("Albedo (RGB)", 2D) = "white" {}
- _MainTex("Mask Texture",2D) = "white"{}
- _Mask("Mask",2D) = "white"{}
-
- }
- SubShader{
- Tags{"RenderType" = "Transparent" "Queue" = "Transparent"}
- pass
- {
- Blend SrcAlpha OneMinusSrcAlpha
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "unitycg.cginc"
-
- struct v2f
- {
- float4 pos:POSITION;
- float2 uv:TEXCOORD1;
- };
-
- //sampler2D _MainTex;
- sampler2D _MainTex;
- sampler2D _Mask;
-
- v2f vert(appdata_base v)
- {
- v2f o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv = v.texcoord;
- return o;
- }
-
- float4 frag(v2f i) :COLOR
- {
- float4 maskTexColor = tex2D(_MainTex,i.uv);
- float4 maskColor = tex2D(_Mask,i.uv);
- maskTexColor.a = 1 - maskColor.a;
- return maskTexColor;
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- SubShader
- {
- LOD 100
-
- Tags
- {
- "Queue" = "Transparent"
- "IgnoreProjector" = "True"
- "RenderType" = "Transparent"
- }
-
- Pass
- {
- Cull Off
- Lighting Off
- ZWrite Off
- Fog { Mode Off }
- ColorMask RGB
- Blend SrcAlpha OneMinusSrcAlpha
- ColorMaterial AmbientAndDiffuse
-
- SetTexture[_MainTex]
- {
- Combine Texture * Primary
- }
- }
- }
- }
C#代码:
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class DrawMask : MonoBehaviour
- {
- public float radius = 0.5f;
- public GameObject brush;
- bool startDraw = false;
- bool twoPoints = false;
- Vector2 lastPos;
- Vector2 penultPos;
- List<GameObject> brushesPool = new List<GameObject>(), activeBrushes = new List<GameObject>();
- public Rect[] rect;
-
- float total1;
- float total2;
- float total3;
- float total4;
- float precess1;
- float precess2;
- float precess3;
- float precess4;
-
- Texture2D t2d;
-
- void Start()
- {
- for (int i = 0; i < Camera.allCameras.Length; i++)
- {
- if (Camera.allCameras[i].name == "Post-Camera")
- {
- RenderTexture rt = Camera.allCameras[i].targetTexture;
- t2d = this.RenderTexture2Texture2D(rt);
- this.total1 = (Convert.ToInt32(t2d.width / 10) * Convert.ToInt32(t2d.height / 10)) / 4;
- this.total4 = this.total3 = this.total2 = this.total1;
- }
- }
- Debug.Log("数组长度:" + Convert.ToInt32(t2d.width / 10) * Convert.ToInt32(t2d.height / 10));
- }
-
- // Update is called once per frame
- void Update()
- {
- GetInput();
- }
-
- void GetInput()
- {
- if (Input.GetMouseButtonDown(0))
- {
- startDraw = true;
- penultPos = Input.mousePosition;
- }
- else if (Input.GetMouseButton(0))
- {
- if (twoPoints && Vector2.Distance(Input.mousePosition, lastPos) > 0.5f)
- {
- Vector2 pos = Input.mousePosition;
- float dis = Vector2.Distance(lastPos, pos);
- int segments = (int)(dis / radius);
- segments = segments < 1 ? 1 : segments;
- Vector2[] points = GetPoint(penultPos, lastPos, pos, segments);
- for (int i = 0; i < points.Length; i++) InstanceBrush(ScreenToWorldPoint(points[i]));
- lastPos = pos;
- penultPos = points[points.Length - 2];
- precess4 = precess3 = precess2 = precess1 = 0;
- for (int i = 0; i < Camera.allCameras.Length; i++)
- {
- if (Camera.allCameras[i].name == "Post-Camera")
- {
- RenderTexture rt = Camera.allCameras[i].targetTexture;
- t2d = this.RenderTexture2Texture2D(rt);
- for (int x = 0; x < this.t2d.width; x += 10)
- {
- for (int y = 0; y < this.t2d.height; y += 10)
- {
- if (this.t2d.GetPixel(x, y).a > 0.1)
- {
- for (int ii = 0; ii < this.rect.Length; ii++)
- {
- if (this.rect[ii].Contains(new Vector2(x, y)))
- {
- if (ii == 0) this.precess1++;
- else if (ii == 1) this.precess2++;
- else if (ii == 2) this.precess3++;
- else if (ii == 3) this.precess4++;
- }
- }
- }
- }
- }
- //Debug.Log("鼠标位置:" + Input.mousePosition);
- Debug.Log("当前进度1:" + (this.precess1 / this.total1) + " 进度2:" + (this.precess2 / this.total2) + " " +
- " 进度3:" + (this.precess3 / this.total3) + " 进度4:" + (this.precess4 / this.total4));
- }
- }
- }
- else
- {
- twoPoints = true;
- lastPos = Input.mousePosition;
- }
- }
- else if (Input.GetMouseButtonUp(0))
- {
- startDraw = false;
- twoPoints = false;
- }
- }
-
- private void OnPostRender()
- {
- InitBrushes();
- }
-
- void InitBrushes()
- {
- for (int i = 0; i < activeBrushes.Count; i++)
- {
- activeBrushes[i].SetActive(false);
- brushesPool.Add(activeBrushes[i]);
- }
- activeBrushes.Clear();
- }
-
- void InstanceBrush(Vector2 pos)
- {
- GameObject brushClone;
- if (brushesPool.Count > 0)
- {
- brushClone = brushesPool[brushesPool.Count - 1];
- brushesPool.RemoveAt(brushesPool.Count - 1);
- }
- else brushClone = Instantiate(brush, pos, Quaternion.identity);
- brushClone.transform.position = pos;
- brushClone.transform.localScale = Vector3.one * radius;
- brushClone.SetActive(true);
- activeBrushes.Add(brushClone);
- }
-
- public Vector2[] GetPoint(Vector2 start, Vector2 mid, Vector2 end, int segments)
- {
- float d = 1f / segments;
- Vector2[] points = new Vector2[segments - 1];
- for (int i = 0; i < points.Length; i++)
- {
- float t = d * (i + 1);
- points[i] = (1 - t) * (1 - t) * mid + 2 * t * (1 - t) * start + t * t * end;
- }
- List<Vector2> rps = new List<Vector2>();
- rps.Add(mid);
- rps.AddRange(points);
- rps.Add(end);
- return rps.ToArray();
- }
-
- Vector2 ScreenToWorldPoint(Vector2 point)
- {
- return Camera.allCameras[0].ScreenToWorldPoint(new Vector3(point.x, point.y, 0));
- }
-
- public Texture2D RenderTexture2Texture2D(RenderTexture rt)
- {
- RenderTexture preRT = RenderTexture.active;
- RenderTexture.active = rt;
- Texture2D tex = null;
- if (!this.t2d)
- tex = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false);
- else
- tex = this.t2d;
- tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
- tex.Apply();
- RenderTexture.active = preRT;
- return tex;
- }
- }
如果笔刷出现不连续情况,调整下面这个值可以解决.
如果有不明白可以下载下来包自己学习(工程使用Unity2020.3.9f1版本)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。