噪声是一种程序生成的随机或伪随机数据,在图形学中常用来创建各种自然现象和复杂纹理效果。
它的本质是一种由数学算法公式生成的有规则性或可控的随机数据。
通过噪声算法生成的随机数据具有以下特点:
- 随机性:噪声数据本质上是随机的,这意味着它具有不规则性,无法通过简单的模式预测
- 平滑性:数据不会突然跳跃或变化,而是呈现出逐渐过渡的效果,适合模拟自然现象
- 周期性:随着坐标的变化,噪声值会重复出现,形成一个封闭的循环。也可以通过调整噪声的范围或修改算法来避免
- 可调性:大多数噪声算法的输出是可以调整的,这种可调性允许你根据需求灵活地控制噪声的表现,适应不同的视觉效果或逻辑处理需求
- 多维性:能够处理多维数据,这意味着它们可以生成二维、三维甚至更高维度的噪声数据
就因为噪声数据具有以上这些特点,我们可以利用噪声来实现一些特殊效果,比如:,地形生成,云层效果,烟雾效果、水面模拟、消融效果、
1、常用的噪声算法
- Perlin Noise(柏林噪声):适合生成自然现象的纹理(比如云、火焰、地形)
- Simplex Noise(简单噪声):Perlin Noise的优化版,更适合实时计算,适用于体积云、流体动画等
- Random Function(随机噪声/白噪音):计算简单,适合生成粒子效果或星空背景
- Fractal Noise(分形噪声):将多层PerlinNoise或SimplexNoise叠加,生成复杂效果,适用于高细节地形、云层、火焰等效果
- Worley Noise(沃利噪音):生成类似"细胞"的纹理,适用于模拟裂纹或有机表面
2、如何在 Unity 中使用噪声
如果想要在Unity中使用这些噪声算法来处理逻辑,你可以采用以下方式:
- 使用一些第三方的噪声库,利用别人写好的内容直接来计算
- 根据噪声算法原理自己实现计算逻辑
- 使用Unity自带的噪声算法API,比如Mathf.PerlinNoise() (但是Unity提供的非常少)
- 使用Shader逻辑流程图插件(Shader Graph或ASE)中提供的噪声节点
- 使用预生成的噪声纹理,通过材质或Shader对纹理进行采样
从性能角度考虑,由于使用噪声算法实时计算一定会增加开销,因此噪声纹理是我们经常会使用的一种方式,它可以帮助我们减少实时计算,减少性能消耗
3、噪声纹理
噪声纹理(Noise Texture)是一种常用于计算机图形学中的纹理类型,常用于模拟自然现象如云层、地形、火焰、岩石表面等等。
它本质上就是通过噪声算法生成的图像。它生成的核心原理是利用噪声函数计算每个纹理坐标的值,再将这些值映射为图像的像素值。
将噪声数据存储到图像中,直接采样拿来使用,而不是实时计算。相当于是在用内存换性能!
提前将噪声数据计算好存在图片中,使用时从内存中的图片中取出数据,直接使用!
噪声纹理生成工具
cs
using System.Collections;
using System.Collections.Generic;
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";
[MenuItem("Custom/柏林噪声纹理生成工具")]
public static void ShowWindow() {
GetWindow<PerlinNoiseTextureTool>("柏林噪声纹理生成工具");
}
private void OnGUI() {
GUILayout.Label("柏林噪声纹理设置");
textureWidth = EditorGUILayout.IntField("纹理宽", textureWidth);
textureHeight = EditorGUILayout.IntField("纹理高", textureHeight);
scale = EditorGUILayout.IntField("缩放", scale);
textureName = EditorGUILayout.TextField("纹理名", textureName);
if (GUILayout.Button("生成柏林噪声纹理")) {
//生成柏林纹理的逻辑
//根据纹理的图片坐标 去得到对应的噪声值 然后将噪声值 存储到颜色信息中 RGB是相同
Texture2D texture = new Texture2D(textureWidth, textureHeight);
for (int y = 0; y < textureHeight; y++) {
for (int x = 0; x < textureWidth; x++) {
float noiseValue = Mathf.PerlinNoise((float)x / textureWidth * scale, (float)y / textureHeight * scale);
texture.SetPixel(x, y, new Color(noiseValue, noiseValue, noiseValue));
}
}
//texture.Apply();
File.WriteAllBytes("Assets/Art/" + textureName + ".png", texture.EncodeToPNG());
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("提示", "噪声纹理生成结束", "确定");
}
}
}