using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; public class MemoryPainter : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler { public Material MemoryMaterial; // 材质 private RenderTexture MaskTexture; // 遮罩纹理 public Texture2D BrushTexture; // 画笔纹理 public float BrushSize = 50f; // 画笔大小 public Camera UICamera; // 用于屏幕坐标到世界坐标转换 public Material BlurMaterial; // 模糊材质 public float BlurSize = 1.0f; // 模糊程度 private bool isDrawing = false; private bool needsBlur = false; private float blurTimer = 0f; private float blurInterval = 0.02f; // 模糊处理的时间间隔 private RectTransform rectTransform; private RawImage rawImage; private Material brushMaterial; private void Start() { // 初始化 rectTransform = GetComponent(); rawImage = GetComponent(); MaskTexture = new RenderTexture(1920, 1080, 0, RenderTextureFormat.ARGB32); // 将遮罩纹理赋给材质 MemoryMaterial.SetTexture("_MaskTexture", MaskTexture); // 初始化遮罩纹理 InitRenderTexture(); // 设置材质到 RawImage rawImage.material = MemoryMaterial; // 创建笔刷材质 brushMaterial = new Material(Shader.Find("Unlit/Transparent")); brushMaterial.mainTexture = BrushTexture; brushMaterial.color = new Color(1, 1, 1, 0.3f); // 半透明,Alpha 值为 0.1 // 设置笔刷材质的混合模式为加法混合 brushMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); //brushMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); brushMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); brushMaterial.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add); brushMaterial.renderQueue = 3000; } private void InitRenderTexture() { RenderTexture currentRT = RenderTexture.active; RenderTexture.active = MaskTexture; GL.Clear(true, true, Color.black); // 全黑表示未上色区域 RenderTexture.active = currentRT; } public void OnPointerDown(PointerEventData eventData) { isDrawing = true; needsBlur = true; // 开启模糊处理 Draw(eventData); } public void OnPointerUp(PointerEventData eventData) { isDrawing = false; // 一段时间后停止模糊处理 StartCoroutine(StopBlurAfterDelay(2.0f)); } private IEnumerator StopBlurAfterDelay(float delay) { yield return new WaitForSeconds(delay); needsBlur = false; } public void OnDrag(PointerEventData eventData) { if (isDrawing) { Draw(eventData); } } private void Draw(PointerEventData eventData) { Vector2 localPoint; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, UICamera, out localPoint)) { // 将本地坐标转换为 UV 坐标 float uvX = (localPoint.x - rectTransform.rect.x) / rectTransform.rect.width; float uvY = (localPoint.y - rectTransform.rect.y) / rectTransform.rect.height; // 绘制到遮罩纹理 DrawAt(uvX, uvY); } } private void DrawAt(float uvX, float uvY) { RenderTexture currentRT = RenderTexture.active; RenderTexture.active = MaskTexture; GL.PushMatrix(); GL.LoadPixelMatrix(0, MaskTexture.width, MaskTexture.height, 0); // 设置绘制位置和大小 float x = uvX * MaskTexture.width - (BrushSize / 2); float y = (1 - uvY) * MaskTexture.height - (BrushSize / 2); // 绘制多次,位置略有偏移,模拟扩散 int iterations = 5; // 您可以根据需要调整迭代次数 float spread = 1.0f; // 扩散范围 for (int i = 0; i < iterations; i++) { float offsetX = Random.Range(-spread, spread); float offsetY = Random.Range(-spread, spread); Graphics.DrawTexture(new Rect(x + offsetX, y + offsetY, BrushSize, BrushSize), BrushTexture, brushMaterial); } GL.PopMatrix(); RenderTexture.active = currentRT; } private void Update() { if (needsBlur) { blurTimer += Time.deltaTime; if (blurTimer >= blurInterval) { ApplyBlurToMaskTexture(); blurTimer = 0f; } } } private void ApplyBlurToMaskTexture() { // 设置模糊程度 BlurMaterial.SetFloat("_BlurSize", BlurSize); // 创建一个临时的 RenderTexture RenderTexture tempRT = RenderTexture.GetTemporary(MaskTexture.width, MaskTexture.height, 0, MaskTexture.format); // 使用模糊材质处理遮罩纹理 Graphics.Blit(MaskTexture, tempRT, BlurMaterial); // 将模糊后的结果拷贝回遮罩纹理 Graphics.Blit(tempRT, MaskTexture); RenderTexture.ReleaseTemporary(tempRT); } }