您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

218 行
9.3 KiB

using UnityEngine;
namespace UnityEditor.VFXToolbox.ImageSequencer
{
class CropProcessor : GPUFrameProcessor<CropProcessorSettings>
{
public CropProcessor(FrameProcessorStack stack, ProcessorInfo info)
: base("Packages/com.unity.vfx-toolbox/ImageSequencer/Editor/Shaders/Crop.shader", stack, info)
{ }
public override string GetName()
{
return "Crop";
}
public override bool OnCanvasGUI(ImageSequencerCanvas canvas)
{
if (Event.current.type != EventType.Repaint)
return false;
Vector2 center = canvas.CanvasToScreen(Vector2.zero);
Vector2 topRight;
Vector2 bottomLeft;
topRight = canvas.CanvasToScreen(new Vector2(-canvas.currentFrame.texture.width/2 - settings.Crop_Right, canvas.currentFrame.texture.height/2 + settings.Crop_Top));
bottomLeft = canvas.CanvasToScreen(new Vector2(canvas.currentFrame.texture.width/2 + settings.Crop_Left, -canvas.currentFrame.texture.height/2 - settings.Crop_Bottom));
Handles.DrawSolidRectangleWithOutline(new Rect(topRight, bottomLeft - topRight), Color.clear, canvas.styles.green);
Vector2 topRightCrop;
Vector2 bottomLeftCrop;
topRightCrop = canvas.CanvasToScreen(new Vector2(-canvas.currentFrame.texture.width/2, canvas.currentFrame.texture.height/2));
bottomLeftCrop = canvas.CanvasToScreen(new Vector2(canvas.currentFrame.texture.width/2, -canvas.currentFrame.texture.height/2));
Handles.DrawSolidRectangleWithOutline(new Rect(topRightCrop, bottomLeftCrop - topRightCrop), Color.clear, canvas.styles.red);
// Arrows
Handles.color = canvas.styles.white;
Handles.DrawLine(new Vector3(center.x, topRight.y), new Vector3(center.x, topRightCrop.y));
Handles.DrawLine(new Vector3(center.x, bottomLeft.y), new Vector3(center.x, bottomLeftCrop.y));
Handles.DrawLine(new Vector3(topRight.x, center.y), new Vector3(topRightCrop.x, center.y));
Handles.DrawLine(new Vector3(bottomLeft.x, center.y), new Vector3(bottomLeftCrop.x, center.y));
Handles.color = Color.white;
// Texts
GUI.Label(new Rect(center.x, topRightCrop.y - 16 , 64, 16), settings.Crop_Top.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(center.x, bottomLeftCrop.y, 64, 16), settings.Crop_Bottom.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(topRightCrop.x, center.y, 64, 16), settings.Crop_Right.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(bottomLeftCrop.x - 64, center.y, 64, 16), settings.Crop_Left.ToString(), canvas.styles.miniLabelRight);
return false;
}
protected override void UpdateOutputSize()
{
int width = (InputSequence.width - (int)settings.Crop_Left) - (int)settings.Crop_Right;
int height = (InputSequence.height - (int)settings.Crop_Top) - (int)settings.Crop_Bottom;
SetOutputSize(width, height);
}
public override bool Process(int frame)
{
UpdateOutputSize();
Texture texture = InputSequence.RequestFrame(frame).texture;
m_Material.SetTexture("_MainTex", texture);
m_Material.SetVector("_CropFactors", new Vector4(
(float)settings.Crop_Left / texture.width,
(float)settings.Crop_Right / texture.width,
(float)settings.Crop_Top / texture.height,
(float)settings.Crop_Bottom / texture.height
));
ExecuteShaderAndDump(frame, texture);
return true;
}
private void FindProperValues(float threshold, ref SerializedProperty top, ref SerializedProperty bottom, ref SerializedProperty left, ref SerializedProperty right)
{
int width = InputSequence.width;
int height = InputSequence.height;
int minX = width;
int maxX = 0;
int minY = height;
int maxY = 0;
Color[] colors;
RenderTexture tempRT = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
for (int i = 0; i < InputSequence.frames.Count; i++)
{
ProcessingFrame f = InputSequence.frames[i];
VFXToolboxGUIUtility.DisplayProgressBar("Crop processor","Evaluating closest bound (Frame #"+i+" on "+ InputSequence.frames.Count+"...)", (float)i/InputSequence.frames.Count);
if(InputSequence.processor != null)
{
f.Process();
colors = VFXToolboxUtility.ReadBack(f.texture as RenderTexture);
}
else
{
Graphics.Blit(f.texture, tempRT);
colors = VFXToolboxUtility.ReadBack( tempRT );
}
// Check frame
for(int j = 0; j < colors.Length; j++)
{
int x = j % width;
int y = j / width;
if (colors[j].a >= threshold)
{
minX = Mathf.Min(minX, x);
maxX = Mathf.Max(maxX, x);
minY = Mathf.Min(minY, y);
maxY = Mathf.Max(maxY, y);
}
}
}
VFXToolboxGUIUtility.ClearProgressBar();
bottom.intValue = minY;
top.intValue = height - maxY - 1;
left.intValue = minX;
right.intValue = width - maxX - 1;
RenderTexture.ReleaseTemporary(tempRT);
}
protected override bool DrawSidePanelContent(bool hasChanged)
{
int sourceWidth = InputSequence.width;
int sourceHeight = InputSequence.height;
var crop_top = m_SerializedObject.FindProperty("Crop_Top");
var crop_bottom = m_SerializedObject.FindProperty("Crop_Bottom");
var crop_left = m_SerializedObject.FindProperty("Crop_Left");
var crop_right = m_SerializedObject.FindProperty("Crop_Right");
var threshold = m_SerializedObject.FindProperty("AutoCropThreshold");
EditorGUI.BeginChangeCheck();
EditorGUILayout.IntSlider(crop_top, 0, (sourceHeight / 2) - 1, VFXToolboxGUIUtility.Get("Top"));
EditorGUILayout.IntSlider(crop_bottom, 0, (sourceHeight / 2) - 1, VFXToolboxGUIUtility.Get("Bottom"));
EditorGUILayout.IntSlider(crop_left, 0, (sourceWidth / 2) - 1, VFXToolboxGUIUtility.Get("Left"));
EditorGUILayout.IntSlider(crop_right, 0, (sourceWidth / 2) - 1, VFXToolboxGUIUtility.Get("Right"));
GUILayout.Space(20);
GUILayout.Label(VFXToolboxGUIUtility.Get("Automatic Crop Values"),EditorStyles.boldLabel);
EditorGUI.indentLevel += 2;
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Slider(threshold, 0.0f, 1.0f, VFXToolboxGUIUtility.Get("Alpha Threshold"));
if(GUILayout.Button(VFXToolboxGUIUtility.Get("Find")))
{
FindProperValues(threshold.floatValue, ref crop_top, ref crop_bottom, ref crop_left, ref crop_right);
GUI.changed = true;
}
}
EditorGUI.indentLevel -= 2;
GUILayout.Space(20);
Rect preview_rect;
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
preview_rect = GUILayoutUtility.GetRect(200, 200);
GUILayout.FlexibleSpace();
}
EditorGUI.DrawRect(preview_rect, new Color(0, 0, 0, 0.1f));
GUI.BeginClip(preview_rect);
GUI.Label(new Rect(0, 0, 200, 16), "Preview");
int top = 40;
int left = 40;
int right = 160;
int bottom = 160;
Handles.color = Color.green;
Handles.DrawLine(new Vector3(left,top), new Vector3(left,bottom));
Handles.DrawLine(new Vector3(left,bottom), new Vector3(right,bottom));
Handles.DrawLine(new Vector3(right,bottom), new Vector3(right,top));
Handles.DrawLine(new Vector3(right,top), new Vector3(left,top));
top = (int)(40 + 120*(float)crop_top.intValue / sourceHeight);
bottom = (int)(160 - 120*(float)crop_bottom.intValue / sourceHeight);
left = (int)(40 + 120*(float)crop_left.intValue / sourceWidth);
right = (int)(160 - 120*(float)crop_right.intValue / sourceWidth);
Handles.color = Color.red;
Handles.DrawLine(new Vector3(left,top), new Vector3(left,bottom));
Handles.DrawLine(new Vector3(left,bottom), new Vector3(right,bottom));
Handles.DrawLine(new Vector3(right,bottom), new Vector3(right,top));
Handles.DrawLine(new Vector3(right,top), new Vector3(left,top));
GUI.EndClip();
if(EditorGUI.EndChangeCheck())
{
UpdateOutputSize();
Invalidate();
hasChanged = true;
}
return hasChanged;
}
}
}