0

わかりましたので、これを見つけまし記事と私はその一部に混乱しています。誰かがこのプロセスをもっと詳しく説明してくれたら、とても感謝しています。なぜなら、私はこれを 2 か月間コード化しようとしてきましたが、まだ正しいバージョンが機能していないからです。私は記事の持続性部分について特に混乱しています。著者がそれについて説明しようとしていることをほとんど理解していないためです。記事の最後で、これの 2D 擬似コード実装について話していますが、PerlinNoise_2D 関数は作成しません。ランダム値が平滑化され補間された後、それは整数値ですが、関数は浮動小数点値を取るので、私には意味がありますか? 持続部分の下にはオ​​クターブ部分があります。彼は平滑化された関数を一緒に「追加」してPerlin関数を取得するため、よくわかりません。あなたは明らかに値を一緒に追加しないので、彼は「追加する」とはどういう意味ですか. 誰かが私にこれらの部分を説明できるなら、私はとても幸せです. ありがとう。

これが私のコードです:

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

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

public static int layers = 3;
public static float[][][][] noise = new float[16][16][81][layers];
public static int[][][][] octaves = new int[16][16][81][layers];
public static int[][][][] perlin = new int[16][16][81][layers];
public static int[][][] perlinnoise = new int[16][16][81];
public static int SmoothAmount = 3;
public static int interpolate1 = 0;
public static int interpolate2 = 10;
public static double persistence = 0.25;

//generate noise
//smooth noise
//interpolate noise
//perlin equation

public TerrainGen() {
    for(int t = 0; t < layers; t++) {
        for(int z = 0; z < 81; z++) {
            for(int y = 0; y < 16; y++) {
                for(int x = 0; x < 16; x++) {
                    noise[x][y][z][t] = GenerateNoise();
                }
            }
        }
    }

    for(int t = 0; t < layers; t++) {
        SmoothNoise(t);
    }

    for(int t = 0; t < layers; t++) {
        for(int z = 0; z < 81; z++) {
            for(int y = 0; y < 16; y++) {
                for(int x = 0; x < 16; x++) {
                    octaves[x][y][z][t] = InterpolateNoise(interpolate1, interpolate2, noise[x][y][z][t]);
                }
            }
        }
    }

    for(int t = 0; t < layers; t++) {
        PerlinNoise(t);
    }
}

public static Random generation = new Random(5);
public float GenerateNoise() {
    float i = generation.nextFloat();
    return i;
}

public void SmoothNoise(int t) {
    //Huge smoothing algorithm
}

//Cosine interpolation
public int InterpolateNoise(int base, int top, float input) {
    return (int) ((1 - ((1 - Math.cos(input * 3.1415927)) * 0.5)) + top * ((1 - Math.cos(input * 3.1415927)) * 0.5));
}

public void PerlinNoise(int t) {
    double f = Math.pow(2.0, new Double(t));
    double a = Math.pow(persistence, new Double(t));
    for(int z = 0; z < 81; z++) {
        for(int y = 0; y < 16; y++) {
            for(int x = 0; x < 16; x++) {
                perlin[x][y][z][t] = (int) ((octaves[x][y][z][t] * f) * a);
            }
        }
    }
}

public static void main(String [] args) {
    JFrame frame = new JFrame();
    frame.setSize(180, 180);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    TerrainGen test = new TerrainGen();
    frame.add(test);
    frame.setVisible(true);
}

public static int size = 5;
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    int i = 0;
    for(int t = 0; t < 9; t++) {
        for(int z = 0; z < 9; z++) {
            for(int y = 0; y < 16; y++) {
                for(int x = 0; x < 16; x++) {
                    g.setColor(new Color(perlin[x][y][i][0] * 10, perlin[x][y][i][0] * 10, perlin[x][y][i][0] * 10));
                    g.fillRect((z * (16 * size)) + (x * size), (t * (16 * size)) + (y * size), size, size);
                }
            }
            i++;
        }
    }
    repaint();
}
}

また、スムージング部分は含めませんでした。これは、チャンク間をスムージングするための約 400 行のコードだったからです。

4

2 に答える 2

1

この記事で永続性と呼ばれるのは、高周波ノイズの振幅が組み合わされたときにどのように「減衰」するかです。

「オクターブ」は、記事がさまざまな周波数でのノイズ関数と呼んでいるものです。

1.0を取り、永続性を繰り返し乗算して、各オクターブを乗算する振幅のリストを取得します。たとえば、永続性が0.8の場合、係数は1.0、0.8、0.64、0.512になります。

ノイズは整数ではありません。彼の関数Noise1は、0..1の範囲のノイズを生成します。つまり、変数nは浮動小数点数を返すInt32ビットです。

入力パラメーターは整数です。つまり、Noise1関数は(1、0)または(2、2)でのみ評価されます。SmoothNoise_1でノイズを少しスムージング/スミアリングした後、値が補間されて中間の値が生成されます。

お役に立てば幸いです!!

于 2012-03-02T21:46:51.707 に答える
0

このループは、2D ノイズからオクターブを作成します。3Dパーリンでも同じループが機能します...

   function octaves( vtx: Vector3 ): float
    {
        var total = 0.0;    
        for (var i:int = 1; i < 7; i ++)//num octaves
        {
            total+= PerlinNoise(Vector3 (vtx.x*(i*i),0.0,vtx.z*(i*i)))/(i*i);
        }

        return total;//added multiple perlins into noise with 1/2/4/8 etc ratios

    }

パーリンを学ぶために私が見た中で最高のものは、次のコードです。ハッシュ テーブルの代わりに、sin ベースの半ランダム関数を使用します。2〜3オクターブを使用すると、高品質のパーリンになります...驚くべきことは、リアルタイムランドスケープでこれを30オクターブ実行しても速度が低下しなかったのに対し、1つのボロノイを1回使用すると速度が低下したことです。だから... 学ぶべき素晴らしいコード。

#ifndef __noise_hlsl_
#define __noise_hlsl_

// hash based 3d value noise
// function taken from https://www.shadertoy.com/view/XslGRr
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// ported from GLSL to HLSL

float hash( float n )
{
    return frac(sin(n)*43758.5453);
}

float noise( float3 x )
{
    // The noise function returns a value in the range -1.0f -> 1.0f

    float3 p = floor(x);
    float3 f = frac(x);

    f       = f*f*(3.0-2.0*f);
    float n = p.x + p.y*57.0 + 113.0*p.z;

    return lerp(lerp(lerp( hash(n+0.0), hash(n+1.0),f.x),
                   lerp( hash(n+57.0), hash(n+58.0),f.x),f.y),
               lerp(lerp( hash(n+113.0), hash(n+114.0),f.x),
                   lerp( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
}

sin は CPU の負荷が高いことに注意してください。代わりに次を使用します。

function hash ( n: float ): float
{//random -1, 1
    var e = ( n *73.9543)%1;
    return  (e*e*142.05432)%2-1;// fast cpu random by me :) uses e*e rather than sin
}
于 2014-02-09T01:01:19.023 に答える