Files
2026-02-21 16:45:37 +08:00

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;
}
}