噪声算法 & 纹理

噪声是一种程序生成的随机或伪随机数据,在图形学中常用来创建各种自然现象和复杂纹理效果。
它的本质是一种由数学算法公式生成的有规则性或可控的随机数据

通过噪声算法生成的随机数据具有以下特点:

  • 随机性:噪声数据本质上是随机的,这意味着它具有不规则性,无法通过简单的模式预测
  • 平滑性:数据不会突然跳跃或变化,而是呈现出逐渐过渡的效果,适合模拟自然现象
  • 周期性:随着坐标的变化,噪声值会重复出现,形成一个封闭的循环。也可以通过调整噪声的范围或修改算法来避免
  • 可调性:大多数噪声算法的输出是可以调整的,这种可调性允许你根据需求灵活地控制噪声的表现,适应不同的视觉效果或逻辑处理需求
  • 多维性:能够处理多维数据,这意味着它们可以生成二维、三维甚至更高维度的噪声数据

就因为噪声数据具有以上这些特点,我们可以利用噪声来实现一些特殊效果,比如:,地形生成,云层效果,烟雾效果、水面模拟、消融效果、

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("提示", "噪声纹理生成结束", "确定");
        }
    }
}
相关推荐
在路上看风景2 小时前
15. 纹理尺寸是4的倍数
unity
AT~4 小时前
unity 使用Socket和protobuf实现网络连接
unity·游戏引擎
怣疯knight11 小时前
Cocos creator判断节点是否能用的方法
unity·cocos2d
tealcwu11 小时前
Google Play的Keystore不可用时的解决方法
unity
呼呼突突11 小时前
Unity使用TouchSocket的RPC
unity·rpc·游戏引擎
qq 180809511 天前
从零构建一个多目标多传感器融合跟踪器
unity
平行云1 天前
实时云渲染支持在网页上运行UE5开发的3A大作Lyra项目
unity·云原生·ue5·webgl·虚拟现实·实时云渲染·像素流送
鹏飞于天1 天前
Shader compiler initialization error: Failed to read D3DCompiler DLL file
unity
wonder135791 天前
UGUI重建流程和优化
unity·游戏开发·ugui
那个村的李富贵1 天前
Unity打包Webgl后 本地运行测试
unity·webgl