プロシージャルノイズ

実行結果

今回のサンプルの実行結果

動的なノイズ生成

今回のテキストでは、当サイトオリジナルのライブラリ noiseX.js を使ったプロシージャルなノイズ生成を解説します。

WebGL に限らず、リアルタイム 3D プログラミングの世界では、様々な場面でノイズが利用されています。たとえば、雲や霧の描画であったり、岩の表面の細かな凹凸であったり、枚挙には暇がありません。

noiseX.js は、動的にノイズ生成を行い、それを HTML の canvas エレメントとして出力することができます。一度 canvas に出力することさえできてしまえば、そこから WebGL 側でテクスチャとして利用することが可能になります。

今回のサンプルは非常にシンプルなもので、HTML 上に、生成したノイズを出力した canvas を埋め込むだけです。HTML 内では事前に noiseX.js を読み込んでおく必要がありますので注意しましょう。

それでは大した内容でもないので、サクッとソースを見てみます。

サンプルの HTML ソース

<html>
	<head>
		<script src="noiseX.js" type="text/javascript"></script>
		<script type="text/javascript">
			var octave = 5;
			var offset = 3;
			var persistence = 0.5;
			var baseWidth = Math.pow(2, octave + offset);
			var n = new noiseX(octave, offset, persistence);
			n.setSeed(new Date().getTime());

			onload = function(){
				var i, j;
				var canvas;
				var noiseColor = new Array(baseWidth * baseWidth);
				for(i = 0; i < baseWidth; i++){
					for(j = 0; j < baseWidth; j++){
						noiseColor[i * baseWidth + j] = n.noise(i, j);
					}
				}
				canvas = n.canvasExport(noiseColor, baseWidth);
				document.body.appendChild(canvas);
			};
		</script>
		<style type="text/css">
			canvas {
				margin: 5px;
			}
		</style>
	</head>
	<body>
	</body>
</html>

ポイントは、オクターブやオフセットを正しくセットしておくことです。今回のサンプルでは最終的に出力される canvas のサイズは、一辺が 256 ピクセルになります。オクターブとオフセットを合計すると 8 という数値が得られますが、2 の 8 乗が 256 となり Math.pow(2, オクターブ + オフセット) = 一辺のサイズ という式が成り立っていることがポイントです。

一辺のサイズがもっと大きなノイズテクスチャがほしい場合には、オクターブかオフセットの数値を修正すればいいですね。もちろん、サイズが大きくなればなるほど生成に掛かる時間や負荷は大きくなりますので注意してください。

サンプルの大まかな流れは、まず noiseX オブジェクトのインスタンスを生成してから、現在の時刻をシード値にセットします。これだけで、noiseX.js 側の初期化は終わりですね。

続いて onload イベントには、実際にノイズを生成する一連のコードを記述します。

サンプル中の baseWidth という変数が、今回出力する canvas の一辺のサイズです。これを 2 乗した数値と同じインデックス数を持つ配列を用意したら、あとはその配列の各要素に noise メソッドを使って値を格納していきます。これで canvas 上の全てのピクセルの色情報が取得できますので、あとは canvasExport メソッドを使って canvas エレメントを取得します。

最後に、HTML へ該当の canvas エレメントを埋め込めば完了ですね。

noiseX.js の詳細なリファレンスは別途用意してありますので、メソッドの役割がよくわからない場合には、そちらを参考にしてみてください。

参考:noiseX.js リファレンス

実際に動作するサンプルは、以下のリンクから参照できます。環境によっては若干重いかもしれませんが、生成するノイズは 256 ピクセル幅なので、それほど負荷は大きくならないと思います。

entry

PR

press Z key