160 lines
5.1 KiB
C#
160 lines
5.1 KiB
C#
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<RectTransform>();
|
|
rawImage = GetComponent<RawImage>();
|
|
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);
|
|
}
|
|
}
|