質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

Q&A

解決済

1回答

849閲覧

パーリンノイズで -1 ~ 1までの範囲にするわけ

apa

総合スコア68

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

0グッド

0クリップ

投稿2020/10/31 16:01

float2 ivec = floor(vec);
float2 fvec = frac(vec);

float a = dot(Random(ivec + float2(0.0, 0.0)) * 2.0 - 1.0, fvec - float2(0, 0)); float b = dot(Random(ivec + float2(1.0, 0.0)) * 2.0 - 1.0, fvec - float2(1, 0)); float c = dot(Random(ivec + float2(0.0, 1.0)) * 2.0 - 1.0, fvec - float2(0, 1)); float d = dot(Random(ivec + float2(1.0, 1.0)) * 2.0 - 1.0, fvec - float2(1, 1)); fvec = smoothstep(0.0, 1.0, fvec); return lerp(lerp(a, b, fvec.x), lerp(c, d, fvec.x), fvec.y);

昔拾ってきたパーリンノイズ作成の処理です(Randomは 0 ~ 0.99までの2次元ベクトル(少数)を返す)
このまま rgb にreturnしてあげた座標を入れてあげると
パーリンノイズが生成されるのですが、*2.0 - 1.0の処理がどうしてもわかりません。
この処理自体は0 ~ 1までの値を -1 ~ 1までにclampしてあげる感じだと思うのですが、
それをするメリットがわかりません
どういった意味があるのでしょうか?
わかる方いらっしゃりましたら是非教えていただきたいです。
イメージ説明) ← * 2.0 - 1.0あり
イメージ説明 ← * 2.0 - 1.0なし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

* 2.0 - 1.0 の処理を行わない場合、 dot 関数の第一引数のベクトルの角度は、x, yが共に0以上のため、第一象限に存在することになります。
一方で、第二引数のベクトルの角度は、それぞれ入力座標の近傍格子点からのベクトルなので、第一~第四象限に1つずつ存在することになります。

角度が第一象限にあるベクトル同士の角度の差は必ず90°以下なので、内積をとると0以上になります。
また、角度が第一象限にあるベクトルと第三象限にあるベクトル同士の角度の差は必ず90°以上なので、内積は0以下になります。

つまり、これによって、aは常に0以上で、dは常に0以下であることが確定してしまいます。また、b, cに関しては、角度が90°に近い確率が高くなることで、内積が0に近い値になる可能性が高くなります。
このような偏りがあると結果に影響が現れます。実際、添付画像の二枚目は、よく見ると格子状のパターンが現れています。

どの格子点から見ても均等になるようにするには、ランダムなベクトルと格子点から見た入力座標のベクトルの差が一様になる必要があり、x,y座標が-1~1の範囲に一様分布するように乱数を生成すると、ランダムな点が第一~第四象限に均等に現れるため、このような偏りがなくなります。

投稿2020/11/02 06:15

kazatsuyu

総合スコア158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

apa

2020/11/02 11:40

返信ありがとうございます なるほどだいぶ理解できました! あともう一つだけ聞きたいのですが、 この内積ってそのピクセルから見た影響度って認識で大丈夫なのでしょうか?
kazatsuyu

2020/11/03 03:03

うーん、回答は数式から読み取れることを書いただけなので、パーリンノイズそのものに詳しい訳ではないのですが、影響度と言うなら線形補間をしている部分で算出しているのではないでしょうか? 格子点から遠い点ほど、線形補間によって影響は少なくなるはずです。 一方で、ある格子点に近ければ近いほど格子点からの距離ベクトルは小さくなり、内積は0に近づくので、格子点上のピクセルは常に0ということになり、影響度で言うのなら近ければ良いというものでもないですね。 周囲の4つの格子点からもっとも遠い点(つまり4つの点の中心)は線形補間の影響により4点から等しく影響を受け、そこから任意の格子点に近づけば近づくほど0に近づいて行くので、任意の格子点のベクトルから最も影響されるのはその中間点ということになりそうです(具体的にどこになるかはsmoothstep関数の形によりそう) ところで書いていて気づいたのですが、このソースでreturnされる値は[-1, 1]になるので、単純に黒から白で表現するなら[0, 1]の範囲に収まるように * 2 - 1 の逆をやらなければいけないのではないでしょうか。どうも添付画像がやたら黒い気がしていました。
apa

2020/11/03 07:16

あ~たしかになんか黒いと思ったら -1~1を出力してしまっていたみたいですね *0.5+0.5で補正しておきます 内積はなにかつかめそうな感じなので、もう少し瞑想してみます ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問