InteractiveMask/Runtime/MaskRenderer.cs

210 lines
4.0 KiB
C#
Raw Normal View History

2021-03-01 17:20:08 +01:00
using UnityEngine;
namespace TAO.InteractiveMask
{
public class MaskRenderer : MonoBehaviour
{
public Shader clearBlit = null;
private Material clearBlitMaterial;
// Camera source.
[HideInInspector]
2021-03-01 17:20:08 +01:00
public RenderTexture source = null;
// Output target.
[HideInInspector]
2021-03-01 17:20:08 +01:00
public RenderTexture target = null;
public Layer[] layers;
public bool debugGui = false;
public void Init()
2021-03-01 17:20:08 +01:00
{
clearBlitMaterial = new Material(clearBlit);
foreach (Layer layer in layers)
{
layer.Init(source, target);
}
}
public void Render()
{
Graphics.Blit(target, target, clearBlitMaterial);
foreach (Layer layer in layers)
{
layer.Blit(source, target);
}
}
// Clears the context of the render targets.
public void Clear()
{
Graphics.Blit(target, target, clearBlitMaterial);
foreach (Layer layer in layers)
{
layer.Clear(clearBlitMaterial);
}
}
2021-03-01 17:20:08 +01:00
private void OnValidate()
{
if (clearBlit == null)
{
clearBlit = Shader.Find("TAO/InteractiveMask/Clear");
}
if (layers != null)
{
for (int i = 0; i < layers.Length; i++)
{
if (layers[i].blit == null)
{
layers[i].blit = Shader.Find("TAO/InteractiveMask/Add");
}
if (layers[i].persistentBlit == null)
{
layers[i].persistentBlit = Shader.Find("TAO/InteractiveMask/AddPersistent");
}
}
}
}
public void GUI()
2021-03-01 17:20:08 +01:00
{
using (new GUILayout.HorizontalScope())
2021-03-01 17:20:08 +01:00
{
GUITexture(source);
GUITexture(target);
2021-03-01 17:20:08 +01:00
foreach (var l in layers)
{
switch (l.type)
2021-03-01 17:20:08 +01:00
{
case Layer.Type.Clear:
break;
case Layer.Type.Persistent:
{
GUITexture(l.PersistentTarget);
}
break;
default:
break;
2021-03-01 17:20:08 +01:00
}
}
}
}
private void GUITexture(Texture texture)
{
using (new GUILayout.VerticalScope())
{
GUILayout.Label(texture, GUILayout.Width(256), GUILayout.Height(256));
GUILayout.Label(string.Format("{0}\n{1}x{2}\n{3}", texture.name, texture.width, texture.height, texture.graphicsFormat));
}
}
}
[System.Serializable]
public class Layer
{
public static int LayerCount = 0;
public Type type = Type.Clear;
public Mask mask = new Mask();
public Shader blit = null;
private Material blitMaterial = null;
2021-03-01 17:20:08 +01:00
// Only when mode is persistent.
public Shader persistentBlit;
public RenderTexture PersistentTarget
{
get; private set;
}
private Material persistentBlitMaterial;
public void Init(RenderTexture source, RenderTexture target)
{
blitMaterial = new Material(blit);
switch (type)
{
case Type.Clear:
break;
case Type.Persistent:
{
persistentBlitMaterial = new Material(persistentBlit);
if (PersistentTarget == null)
{
PersistentTarget = new RenderTexture(target)
{
name = LayerCount.ToString()
};
}
persistentBlitMaterial.SetTexture("_Source", source);
persistentBlitMaterial.SetTexture("_Persistent", PersistentTarget);
}
break;
default:
break;
}
blitMaterial.SetTexture("_Source", source);
blitMaterial.SetVector("_Channels", mask.GetMaskVector);
LayerCount++;
2021-03-01 17:20:08 +01:00
}
public void Blit(RenderTexture source, RenderTexture target)
{
switch (type)
{
case Type.Clear:
{
Graphics.Blit(source, target, blitMaterial);
}
break;
case Type.Persistent:
{
Graphics.Blit(source, PersistentTarget, persistentBlitMaterial);
Graphics.Blit(PersistentTarget, target, blitMaterial);
}
break;
default:
break;
}
}
public void Clear(Material clearBlit)
{
if (PersistentTarget)
{
Graphics.Blit(PersistentTarget, PersistentTarget, clearBlit);
}
}
2021-03-01 17:20:08 +01:00
public enum Type
{
Clear,
Persistent
}
}
[System.Serializable]
public struct Mask
{
public bool r;
public bool g;
public bool b;
public bool a;
public Vector4 GetMaskVector
{
get { return new Vector4(r ? 1 : 0, g ? 1 : 0, b ? 1 : 0, a ? 1 : 0); }
}
}
2021-03-01 17:20:08 +01:00
}