問題 3.4
計算
3_1_vnoiseGrad.frag では、関数 vnoise21()
を数値微分して勾配を求めていたが、この演習問題では、同関数を解析微分することで、勾配を求めてみたい。
まず、関数 vnoise21()
の内部を改めて確認すると、与えられた2次元ベクトルp
に対し、p
から生成される4つのハッシュ値(v[0], v[1], v[2], v[3]
)およびエルミート補間関数で補間された各次元ごとの値(f[0], f[1]
)を使って、以下の値を返すものである。
return mix(mix(v[0], v[1], f[0]), mix(v[2], v[3], f[0]), f[1]);
以降でこれを数式で表記するため、以下の様に置き換えて考えることにする。
vnoise21(p)
関数:- 4つのハッシュ値(
v[0], v[1], v[2], v[3]
): - エルミート補間関数:
さて、 の実装を素直に数式で表現すると、
である。この(ex3.4.1)式の右辺に登場する を計算しておくと
となるので、改めて(ex3.4.1)式と(ex3.4.2)式より は以下の様に記述することができる。
ただし、ここで
である
さて、この を , でそれぞれ偏微分すると、
となる。 つまり、(ex3.4.3)式の , , とエルミート関数 およびその導関数 を用いれば、勾配 は
と表現できることがわかった。
確認
上記で得られた勾配をプログラムで実装したい。 なお、エルミート関数の導関数が以下であることを利用している。
exercise_3_4.frag