US4L8-2——柏林噪声纹理生成工具实现

本章代码关键字

1
2
Mathf.PerlinNoise()            // 传入柏林噪声空间中的xy值,返回噪声值
texture2D.EncodeToPNG() // 将Texture2D对象保存为png格式的byte[]数据,之后方便保存

柏林噪声纹理生成工具

这里要实现的柏林噪声纹理生成工具,就是利用 Unity 提供给我们的 Mathf.PerlinNoise()​ 方法
将噪声数据存储在图片中的工具,我们利用程序代码去生成柏林噪声纹理

制作编辑器拓展UI界面

前置知识点:UED——Unity编辑器拓展

先将必要的 柏林噪声纹理参数 和 生成按钮 显示在窗口上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System.IO;
using UnityEditor;
using UnityEngine;

public class PerlinNoiseTextureTool : EditorWindow
{
private int textureWidth = 512; // 生成纹理的宽
private int textureHeight = 512; // 生成纹理的高
private int scale = 20; // 纹理的缩放
private string textureName = "PerlinNoiseTexture"; // 生成的纹理名
private string savePath = Application.dataPath; // 保存路径

[MenuItem("Tools/柏林噪声生成工具/打开窗口")]
public static void ShowWindow()
{
EditorWindow.GetWindow<PerlinNoiseTextureTool>("柏林噪声生成工具").Show();
}

private void OnGUI()
{
GUILayout.Label("柏林噪声纹理设置");
textureWidth = EditorGUILayout.IntField("纹理宽", textureWidth);
textureHeight = EditorGUILayout.IntField("纹理高", textureHeight);
scale = EditorGUILayout.IntField("缩放", scale);
textureName = EditorGUILayout.TextField("生成纹理名", textureName);
savePath = EditorGUILayout.TextField("保存路径", savePath);
if (GUILayout.Button("选择保存路径"))
{
savePath = EditorUtility.SaveFolderPanel("选择噪声纹理保存路径", savePath, string.Empty);
if (string.IsNullOrEmpty(savePath))
{
savePath = Application.dataPath;
}
}

if (GUILayout.Button("生成柏林噪声纹理"))
{
// TODO.. 生成柏林噪声纹理的逻辑
}
}
}

显示效果:

image

Unity提供的生成柏林噪声的方法

1
float Mathf.PerlinNoise(float x, float y)

该函数是 Unity 提供的一个用于生成 Perlin Noise 的函数,主要用于生成平滑、连续的伪随机值。
它广泛应用于纹理生成、地形生成、动画和特效等需要平滑过渡的场景

传入的两个参数是二维坐标点(需要注意传入的相邻值间隔最好不要太大,否则可能输出纯灰色的图),通常用于表示柏林噪声空间中的位置,
返回值为一个浮点数,范围为 0~1 之间(返回值可能会稍微低于 0.0 或超过 1.0。)
返回的噪声值具有连续性,即相邻输入值对应的输出值是平滑过渡的

生成柏林噪声纹理图片

首先实例化一个新的 Texture2D​ 并根据设置的参数设置尺寸,然后遍历其每一个像素,
根据像素所在位置生成柏林噪声值,其中传入的参数可以由 scale​ 属性修改
将生成的柏林噪声值作为像素的颜色 RGB 值存储到像素内,然后使用 texture2D.EncodeToPNG()​ 将 Texture2D​ 转换为 png​ 格式的 byte[]​ 数据,
最后将 byte[]​ 数据使用 File.WriteAllBytes​ 方法来存储为 .png​ 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 生成柏林噪声纹理的逻辑
Texture2D texture = new Texture2D(textureWidth, textureHeight);
// 遍历纹理每一个像素,为其设置颜色,颜色的rgb值就是噪声值
for (int x = 0; x < textureWidth; x++)
{
for (int y = 0; y < textureHeight; y++)
{
float noiseValue = Mathf.PerlinNoise((float)x / textureWidth * scale, (float)y / textureWidth * scale);
texture.SetPixel(x, y, new Color(noiseValue, noiseValue, noiseValue));
}
}
texture.Apply();
// 使用texture2D.EncodeToPNG方法可以将Texture2D保存为byte[]形式的png格式图片,之后即可保存该图片
File.WriteAllBytes(Path.Join(savePath, textureName + ".png"), texture.EncodeToPNG());
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("提示", "噪声纹理生成完毕", "确定");

完整的生成柏林噪声的 C# 脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System.IO;
using UnityEditor;
using UnityEngine;

public class PerlinNoiseTextureTool : EditorWindow
{
private int textureWidth = 512; // 生成纹理的宽
private int textureHeight = 512; // 生成纹理的高
private int scale = 20; // 纹理的缩放
private string textureName = "PerlinNoiseTexture"; // 生成的纹理名
private string savePath = Application.dataPath; // 保存路径

[MenuItem("Tools/柏林噪声生成工具/打开窗口")]
public static void ShowWindow()
{
EditorWindow.GetWindow<PerlinNoiseTextureTool>("柏林噪声生成工具").Show();
}

private void OnGUI()
{
GUILayout.Label("柏林噪声纹理设置");
textureWidth = EditorGUILayout.IntField("纹理宽", textureWidth);
textureHeight = EditorGUILayout.IntField("纹理高", textureHeight);
scale = EditorGUILayout.IntField("缩放", scale);
textureName = EditorGUILayout.TextField("生成纹理名", textureName);
savePath = EditorGUILayout.TextField("保存路径", savePath);
if (GUILayout.Button("选择保存路径"))
{
string newPath = EditorUtility.SaveFolderPanel("选择噪声纹理保存路径", savePath, string.Empty);
if (!string.IsNullOrEmpty(newPath))
{
savePath = newPath;
}
}

if (GUILayout.Button("生成柏林噪声纹理"))
{
// 生成柏林噪声纹理的逻辑
Texture2D texture = new Texture2D(textureWidth, textureHeight);
// 遍历纹理每一个像素,为其设置颜色,颜色的rgb值就是噪声值
for (int x = 0; x < textureWidth; x++)
{
for (int y = 0; y < textureHeight; y++)
{
float noiseValue = Mathf.PerlinNoise((float)x / textureWidth * scale, (float)y / textureWidth * scale);
texture.SetPixel(x, y, new Color(noiseValue, noiseValue, noiseValue));
}
}
texture.Apply();
// 使用texture2D.EncodeToPNG方法可以将Texture2D保存为byte[]形式的png格式图片,之后即可保存该图片
File.WriteAllBytes(Path.Join(savePath, textureName + ".png"), texture.EncodeToPNG());
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("提示", "噪声纹理生成完毕", "确定");
}
}
}

生成的柏林噪声图如下(宽高为512,缩放为20):

PerlinNoinseTexture