性能问题待修复

This commit is contained in:
shenjianxing 2025-02-24 17:03:44 +08:00
parent 8cfeecd8e8
commit 3802bfbc6b
3 changed files with 162 additions and 139 deletions

View File

@ -187,6 +187,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
captureBGImg: {fileID: 1613795782999759057} captureBGImg: {fileID: 1613795782999759057}
RawImg: {fileID: 3350589312635769069} RawImg: {fileID: 3350589312635769069}
TempImg: {fileID: 0}
Content: {fileID: 6174875567737795578} Content: {fileID: 6174875567737795578}
ClearBtn: {fileID: 2761790485595999517} ClearBtn: {fileID: 2761790485595999517}
BackBtn: {fileID: 8433557736356431636} BackBtn: {fileID: 8433557736356431636}

View File

@ -3,9 +3,12 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Security.Cryptography;
using UnityEditor.Rendering;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.UI; using UnityEngine.UI;
using static UnityEditor.Progress; using static UnityEditor.Progress;
@ -14,14 +17,14 @@ public class ScreenShotPainter : MonoBehaviour
{ {
public class LineSegment public class LineSegment
{ {
public List<Vector2> Points { get; set; } public RenderTexture Texture { get; set; }
public Color Color { get; set; } public Color Color { get; set; }
public float Width { get; set; } public float Width { get; set; }
public bool IsEraser { get; set; } public bool IsEraser { get; set; }
public LineSegment(Color color, float width, bool isEraser) public LineSegment(Color color, float width, bool isEraser)
{ {
Points = new List<Vector2>(); Texture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24);
Color = color; Color = color;
Width = width; Width = width;
IsEraser = isEraser; IsEraser = isEraser;
@ -44,11 +47,11 @@ public class ScreenShotPainter : MonoBehaviour
/// <summary> /// <summary>
/// 涂鸦的RenderTexture图片 /// 涂鸦的RenderTexture图片
/// </summary> /// </summary>
private RenderTexture _blitRenderTexture; private RenderTexture _currentRenderTexture;
/// <summary> /// <summary>
/// 涂鸦的RenderTexture图片 /// 涂鸦的RenderTexture图片
/// </summary> /// </summary>
private RenderTexture _tempRenderTexture; //private RenderTexture _historyRenderTexture;
/// <summary> /// <summary>
/// 截图灰化背景图 /// 截图灰化背景图
/// </summary> /// </summary>
@ -229,6 +232,14 @@ public class ScreenShotPainter : MonoBehaviour
bool isInited = false; bool isInited = false;
Status status = Status.Pen; Status status = Status.Pen;
private CommandBuffer _commandBuffer;
private float _lastPaintTime;
private float _paintInterval = 0.02f; // 每0.02秒绘制一次
void Awake() void Awake()
{ {
instance = this; instance = this;
@ -239,6 +250,9 @@ public class ScreenShotPainter : MonoBehaviour
if (isInited == false) if (isInited == false)
{ {
isInited = true; isInited = true;
_commandBuffer = new CommandBuffer();
_commandBuffer.name = "PaintCommandBuffer";
_bgRawImage = bgRawImg; _bgRawImage = bgRawImg;
_paintCanvasImg = drawImg; _paintCanvasImg = drawImg;
@ -274,13 +288,12 @@ public class ScreenShotPainter : MonoBehaviour
_eraserBrushMat.SetFloat("_SizeY", _eraserSize * (float)_screenHeight / (float)_screenWidth); _eraserBrushMat.SetFloat("_SizeY", _eraserSize * (float)_screenHeight / (float)_screenWidth);
_tempRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_blitRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24); _currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_paintCanvasImg.texture = _blitRenderTexture; _paintCanvasImg.texture = _currentRenderTexture;
// 激活渲染纹理,确保它可以被写入 // 激活渲染纹理,确保它可以被写入
RenderTexture.active = _blitRenderTexture; RenderTexture.active = _currentRenderTexture;
GL.Clear(true, true, Color.clear); GL.Clear(true, true, Color.clear);
//给画布添加事件 //给画布添加事件
@ -306,7 +319,7 @@ public class ScreenShotPainter : MonoBehaviour
paintEventTrigger.triggers.Add(beginDrawEntry); paintEventTrigger.triggers.Add(beginDrawEntry);
// 使用 Graphics.Blit 清除渲染纹理 // 使用 Graphics.Blit 清除渲染纹理
Graphics.Blit(null, _blitRenderTexture, _clearBrushMat); Graphics.Blit(null, _currentRenderTexture, _clearBrushMat);
// 恢复默认的渲染纹理 // 恢复默认的渲染纹理
RenderTexture.active = null; RenderTexture.active = null;
@ -338,7 +351,7 @@ public class ScreenShotPainter : MonoBehaviour
_leftDownConnerPoint = Vector2.zero; _leftDownConnerPoint = Vector2.zero;
_rightUpConnerPoint = Vector2.zero; _rightUpConnerPoint = Vector2.zero;
_rightDownConnerPoint = Vector2.zero; _rightDownConnerPoint = Vector2.zero;
_blitRenderTexture.Release(); _currentRenderTexture.Release();
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 0, 0)); _bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 0, 0));
_eraserFlag = false; _eraserFlag = false;
//Graphics.Blit(_blitRenderTexture, _blitRenderTexture, _clearBrushMat); //清除一下 //Graphics.Blit(_blitRenderTexture, _blitRenderTexture, _clearBrushMat); //清除一下
@ -458,11 +471,12 @@ public class ScreenShotPainter : MonoBehaviour
void OnPostRender() void OnPostRender()
{ {
Debug.LogError(" OnPostRender");
if (!enabled) if (!enabled)
return; return;
if (_drawRegionRect) if (_drawRegionRect)
{ {
Debug.LogError("111");
//如果材质球不存在 //如果材质球不存在
if (!_lineMaterial) if (!_lineMaterial)
{ {
@ -555,7 +569,7 @@ public class ScreenShotPainter : MonoBehaviour
#endif #endif
//Texture2D CombineTex = new Texture2D(_renderTex.width, _renderTex.height, TextureFormat.ARGB32, false); //Texture2D CombineTex = new Texture2D(_renderTex.width, _renderTex.height, TextureFormat.ARGB32, false);
RenderTexture prev = RenderTexture.active; RenderTexture prev = RenderTexture.active;
RenderTexture.active = _blitRenderTexture; RenderTexture.active = _currentRenderTexture;
Texture2D BliTexture2D = new Texture2D((int)width, (int)height, TextureFormat.ARGB32, false); Texture2D BliTexture2D = new Texture2D((int)width, (int)height, TextureFormat.ARGB32, false);
@ -613,7 +627,6 @@ public class ScreenShotPainter : MonoBehaviour
case Status.Pen: case Status.Pen:
break; break;
case Status.Line: case Status.Line:
case Status.Rect:
if (Input.GetMouseButton(0)) if (Input.GetMouseButton(0))
{ {
@ -621,24 +634,18 @@ public class ScreenShotPainter : MonoBehaviour
{ {
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag); _currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
} }
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, _eraserFlag); LerpPaint(Input.mousePosition, _eraserFlag);
} }
break; break;
case Status.Circle: case Status.Circle:
if (_currentLine == null)
{
if (_currentLine == null)
{
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag); _currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
}
_lastPoint = Input.mousePosition; _lastPoint = Input.mousePosition;
} break;
case Status.Rect:
fixedPoint = Input.mousePosition;
prePoint = fixedPoint;
break; break;
} }
} }
@ -650,52 +657,59 @@ public class ScreenShotPainter : MonoBehaviour
ChangeToEraser(this.status == Status.Eraser); ChangeToEraser(this.status == Status.Eraser);
} }
Vector2 fixedPoint = default;
Vector2 prePoint = default;
bool needUndo = false;
private void PaintDragging(BaseEventData data) private void PaintDragging(BaseEventData data)
{ {
if (_enabled && _haveRegion) if (_enabled && _haveRegion)
{ {
if (Input.GetMouseButton(0) && Time.time - _lastPaintTime > _paintInterval)
{
_lastPaintTime = Time.time;
// 绘制逻辑
if (Input.GetMouseButton(0)) if (Input.GetMouseButton(0))
{ {
switch (status) switch (status)
{ {
case Status.Pen: case Status.Pen:
case Status.Eraser: case Status.Eraser:
if (_currentLine == null) if (_currentLine == null)
{ {
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag); _currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
} }
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, _eraserFlag); LerpPaint(Input.mousePosition, _eraserFlag);
break; break;
//case Status.Line: case Status.Rect:
// if (_currentLine != null) if (needUndo)
// { {
// if (_currentLine.Points.Count <= 0) if (_lineStack.Count > 0)
// { {
// _currentLine.Points.Add(Input.mousePosition); Undo();
// LerpPaint(Input.mousePosition, false); }
// } else
// } {
// break; Clear();
//case Status.Rect: }
// if (_currentLine != null) needUndo = false;
// { }
// if (_currentLine.Points.Count <= 0) if (Vector2.Distance(prePoint, Input.mousePosition) > 1)
// { {
// _currentLine.Points.Add(Input.mousePosition); prePoint = Input.mousePosition;
// LerpPaint(Input.mousePosition, false); _currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
// } _lastPoint = fixedPoint;
// } RectFactory();
// break; needUndo = true;
}
break;
} }
} }
} }
} }
}
private void OnPaintEndDrag(BaseEventData data) private void OnPaintEndDrag(BaseEventData data)
{ {
if (_enabled && _haveRegion) if (_enabled && _haveRegion)
@ -708,56 +722,40 @@ public class ScreenShotPainter : MonoBehaviour
{ {
FinishedRaw(); FinishedRaw();
} }
break; break;
case Status.Line: case Status.Line:
if (_currentLine != null) if (_currentLine != null)
{ {
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, false); LerpPaint(Input.mousePosition, false);
FinishedRaw(); FinishedRaw();
} }
break; break;
case Status.Rect: case Status.Rect:
{ fixedPoint = default;
if (_currentLine != null) needUndo = false;
{
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
_currentLine.Points.Add(points[1]);
LerpPaint(points[1], false);
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, false);
_currentLine.Points.Add(points[2]);
LerpPaint(points[2], false);
_currentLine.Points.Add(_lastPoint);
LerpPaint(points[0], false);
FinishedRaw();
}
}
break; break;
case Status.Circle: case Status.Circle:
if (_currentLine != null)
{ {
float radius = Vector2.Distance(_lastPoint, Input.mousePosition); float radius = Vector2.Distance(_lastPoint, Input.mousePosition);
var points = GenerateCirclePoints(_lastPoint, radius); var points = GenerateCirclePoints(_lastPoint, radius);
_lastPoint = default; _lastPoint = default;
foreach (var item in points) foreach (var item in points)
{ {
_currentLine.Points.Add(item);
LerpPaint(item, false); LerpPaint(item, false);
} }
_currentLine.Points.Add(points[0]);
LerpPaint(points[0], false); LerpPaint(points[0], false);
FinishedRaw(); FinishedRaw();
} }
break; break;
default: default:
break; break;
} }
@ -777,40 +775,57 @@ public class ScreenShotPainter : MonoBehaviour
} }
return points; return points;
} }
Vector2[] GenerateRectanglePoints(Vector2 start, Vector2 end)
public void RectFactory()
{
if (_lastPoint != default)
{
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
LerpPaint(points[0], false);
LerpPaint(points[1], false);
LerpPaint(points[2], false);
LerpPaint(points[3], false);
LerpPaint(points[0], false);
FinishedRaw();
}
}
public Vector2[] GenerateRectanglePoints(Vector2 start, Vector2 thirdPoint)
{ {
Vector2[] points = new Vector2[4]; Vector2[] points = new Vector2[4];
points[0] = start; points[0] = start;
points[3] = end; // 原本的 end 点(这里用 thirdPoint 替代)作为数组的第三个元素
points[2] = thirdPoint;
if (start.x < end.x) if (start.x < thirdPoint.x)
{ {
if (start.y < end.y) if (start.y < thirdPoint.y)
{ {
// 从左下方到右上方 // 从左下方到右上方
points[1] = new Vector2(end.x, start.y); points[1] = new Vector2(thirdPoint.x, start.y);
points[2] = new Vector2(start.x, end.y); points[3] = new Vector2(start.x, thirdPoint.y);
} }
else else
{ {
// 从左上方到右下方 // 从左上方到右下方
points[1] = new Vector2(end.x, start.y); points[1] = new Vector2(thirdPoint.x, start.y);
points[2] = new Vector2(start.x, end.y); points[3] = new Vector2(start.x, thirdPoint.y);
} }
} }
else else
{ {
if (start.y < end.y) if (start.y < thirdPoint.y)
{ {
// 从右下方到左上方 // 从右下方到左上方
points[1] = new Vector2(start.x, end.y); points[1] = new Vector2(start.x, thirdPoint.y);
points[2] = new Vector2(end.x, start.y); points[3] = new Vector2(thirdPoint.x, start.y);
} }
else else
{ {
// 从右上方到左下方 // 从右上方到左下方
points[1] = new Vector2(start.x, end.y); points[1] = new Vector2(start.x, thirdPoint.y);
points[2] = new Vector2(end.x, start.y); points[3] = new Vector2(thirdPoint.x, start.y);
} }
} }
@ -820,56 +835,64 @@ public class ScreenShotPainter : MonoBehaviour
public void FinishedRaw() public void FinishedRaw()
{ {
if (_currentLine != null) if (_currentLine != null)
{ {
// 保存当前纹理到 LineSegment
RenderTexture.active = _currentLine.Texture;
Graphics.Blit(_currentRenderTexture, _currentLine.Texture);
RenderTexture.active = null;
_lineStack.Push(_currentLine); _lineStack.Push(_currentLine);
_paintCanvasImg.texture = _currentLine.Texture;
_currentLine = null; _currentLine = null;
} }
_lastPoint = Vector2.zero;
}
_lastPoint = Vector2.zero;
}
public void Undo() public void Undo()
{ {
if (_lineStack.Count > 0) if (_lineStack.Count > 0)
{ {
Clear();
// 移除最后一条线 // 移除最后一条线
var line = _lineStack.Pop(); var line = _lineStack.Pop();
//重新绘制所有剩余的线条 // 如果栈中还有剩余的线条,切换到上一个线条的纹理
foreach (var item in _lineStack) if (_lineStack.Count > 0)
{ {
var previousLine = _lineStack.Peek();
_paintBrushMat.SetColor("_Color", item.Color); RenderTexture.active = _currentRenderTexture;
foreach (var point in item.Points) Graphics.Blit(previousLine.Texture, _currentRenderTexture);
{ RenderTexture.active = null;
LerpPaint(point, item.IsEraser); _paintCanvasImg.texture = previousLine.Texture;
} }
_lastPoint = Vector2.zero; else
{
Clear();
} }
} }
} }
public void Clear() public void Clear()
{ {
_blitRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24); // 重新分配 RenderTexture
_tempRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24); _currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_paintCanvasImg.texture = _blitRenderTexture; // 更新画布的纹理
_paintCanvasImg.texture = _currentRenderTexture;
// 清空线条栈
_lineStack.Clear(); _lineStack.Clear();
} }
/// <summary> /// <summary>
/// 绘画进行插值 /// 绘画进行插值
/// </summary> /// </summary>
/// <param name="point"></param> /// <param name="point"></param>
Vector2[] vector2s = new Vector2[10000];
private void LerpPaint(Vector2 point, bool isEraser) private void LerpPaint(Vector2 point, bool isEraser)
{ {
Paint(point, isEraser); Paint(isEraser, point);
if (_lastPoint == Vector2.zero) if (_lastPoint == Vector2.zero)
{ {
@ -881,42 +904,41 @@ public class ScreenShotPainter : MonoBehaviour
if (dis > _brushLerpSize) if (dis > _brushLerpSize)
{ {
Vector2 dir = (point - _lastPoint).normalized; Vector2 dir = (point - _lastPoint).normalized;
int num = (int)(dis / _brushLerpSize); int num = (int)(dis / (_brushLerpSize));
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
{ {
Vector2 newPoint = _lastPoint + dir * (i + 1) * _brushLerpSize; vector2s[i] = _lastPoint + dir * (i + 1) * _brushLerpSize;
Paint(newPoint, isEraser); Paint(isEraser, vector2s[i]);
} }
Debug.LogError(num);
} }
_lastPoint = point; _lastPoint = point;
} }
// 画点方法 // 画点方法
private void Paint(Vector2 point, bool isDraser) private void Paint(bool isEraser, Vector2 point)
{ {
Material material = null;
if (point.x < _leftDownConnerPoint.x || point.x > _rightUpConnerPoint.x || point.y < _leftDownConnerPoint.y || point.y > _rightUpConnerPoint.y) if (point.x < _leftDownConnerPoint.x || point.x > _rightUpConnerPoint.x || point.y < _leftDownConnerPoint.y || point.y > _rightUpConnerPoint.y)
return; return;
Vector2 uv = new Vector2(point.x / (float)_screenWidth, point.y / (float)_screenHeight);
Vector2 uv = new Vector2(point.x / (float)_screenWidth, if (isEraser)
point.y / (float)_screenHeight);
if (isDraser)
{ {
_eraserBrushMat.SetVector("_UV", uv); _eraserBrushMat.SetVector("_UV", uv);
// 先将源纹理内容渲染到临时纹理 material = _eraserBrushMat;
Graphics.Blit(_blitRenderTexture, _tempRenderTexture, _eraserBrushMat);
// 再将临时纹理内容复制回源纹理
Graphics.Blit(_tempRenderTexture, _blitRenderTexture);
} }
else else
{ {
_paintBrushMat.SetVector("_UV", uv); _paintBrushMat.SetVector("_UV", uv);
// 先将源纹理内容渲染到临时纹理 material = _paintBrushMat;
Graphics.Blit(_blitRenderTexture, _tempRenderTexture, _paintBrushMat);
// 再将临时纹理内容复制回源纹理
Graphics.Blit(_tempRenderTexture, _blitRenderTexture);
}
} }
_commandBuffer.Blit(_currentRenderTexture, _currentRenderTexture, material);
Graphics.ExecuteCommandBuffer(_commandBuffer);
_commandBuffer.Clear();
}
public Vector2 GetCaptureViewLeftDownConnerPoint() public Vector2 GetCaptureViewLeftDownConnerPoint()
{ {
Vector2 vec = new Vector2(Mathf.Min(_startPoint.x, _endPoint.x), Mathf.Min(_startPoint.y, _endPoint.y)); Vector2 vec = new Vector2(Mathf.Min(_startPoint.x, _endPoint.x), Mathf.Min(_startPoint.y, _endPoint.y));
@ -1003,7 +1025,7 @@ public class ScreenShotPainter : MonoBehaviour
_drawRegionRect = false; _drawRegionRect = false;
_haveRegion = false; _haveRegion = false;
_haveCirmformRectStarPoint = false; _haveCirmformRectStarPoint = false;
_blitRenderTexture.Release(); _currentRenderTexture.Release();
_startPoint = Vector2.zero; _startPoint = Vector2.zero;
_endPoint = Vector2.zero; _endPoint = Vector2.zero;
_leftUpConnerPoint = Vector2.zero; _leftUpConnerPoint = Vector2.zero;

View File

@ -5,7 +5,7 @@ using QFramework;
namespace QFramework.Example namespace QFramework.Example
{ {
// Generate Id:4d840482-3ece-436e-9579-de5573072430 // Generate Id:f3b60a04-6dce-45f6-968a-cb101a31a0c9
public partial class UIDraw public partial class UIDraw
{ {
public const string Name = "UIDraw"; public const string Name = "UIDraw";