Unity实现噪声图(Perlin Noise)的制作

2019-10-09  本文已影响0人  上善若水_2019

游戏制作中,有很多情况下我们需要用到噪声图,而噪声图去哪儿找呢?第一个我会想到的是找美术要,然而。。。美术根本不知道这是个什么玩意儿(或许美术知道但也不知道怎么做),又如何叫他们做呢?于是我就利用了万能的谷歌,找出噪声图这东西背后居然还有那么复杂的理论,冯乐乐前辈的这篇博客可以是个很好的入门。但是我们自己真的需要看着论文一步步的自己实现么?要是在学生时代,说不定一拍脑袋就干了,不过现在工作了人好像变了,别人实现好的轮子为什么非要自己再造一变呢?于是我找到了Unity自带的一个API叫Mathf.PerlinNoise,有了它我自己也能很方便的制作出噪声图了。

比如这样的
又比如这样的
或者这样

代码如下

public class NoiseGenerator : EditorWindow
{
    int x;
    int y;
    string texName;
    int scale = 1;
    int step = 1;

    [MenuItem("Tools/生成噪声图")]
    static void Init(){
        EditorWindow.GetWindow(typeof(NoiseGenerator)).Show();
    }

    void GenerateNoiseImage(int x, int y){
       int size = Mathf.Min(x,y);
        Texture2D tex = new Texture2D(x,y,TextureFormat.RGB24,false);
        Color[] pixel = new Color[x*y];
        for (int i=0;i<x;i=i+step){
            pixel[i] = new Color(1,1,1);
        }
        for (int i=0;i<x;i=i+step){
            for (int j=0;j<x;j=j+step){
                float sample = Mathf.PerlinNoise((float)i/x * scale, (float)j/y * scale);
                sample = Mathf.Clamp(sample,0f,1f);
                pixel[i*size + j] = new Color(sample,sample,sample);
            } 
        }
        tex.SetPixels(pixel);
        tex.Apply();

        File.WriteAllBytes(System.Environment.CurrentDirectory + "\\Assets\\" + texName + ".png", tex.EncodeToPNG());
        EditorUtility.DisplayDialog("成功","噪声图\"" + texName + "\"" + "已在Assets目录下生成!","确定","取消");
    }

    private void OnGUI() {
        EditorGUILayout.BeginHorizontal();
        texName = EditorGUILayout.TextField("图片名: ", texName);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        y = EditorGUILayout.IntField("图片长: ", y);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        x = EditorGUILayout.IntField("图片宽: ", x);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        scale = EditorGUILayout.IntField("Scale: ", scale);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        step = EditorGUILayout.IntField("Step: ", step);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("生成")){
            if (x < 1 || y < 1){
                Debug.LogError("图片长或宽必须大于1");
                return;
            }
            if (texName == null || texName.Length < 1){
                Debug.LogError("请为图片命名");
                return;
            }
            if (step >= x || step >= y){
                Debug.LogError("密度不能超过图片的长或宽");
                return;
            }else if (step < 1){
                step = 1;
            }
            GenerateNoiseImage(x,y);
        }
        EditorGUILayout.EndHorizontal();
    }
}

Mathf.PerlinNoise一定要传float进去,integer进去的话永远会得到0.4652731这个数。还有就是这个方法最后得出的结果有可能略微超出1,作为颜色值的话需要用clamp方法限制在0-1之间才行。

参考
Mathf.PerlinNoise

上一篇 下一篇

猜你喜欢

热点阅读