Advertisement
Guest User

Perlin noise generation - DEMO

a guest
Sep 27th, 2013
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.67 KB | None | 0 0
  1. mport java.awt.Color;
  2. import java.awt.Graphics;
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.KeyListener;
  5. import java.util.Random;
  6.  
  7. import javax.swing.JFrame;
  8. import javax.swing.JPanel;
  9.  
  10. /* Project Name: Perlin Noise Demo
  11.  * Author: Nick Peluso
  12.  * Last Modified: 8/17/2012 11:59PM
  13.  *
  14.  * Description: Perlin Noise is used in procedural generation. Followed a tutorial on gamedev.tutsplus.com, but adapted it to my liking and display method.
  15.  * Although the perlin noise function is still unclear to me, I am starting to get a better understanding. Fun to play around with, w/h/k control pretty much
  16.  * everything except the color choice - that can be found in genColor. Enjoy.
  17.  */
  18.  
  19. public class PerlinNoiseDemo extends JPanel implements KeyListener{
  20.     int w = 1920, h = 1080, k = 7;//Dimensions of arrays/# of octaves("zoom"/"scale")
  21.     Color[][] map;
  22.    
  23.     public static void main(String[]args){
  24.         PerlinNoiseDemo pnd = new PerlinNoiseDemo();
  25.         pnd.execute();
  26.     }
  27.     public void execute(){
  28.         float[][] whiteNoise = genWhiteNoise(w, h);
  29.         float[][] perlinNoise = genPerlinNoise(whiteNoise, k);
  30.        
  31.         map = genMap(perlinNoise);
  32.         addKeyListener(this);
  33.        
  34.         JFrame f = new JFrame();
  35.         f.add(this);
  36.         f.setSize(w,h);
  37.         f.setTitle("Perlin Noise Demo by Nick Peluso");
  38.         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  39.         f.setVisible(true);
  40.        
  41.         setFocusable(true);
  42.        
  43.     }
  44.    
  45.     public void paint(Graphics g){
  46.         for(int i = 0; i < map.length; i++){
  47.             for(int j = 0; j < map[0].length; j++){
  48.                 g.setColor(map[i][j]);
  49.                 g.fillRect(i, j, 1, 1);
  50.             }
  51.         }
  52.         g.setColor(Color.white);
  53.         g.drawString("k:"+k, 100, 100);
  54.     }
  55.    
  56.     public float[][] genWhiteNoise(int width, int height){
  57.         Random random = new Random();
  58.         float[][] noise = new float[width][height];
  59.         for(int i = 0; i < width; i++){
  60.             for(int j = 0; j < height; j++){
  61.                 noise[i][j] = random.nextFloat();
  62.             }
  63.         }
  64.         return noise;
  65.     }
  66.  
  67.     public float[][] genSmoothNoise(float[][] whiteNoise, int octave){
  68.         int width = whiteNoise.length;
  69.         int height = whiteNoise[0].length;
  70.        
  71.         float[][] smoothNoise = new float[width][height];
  72.        
  73.         int samplePeriod = (int) Math.pow(2, octave);
  74.         float sampleFrequency = 1.0f / samplePeriod;
  75.        
  76.         for(int i = 0; i < width; i++){
  77.             //blend the horizontal sampling indices
  78.             int sample_i0 = (i / samplePeriod) * samplePeriod;
  79.             int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
  80.             float horizontal_blend = (i - sample_i0) * sampleFrequency;
  81.            
  82.             for(int j = 0; j < height; j++){
  83.                 //blend the vertical sampling indices
  84.                 int sample_j0 = (j / samplePeriod) * samplePeriod;
  85.                 int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
  86.                 float vertical_blend = (j - sample_j0) * sampleFrequency;
  87.                
  88.                 //blend the top two corners
  89.                 float top = Interpolate(whiteNoise[sample_i0][sample_j0], whiteNoise[sample_i1][sample_j0], horizontal_blend);
  90.                
  91.                 //blend the bottom two corners
  92.                 float bottom = Interpolate(whiteNoise[sample_i0][sample_j1], whiteNoise[sample_i1][sample_j1], horizontal_blend);
  93.                
  94.                 //final blend
  95.                 smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
  96.             }
  97.         }
  98.         return smoothNoise;
  99.     }
  100.    
  101.     public float[][] genPerlinNoise(float[][] whiteNoise, int octaveCount){
  102.         int width = whiteNoise.length;
  103.         int height = whiteNoise[0].length;
  104.        
  105.         float smoothNoise[][][] = new float[octaveCount][][];
  106.        
  107.         float persistance = 0.5f;
  108.        
  109.         //generate smooth noise
  110.         for(int k = 0; k < octaveCount; k++){
  111.             smoothNoise[k] = genSmoothNoise(whiteNoise, k);
  112.         }
  113.        
  114.         float[][] perlinNoise = new float[width][height];
  115.         float amplitude = 1.0f;
  116.         float totalAmplitude = 0.0f;
  117.        
  118.         //blend noise together
  119.         for(int octave = octaveCount-1; octave >= 0; octave--){
  120.             amplitude *= persistance;
  121.             totalAmplitude += amplitude;
  122.            
  123.             for(int i = 0; i < width; i++){
  124.                 for(int j = 0; j < height; j++){
  125.                     perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;
  126.                 }
  127.             }
  128.         }
  129.        
  130.         //normalization
  131.         for(int i = 0; i < width; i++){
  132.             for(int j = 0; j < height; j++){
  133.                 perlinNoise[i][j] /= totalAmplitude;
  134.             }
  135.         }
  136.        
  137.         return perlinNoise;
  138.     }
  139.  
  140.     public Color[][] genMap(float[][] perlinNoise){
  141.         int width = perlinNoise.length;
  142.         int height = perlinNoise[0].length;
  143.        
  144.         Color[][] colorMap = new Color[width][height];
  145.        
  146.         for(int i = 0; i < width; i++){
  147.             for(int j = 0; j < height; j++){
  148.                 float x = perlinNoise[i][j];
  149.                 if(x > .9){ colorMap[i][j] = new Color(255,255,255);}
  150.                 else if(x > .85){colorMap[i][j] = new Color(200,200,200);}
  151.                 else if(x > .8){ colorMap[i][j] = new Color(173,173,173);}
  152.                 else if(x > .75){colorMap[i][j] = new Color(130,130,130);}
  153.                 else if(x > .7){ colorMap[i][j] = new Color(191,124,47);}
  154.                 else if(x > .6){ colorMap[i][j] = new Color(44,84,0);}
  155.                 else if(x > .5){ colorMap[i][j] = new Color(17,130,0);}
  156.                 else if(x > .4){ colorMap[i][j] = new Color(0,188,88);}
  157.                 else if(x > .3){ colorMap[i][j] = new Color(191,124,47);}
  158.                 else if(x > .2){ colorMap[i][j] = new Color(229,202,0);}
  159.                 else if(x > .1){ colorMap[i][j] = new Color(0,135,204);}
  160.                 else{ colorMap[i][j] = new Color(0,78,142);}
  161.             }
  162.         }
  163.        
  164.         return colorMap;
  165.     }
  166.    
  167.     float Interpolate(float x0, float x1, float alpha){
  168.         return x0 * (1 - alpha) + alpha * x1;
  169.     }
  170.    
  171.     public void keyPressed(KeyEvent e){
  172.         if(e.getKeyCode() == KeyEvent.VK_UP){
  173.             k++;
  174.             map = genMap(genPerlinNoise(genWhiteNoise(w, h), k));
  175.             repaint();
  176.         }
  177.         if(e.getKeyCode() == KeyEvent.VK_DOWN){
  178.             k--;
  179.             map = genMap(genPerlinNoise(genWhiteNoise(w, h), k));
  180.             repaint();
  181.         }
  182.         System.out.println(""+k);
  183.     }
  184.     public void keyReleased(KeyEvent e){}
  185.     public void keyTyped(KeyEvent e){}
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement