我创建了一个函数来生成 Perlin 噪声数据的二维数组,从 0 到 1 之间的随机值的基本噪声数组开始。
基本白噪声数组如下所示:
从那里,我使用 smoothNoise() 函数插入值以创建好看的图像(我没有,因为它不起作用)
每个八度音程调用一次平滑噪声函数。平滑噪声函数返回什么数据的图像如下(八度从最低到最高)
完成所有平滑后,输出的图像变为黑色。我会上传一张图片,但它只是黑色的,所以没有必要。
我的代码是:
import java.util.Random;
public class Noise2D {
int width;
int height;
public Noise2D(int width, int height){
this.width = width;
this.height = height;
}
public double[][] generateWhiteNoise(int width,int height){
Random r = new Random(0);
double[][] whiteNoise = new double[width][height];
for(int i = 0; i<whiteNoise.length; i++){
for(int j = 0; j<whiteNoise[0].length;j++){
double rNum = r.nextDouble()%1;
whiteNoise[i][j] = (double)rNum;
}
}
ImageWriter.writeImage(whiteNoise, "WhiteNoise");
return whiteNoise;
}
public double interpolate(double x0, double x1, double alpha){
return x0 * (1 - alpha) + alpha * x1;
}
public double[][] generateSmoothNoise(double[][] baseNoise, int octave){
int width = baseNoise.length;
int height = baseNoise[0].length;
double[][] smoothNoise = new double[width][height];
int period = 1<< octave; //2^i
double frequency = 1.0/period;
for(int x = 0; x<width; x++){
int x0 = (x/period)*period; //7/3 = 2 *3 = 6
int x1 = (x0+period)%width;
double hBlend = (x-x0)*frequency;
for(int y = 0; y<height; y++){
int y0 = (y/period)*period;
int y1 = (y0 + period)%height;
double vBlend = (y - y0)*frequency;
double top = interpolate(baseNoise[x0][y0],baseNoise[x1][y1],hBlend);
double bottom = interpolate(baseNoise[x0][y1],baseNoise[x1][y0],hBlend);
smoothNoise[x][y] = interpolate(top,bottom,vBlend);
}
}
ImageWriter.writeImage(smoothNoise,"Smooth"+Integer.toString(octave));
return smoothNoise;
}
public double[][] generatePerlinNoise(double baseNoise[][], int octaves){
int width = baseNoise.length;
int height = baseNoise[0].length;
double persistence = 0.5;
double[][][] smoothNoise = new double[octaves][][];
for(int i = 0; i<octaves; i++){
smoothNoise[i] = generateSmoothNoise(baseNoise,i);
}
double[][] perlinNoise = new double[width][height];
double amplitude = 1;
double totalAmplitude = 0;
for(int octave = octaves-1; octave>=0; octave--){
amplitude*=persistence;
totalAmplitude+=amplitude;
for(int x = 0; x<width;x++){
for(int y = 0; y<height; y++){
perlinNoise[x][y] = smoothNoise[octave][x][y] * amplitude;
}
}
}
ImageWriter.writeImage(perlinNoise,"files");
for(int i = 0; i<width; i++){
for(int j = 0; j<height; j++){
perlinNoise[i][j] /= totalAmplitude;
}
}
return perlinNoise;
}
}
定义类并调用方法:
Perlin p = new Perlin(256,256);
writeImage(p.smoothNoise(p.makeNoise(256,256), 1, 16), "Perlin");
1 是频率,16 是八度数 数据写入函数 writeImage(2d array, "name") 的位置使用以下代码(我认为这部分没有问题,但我还是会发布它) :
public static void writeImage(double[][] data,String name){
BufferedImage img = new BufferedImage(data.length,data[0].length,BufferedImage.TYPE_INT_RGB);
for(int y = 0; y<data.length; y++){
for(int x = 0; x<data[y].length; x++){
if(data[y][x]>1){
data[y][x] = 1;
}
if(data[y][x]<0){
data[y][x] = 0;
}
Color c = new Color((float)data[y][x],(float)data[y][x],(float)data[y][x]);
img.setRGB(x,y,c.getRGB());
}
}
try{
File file = new File(name+".png");
file.createNewFile();
ImageIO.write(img,"png",file);
}catch(IOException e){
e.printStackTrace();
}
}
public static void writeExistingImage(BufferedImage img){
try{
File file = new File("noise2.png");
file.createNewFile();
ImageIO.write(img,"png",file);
}catch(IOException e){
e.printStackTrace();
}
}
总而言之,我相信问题出在 smoothNoise 方法上,尽管我很可能是错的,因为我对 Perlin Noise 的了解并不广泛。如果问题不在于这里,我认为它在于 generatePerlinNoise() 方法。任何帮助将不胜感激。任何建议我都会很高兴,我已经尝试解决这个问题很长时间了。
澄清一下:我的问题是 generatePerlinNoise 方法返回一组数据(2d)数组,该数组生成黑色图像(而不是酷噪声图像)我还认为平滑噪声图像不应该看起来像它们被分割成正方形