190 lines
5.3 KiB
C#
190 lines
5.3 KiB
C#
using Es.InkPainter;
|
|
using UnityEngine;
|
|
|
|
namespace Es.WaveformProvider
|
|
{
|
|
[RequireComponent(typeof(Renderer))]
|
|
[DisallowMultipleComponent]
|
|
public class WaveConductor : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
public bool update = true;
|
|
|
|
[Range(1f, 10f)]
|
|
public int updateFrameTiming = 3;
|
|
|
|
[Range(0f, 1f)]
|
|
public float adjuster;
|
|
|
|
[Range(0.01f, 2f)]
|
|
public float stride = 1f;
|
|
|
|
[Range(0.1f, 1f)]
|
|
public float attenuation = 0.96f;
|
|
|
|
[Range(0.01f, 0.5f)]
|
|
public float propagationSpeed = 0.1f;
|
|
|
|
[SerializeField]
|
|
private int inputTextureSize = 512;
|
|
|
|
[SerializeField]
|
|
private RenderTexture output;
|
|
|
|
[SerializeField]
|
|
private bool debug;
|
|
|
|
private static Material waveMaterial;
|
|
|
|
private Texture2D init;
|
|
|
|
private RenderTexture input;
|
|
|
|
private RenderTexture prev;
|
|
|
|
private RenderTexture prev2;
|
|
|
|
private RenderTexture result;
|
|
|
|
private InkCanvas inkCanvas;
|
|
|
|
private Brush brush;
|
|
|
|
private readonly int ShaderPropertyAdjust = Shader.PropertyToID("_RoundAdjuster");
|
|
|
|
private readonly int ShaderPropertyStride = Shader.PropertyToID("_Stride");
|
|
|
|
private readonly int ShaderPropertyAttenuation = Shader.PropertyToID("_Attenuation");
|
|
|
|
private readonly int ShaderPropertyC = Shader.PropertyToID("_C");
|
|
|
|
private readonly int ShaderPropertyInputTex = Shader.PropertyToID("_InputTex");
|
|
|
|
private readonly int ShaderPropertyPrevTex = Shader.PropertyToID("_PrevTex");
|
|
|
|
private readonly int ShaderPropertyPrev2Tex = Shader.PropertyToID("_Prev2Tex");
|
|
|
|
public RenderTexture Output
|
|
{
|
|
get
|
|
{
|
|
return output;
|
|
}
|
|
set
|
|
{
|
|
output = value;
|
|
}
|
|
}
|
|
|
|
private Material WaveMaterial
|
|
{
|
|
get
|
|
{
|
|
if (waveMaterial == null)
|
|
{
|
|
waveMaterial = new Material(Resources.Load<Material>("Es.WaveformProvider.WaveProvide"));
|
|
}
|
|
return waveMaterial;
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
brush = new Brush(Texture2D.whiteTexture, 0.1f, Color.white, null, 0f, Texture2D.whiteTexture, 1f, Brush.ColorBlendType.UseBrush, Brush.NormalBlendType.UseBrush, Brush.HeightBlendType.Add);
|
|
Material material = new Material(Resources.Load<Material>("Es.WaveformProvider.WaveInput"));
|
|
InkCanvas.PaintSet paintSet = new InkCanvas.PaintSet("", "", "_ParallaxMap", useMainPaint: false, useNormalPaint: false, useHeightPaint: true, material);
|
|
inkCanvas = base.gameObject.AddInkCanvas(paintSet);
|
|
inkCanvas.hideFlags = HideFlags.HideInInspector;
|
|
inkCanvas.OnInitializedAfter += delegate
|
|
{
|
|
paintSet.paintHeightTexture = new RenderTexture(inputTextureSize, inputTextureSize, 0, RenderTextureFormat.R8);
|
|
init = new Texture2D(1, 1);
|
|
init.SetPixel(0, 0, new Color(0f, 0f, 0f, 0f));
|
|
init.Apply();
|
|
input = paintSet.paintHeightTexture;
|
|
prev = new RenderTexture(input.width, input.height, 0, RenderTextureFormat.R8);
|
|
prev2 = new RenderTexture(input.width, input.height, 0, RenderTextureFormat.R8);
|
|
result = new RenderTexture(input.width, input.height, 0, RenderTextureFormat.R8);
|
|
Texture2D texture2D = new Texture2D(1, 1);
|
|
texture2D.SetPixel(0, 0, new Color(0.5f, 0f, 0f, 1f));
|
|
texture2D.Apply();
|
|
Graphics.Blit(texture2D, prev);
|
|
Graphics.Blit(texture2D, prev2);
|
|
};
|
|
}
|
|
|
|
private void OnWillRenderObject()
|
|
{
|
|
WaveUpdate();
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
if (debug)
|
|
{
|
|
int num = Screen.height / 3;
|
|
GUI.Box(new Rect(0f, 0f, num, num * 3), "");
|
|
GUI.DrawTexture(new Rect(0f, 0f, num, num), input);
|
|
GUI.DrawTexture(new Rect(0f, num, num, num), prev);
|
|
GUI.DrawTexture(new Rect(0f, 2 * num, num, num), prev2);
|
|
GUI.Box(new Rect(0f, num - 20, num, 20f), "INPUT");
|
|
GUI.Box(new Rect(0f, 2 * num - 20, num, 20f), "PREV");
|
|
GUI.Box(new Rect(0f, 3 * num - 20, num, 20f), "PREV2");
|
|
}
|
|
}
|
|
|
|
public void Input(Texture2D waveform, Vector2 uv, float scale, float strength = 0.1f)
|
|
{
|
|
brush.BrushTexture = waveform;
|
|
brush.Scale = scale;
|
|
brush.HeightBlend = strength;
|
|
inkCanvas.PaintUVDirect(brush, uv);
|
|
}
|
|
|
|
public void Input(Texture2D waveform, Vector3 worldPos, float scale, float strength = 0.1f)
|
|
{
|
|
brush.BrushTexture = waveform;
|
|
brush.Scale = scale;
|
|
brush.HeightBlend = strength;
|
|
inkCanvas.Paint(brush, worldPos);
|
|
}
|
|
|
|
public void Input(Texture2D waveform, RaycastHit hitInfo, float scale, float strength = 0.1f)
|
|
{
|
|
brush.BrushTexture = waveform;
|
|
brush.Scale = scale;
|
|
brush.HeightBlend = strength;
|
|
inkCanvas.Paint(brush, hitInfo);
|
|
}
|
|
|
|
public void InputNearestTriangleSurface(Texture2D waveform, Vector3 worldPos, float scale, float strength = 0.1f)
|
|
{
|
|
brush.BrushTexture = waveform;
|
|
brush.Scale = scale;
|
|
brush.HeightBlend = strength;
|
|
inkCanvas.PaintNearestTriangleSurface(brush, worldPos);
|
|
}
|
|
|
|
private void WaveUpdate()
|
|
{
|
|
if (update && Time.frameCount % updateFrameTiming == 0 && !(input == null) && !(output == null))
|
|
{
|
|
WaveMaterial.SetFloat(ShaderPropertyAdjust, adjuster);
|
|
WaveMaterial.SetFloat(ShaderPropertyStride, stride);
|
|
WaveMaterial.SetFloat(ShaderPropertyAttenuation, attenuation);
|
|
WaveMaterial.SetFloat(ShaderPropertyC, propagationSpeed);
|
|
WaveMaterial.SetTexture(ShaderPropertyInputTex, input);
|
|
WaveMaterial.SetTexture(ShaderPropertyPrevTex, prev);
|
|
WaveMaterial.SetTexture(ShaderPropertyPrev2Tex, prev2);
|
|
Graphics.Blit(null, result, WaveMaterial);
|
|
RenderTexture renderTexture = prev2;
|
|
prev2 = prev;
|
|
prev = result;
|
|
result = renderTexture;
|
|
Graphics.Blit(init, input);
|
|
Graphics.Blit(prev, output);
|
|
}
|
|
}
|
|
}
|
|
}
|