Coder Social home page Coder Social logo

perlin_noise_flowfields's Introduction

perlin_noise_flowfields

Using perlin noise and flowfields to create beautiful pictures.

使用柏林噪声和向量场来实现优美图像的绘制,大概原理是:将画布分为若干小方格当作向量场,每个小方格里面根据柏林噪声生成梯度方向当作向量,然后使用粒子系统随机运动,粒子的加速度是为当下运动到的小方格里面的向量。随着时间的变化,向量场发生着有规律的变化,粒子运动的轨迹就是随机但又有一定规律的曲线,若干粒子的运动曲线就组合成了优美的图像。

  • 代码架构
  • 原理解析
    • 柏林噪声
    • 粒子系统
    • 向量场
    • 绘制曲线

代码架构

  • home.html 浏览器打开主页
  • perlin_noise.js Perlin Noise的生成代码
  • particle.js 粒子系统
  • sketch.js 向量场构造,绘制优美图形

原理解析

  • 柏林噪声
    柏林噪声是一种使物体运动显得更自然,展示物体纹理的一种方法。柏林噪声的基本**是:假设要想获得N个噪声点,给定幅度和频率生成K(K < N)个噪声点(通常是均匀分布),然后对每两个噪声点之间进行插值若干点,从而得到N个比较连续的噪声点。然后对不同幅度和频率的结果进行求平均得到柏林噪声。
    上面是柏林噪声的基本**,下面给出柏林噪声的具体实现方法。柏林噪声的输入是三个double类型的数据,即xoff,yoff,zoff,函数返回结果是一个0~1之间的随机数。假如要生成一个噪声点,使用noise(0.01, 1.02, 2.01)即可返回一个随机数,同样的noise(1.3, 2.1, 3.2)也会返回一个随机数。所以假如现在要生成一个一维的长度为N的柏林噪声,可以使用noise(i * 0.01,, 0.0, 0.0)来实现,即xoff参数值每次增加0.01(步长可以根据实际情况调整);假若要生成二维的柏林噪声,每次更新xoff和yoff参数值即可,不同的z值会产生不同的二维柏林噪声。
    下面来看看柏林噪声的原理,为了方便解释,这里使用zoff = 0.0情况下来进行解释,即只有xoff和yoff两个参数。柏林噪声生成的过程可以分为映射、影响度计算、插值三步。
    (1)第一步是映射,即将xoff和yoff映射到一个{(x, y),(x + 1, y),(x, y + 1),(x + 1, y + 1)}的正方形小方格,可以简单使用对x = floor(xoff),y = floor(yoff)的方法实现,在下图里面即表现为将Q点映射到I、J、K、L四个点组成的小方格。
    (2)第二步是影响度计算,通过第一步映射之后,I、J、K、L四个点的坐标即可以获得,那么根据坐标获得一个hash值。这里有很多实现hash的方法,最简单的是建立一个p数组,p有512项,是0~255这些数的随机排列,并重复一遍,然后根据p[p[x] + y]得到hash值。然后根据hash值取得相应的梯度,比如:if hash % 4 == 0 then return (1, 0)等等。假如现在I的梯度为(-1,-1),即图中向量IM,那么计算向量内积<IM, IQ>,这里即是-1 * fx - 1 * fy,作为I对点Q的影响度。同理可以获得其余三个顶点对Q的影响度。
    (3)第三步是插值,假设记I、J、K、L四个点的影响度分别为aa,ab,bb,ba,那么插值时候使用:y1 = fy * aa + (1 - fy) * ba, y2 = fy * ab + (1 - fy) * bb,res = fx * y1 + (1 - fx) * y2 进行插值。即先对y轴进行插值,然后在对x轴方向进行插值。上面使用的是线性插值,为了方便,通常使用衰减函数,f(x) = t * t * t * (t * (t * 6 - 15) + 10)来进行改变fx和fy。

  • 粒子系统
    粒子系统的具体实现在之前项目text_particle里面有过详细介绍,这里不再详细解释。这里为了说明的一点是,本次项目使用的粒子系统通过applyForce对粒子施加外力,即改变加速度;为了避免粒子运动过快,加了速度上限限制;另外为了方便绘制粒子运动轨迹,保存了粒子的上一次运动的位置,每次绘图时从上一次位置到现在位置画线。
  • 向量场
    将画布分为若干大小一样的小方格,每个小方格里面生成一个柏林噪声,然后将柏林噪声乘以2 * pi,得到一个角度alpha,生成一个向量模大小为D,角度为alpha的向量作为该小方格内向量场的方向。

  • 绘图
    由粒子系统生成一定数目的粒子,初始位置在画布的任意位置,初始速度为0,然后进行运动。每个粒子的加速度由其所在的小方格的向量确定,即可以理解为:向量场给粒子施加了外力,使得粒子沿着向量场进行加速减速运动。那么绘制粒子轨迹的变化,设置透明度为5,就可以得到优美的图形。粒子数目、粒子最大速度、向量场向量模大小以及柏林噪声到向量角度的映射都是可以调整的参数,可以得到不同的图形。




perlin_noise_flowfields's People

Contributors

lxcnju avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.