258 lines
8.4 KiB
C#
258 lines
8.4 KiB
C#
using UnityEngine;
|
|
|
|
namespace Es.InkPainter.Effective
|
|
{
|
|
[DisallowMultipleComponent]
|
|
[RequireComponent(typeof(InkCanvas))]
|
|
public class HeightFluid : MonoBehaviour
|
|
{
|
|
private enum ColorSynthesis
|
|
{
|
|
Add = 0,
|
|
Overwrite = 1
|
|
}
|
|
|
|
[SerializeField]
|
|
private bool useMainTextureFluid = true;
|
|
|
|
[SerializeField]
|
|
private bool useNormalMapFluid = true;
|
|
|
|
[SerializeField]
|
|
private int createTextureSize = 1024;
|
|
|
|
[SerializeField]
|
|
private ColorSynthesis colorSynthesis = ColorSynthesis.Overwrite;
|
|
|
|
[SerializeField]
|
|
[Range(0f, 1f)]
|
|
private float alpha = 1f;
|
|
|
|
[SerializeField]
|
|
private Vector2 flowDirection = Vector2.up;
|
|
|
|
[SerializeField]
|
|
[Range(0f, 1f)]
|
|
private float flowingForce = 1f;
|
|
|
|
[SerializeField]
|
|
[Range(0.1f, 10f)]
|
|
private float easeOfDripping = 1f;
|
|
|
|
[SerializeField]
|
|
[Range(1f, 0f)]
|
|
private float influenceOfNormal = 1f;
|
|
|
|
[SerializeField]
|
|
[Range(0.01f, 1f)]
|
|
private float horizontalSpread = 0.01f;
|
|
|
|
[SerializeField]
|
|
private float normalScaleFactor = 1f;
|
|
|
|
[SerializeField]
|
|
[Range(0.001f, 0.999f)]
|
|
private float AdhesionBorder = 0.01f;
|
|
|
|
[SerializeField]
|
|
private bool performanceOptimize = true;
|
|
|
|
[SerializeField]
|
|
[Range(0.01f, 10f)]
|
|
private float fluidProcessStopTime = 5f;
|
|
|
|
private bool enabledFluid;
|
|
|
|
private float lastPaintedTime;
|
|
|
|
private Material heightFluid;
|
|
|
|
private Material height2Normal;
|
|
|
|
private Material height2Color;
|
|
|
|
private Material singleColorFill;
|
|
|
|
private Material invertAlpha;
|
|
|
|
private InkCanvas canvas;
|
|
|
|
private Color lastPaintedColor;
|
|
|
|
private const string COLOR_SYNTHESIS_ADD = "COLOR_SYNTHESIS_ADD";
|
|
|
|
private const string COLOR_SYNTHESIS_OVERWRITE = "COLOR_SYNTHESIS_OVERWRITE";
|
|
|
|
private void Init(InkCanvas canvas)
|
|
{
|
|
foreach (InkCanvas.PaintSet paintData in canvas.PaintDatas)
|
|
{
|
|
RenderTexture paintHeightTexture = canvas.GetPaintHeightTexture(paintData.material.name);
|
|
if (paintHeightTexture != null)
|
|
{
|
|
SingleColorFill(paintHeightTexture, Vector4.zero);
|
|
}
|
|
canvas.OnPaintStart += delegate(InkCanvas own, Brush brush)
|
|
{
|
|
if (lastPaintedColor != brush.Color)
|
|
{
|
|
lastPaintedColor = brush.Color;
|
|
StopFluid();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private void SingleColorFill(RenderTexture texture, Color color)
|
|
{
|
|
RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
singleColorFill.SetVector("_Color", color);
|
|
Graphics.Blit(texture, temporary, singleColorFill);
|
|
Graphics.Blit(temporary, texture);
|
|
RenderTexture.ReleaseTemporary(temporary);
|
|
}
|
|
|
|
private void InvertAlpha(RenderTexture texture)
|
|
{
|
|
RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
Graphics.Blit(texture, temporary, invertAlpha);
|
|
Graphics.Blit(temporary, texture);
|
|
RenderTexture.ReleaseTemporary(temporary);
|
|
}
|
|
|
|
private void EnabledFluid(InkCanvas canvas, Brush brush)
|
|
{
|
|
enabledFluid = true;
|
|
lastPaintedTime = Time.time;
|
|
brush.ColorBlending = Brush.ColorBlendType.AlphaOnly;
|
|
brush.NormalBlending = Brush.NormalBlendType.UseBrush;
|
|
brush.HeightBlending = Brush.HeightBlendType.ColorRGB_HeightA;
|
|
}
|
|
|
|
private void StopFluid()
|
|
{
|
|
foreach (InkCanvas.PaintSet paintData in canvas.PaintDatas)
|
|
{
|
|
string materialName = paintData.material.name;
|
|
RenderTexture paintHeightTexture = canvas.GetPaintHeightTexture(materialName);
|
|
if (paintHeightTexture != null)
|
|
{
|
|
InvertAlpha(paintHeightTexture);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
heightFluid = new Material(Resources.Load<Material>("Es.InkPainter.Fluid.HeightDrip"));
|
|
height2Normal = new Material(Resources.Load<Material>("Es.InkPainter.Fluid.HeightToNormal"));
|
|
height2Color = new Material(Resources.Load<Material>("Es.InkPainter.Fluid.HeightToColor"));
|
|
singleColorFill = new Material(Resources.Load<Material>("Es.InkPainter.Fluid.SingleColorFill"));
|
|
invertAlpha = new Material(Resources.Load<Material>("Es.InkPainter.Fluid.InvertAlpha"));
|
|
canvas = GetComponent<InkCanvas>();
|
|
canvas.OnInitializedAfter += Init;
|
|
canvas.OnPaintStart += EnabledFluid;
|
|
}
|
|
|
|
private void OnWillRenderObject()
|
|
{
|
|
if (performanceOptimize && enabledFluid && Time.time - lastPaintedTime > fluidProcessStopTime)
|
|
{
|
|
StopFluid();
|
|
enabledFluid = false;
|
|
}
|
|
if (!enabledFluid)
|
|
{
|
|
return;
|
|
}
|
|
foreach (InkCanvas.PaintSet paintData in canvas.PaintDatas)
|
|
{
|
|
string materialName = paintData.material.name;
|
|
RenderTexture renderTexture = canvas.GetPaintHeightTexture(materialName);
|
|
if (renderTexture == null)
|
|
{
|
|
RenderTexture renderTexture2 = new RenderTexture(createTextureSize, createTextureSize, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
SingleColorFill(renderTexture2, Vector4.zero);
|
|
canvas.SetPaintHeightTexture(materialName, renderTexture2);
|
|
renderTexture = renderTexture2;
|
|
paintData.material.SetFloat("_Parallax", 0f);
|
|
}
|
|
RenderTexture temporary = RenderTexture.GetTemporary(renderTexture.width, renderTexture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
heightFluid.SetFloat("_ScaleFactor", flowingForce);
|
|
heightFluid.SetFloat("_Viscosity", easeOfDripping);
|
|
heightFluid.SetFloat("_HorizontalSpread", horizontalSpread);
|
|
heightFluid.SetFloat("_InfluenceOfNormal", influenceOfNormal);
|
|
heightFluid.SetVector("_FlowDirection", flowDirection.normalized);
|
|
heightFluid.SetVector("_FixedColor", lastPaintedColor);
|
|
string[] shaderKeywords = heightFluid.shaderKeywords;
|
|
foreach (string keyword in shaderKeywords)
|
|
{
|
|
heightFluid.DisableKeyword(keyword);
|
|
}
|
|
switch (colorSynthesis)
|
|
{
|
|
case ColorSynthesis.Add:
|
|
heightFluid.EnableKeyword("COLOR_SYNTHESIS_ADD");
|
|
break;
|
|
default:
|
|
heightFluid.EnableKeyword("COLOR_SYNTHESIS_OVERWRITE");
|
|
break;
|
|
}
|
|
if (canvas.GetNormalTexture(materialName) != null)
|
|
{
|
|
heightFluid.SetTexture("_NormalMap", canvas.GetNormalTexture(materialName));
|
|
}
|
|
Graphics.Blit(renderTexture, temporary, heightFluid);
|
|
Graphics.Blit(temporary, renderTexture);
|
|
RenderTexture.ReleaseTemporary(temporary);
|
|
if (useMainTextureFluid)
|
|
{
|
|
RenderTexture renderTexture3 = canvas.GetPaintMainTexture(materialName);
|
|
if (renderTexture3 == null)
|
|
{
|
|
RenderTexture renderTexture4 = new RenderTexture(createTextureSize, createTextureSize, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
if (canvas.GetMainTexture(materialName) != null)
|
|
{
|
|
Graphics.Blit(canvas.GetMainTexture(materialName), renderTexture4);
|
|
}
|
|
canvas.SetPaintMainTexture(materialName, renderTexture4);
|
|
renderTexture3 = renderTexture4;
|
|
}
|
|
RenderTexture temporary2 = RenderTexture.GetTemporary(renderTexture3.width, renderTexture3.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
height2Color.SetTexture("_ColorMap", renderTexture3);
|
|
height2Color.SetTexture("_BaseColor", canvas.GetMainTexture(materialName));
|
|
height2Color.SetFloat("_Alpha", alpha);
|
|
height2Color.SetFloat("_Border", AdhesionBorder);
|
|
Graphics.Blit(renderTexture, temporary2, height2Color);
|
|
Graphics.Blit(temporary2, renderTexture3);
|
|
RenderTexture.ReleaseTemporary(temporary2);
|
|
}
|
|
if (!useNormalMapFluid)
|
|
{
|
|
continue;
|
|
}
|
|
RenderTexture renderTexture5 = canvas.GetPaintNormalTexture(materialName);
|
|
if (renderTexture5 == null)
|
|
{
|
|
RenderTexture renderTexture6 = new RenderTexture(createTextureSize, createTextureSize, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
SingleColorFill(renderTexture6, Vector4.one * 0.5f);
|
|
paintData.material.EnableKeyword("_NORMALMAP");
|
|
if (canvas.GetNormalTexture(materialName) != null)
|
|
{
|
|
Graphics.Blit(canvas.GetNormalTexture(materialName), renderTexture6);
|
|
}
|
|
canvas.SetPaintNormalTexture(materialName, renderTexture6);
|
|
renderTexture5 = renderTexture6;
|
|
}
|
|
RenderTexture temporary3 = RenderTexture.GetTemporary(renderTexture5.width, renderTexture5.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
height2Normal.SetTexture("_BumpMap", renderTexture5);
|
|
height2Normal.SetFloat("_NormalScaleFactor", normalScaleFactor);
|
|
height2Normal.SetFloat("_Border", AdhesionBorder);
|
|
Graphics.Blit(renderTexture, temporary3, height2Normal);
|
|
Graphics.Blit(temporary3, renderTexture5);
|
|
RenderTexture.ReleaseTemporary(temporary3);
|
|
}
|
|
}
|
|
}
|
|
}
|