From c47b92e92cf33ae8bf2f38929e137294397e4735 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 7 Apr 2021 21:33:14 +0800 Subject: +init --- Assets/Scripts/Common/ParameterTexture.cs | 190 ++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 Assets/Scripts/Common/ParameterTexture.cs (limited to 'Assets/Scripts/Common/ParameterTexture.cs') diff --git a/Assets/Scripts/Common/ParameterTexture.cs b/Assets/Scripts/Common/ParameterTexture.cs new file mode 100644 index 0000000..3249828 --- /dev/null +++ b/Assets/Scripts/Common/ParameterTexture.cs @@ -0,0 +1,190 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; +using System; + +namespace Coffee.UIEffects +{ + public interface IParameterTexture + { + int parameterIndex { get; set; } + + ParameterTexture paramTex { get; } + } + + /// + /// Parameter texture. + /// + [System.Serializable] + public class ParameterTexture + { + //################################ + // Public Members. + //################################ + + /// + /// Initializes a new instance of the class. + /// + /// Channels. + /// Instance limit. + /// Property name. + public ParameterTexture(int channels, int instanceLimit, string propertyName) + { + _propertyName = propertyName; + _channels = ((channels - 1) / 4 + 1) * 4; + _instanceLimit = ((instanceLimit - 1) / 2 + 1) * 2; + _data = new byte[_channels * _instanceLimit]; + + _stack = new Stack(_instanceLimit); + for (int i = 1; i < _instanceLimit + 1; i++) + { + _stack.Push(i); + } + } + + + /// + /// Register the specified target. + /// + /// Target. + public void Register(IParameterTexture target) + { + Initialize(); + if (target.parameterIndex <= 0 && 0 < _stack.Count) + { + target.parameterIndex = _stack.Pop(); +// Debug.LogFormat("@@@ Register {0} : {1}", target, target.parameterIndex); + } + } + + /// + /// Unregister the specified target. + /// + /// Target. + public void Unregister(IParameterTexture target) + { + if (0 < target.parameterIndex) + { +// Debug.LogFormat("@@@ Unregister {0} : {1}", target, target.parameterIndex); + _stack.Push(target.parameterIndex); + target.parameterIndex = 0; + } + } + + /// + /// Sets the data. + /// + /// Target. + /// Channel identifier. + /// Value. + public void SetData(IParameterTexture target, int channelId, byte value) + { + int index = (target.parameterIndex - 1) * _channels + channelId; + if (0 < target.parameterIndex && _data[index] != value) + { + _data[index] = value; + _needUpload = true; + } + } + + /// + /// Sets the data. + /// + /// Target. + /// Channel identifier. + /// Value. + public void SetData(IParameterTexture target, int channelId, float value) + { + SetData(target, channelId, (byte) (Mathf.Clamp01(value) * 255)); + } + + /// + /// Registers the material. + /// + /// Mat. + public void RegisterMaterial(Material mat) + { + if (_propertyId == 0) + { + _propertyId = Shader.PropertyToID(_propertyName); + } + + if (mat) + { + mat.SetTexture(_propertyId, _texture); + } + } + + /// + /// Gets the index of the normalized. + /// + /// The normalized index. + /// Target. + public float GetNormalizedIndex(IParameterTexture target) + { + return ((float) target.parameterIndex - 0.5f) / _instanceLimit; + } + + + //################################ + // Private Members. + //################################ + + Texture2D _texture; + bool _needUpload; + int _propertyId; + readonly string _propertyName; + readonly int _channels; + readonly int _instanceLimit; + readonly byte[] _data; + readonly Stack _stack; + static List updates; + + /// + /// Initialize this instance. + /// + void Initialize() + { +#if UNITY_EDITOR + if (!UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + { + return; + } +#endif + if (updates == null) + { + updates = new List(); + Canvas.willRenderCanvases += () => + { + var count = updates.Count; + for (int i = 0; i < count; i++) + { + updates[i].Invoke(); + } + }; + } + + if (!_texture) + { + bool isLinear = QualitySettings.activeColorSpace == ColorSpace.Linear; + _texture = new Texture2D(_channels / 4, _instanceLimit, TextureFormat.RGBA32, false, isLinear); + _texture.filterMode = FilterMode.Point; + _texture.wrapMode = TextureWrapMode.Clamp; + + updates.Add(UpdateParameterTexture); + _needUpload = true; + } + } + + void UpdateParameterTexture() + { + if (_needUpload && _texture) + { + _needUpload = false; + _texture.LoadRawTextureData(_data); + _texture.Apply(false, false); + } + } + } +} -- cgit v1.1-26-g67d0