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

286 lines
5.9 KiB
C#

using System;
using UltimateWater.Internal;
using UltimateWater.Utils;
using UnityEngine;
namespace UltimateWater
{
public class WaterDropsIME : MonoBehaviour, IWaterImageEffect
{
public enum Type
{
NormalMap = 0,
Blur = 1
}
public interface IWaterDropsModule
{
void Initialize(WaterDropsIME ime);
void Validate();
void Advance();
void UpdateMask(RenderTexture mask);
void RenderImage(RenderTexture source, RenderTexture destination);
}
[Serializable]
public struct BlurModule : IWaterDropsModule
{
public float FadeSpeed;
private WaterDropsIME _Reference;
private WaterCamera _Camera;
private float _Intensity;
[SerializeField]
[HideInInspector]
private Blur _Blur;
public void Initialize(WaterDropsIME effect)
{
_Reference = effect;
_Camera = effect.GetComponent<WaterCamera>();
}
public void Validate()
{
_Blur.Validate("UltimateWater/Utilities/Blur (VisionBlur)");
}
public void Advance()
{
if (Application.isPlaying)
{
_Intensity += Mathf.Max(0f, _Camera.WaterLevel - _Reference.transform.position.y);
_Intensity *= 1f - Time.deltaTime * FadeSpeed;
_Intensity = Mathf.Clamp01(_Intensity);
}
}
public void RenderImage(RenderTexture source, RenderTexture destination)
{
float size = _Blur.Size;
_Blur.Size *= _Intensity;
_Blur.Apply(source);
_Blur.Size = size;
Graphics.Blit(source, destination);
}
public void UpdateMask(RenderTexture mask)
{
}
}
[Serializable]
public struct NormalModule : IWaterDropsModule
{
public Texture NormalMap;
public float Intensity;
public bool Preview;
private Material _Material;
public void Initialize(WaterDropsIME effect)
{
_Material = ShaderUtility.Instance.CreateMaterial(ShaderList.WaterdropsNormal);
_Material.SetTexture("_NormalMap", NormalMap);
}
public void UpdateMask(RenderTexture mask)
{
if (Preview)
{
Graphics.Blit(DefaultTextures.Get(Color.white), mask);
}
_Material.SetTexture("_Mask", mask);
}
public void RenderImage(RenderTexture source, RenderTexture destination)
{
if (!Application.isPlaying && !Preview)
{
Graphics.Blit(source, destination);
return;
}
_Material.SetFloat("_Intensity", Intensity);
Graphics.Blit(source, destination, _Material);
}
public void Validate()
{
ShaderUtility.Instance.Use(ShaderList.WaterdropsNormal);
if (_Material == null)
{
_Material = ShaderUtility.Instance.CreateMaterial(ShaderList.WaterdropsNormal);
}
_Material.SetTexture("_NormalMap", NormalMap);
}
public void Advance()
{
}
}
private struct MaskingModule
{
internal Material _Material;
internal RenderTexture _MaskA;
internal RenderTexture _MaskB;
internal void Blit()
{
Graphics.Blit(_MaskA, _MaskB, _Material, 0);
}
internal void Swap()
{
RenderTexture maskA = _MaskA;
_MaskA = _MaskB;
_MaskB = maskA;
}
internal void Release()
{
TextureUtility.Release(ref _MaskA);
TextureUtility.Release(ref _MaskB);
}
}
[Tooltip("How slow the effects disappear")]
[Range(0.95f, 1f)]
public float Fade = 1f;
public BlurModule Blur;
public NormalModule Normal;
[SerializeField]
private Type _Type;
private MaskingModule _Masking;
private IWaterDropsModule _SelectedModule;
[SerializeField]
[InspectorWarning("Validation", InspectorWarningAttribute.InfoType.Warning)]
private string _Validation;
public RenderTexture Mask
{
get
{
return _Masking._MaskB;
}
}
public void OnWaterCameraEnabled()
{
}
public void OnWaterCameraPreCull()
{
}
private void Awake()
{
_Masking._Material = ShaderUtility.Instance.CreateMaterial(ShaderList.WaterdropsMask);
AssignModule();
}
private void OnValidate()
{
ShaderUtility.Instance.Use(ShaderList.WaterdropsMask);
AssignModule();
_SelectedModule.Validate();
if (Application.isPlaying && _Masking._Material != null)
{
_Masking._Material.SetFloat("_Fadeout", Fade * 0.98f);
}
}
private void OnPreCull()
{
_SelectedModule.Advance();
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (Application.isPlaying)
{
CheckResources();
_Masking.Blit();
_Masking.Swap();
_SelectedModule.UpdateMask(_Masking._MaskB);
}
_SelectedModule.RenderImage(source, destination);
}
private void Reset()
{
Normal.Intensity = 1f;
Blur.FadeSpeed = 1f;
}
private void OnDestroy()
{
_Masking.Release();
}
private void AssignModule()
{
switch (_Type)
{
case Type.Blur:
_SelectedModule = Blur;
break;
case Type.NormalMap:
_SelectedModule = Normal;
break;
}
_SelectedModule.Initialize(this);
}
private void CheckResources()
{
if (_Masking._MaskA == null || _Masking._MaskA.width != Screen.width >> 1 || _Masking._MaskA.height != Screen.height >> 1)
{
_Masking._MaskA = CreateMaskRt();
_Masking._MaskB = CreateMaskRt();
_Masking._MaskA.name = "[UWS] WaterDropsIME - Mask A";
_Masking._MaskB.name = "[UWS] WaterDropsIME - Mask B";
}
}
private static RenderTexture CreateMaskRt()
{
RenderTexture renderTexture = new RenderTexture(Screen.width >> 1, Screen.height >> 1, 0, RenderTextureFormat.RHalf, RenderTextureReadWrite.Linear);
renderTexture.hideFlags = HideFlags.DontSave;
renderTexture.filterMode = FilterMode.Bilinear;
renderTexture.name = "[UWS] WaterDropsIME - CreateMaskRt";
RenderTexture renderTexture2 = renderTexture;
Graphics.SetRenderTarget(renderTexture2);
GL.Clear(false, true, Color.black);
return renderTexture2;
}
private string Validation()
{
string text = string.Empty;
if (_Type == Type.NormalMap && Normal.NormalMap == null)
{
text += "warning: select normal map texture";
}
return text;
}
}
}