最近開發項目中,需要自己繪制一張離散的噪點圖。研究了好久,終於實現了。
其中我們使用了正態分布。正態分布(英語:normal distribution)又名高斯分布(英語:Gaussian distribution),是一個非常常見的連續概率分布。
這里就不過多介紹了,對正態分布不了解的,可以自己百度一下https://baike.baidu.com/item/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83/829892?fr=aladdin。
正態分布公式如下:
首先,我們要做的就是,把上面的公式轉換成可執行代碼,如下:
1 /// <summary> 2 /// 高斯分布概率模型 3 /// </summary> 4 /// <param name="_x">隨機變量</param> 5 /// <param name="_μ">位置參數</param> 6 /// <param name="_σ">尺度參數</param> 7 /// <returns></returns> 8 private static float NormalDistribution(float _x, float _μ, float _σ) 9 { 10 float _inverseSqrt2PI = 1 / Mathf.Sqrt(2 * Mathf.PI); 11 float _powOfE = -(Mathf.Pow((_x - _μ), 2) / (2 * _σ * _σ)); 12 float _result = (_inverseSqrt2PI / _σ) * Mathf.Exp(_powOfE); 13 return _result; 14 }
假設我們要繪制一張大小為1024*1024,從中心向四周逐漸稀疏,並且顏色越來越淡的噪點圖,代碼如下:
1 /// <summary> 2 /// 通過高斯分布公式繪制一張離散效果圖 3 /// </summary> 4 /// <param name="_centerPoint">中心點坐標</param> 5 /// <param name="_consi">圖顏色的阿爾法值</param> 6 /// <returns></returns> 7 public Texture2D CreateTeture2D(Vector2 _centerPoint, float _consi) 8 { 9 Texture2D _newTex = new Texture2D(1024, 1024, TextureFormat.ARGB32, true); 10 Color[] _colorBase = new Color[1024 * 1024]; 11 int _hwidth = (int)(1024 * _centerPoint.x); 12 int _hheight = (int)(1024 * _centerPoint.y); 13 14 float _per; 15 int _index; 16 for (int i = 0; i < 1024; i++) 17 { 18 for (int j = 0; j < 1024; j++) 19 { 20 _per = (Mathf.Sqrt((i - _hwidth) * (i - _hwidth) + (j - _hheight) * (j - _hheight))) / 512; 21 float _tr = NormalDistribution(_per, 0, 1); //float _tr = NormalDistribution(0, 0, 1)=0.3989423f;也就是說中心點的概率為0.3989423f,即最大概率 22 bool _drawing = Random.Range(0, 0.3989423f) < _tr ? true : false; 23 if (_drawing) 24 { 25 _index = i * 1024 + j; 26 _colorBase[_index] = new Color(1, 0, 0, _tr * _consi); 27 } 28 else 29 { 30 _colorBase[i * 1024 + j] = new Color(0, 0, 0, 0); 31 } 32 } 33 } 34 _newTex.SetPixels(_colorBase); 35 _newTex.Apply(); 36 _colorBase = null; 37 System.GC.Collect(); 38 return _newTex; 39 }
當中心點坐標為(0.5,,05),顏色阿爾法值為1時,效果如下:
當中心點坐標為(0.2,0.3)時,效果如下:
我們可以將 _colorBase[_index] = new Color(1, 0, 0, _tr * _consi );這句代碼更改為:_colorBase[_index] = new Color(1, 0, 0, _tr * _consi * (1 - _per));這樣繪制的圖,顏色從中心點漸變到邊緣時,會完全透明,效果如下: