215 lines
4.6 KiB
C#
215 lines
4.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using BitStrap;
|
|
using UnityEngine;
|
|
|
|
[AddComponentMenu("Image Effects/Rain/RainEffect")]
|
|
[ExecuteInEditMode]
|
|
public class RainEffect : MonoBehaviour
|
|
{
|
|
public enum RainType
|
|
{
|
|
Single = 0,
|
|
Double = 1,
|
|
Triple = 2,
|
|
Quadruple = 3
|
|
}
|
|
|
|
[Serializable]
|
|
private class NormData
|
|
{
|
|
public float timeLeft;
|
|
|
|
public float intensity;
|
|
|
|
public float acceleration = 0.1f;
|
|
|
|
public float valx;
|
|
|
|
public float valy;
|
|
|
|
public float t;
|
|
|
|
public float c;
|
|
|
|
public float fadeSpeed;
|
|
}
|
|
|
|
public int typeCount = 10;
|
|
|
|
public Shader shader;
|
|
|
|
public RainType rainType = RainType.Triple;
|
|
|
|
public Texture2D NormalMap;
|
|
|
|
public Color rainColor = Color.gray;
|
|
|
|
public bool FitToScreen;
|
|
|
|
[Range(0.05f, 5f)]
|
|
public float Intensity = 0.7f;
|
|
|
|
[Range(0.05f, 1f)]
|
|
public float Distortion = 0.6f;
|
|
|
|
[Range(0f, 1f)]
|
|
public float reliefEffect = 0.2f;
|
|
|
|
[Range(0.1f, 50f)]
|
|
public float Size = 0.75f;
|
|
|
|
[Range(0f, 10f)]
|
|
public float InitialVelocity;
|
|
|
|
[Range(0f, 10f)]
|
|
public float AccelerationMin = 0.06f;
|
|
|
|
[Range(0f, 10f)]
|
|
public float AccelerationMax = 0.2f;
|
|
|
|
[Range(0.05f, 60f)]
|
|
public float IntervalMin = 0.6f;
|
|
|
|
[Range(0.05f, 60f)]
|
|
public float IntervalMax = 1.4f;
|
|
|
|
[Range(0.0001f, 3f)]
|
|
public float FadeSpeedMin = 0.09f;
|
|
|
|
[Range(0.0001f, 3f)]
|
|
public float FadeSpeedMax = 0.09f;
|
|
|
|
private Material mat;
|
|
|
|
private Texture2D Overlay;
|
|
|
|
private NormData[] normals;
|
|
|
|
private int index
|
|
{
|
|
get
|
|
{
|
|
return (int)rainType;
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (!SystemInfo.supportsImageEffects)
|
|
{
|
|
base.enabled = false;
|
|
return;
|
|
}
|
|
normals = new NormData[typeCount];
|
|
if (!shader)
|
|
{
|
|
shader = Resources.Load("RainEffectShader", typeof(Shader)) as Shader;
|
|
}
|
|
if (!NormalMap)
|
|
{
|
|
NormalMap = Resources.Load("NormRain", typeof(Texture2D)) as Texture2D;
|
|
}
|
|
mat = new Material(shader);
|
|
mat.SetTexture("_NormalTex", NormalMap);
|
|
Overlay = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
|
Overlay.SetPixel(0, 0, rainColor);
|
|
Overlay.Apply();
|
|
mat.SetTexture("_OverlayTex", Overlay);
|
|
for (int i = 0; i < typeCount; i++)
|
|
{
|
|
normals[i] = new NormData();
|
|
normals[i].timeLeft = UnityEngine.Random.Range(0f, IntervalMax);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
Init();
|
|
for (int i = 0; i < typeCount; i++)
|
|
{
|
|
UpdateInstance(i);
|
|
}
|
|
}
|
|
|
|
private void UpdateInstance(int i)
|
|
{
|
|
normals[i].t += Time.deltaTime;
|
|
normals[i].timeLeft -= Time.deltaTime;
|
|
normals[i].valy = normals[i].c + 0.5f * normals[i].t * normals[i].t * normals[i].acceleration * 0.1f + InitialVelocity * normals[i].t;
|
|
normals[i].intensity = Mathf.Max(0f, normals[i].intensity - 0.5f * normals[i].t * normals[i].fadeSpeed * 0.1f);
|
|
}
|
|
|
|
private void Init()
|
|
{
|
|
if (IntervalMin > IntervalMax)
|
|
{
|
|
swap(ref IntervalMin, ref IntervalMax);
|
|
}
|
|
if (AccelerationMin > AccelerationMax)
|
|
{
|
|
swap(ref AccelerationMin, ref AccelerationMax);
|
|
}
|
|
if (FadeSpeedMin > FadeSpeedMax)
|
|
{
|
|
swap(ref FadeSpeedMin, ref FadeSpeedMax);
|
|
}
|
|
}
|
|
|
|
private void swap(ref float a, ref float b)
|
|
{
|
|
float num = a;
|
|
a = b;
|
|
b = num;
|
|
}
|
|
|
|
private string s(int num)
|
|
{
|
|
return num.ToString();
|
|
}
|
|
|
|
private void OnRenderImage(RenderTexture source, RenderTexture destination)
|
|
{
|
|
Overlay.SetPixel(0, 0, rainColor);
|
|
Overlay.Apply();
|
|
mat.SetTexture("_NormalTex", NormalMap);
|
|
mat.SetTexture("_OverlayTex", Overlay);
|
|
mat.SetFloat("_Distortion", 0f - Distortion);
|
|
mat.SetFloat("_Relief", reliefEffect);
|
|
for (int i = 0; i < typeCount; i++)
|
|
{
|
|
mat.SetFloat("_Intensity" + s(i + 1), normals[i].intensity);
|
|
mat.SetVector("_NormalOffsetScale" + s(i + 1), new Vector4(normals[i].valx, normals[i].valy, (!FitToScreen) ? ((float)Screen.width / (float)NormalMap.width * (1f - Size)) : (2.5f * (1f - Size)), (!FitToScreen) ? ((float)Screen.height / (float)NormalMap.height * (1f - Size)) : (2.5f * (1f - Size))));
|
|
}
|
|
Graphics.Blit(source, destination, mat, index);
|
|
}
|
|
|
|
[Button]
|
|
public void ShowDrops()
|
|
{
|
|
StartCoroutine(ShowDropsAnim());
|
|
}
|
|
|
|
public IEnumerator ShowDropsAnim()
|
|
{
|
|
Intensity = 2f;
|
|
for (int i = 0; i < typeCount; i++)
|
|
{
|
|
normals[i].t = 0f;
|
|
normals[i].intensity = Intensity;
|
|
normals[i].timeLeft = UnityEngine.Random.Range(IntervalMin, IntervalMax);
|
|
normals[i].acceleration = UnityEngine.Random.Range(AccelerationMin, AccelerationMax);
|
|
normals[i].valx = UnityEngine.Random.value;
|
|
normals[i].valy = (normals[i].c = UnityEngine.Random.value);
|
|
normals[i].fadeSpeed = UnityEngine.Random.Range(FadeSpeedMin, FadeSpeedMax);
|
|
}
|
|
yield return new WaitForSeconds(2f);
|
|
LeanTween.value(2f, 0f, 3f).setOnUpdate(delegate(float val)
|
|
{
|
|
Intensity = val;
|
|
});
|
|
yield return new WaitForSeconds(3f);
|
|
yield return null;
|
|
}
|
|
}
|