仮眠プログラマーのつぶやき

自分がプログラムやっていて、思いついたことをつぶやいていきます。 2025年からzennに移行

自作ゲームやツール、ソースなどを公開しております。
①ポンコツ自動車シュライシュラー
DOWNLOAD
②流体力学ソース付き
汚いほうDOWNLOAD
綺麗なほうDOWNLOAD
③ミニスタヲズ
DOWNLOAD
④地下鉄でGO
DOWNLOAD
⑤ババドン
DOWNLOAD
⑥圧縮拳(ツール)
DOWNLOAD
⑦複写拳
DOWNLOAD
⑧布シミュレーション
DOWNLOAD
⑨minecraft巨大電卓地形データ
DOWNLOAD
⑩フリュードランダー
デジゲー博頒布α版
DOWNLOAD
⑪パズドラルート解析GPGPU版
DOWNLOAD
⑫ゲーム「流体de月面着陸」
DOWNLOAD

パーリンノイズ

パーリンノイズアルゴリズム 後編

以下の説明は引き続きバリューノイズの説明です。パーリンノイズは近日中にコード載せます

完成系
02c458d3.png

を作るには今まで説明に使ってきたような、テクスチャをいくつか使用して作る方法と、関数のみで作る方法の2種類がある。
関数のみでやる場合、作業用のテクスチャは1バイトも使わなくてすみ、並列処理化が容易であるためGPUでの処理もできる。
関数のみで作る方法は前の記事の外部リンク(リンク)で見ることができた。
自分でもHSPで関数のみのほうのアルゴリズムを作ってみたのだがどっかにやってしまった・・・
結局テクスチャを使うほうが圧倒的に早かったのだ

ちなみに前の前の記事で載せたgifたちは全て完成系を3D展開して、sin やらabsやら1/fの変換をほどこしたものである。
そして3Dのスライス面をgifのフレームに対応させてある

後編というわりに内容がほとんどないけどパーリンノイズの話は終わり
アルゴリズムのアの字も書けなかった・・ソース発見したらはるかも







追記、ソース発見!!

HSPスクリプトエディタに貼りつければ単独実行
(※処理に時間がかかります・・3分とか)

#module

#defcfunc Interpolate double a,double b,double c;aとbのあいだをcos補間で出す(内挿処理)
f = (1.0 - cos(c * 3.1415927)) * 0.5
return a*(1.0-f) + b*f

#defcfunc Noise int x,int y;ただのランダム数値を出す
z=y*9799+(y*y+435547)*(x-904120)*319-8129471
r=(z-32459)*(z+235152)+z+9022093
repeat (abs(z))\19+13+((r\11)*82)\12
r=(r+1114122123)*(r-108612193)+1182655124+r\12392874
loop
return 1.0*(r*(r*r*15731+789221)+1376312589)/2147483647.0

#defcfunc SmoothedNoise int x,int y;ガウシアンフィルタ3*3
return Noise(x, y) / 4+( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8+( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16

#defcfunc InterpolatedNoise double a,double b;加算合成する前の画像のx,yのドット色を出す
integer_X = int(a)
fractional_X = a - integer_X
integer_Y = int(b)
fractional_Y = b - integer_Y
v1 = SmoothedNoise(integer_X, integer_Y)
v2 = SmoothedNoise(integer_X + 1, integer_Y)
v3 = SmoothedNoise(integer_X, integer_Y + 1)
v4 = SmoothedNoise(integer_X + 1, integer_Y + 1)
i1 = Interpolate(v1 , v2 , fractional_X)
i2 = Interpolate(v3 , v4 , fractional_X)
return Interpolate(i1 , i2 , fractional_Y)

#defcfunc pnoise double a,double b;n枚の画像をブレンド率変えて加算合成
persistence=0.6
total = 0.0
p = persistence
n = Number_Of_Octaves@
frequency=1.0
amplitude=0.65
repeat n
total=total+(InterpolatedNoise(a*frequency,b*frequency)) *amplitude
frequency*=2.0
amplitude*=p
loop
return total

#global

;ここまで関数とかの定義

;スクリーンにレンダリング
Number_Of_Octaves=6
ddim k,640,480
screen 0,640,480,0

repeat 640
d=cnt
repeat 480
k.d.cnt=pnoise(0.01*d,0.01*cnt)
a=limit(218.0*(0.5+k.d.cnt),0,255)
color a,a,a
pset d,cnt
loop
loop
;bmpsave "a.bmp"



結果
f61c76fa.jpg 

パーリンノイズアルゴリズム 前編

Perlin noiseのことを最初適当に知ろうと思ってwikipediaをのぞいてみたが、なんかあんま参考にならん・・・ページの下に関連リンクがあったので覗いてみた。

生成方 

KEN 

(2019/12現在リンク切れ)

図やグラフから文章を推測するというなんとも奇妙な解読法で、なんとか理解したような気がした。



実際プログラムするときは上の生成方のHPが参考になった。

ではわかったことだけでもまとめていきたいと思う。


Perlin noise と普通のnoiseの違い (導入)

以下の話は全てパーリンノイズではなくバリューノイズというやつでした。すみませんでした。パーリンノイズは近日中にコード載せます。

定義の話とか面倒なので具体的な話から・・


ノイズ関数とパーリンノイズ関数があったとしよう。


ノイズ関数・・・noise(a)

パーリンノイズ関数・・・Pnoise(a)

 

2つの関数は-100~100までのどれかの整数値を返すとして

aに0,1,2,3,4・・・と代入していき、それぞれの関数からどんな値が返ってくるか。



noise(a)はというと・・・

61,-79,24,-10,-31,95,7,56,-88,-12,8,-47


Pnoise(a)はというと・・

36,22,-19,-14,-45,-50,-38,12,52,59,59,53,69,89



ノイズ完全にランダム。ばらついてる。規則性がない。


パーリンノイズ規則性が見えないけどちょっと連続しているような・・・。ランダムに見えて不自然にばらついてるようなランダムではない。


a(0,1,2,3…)に、関数の返り値に取ったグラフが下だ。
 



noise(a) の値

31b08ed0.png 

Pnoise(a)の値

e8644708.png

こうやって見ると一目瞭然である!
(もしや・・・Pnoise(a)は、グラフの微分係数をランダムな値にすればできるのでは?って思うかもしれないけどそうでもない!ま、具体的なPnoise(a)関数の生成方は後にして・・・)


パーリンノイズの特徴はなんといっても、山の起伏のような、自然なばらつきがある雰囲気を出せることなのだ。


このPnoise(a)関数を使えば年輪などの模様ゆらぐようなテクスチャを作れるって言う、ちょっと想像もつかないような話なのだが、本当だ。




Perlin noiseの原理

バリューノイズの原理!


まずいきなり完成系の画像をお見せしよう!

02c458d3.png



これは以下のように作る


一番左の画像=ぼかす前&拡大前


0d6d9c92.jpg

80db9bc1.jpg


画像×6枚は、単にランダムな濃さの点を打って作成したノイズ画像である。


ただし6枚それぞれが、ドットの数というかスケールが違うのだ。



上から256ドット四方、128、64、32、16とスケールが2分の1ずつ小さくなっている。



なので一番左の画像枚数のことをオクターブと呼ぶ。


今回は6枚なので6オクターブと言うことになる。普通5~6である。


あまり少なくしても、細部のスケールが表現できなかったりするし、大きすぎても処理時間がかかるだけなので・・・



ぼかす処理はガウスぼかし等で。そしてぼかし終わった後できた256ドット四方の6枚の画像を加算合成するのだが、普通加算するときにブレンド率にpersistence(振幅の変化)を掛けて加算する必要がある。


つまり左の自家製の汚いイメージ図で言うと、上のほうの画像を弱く、下のほうの画像を強くして加算合成することで完成系ができあがるのだ。


「最初一番小さくて一番拡大する画像ほどpersistenceは大きく、一番拡大しない画像ほどpersistenceを小さくして加算することが重要!」



具体的に言うと、拡大しない画像ほどブレンド率2分の1ずつに減っていくのが理想の形!


上の画像は1.8分の1なので約2分の1と言える。


次回:パーリンノイズアルゴリズム 後編

パーリンノイズの幻想的なアニメーション

※2019/12追記:ここで言うパーリンノイズは実は全部バリューノイズというものでした。でも似てるから許して

前回パーリンノイズの生成方の記事を書くといいつつも、地獄のような多忙の日々で全く記事がかけない状況が続いているので、せめて完成系のものだけでもUPしようと思います。。。m(_ _ )m

以下のものは全部プログラムで作られているので、色や大きさ、速度、濃度などの変更が簡単にできます!
 
またパーリンノイズでできた画像はつなぎ目が不自然にならないので縦横にいくつもつなげられますし、gifアニメを見ればわかるとおりループするとき全くフレームが違和感なくつながります!

abbf4e9d.gif

b3574caf.gif

5ce6df29.gif

2a89c817.gif

bc5d2f3a.gif

32df126a.gif

a4525e19.gif

4c2fdd15.gif

d2df5b89.gif

925d0438.gif

03a7de4f.gif

8ad62a10.gif

f425dee8.gif

4c97c4ec.gif

ea27e1f3.gif

60d47c8b.gif

3d223719.gif

1ec1a2db.gif

ef8f7acd.gif

4503dad8.gif

8239754a.gif

7b528b9f.gif

aa342e75.gif

d6503199.gif

592770a5.gif

5ddb448d.gif

fd28b01b.gif

c107f416.gif

43925ce8.gif

34690c64.gif

e0f4bec8.gif

cc4b314f.gif

気もちわる!!って思うかもしれないですが、これは悪魔で雲や炎にたどり着く手前の計算途中の画像のようなもんです。さっきの完成系ってのはこりゃ嘘w

(ちなみに基本形となるのは一番上のgifです)



きれいな雲、炎の表現のためには、これらできた画像にlogなどさらなる操作を加えそれっぽくみせる必要があるのです。

年輪の表現だと定数で割った余りだけを抽出とか





「アニメーション画像」の作成のみならず、静止画、3Dモデリングで山の起伏の形状の作成などにもパーリンノイズは使えます!


パーリンノイズとは

最近まともなプログラムの技術解説をして来なかったけど、やっと新しい技術関連記事を書く気になったこのごろ・・
初期と比べ技術解説もマイナーな方向に行き、だんだん自分がマニアックな方向に進んでいくのがわかる・・


そして次の記事では「パーリンノイズ」について書いていこうと思う。

これはなんというか、あまりにマニアックすぎて解説HPが英語のサイトしかないようなものであるが(wikipediaにも詳しくのってない)、その英語のサイトを高1までの知識で無理やり解読したところ、これは意外と需要があるのではないかと思い自分なりにまとめて書いてみようと思った。


まずパーリンノイズというマニアックなコンピューターグラフィックス作成技法にたどり着いたわけを説明しよう。

プログラムだけでリアルな雲、炎の再現に挑戦しようとしたのがことの発端。

本来の科学的手法ならリアルな雲や炎を作るには流体方程式や乱流方程式をコンピューターにとかせるという、アマチュアプログラマーにとっては物凄く難しい課題があったわけだが、それをしなくても擬似的にそれっぽく見せる方法があって、それもかなり簡単なプログラムでできるというのだ

それがパーリンノイズ・・

これで作られる画像は自然界にある雲に似ていて、ほかにもパーリンノイズを使えば、「年輪」の表現や、大理石の幾何学模様が簡単に作れてしまうと言う!

ほかにもフラクタル平面とかいうのと関係あるらしい
ランダムな高低差の山を作れたり、パーリンノイズで作った画像は連番アニメーションにしても縦横につなげてもつなぎ目が全く気にならないなど、いろいろな使い方ができるのだ!



もともとグラフィックの画力が極端にない私はプログラムでエフェクト画像を生成することが多く、パーリンノイズを使えば作れる画像がさらに飛躍的に多くなるってことで、興味がわいた訳だ。

プログラムの中でも四則演算と画像処理の分野は自分の十八番で、ひとまずパーリンノイズは画像処理のアルゴリズムとして自分で極めたいというのがあるので、次の記事では徹底的に細かいところまで書いていこうと思う・・・。

レイトレーシングとパーリンノイズの組み合わせなんてのも考えてみたのでそれもCG画像がうまく作れたらUPしたいと思っている。

次回のパーリンノイズの技術解説の記事では、「自分の全ての知識が詰まっていると言っても過言ではない」って言えるくらいに頑張って書いていきたい!

※2019/12、今まで自分がパーリンノイズだったと思っていたものがバリューノイズというものであると知りました。適宜記載修正しました。

プロフィール

toropippi

記事検索
アクセスカウンター

    QRコード
    QRコード
    • ライブドアブログ