博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图形学噪声解析
阅读量:4958 次
发布时间:2019-06-12

本文共 3539 字,大约阅读时间需要 11 分钟。

新博客:

欢迎关注,同步更新

Prelin噪声

Prelin噪声由Ken Perlin在1983年提出,因参与制作迪士尼的动画电影《电子世界争霸战》,但不满于当时那种非常不自然的纹理效果,而提出了Perlin噪声

本篇文章借鉴各路大神的文章总结而来:

  • 冯乐乐:
  • 则卷大明:
  • Unity API:

此文章源码在我的个人上,本文章的仅仅实现了Prelin噪声中的最简单版本。上图先~

371236-20180731211054966-1330170859.png

利用Unity实现2D Prelin噪声

candycat的文章非常好,不过没有Unity的具体实现代码,而则卷大明的文章中只给出了一部分的代码。最后发现了Unity自带2D噪声,所以结合多方文章最终完成了最简单的Prelin噪声。

如果你懂GLSL的pixel shaders,那你就可以直接去阅读由iq大神写的:。而这里我只是用Unity代码还原冯乐乐博客中利用shaderToy编写的代码

在开始正文之前,我们得知道几个数学小知识。图形学中涉及矩阵计算的东西有太多,在ShaderToy中都有封装,而Unity并没有,所以我们得实现几个图形学函数

Floor:向下取整

private static Vector2 Floor(Vector2 p){    return new Vector2(Mathf.Floor(p.x), Mathf.Floor(p.y));}

Fract:取小数部分

private static Vector2 Fract(Vector2 p){    return p - Floor(p);}

Sin:正弦函数

private static Vector2 Sin(Vector2 p){    return new Vector2(Mathf.Sin(p.x), Mathf.Sin(p.y));}

其实这些函数在Unity中也有实现,不过我这里要实现2D的噪声,所以得处理2D情况下的操作。接下来就是正片了~

首先还原冯乐乐博客中的梯度函数

private static Vector2 Hash22(Vector2 p){    p = new Vector2(Vector2.Dot(p, new Vector2(127.1f, 311.7f)),                    Vector2.Dot(p, new Vector2(269.5f, 183.3f)));    return new Vector2(-1, -1) + 2.0f * Fract(Sin(p) * 43758.5453123f);}

然后还原缓和曲线,这里利用新提出的缓和曲线,使其在二阶的情况下也能满足连续性,公式如下:

\(s(t)=6*t^5-15*t^4+10*t^3\)

// 一阶private static float GetEaseCurves(float t){    return t * t * t * (t * (t * 6 - 15) + 10);}// 二阶private static Vector2 GetEaseCurves(Vector2 p){    return new Vector2(GetEaseCurves(p.x), GetEaseCurves(p.y));}

这里将冯乐乐中的-1.0f改为Unity中可计算的Vector(-1, -1)

接下来是生成prelin噪声的主函数了

public static float prelin_noise(Vector2 p){    Vector2 pi = Floor(p);    Vector2 pf = p - pi;    Vector2 w = GetEaseCurves(pf);    float corner1 = Vector2.Dot(Hash22(pi + Vector2.zero), pf - Vector2.zero);    float corner2 = Vector2.Dot(Hash22(pi + Vector2.right), pf - Vector2.right);    float corner3 = Vector2.Dot(Hash22(pi + Vector2.up), pf - Vector2.up);    float corner4 = Vector2.Dot(Hash22(pi + Vector2.one), pf - Vector2.one);    return Mathf.Lerp(Mathf.Lerp(corner1, corner2, w.x),                      Mathf.Lerp(corner3, corner4, w.x),                      w.y);}

到这里我们完成了2D Prelin噪声的构建,加下来就是怎么利用噪声生成贴图并转成PNG存储起来~

下面的代码生成了一个噪声的贴图并且返回

private int width = 512;  // 贴图宽度private int height = 512; // 贴图高度private float xOrg = 0f;  // 宽度偏移起点private float yOrg = 0f;  // 高度偏移起点private float scale = 15f; // 周期private Texture2D CreateTexture(){      Texture2D tex = new Texture2D(width, height);      Color[] pix = new Color[width * height];      float y = 0f;      while (y < height)      {          float x = 0f;          while (x < width)          {              float xCoord = xOrg + x / width * scale;              float yCoord = yOrg + y / height * scale;              float sample = PrelinNoise.prelin_noise(new Vector2(xCoord, yCoord));              pix[(int)y * width + (int)x] = new Color(sample, sample, sample);              x++;          }          y++;      }      tex.SetPixels(pix);      tex.Apply();      return tex;}

下面的函数将贴图转换成PNG图片存储到特定位置

private bool SaveTexture(Texture2D tex, string path){      if (File.Exists(path))      {          Debug.LogWarning("已有文件");          return false;      }      if (tex == null)      {          Debug.LogWarning("贴图为空");          return false;      }      // 贴图转换为PNG图片      byte[] texData = tex.EncodeToPNG();      // 如果没有目录则创建目录      int index = path.LastIndexOf('/');      string dir = path.Remove(index);      if (!Directory.Exists(dir))      {          Directory.CreateDirectory(dir);      }      // 贴图存储      File.WriteAllBytes(path, texData);      return true;  }

后续还会陆续更新Sample噪声,分型噪声等利用Unity实现的方式

转载于:https://www.cnblogs.com/SHOR/p/9398231.html

你可能感兴趣的文章
MVC3分页传2参
查看>>
2016-2017-2点集拓扑作业[本科生上课时]讲解视频
查看>>
appium(13)- server config
查看>>
IIS负载均衡-Application Request Route详解第六篇:使用失败请求跟踪规则来诊断ARR...
查看>>
管理信息系统 第三部分 作业
查看>>
[Leetcode Week13]Search a 2D Matrix
查看>>
通过被调函数改变主调函数的值
查看>>
java 对象的序列化与反序列化
查看>>
二叉树、树、森林
查看>>
查看端口占用cmd命令
查看>>
2019.01.17王苛震作业
查看>>
Halcon学习(八)文本操作
查看>>
MFC电子词典
查看>>
简单工厂(Simple Factory)
查看>>
04: 打开tornado源码剖析处理过程
查看>>
02: 安装epel 解决centos7无法使用yum安装nginx
查看>>
清除浮动
查看>>
PayPal(贝宝)支付接口、文档、IPN
查看>>
站立会议总结07
查看>>
ORACLE 10G R2_执行计划中cost cardinality bytes cpu_cost io_cost解释
查看>>