Unity uses normal distribution to draw noise map

Table of contents

​edit

foreword

normal distribution

noise

What is noise?

Introduction To Noise Functions

Actual operation

Convert the above formula into executable code:

Scenario

Effect demonstration


foreword

normal distribution

The normal distribution, also known as the Gaussian distribution, is a very common continuous probability distribution.

Here is a brief introduction:

noise

What is noise?

The noise we usually see is the thousands of tiny blobs in the frame that can reduce detail or make dark details in the frame appear "dirty". This is why, in most cases, noise is considered an "uninvited guest".

Noise, like many things, is a "double-edged sword", and reasonable use can produce some good results:

Such as showing the effect of an old film, creating a horror atmosphere, etc.

Of course, you can also use noise to complete some effects, such as: Unity Shader - Noise noise application, to achieve a surface effect similar to water - Jave.Lin's Blog - CSDN Blog - Shader Noise

Introduction To Noise Functions

Detailed reference: Perlin Noise (Translation)

Actual operation

So where should we start in Unity?

Convert the above formula into executable code:

/// <summary>
    /// 高斯分布概率模型
    /// </summary>
    /// <param name="_x">随机变量</param>
    /// <param name="_μ">位置参数</param>
    /// <param name="_σ">尺度参数</param>
    /// <returns></returns>
    private static float NormalDistribution(float _x, float _μ, float _σ)
    {
        float _inverseSqrt2PI = 1 / Mathf.Sqrt(2 * Mathf.PI);
        float _powOfE = -(Mathf.Pow((_x - _μ), 2) / (2 * _σ * _σ));
        float _result = (_inverseSqrt2PI / _σ) * Mathf.Exp(_powOfE);
        return _result;
    }

Scenario

Suppose we want to draw a noise map with a size of 1024*1024, gradually sparse from the center to the surrounding, and the color is getting lighter and lighter, the code is as follows:

/// <summary>
    /// 通过高斯分布公式绘制一张离散效果图
    /// </summary>
    /// <param name="_centerPoint">中心点坐标</param>
    /// <param name="_consi">图颜色的阿尔法值</param>
    /// <returns></returns>
    public Texture2D CreateTeture2D(Vector2 _centerPoint, float _consi)
    {
        Texture2D _newTex = new Texture2D(1024, 1024, TextureFormat.ARGB32, true);
        Color[] _colorBase = new Color[1024 * 1024];
        int _hwidth = (int)(1024 * _centerPoint.x);
        int _hheight = (int)(1024 * _centerPoint.y);

        float _per;
        int _index;
        for (int i = 0; i < 1024; i++)
        {
            for (int j = 0; j < 1024; j++)
            {
                _per = (Mathf.Sqrt((i - _hwidth) * (i - _hwidth) + (j - _hheight) * (j - _hheight))) / 512;
                float _tr = NormalDistribution(_per, 0, 1); //float _tr = NormalDistribution(0, 0, 1)=0.3989423f;也就是说中心点的概率为0.3989423f,即最大概率
                bool _drawing = Random.Range(0, 0.3989423f) < _tr ? true : false;
                if (_drawing)
                {
                    _index = i * 1024 + j;
                    _colorBase[_index] = new Color(1, 0, 0, _tr * _consi);
                }
                else
                {
                    _colorBase[i * 1024 + j] = new Color(0, 0, 0, 0);
                }
            }
        }
        _newTex.SetPixels(_colorBase);
        _newTex.Apply();
        _colorBase = null;
        System.GC.Collect();
        return _newTex;
    }

Effect demonstration

When the coordinates of the center point are (0.5, 0.5) and the color alpha value is 1, the effect is as follows:

When the coordinates of the center point are (0.2, 0.3), the effect is as follows:

We can also add this code:

 _colorBase[_index] = new Color(1, 0, 0, _tr * _consi );

change to:

_colorBase[_index] = new Color(1, 0, 0, _tr * _consi * (1 - _per));

The graph drawn in this way, when the color gradients from the center point to the edge, will be completely transparent, and the effect is as follows:

Guess you like

Origin blog.csdn.net/flyTie/article/details/126320780