0

I need to make perlin noise like in AS3.0:

bitmapData.perlinNoise(baseX, baseY, numOctaves, 
randomSeed, stitch, fractalNoise, grayScale, offsets);

It's seamless noise:

enter image description here

I found a lot of material about it, but I can't make it like in my as3.0 image. Java code:

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Noise extends JPanel{

    public static int octaves = 4;
    public static int size =  128;
    public static float[][][] noise = new float[size][size][octaves];
    public static float[][] perlinnoise = new float[size][size];

    public static float p = (float) 1/4;

    public static Random gen = new Random();

    public static float GenerateNoise() {
        return gen.nextFloat();
    }

    public static float SmoothNoise(int x, int y, int z) {
        try{
            float corners = (noise[x - 1][y - 1][z] + noise[x + 1][y - 1][z] + noise[x - 1][y + 1][z] + noise[x + 1][y + 1][z]) / 16;
            float sides = (noise[x - 1][y][z] + noise[x + 1][y][z] + noise[x][y - 1][z] + noise[x][y + 1][z]) / 8;
            float center = noise[x][y][z] / 4;
            return corners + sides + center;
        }catch(Exception e) {
            return 0;
        }
    }

    public static float InterpolatedNoise(float x, float y, int pX, int pY, int pZ) {
        int intX = (int) x;
        int intY = (int) y;
        float fracX = x - intX;
        float fracY = y - intY;
        float v1 = SmoothNoise(pX, pY, pZ);
        float v2 = SmoothNoise(pX + 1, pY, pZ);
        float v3 = SmoothNoise(pX, pY + 1, pZ);
        float v4 = SmoothNoise(pX + 1, pY + 1, pZ);
        float i1 = Interpolate(v1, v2, fracX);
        float i2 = Interpolate(v3, v4, fracX);
        return Interpolate(i1, i2, fracY);
    }

    public static float Interpolate(float a, float b, float x) {
        float ft = (float) (x * 3.1415927);
        float f = (float) ((1 - Math.cos(ft)) * 0.5);
        return (float) (a * (1 - f) + b * f);
    }

    public static float Perlin2D(float x, float y, int posX, int posY, int posZ) {
        float total = 0;
        for(int i = 0; i < octaves; i++) {
            double f = Math.pow(2, i);
            double a = Math.pow(p, i);
            total = (float) (total + InterpolatedNoise((float)(x * f), (float)(y * f), posX, posY, posZ) * a);
        }
        return total;
    }

    public static void main(String [] args) {
        for(int z = 0; z < octaves; z++) {
            for(int y = 0; y < size; y++) {
                for(int x = 0; x < size; x++) {
                    noise[x][y][z] = GenerateNoise();
                }
            }
        }

        for(int z = 0; z < octaves; z++) {
            for(int y = 0; y < size; y++) {
                for(int x = 0; x < size; x++) {
                    perlinnoise[x][y] = Perlin2D(x / (size - 1), y / (size - 1), x, y, z) / octaves;
                }
            }
        }

        JFrame f = new JFrame("Perlin Noise");
        f.setSize(400, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new Noise());
        f.setVisible(true);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for(int y = 0; y < size; y++) {
            for(int x = 0; x < size; x++) {
                g.setColor(new Color(perlinnoise[x][y], perlinnoise[x][y], perlinnoise[x][y]));
                g.fillRect(x * 2, y * 2, 2, 2);
            }
        }
        repaint();
    }
}

Help please!

Leo
  • 3,003
  • 5
  • 38
  • 61

1 Answers1

1

The trick is, the Perlin noise does not use pseudo-random generator, it uses a function that takes an argument and returns predefined value for that argument, but when argument shifts by 1, the value jumps almost randomly. Check the sources for the permutation formulae, the init() method makes a permutation that then is used to make the entire noise.

Vesper
  • 18,599
  • 6
  • 39
  • 61