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