2017-06-03 15 views
1

Perlin Noiseの仕組みを説明する2つのチュートリアルがありますが、最初のチュートリアルではわかりにくい勾配の謎が見つかりました.2番目の例ではサーフィスの謎が見つかりました。Perlinノイズの理解

まずケース

最初のチュートリアルはcatlikecoding.com/unity/tutorials/noiseここに位置しています。私たちが行う必要があるのは、ランダムな色のグリッドを描き、次に色の間を補間するだけなので、最初はautorが完全に理解できる値ノイズを説明します。

しかし、Perlin Noiseについては、単一の色ではなく、グラデーションを扱う必要があります。最初は勾配を色として考えるので、2つの勾配があり、それらの間の補間を行いたい場合は、最初の勾配のそれぞれの点を取って、2番目の勾配のそれぞれの点で補間する必要があります。しかし、グラデーションが同じであれば、グラデーションと同じ結果が得られます。

このチュートリアルでは、別の方法で作成します。同じ勾配で塗りつぶされた列からなる1次元グリッドがあり、各勾配は0から1へのトランジションとして表現できます(ここでは0は黒色、1は白色です)。次に著者は言う

すべてのストライプは、オフセット値が であることを除き、すべて同じストライプです。したがって、すべてのt0について、右の勾配は です。t1 = t0-1です。スムーズにそれらを補間しましょう。

だから、私たちが0から1への遷移として表され勾配、および0.1

にそれはすべての勾配を意味から-1の遷移として表されている勾配の間を補間しなければならないことを意味値0の位置で開始せず、値1の位置で停止しません。-1のどこかで開始し、2のどこかで終了します。開始点と終了点がない可能性があります。私たちは0から1の範囲しか見ることができません。なぜこのようなものなのか理解できません。いつ私たちは連続グラデーションのアイデアをとったのですか?私は、すべてのストリップに0から1までのグラデーションしかないと思っていました。それだけです。私は彼がこのように答えたすべてのこれについて著者に尋ね

continuous gradientは右へ

勾配明らかに何かが視覚的に参照されています。次の上位整数の勾配は です。あなたはそれが左に に負になるというのは正しいです。彼らは皆です。

したがって、t0は、左の格子点でゼロである勾配であり、2つの整数の間の領域の側の です。そして、t1は、同じ領域の右側の格子点でゼロの勾配であり、 です。 グラディエントノイズは、格子点間のこれらの2つの勾配の間の補間によって得られます。そしてはい、それは黒くなって 否定結果を生成することができます。そのため、次のステップは、 にスケールし、結果をオフセットすることです。

私はこのことがどういう仕組みか分かりませんので、賢明な人たちの後で信じて繰り返す必要があります。しかし、最後に希望がなくなるので、何とか私に説明してください。

セカンド場合

第二のチュートリアルはここeastfarthing.com/blog/2015-04-21-noise/に位置しており、それははるかに少ない洗練された前のものよりもです。 私が遭遇していた唯一の問題は、私は次の段落を理解することはできませんので、これを与えられたこの

後に何が起こっているのか、私達はちょうどGの方向に集中することができ、常に 単位長ベクトルを使用することです。フォールオフカーネルの積と の積を2×2平方を超えるすべての点で0に固定すると、これはわかりやすい文章に記載されているサーフレット を返します。

私の貧しい数学や英語の知識に問題があるかどうかはわかりませんので、簡単に言えば、実際にはどういう意味なのかを説明してください。ここで

は、私がこれまでに書かれているいくつかのコードですが、それはここで

import sys 
import random 
import math 
from PyQt4.QtGui import * 
from PyQt4.QtCore import pyqtSlot 

class Example(QWidget): 

    def __init__(self): 
     super(Example, self).__init__() 
     self.gx=1 
     self.gy=0 
     self.lbl=QLabel() 
     self.tlb = None 
     self.image = QImage(512, 512, QImage.Format_RGB32) 
     self.hbox = QHBoxLayout() 
     self.pixmap = QPixmap() 
     self.length = 1 
     self.initUI() 

    def mousePressEvent(self, QMouseEvent): 
     px = QMouseEvent.pos().x() 
     py = QMouseEvent.pos().y() 

     size = self.frameSize() 

     self.gx = px-size.width()/2 
     self.gy = py-size.height()/2 

     h = (self.gx**2+self.gy**2)**0.5 

     self.gx/=h 
     self.gy/=h 

     self.fillImage() 

    def wheelEvent(self,event): 
     self.length+=(event.delta()*0.001) 
     print(self.length) 


    def initUI(self):  
     self.hbox = QHBoxLayout(self) 
     self.pixmap = QPixmap() 
     self.move(300, 200) 
     self.setWindowTitle('Red Rock') 

     self.addedWidget = None 

     self.fillImage() 

     self.setLayout(self.hbox) 

     self.show() 

    def fillImage(self): 

     step = 128 
     for x in range(0, 512, step): 
      for y in range(0, 512, step): 

       rn = random.randrange(0, 360) 
       self.gx = math.cos(math.radians(rn)) 
       self.gy = math.sin(math.radians(rn)) 

       for x1 in range(0, step): 

        t = -1+(x1/step)*2 
        color = (1 - (3 - 2*abs(t))*t**2) 

        for y1 in range(0, step): 

         t1 = -1+(y1/step)*2 
         color1 = (1 - (3 - 2*abs(t1))*t1**2) 
         result = (255/2)+(color * color1 * (t*self.gx+t1*self.gy))*(255/2) 
         self.image.setPixel(x+x1, y+y1, qRgb(result, result, result)) 


     self.pixmap = self.pixmap.fromImage(self.image) 

     if self.lbl == None: 
      self.lbl = QLabel(self) 
     else: 
      self.lbl.setPixmap(self.pixmap) 

     if self.addedWidget == None: 
      self.hbox.addWidget(self.lbl) 
      self.addedWidget = True 

     self.repaint() 
     self.update() 


def main(): 

    app = QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main()  

答えて

0
float Noise::perlin1D(glm::vec3 point, float frequency) 
{ 
    // map the point to the frequency space 
    point *= frequency; 

    // get the base integer the point exists on 
    int i0 = static_cast<int>(floorf(point.x)); 

    // distance from the left integer to the point 
    float t0 = point.x - static_cast<float>(i0); 

    // distance from the right integer to the point 
    float t1 = t0 - 1.f; 

    // make sure the base integer is in the range of the hash function 
    i0 &= hashMask; 

    // get the right integer (already in range of the hash function) 
    int i1 = i0 + 1; 

    // choose a pseudorandom gradient for the left and the right integers 
    float g0 = gradients1D[hash[i0] & gradientsMask1D]; 
    float g1 = gradients1D[hash[i1] & gradientsMask1D]; 

    // take the dot product between our gradients and our distances to 
    // get the influence values. (gradients are more influential the closer they are to the point) 
    float v0 = g0 * t0; 
    float v1 = g1 * t1; 

    // map the point to a smooth curve with first and second derivatives of 0 
    float t = smooth(t0); 

    // interpolate our influence values along the smooth curve 
    return glm::mix(v0, v1, t) * 2.f; 
} 

は、問題のコードのコメントバージョンである第二の場合にも関します。しかし、C++のために書き直されました。明らかにすべてのクレジットはcatlikecodingに行きます。

ここでは、関数のポイントをpとしています。さんはPが0.25である場合Pは、例えばので、端数となる点を仮定しましょう、その後Pの左側に整数が0であるとPの右側の整数のがリットルこれらの整数を呼ぶことにしましょう。1.ありますおよびrである。

次にT0はリットルにPからの距離であり、t1はRにPからの距離です。距離は、負の方向に移動してからpに移動する必要があるため、t1では負の値になります。

この実装のパーリンノイズ部分に続く場合、g0とg1は1次元の擬似乱数勾配です。 g0とg1は浮動小数点であるため、勾配は単なる方向であり、ある次元では正または負にしかならないので、これらの勾配は+1と-1です。グラデーションと距離の間にドット積を取るが、一次元ではこれは単純に乗算である。内積の結果は、2つの浮動小数点v0およびv1です。これらは、パーリンノイズ実装の影響値です。最後に、これらの影響値を円滑に補間して、滑らかなノイズ関数を生成します。これが役に立ったら教えてください! This perlin noise explanationはこのコードの理解に非常に役立ちました。

関連する問題