【GLSL】ホワイトノイズ

GLSL,ノイズ

3年ぶりのブログ更新。
元気いっぱいゲームやってました。

おひさしぶりです

最近またGLSLのお勉強を再開しました。久しぶりという事で、まずはホワイトノイズのお勉強です。

ホワイトノイズとは

各ピクセルに独立したランダムな値を割り当てて作るノイズです。

こんなの。テレビの砂嵐みたいな感じですね。

コード

uniform vec2 uResolution; // ウィンドウの幅と高さ
out vec4 fragColor; // 最終的なピクセルの色

// 乱数を生成する関数
float rand(vec2 p) {
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}

// メイン関数
void main(void) {
  vec2 pos = gl_FragCoord.xy / uResolution.xy; // 0.0~1.0に正規化
  float color = rand(pos);
  fragColor = vec4(vec3(color), 1.0);
}

まずは乱数を生成する関数rand()を作ります。

2つのベクトルの内積を求めてサインを求めてそれになんか掛けてそれの小数部分を返す!素晴らしいですね。

12.9898とか78.233とか43758.5453とかが気になります。何か意味があるのかなぁと思ってChatGPTに聞いてみたところ、

特別な意味を持つ値ではなく、経験的に「うまく機能する」値として選ばれている からです。
これらの値は、規則的なパターンを生じにくく、見た目がランダムに近くなるように選ばれた ものです。

ChatGPTより

だそうです。とりあえずこの数字を使っておけばイイ感じになるようです。

ゴチャゴチャと計算していますが、最後にfract()を使っているので0.0以上1.0未満の数値が返ってきます。それをfragColorに渡してあげるとホワイトノイズのできあがりです。

座標は正規化した方が良い

rand()に直接gl_FragCoordを渡してもホワイトノイズができます。が、座標の数値が大きすぎるとsin()の精度が落ちることがあるようです。そのせいで、もっと滑らかなノイズを作ろうとした時にうまくいかないこともあるとか。あと、正規化していないと画面解像度が変わったときにノイズのパターンが変わってしまいます。そんなワケで座標は正規化した方が良い。

あとがき

久しぶりという事でまずは簡単なものから。ずっとストリートファイター6やってたのですっかり忘れてしまいました。ゆっくりと思い出しながらプログラミングの勉強していこうと思います。スト6も頑張ります!ありがとうございました!

おしゃれ度

★☆☆☆☆

Posted by ナカタ