Difference between revisions of "Perlin Noise"

From Free Pascal wiki
Jump to navigationJump to search
 
 
(14 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{Developing with Graphics}}
+
{{Perlin Noise}}
  
 
This page is the start of a tutorial about using Perlin Noise on LCL applications to generate natural looking images. It will cover both basic theory and real usage examples, with a focus on compilable examples.
 
This page is the start of a tutorial about using Perlin Noise on LCL applications to generate natural looking images. It will cover both basic theory and real usage examples, with a focus on compilable examples.
  
Perlin Noise was invented by [Ken Perlin|http://mrl.nyu.edu/~perlin/] to generate textures for a movie called Tron. Today it is widely used on movies and video games to produce natural looking smoke, landscapes, clouds and any texture including marble, irregular glass,  etc.
+
Perlin Noise was invented by [http://mrl.nyu.edu/~perlin/ Ken Perlin] to generate textures for a movie called Tron. Today it is widely used on movies and video games to produce natural looking smoke, landscapes, clouds and any texture including marble, irregular glass,  etc.
  
 
__TOC__
 
__TOC__
Line 16: Line 16:
 
==First Example==
 
==First Example==
  
[[Image:Noise1D.png]]
+
This application demonstrates a simple noise function with the following properties:
  
Noise1D.dpr file:
+
* Only 1 harmonic present
 +
* Amplitude of 250 pixels
 +
* Wavelength of 20 pixels
 +
* Frequency of 0.05
 +
* You can use a combo box to choose between Linear, Cossine and Cubic interpolation
  
<pre>
+
[[Image:Noise1D.png]]
program noise1d;
 
  
{$ifdef fpc}
+
Files:
  {$mode delphi}
 
{$endif}
 
  
uses
+
* noise1d.lpi
  {$ifdef fpc}
+
* noise1d.dpr
  Interfaces, // this includes the LCL widgetset
+
* noise.pas
  {$endif}
 
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
 
  noise;
 
  
type
+
==Persistence Example==
  
  { TMainWindow }
+
This application demonstrates how to sum many noise functions to get a perlin noise function. It has the following properties:
  
  TMainWindow = class(TForm)
+
* 3 harmonics present
  private
+
* Amplitudes of 250, 125 and 62 pixels
    { private declarations }
+
* Wavelength of 20, 10, and 5 pixels
    SelectInterpolation: TComboBox;
+
* Frequency of 0.05, 0.1, 0.2
    procedure DoPaint(Sender: TObject);
+
* You can use a combo box to choose between Linear, Cossine and Cubic interpolation
    procedure DoRefresh(Sender: TObject);
 
    function NormalizeNoise(x: Double): Integer;
 
  public
 
    { public declarations }
 
    constructor Create(AOwner: TComponent); override;
 
    destructor Destroy; override;
 
  end;
 
  
var
+
[[Image:Perlin1D.png]]
  vMainWindow: TMainWindow;
 
  
{ TMainWindow }
+
Files:
  
procedure TMainWindow.DoPaint(Sender: TObject);
+
* perlin1d.lpi
var
+
* perlin1d.dpr
  i, j, interpolation: Integer;
+
* noise.pas
begin
 
  { Draws rulers }
 
  Canvas.MoveTo(25,  25 );
 
  Canvas.LineTo(25,  275);
 
  Canvas.LineTo(275, 275);
 
 
 
  { Draws 12 points and the interpolation between them }
 
  for i := 0 to 11 do
 
  begin
 
    Canvas.Ellipse(i * 20 + 25 + 1, NormalizeNoise(IntNoise(i)) + 1,
 
    i * 20 + 25 - 1, NormalizeNoise(IntNoise(i)) - 1);
 
   
 
    if (i = 11) then Continue;
 
   
 
    for j := 1 to 19 do
 
    begin
 
      case SelectInterpolation.ItemIndex of
 
      0: interpolation := Linear_Interpolate(NormalizeNoise(IntNoise(i)), NormalizeNoise(IntNoise(i + 1)), j / 20);
 
      1: interpolation := Cosine_Interpolate(NormalizeNoise(IntNoise(i)), NormalizeNoise(IntNoise(i + 1)), j / 20);
 
      else
 
        interpolation := Cubic_Interpolate(NormalizeNoise(IntNoise(i - 1)),
 
        NormalizeNoise(IntNoise(i)), NormalizeNoise(IntNoise(i + 1)),
 
        NormalizeNoise(IntNoise(i + 2)), j / 20);
 
      end;
 
  
      Canvas.Pixels[i * 20 + 25 + j, interpolation] := clBlack;
+
==Use Perlin noise to create textures==
    end;
 
  end;
 
end;
 
  
procedure TMainWindow.DoRefresh(Sender: TObject);
+
It is possible to create tilable textures of stone, water, wood... with Perlin noise.
begin
 
  Repaint;
 
end;
 
  
function TMainWindow.NormalizeNoise(x: Double): Integer;
+
Here is a tutorial on how to do this: [[BGRABitmap tutorial 8]]
begin
 
  Result := Round( 25 + (x + 1.0) * 125 );
 
end;
 
  
constructor TMainWindow.Create(AOwner: TComponent);
+
==Subversion==
begin
 
  inherited Create(AOwner);
 
  
  Position := poScreenCenter;
+
You can download the source code for the examples and the library using this command:
  Width := 300;
 
  Height := 300;
 
  Caption := 'Noise 1D';
 
  
  OnPaint := DoPaint;
+
svn co  https://svn.code.sf.net/p/lazarus-ccr/svn/examples/noise noise
  
  SelectInterpolation := TComboBox.Create(Self);
+
==External Links==
  SelectInterpolation.Parent := Self;
 
  SelectInterpolation.Items.Add('Linear Interpolation');
 
  SelectInterpolation.Items.Add('Cosine Interpolation');
 
  SelectInterpolation.Items.Add('Cubic Interpolation');
 
  SelectInterpolation.Left := 100;
 
  SelectInterpolation.Width := 200;
 
  SelectInterpolation.ItemIndex := 0;
 
 
 
  SelectInterpolation.OnChange := DoRefresh;
 
end;
 
 
 
destructor TMainWindow.Destroy;
 
begin
 
 
 
  inherited Destroy;
 
end;
 
  
begin
+
* [http://web.archive.org/web/20160325134143/http://freespace.virgin.net/hugo.elias/models/m_perlin.htm Article] with the theory of Perlin Noise.
  Application.Initialize;
 
  Application.CreateForm(TMainWindow, vMainWindow);
 
  Application.Run;
 
end.
 
</pre>
 
  
noise.pas file:
+
[[Category:Tutorials]]
 
+
[[Category:Graphics]]
<pre>
+
[[Category:Game Development]]
unit noise;
+
[[Category:Lazarus-CCR]]
 
+
[[Category:SciTech]]
{$ifdef fpc}
 
  {$mode delphi}
 
{$endif}
 
 
 
interface
 
 
 
uses
 
  Classes, SysUtils;
 
 
 
function IntNoise(x: Integer): Double;
 
function Linear_Interpolate(a, b: Integer; x: Double): Integer;
 
function Cosine_Interpolate(a, b: Integer; x: Double): Integer;
 
function Cubic_Interpolate(v0, v1, v2, v3: Integer; x: Double): Integer;
 
 
 
implementation
 
 
 
function IntNoise(x: Integer): Double;
 
var
 
  xl: Integer;
 
begin
 
  xl := (x shl 13) xor x;
 
  Result := (xl * (xl * xl * 15731 + 789221) + 1376312589) and $7fffffff;
 
  Result := 1.0 - (Result / 1073741824.0);
 
end;
 
 
 
function Linear_Interpolate(a, b: Integer; x: Double): Integer;
 
begin
 
  Result := Round(a * (1-x) + b * x);
 
end;
 
 
 
function Cosine_Interpolate(a, b: Integer; x: Double): Integer;
 
var
 
  f, ft: Double;
 
begin
 
  ft := x * Pi;
 
  f := (1.0 - cos(ft)) * 0.5;
 
  Result := Round( a * (1 - f) + b * f );
 
end;
 
 
 
function Cubic_Interpolate(v0, v1, v2, v3: Integer; x: Double): Integer;
 
var
 
  P, Q, R, S: Double;
 
begin
 
  P := (v3 - v2) - (v0 - v1);
 
  Q := (v0 - v1) - P;
 
  R := v2 - v0;
 
  S := v1;
 
 
 
  Result := Round( P * x * x * x + Q * x * x + R * x + S );
 
end;
 
 
 
end.
 
</pre>
 
 
 
==External Links==
 

Latest revision as of 08:06, 11 April 2019

English (en) français (fr) 中文(中国大陆)‎ (zh_CN)

This page is the start of a tutorial about using Perlin Noise on LCL applications to generate natural looking images. It will cover both basic theory and real usage examples, with a focus on compilable examples.

Perlin Noise was invented by Ken Perlin to generate textures for a movie called Tron. Today it is widely used on movies and video games to produce natural looking smoke, landscapes, clouds and any texture including marble, irregular glass, etc.

Getting Started

Perlin Noise is based on the idea of fractals, that things in nature show different degrees of change. On a rocky mountain landscape for example when can see changes with a very big amplitude, which are the mountains themselves. Smaller changes represent irregularities on those mountains and even smaller ones represent rocks.

mountain landscape.png


First Example

This application demonstrates a simple noise function with the following properties:

  • Only 1 harmonic present
  • Amplitude of 250 pixels
  • Wavelength of 20 pixels
  • Frequency of 0.05
  • You can use a combo box to choose between Linear, Cossine and Cubic interpolation

Noise1D.png

Files:

  • noise1d.lpi
  • noise1d.dpr
  • noise.pas

Persistence Example

This application demonstrates how to sum many noise functions to get a perlin noise function. It has the following properties:

  • 3 harmonics present
  • Amplitudes of 250, 125 and 62 pixels
  • Wavelength of 20, 10, and 5 pixels
  • Frequency of 0.05, 0.1, 0.2
  • You can use a combo box to choose between Linear, Cossine and Cubic interpolation

Perlin1D.png

Files:

  • perlin1d.lpi
  • perlin1d.dpr
  • noise.pas

Use Perlin noise to create textures

It is possible to create tilable textures of stone, water, wood... with Perlin noise.

Here is a tutorial on how to do this: BGRABitmap tutorial 8

Subversion

You can download the source code for the examples and the library using this command:

svn co https://svn.code.sf.net/p/lazarus-ccr/svn/examples/noise noise

External Links

  • Article with the theory of Perlin Noise.