2012-03-02 2 views
0

Хорошо, поэтому я нашел this статью, и я смущен некоторыми ее частями. Если кто-то может объяснить этот процесс более подробно, я бы очень признателен за это, потому что я пытался это сделать уже 2 месяца и до сих пор не получил правильную версию. Я определенно запутался в частичности Персистентности, потому что я в основном не понимаю, что автор пытается объяснить об этом, а в нижней части статьи он говорит о реализации 2D-псевдокода, но функция PerlinNoise_2D не делает для меня, потому что после того, как случайное значение сглажено и интерполировано, это целочисленное значение, но функция принимает значения float? Под участком персистентности находится часть октавы. Я не совсем понимаю, потому что он «добавляет» сглаженные функции вместе, чтобы получить функцию Perlin. Что он подразумевает под «добавляет», потому что вы, очевидно, не добавляете значения вместе. Поэтому, если кто-нибудь сможет объяснить эти части мне, я был бы очень счастлив. Благодарю.Perlin Noise Assistance

Вот мой код:

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 строк кода, чтобы сгладить между кусками.

+0

Вы действительно врач * и * профессор? –

+0

..... спасибо за помощь ... hahaha – MrDrProfessorTyler

ответ

1

То, что статья называет упорством, заключается в том, как амплитуда высокочастотных шумов «падает», когда они объединены.

«октавы» - это именно то, что статья называет шумовыми функциями на разных частотах.

Вы принимаете 1.0 и многократно умножаетесь настойчивость, чтобы получить список амплитуд, чтобы умножить каждую октаву на, например. постоянство 0,8 дает факторы 1,0, 0,8, 0,64, 0,512.

Шум не является целым числом, его функция Noise1 производит шум в диапазоне 0..1 - то есть переменная n является битом Int32, который возвращает float.

Входные параметры являются целыми числами, то есть функция Noise1 является только оценена по адресу (1, 0) или (2, 2). После сглаживания/размазывания шума в SmoothNoise_1 значения получают интерполяцию для получения значений между ними.

Надеюсь, что помогло!

+0

И частота просто умножается на 2 каждый раз? – MrDrProfessorTyler

+0

Да, но, наверное, неважно, если бы вы использовали другие факторы для повышения частоты. –

+0

Хорошо спасибо и еще 1 или 2 вопроса ... В каком порядке идет этот процесс? Генерировать шум, плавно, интерполировать, затем использовать уравнение перлина или что-то еще? – MrDrProfessorTyler

0

Эта петля делает октавы от 2d шума. такой же цикл будет работать для 3d perlin ...

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 

    } 

Лучшая вещь, которую я видел для изучения perlin, - это следующий код. вместо хэш-таблиц он использует полуслучайную функцию на основе греха. используя 2-3 октавы, он становится высококачественным перлином ... удивительная вещь заключается в том, что я управлял 30 октавами этого в реальном времени и не замедлялся, тогда как я использовал 1 voronoi один раз, и это замедлялось. так что ... удивительный код, чтобы учиться.

#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); 
} 

отмечают, что грех дороже на 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 
} 
Смежные вопросы