パストレーシング
TRANSCRIPT
![Page 1: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/1.jpg)
パストレーシング
渡部 心 @Shocker_0x15
レイトレ合宿3!!! 2015/08/29-30 https://sites.google.com/site/raytracingcamp3/
PATH TRACING
![Page 2: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/2.jpg)
レンダリング方程式 Lo(x, ��o) = Le(x, ��o) +
�
S2Li(x, ��i)fs(x, ��i, ��o) |�n · ��i| d��i
モンテカルロ積分
�Lo(x, ��o)� = Le(x, ��o) +Li(x, ��i)fs(x, ��i, ��o) |�n · ��i|
p�(��i)
: ランダムにサンプルされた入射方向 ��i
p�(��i) : をサンプルするPDF ��i
![Page 3: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/3.jpg)
入射方向を確率的にサンプル、光源に当たれば寄与を計算 視点から光輸送経路をトレース
![Page 4: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/4.jpg)
入射方向のサンプリング
Diffuse BSDF Glossy BSDF Specular BSDF
どの方向も似たような値 鏡面反射方向の 周囲に大きな値
鏡面反射方向以外の 値はゼロ
少なくともBSDFが大きな値を持つ方向を 多くサンプルするのが望ましいàBSDFの重点的サンプリング
![Page 5: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/5.jpg)
for (int j = 0; j < ImageHeight; ++j) { for (int i = 0; i < ImageWidth; ++i) { px = i + rnd01(); py = j + rnd01(); ray, We, dirPDF = sampleCameraRay(px, py); alpha *= We / dirPDF;
// シーンと交叉判定 hit, surfPt = intersect(ray); if (!hit) break;
while (true) { ... ray = Ray(surfPt.p, dir);
// シーンと交叉判定 hit, surfPt = intersect(ray); if (!hit) break;
// Russian Roulette if (rnd01() >= ProbRR) break; alpha /= ProbRR; } }
}
// 光源にヒットした場合、寄与を蓄積 if (surfPt.isEmitting()) contribution += alpha * surfPt.Le(-ray.dir); // BSDFの重点的サンプリング fs, dir, dirPDF = surfPt.BSDF.sample(rnd01(), rnd01()); alpha *= fs * absDot(surfPt.n, dir) / dirPDF;
レンダリング方程式そのまま Li(x, ��i)fs(x, ��i, ��o) |�n · ��i|
p�(��i)
![Page 6: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/6.jpg)
入射方向を確率的にサンプル、光源に当たれば寄与がとれる 視点から光輸送経路をトレース
なかなか当たらない!(特に光源が小さいとき)
![Page 7: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/7.jpg)
NEXT EVENT ESTIMATION!
![Page 8: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/8.jpg)
NEXT EVENT ESTIMATION
光源上の点を明示的にサンプル、視線経路と接続する
![Page 9: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/9.jpg)
for (int j = 0; j < ImageHeight; ++j) { for (int i = 0; i < ImageWidth; ++i) { px = i + rnd01(); py = j + rnd01(); ray, We, dirPDF = sampleCameraRay(px, py); alpha *= We / dirPDF;
// シーンと交叉判定 hit, surfPt = intersect(ray); if (!hit) break;
while (true) { ...
// BSDFの重点的サンプリング fs, dir, dirPDF = surfPt.BSDF.sample(rnd01(), rnd01()); alpha *= fs * absDot(surfPt.n, dir) / dirPDF;
ray = Ray(surfPt.p, dir);
// シーンと交叉判定 hit, surfPt = intersect(ray); if (!hit) break;
// Russian Roulette if (rnd01() >= ProbRR) break; alpha /= ProbRR; } }
}
// 光源上の点を明示的にサンプリングして現在の点と接続 lightSurfPt, lightPDF = sampleLightPoint(rnd01(), rnd01()); if (unoccluded(surfPt, lightSurfPt)) { shadowDir = normalize(lightSurfPt.p – surfPt.p); fs = surfPt.BSDF.eval(shadowDir, -ray.dir); G = absDot(surfPt.n, shadowDir) * absDot(lightSurfPt.n, shadowDir) / sqDistance(surfPt.p, lightSurfPt.p); contribution += alpha * fs * lightSurfPt.Le(-shadowDir) * G / lightPDF; }
シャドウレイを飛ばして 遮蔽をチェックする
![Page 10: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/10.jpg)
???
![Page 11: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/11.jpg)
// 光源上の点を明示的にサンプリングして現在の点と接続 lightSurfPt, lightPDF = sampleLightPoint(rnd01(), rnd01()); if (unoccluded(surfPt, lightSurfPt)) { shadowDir = normalize(lightSurfPt.p – surfPt.p); fs = surfPt.BSDF.eval(shadowDir, -ray.dir); G = absDot(surfPt.n, shadowDir) * absDot(lightSurfPt.n, shadowDir) / sqDistance(surfPt.p, lightSurfPt.p);
contribution += alpha * fs * lightSurfPt.Le(-shadowDir) * G / lightPDF; }
これは何?
cos項2つと距離の二乗 確かにそれっぽい項だが...
レンダリング方程式にそんな項あったっけ??
![Page 12: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/12.jpg)
...無い cos項ひとつだし距離二乗も無い
Lo(x, ��o) = Le(x, ��o) +�
S2Li(x, ��i)fs(x, ��i, ��o) |�n · ��i| d��i
![Page 13: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/13.jpg)
単位の話
![Page 14: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/14.jpg)
確率に単位は無いが確率密度(PDF)には単位がある
�Lo(x, ��o)� = Le(x, ��o) +Li(x, ��i)fs(x, ��i, ��o) |�n · ��i|
p�(��i)
BSDFのサンプリングでは入射方向をサンプリング 方向(立体角)に関するPDF
[sr�1]Next Event Estimationでは光源上の位置をサンプリング
物体表面上の位置に関するPDF [m�2]
![Page 15: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/15.jpg)
位置に関するサンプリングでは レンダリング方程式の形が若干変わる
Lo(x�x��) = Le(x�x��) +�
MLi(x��x)fs(x��x�x��)G(x�x�)dA
x��
x�
x�
x
積分項はシーン中の物体表面 上の積分として変形される M
幾何項 は積分の変数変換の結果(ヤコビアン) G
![Page 16: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/16.jpg)
BSDFのサンプリング Next Event Estimation
ただしNext Event Estimationが逆効果になることも...
![Page 17: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/17.jpg)
MULTIPLE IMPORTANCE SAMPLING!多重重点的サンプリング
![Page 18: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/18.jpg)
Light
光沢BSDF
BSDFの寄与に沿った重点的サンプリング
BSDF寄与に沿って入射方向サンプル:高い確率で高い寄与 à低い分散(光源が良い場所にあれば)
�C� =1N
N�
i=1
f(x̄i)pBSDF (x̄i)
![Page 19: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/19.jpg)
Light
拡散BSDF
BSDFの寄与に沿った重点的サンプリング
BSDF寄与に沿って入射方向サンプル:低い確率で高い寄与 à高い分散(たまにしか当たらないため)
�C� =1N
N�
i=1
f(x̄i)pBSDF (x̄i)
![Page 20: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/20.jpg)
Light
拡散BSDF
光源上の位置の重点的サンプリング
光源上の位置をサンプルして接続:高い確率で高い寄与 à低い分散(BSDFの値が比較的一様であれば)
�C� =1N
N�
i=1
f(x̄i)plight(x̄i)
![Page 21: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/21.jpg)
Light
光沢BSDF
光源上の位置の重点的サンプリング
光源上の位置をサンプルして接続:低い確率で高い寄与 à高い分散(BSDFの値が非一様なため)
�C� =1N
N�
i=1
f(x̄i)plight(x̄i)
![Page 22: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/22.jpg)
光源面のサンプリング BSDFのサンプリング n VEACH, E. 1997. Robust Monte Carlo methods for light transport simulation. PhD thesis, Stanford, CA, USA.!
![Page 23: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/23.jpg)
多重重点的サンプリング
�C� =1N
N�
i=1
f(x̄light,i)plight(x̄light,i)
�C� =1N
N�
i=1
f(x̄BSDF,i)pBSDF (x̄BSDF,i)
�C� =1N
N�
i=1
�wBSDF (x̄BSDF,i)
f(x̄BSDF,i)pBSDF (x̄BSDF,i)
+ wlight(x̄light,i)f(x̄light,i)
plight(x̄light,i)
�
![Page 24: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/24.jpg)
MISウェイト
バランスヒューリスティック
�C� =1N
N�
i=1
�wBSDF (x̄BSDF,i)
f(x̄BSDF,i)pBSDF (x̄BSDF,i)
+ wlight(x̄light,i)f(x̄light,i)
plight(x̄light,i)
�
wBSDF (x̄) =pBSDF (x̄)
pBSDF (x̄) + plight(x̄)wlight(x̄) =
plight(x̄)pBSDF (x̄) + plight(x̄)
![Page 25: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/25.jpg)
バランスヒューリスティック:要するに
BSDF 「パス持ってきたよ」
「推定結果に自信のほどは」
BSDF 「3」
「lightが仮にこのパスつくったなら自信は」
light 「8」
「じゃあBSDFが持ってきたパスの重みは 3 / (3 + 8)ってことで」
light 「パス持ってきたよ」
「推定結果に自信のほどは」
light 「8」
「BSDFが仮にこのパスつくったなら自信は」
BSDF 「3」
「じゃあlightが持ってきたパスの重みは 8 / (3 + 8)ってことで」
![Page 26: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/26.jpg)
MISによるウェイト配分 Multiple Importance Sampling n VEACH, E. 1997. Robust Monte Carlo methods for light transport simulation. PhD thesis, Stanford, CA, USA.!
![Page 27: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/27.jpg)
for (int j = 0; j < ImageHeight; ++j) { for (int i = 0; i < ImageWidth; ++i) { px = i + rnd01(), py = j + rnd01(); ray, We, dirPDF = sampleCameraRay(px, py); alpha *= We / dirPDF; hit, surfPt = intersect(ray); if (!hit) continue;
while (true) { ...
// BSDFの重点的サンプリング fs, dir, dirPDF = surfPt.BSDF.sample(rnd01(), rnd01()); alpha *= fs * absDot(surfPt.n, dir) / dirPDF;
ray = Ray(surfPt.p, dir);
hit, surfPt = intersect(ray); if (!hit) break; ...
// Russian Roulette if (rnd01() >= ProbRR) break; alpha /= ProbRR; } }
}
// 光源上の点を明示的にサンプリングして現在の点と接続 lightSurfPt, lightPDF = sampleLightPoint(rnd01(), rnd01()); if (unoccluded(surfPt, lightSurfPt)) { shadowDir = normalize(lightSurfPt.p – surfPt.p); cosShd = absDot(surfPt.n, shadowDir); cosLight = absDot(lightSurfPt.n, shadowDir); dist2 = sqDistance(surfPt.p, lightSurfPt.p);
fs = surfPt.BSDF.eval(shadowDir, -ray.dir); G = cosShd * cosLight / dist2;
// 単位をlightPDFに合わせる。 bsdfPDF = surfPt.BSDF.evalDirectionalPDF(shadowDir, -ray.dir) * cosLight / dist2; MISWeight = lightPDF / (bsdfPDF + lightPDF);
contribution += alpha * MISWeight * fs * lightSurfPt.Le(-shadowDir) * G / lightPDF;
}
Next Event Estimation + MISウェイト
![Page 28: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/28.jpg)
for (int j = 0; j < ImageHeight; ++j) { for (int i = 0; i < ImageWidth; ++i) { px = i + rnd01(), py = j + rnd01(); ray, We, dirPDF = sampleCameraRay(px, py); alpha *= We / dirPDF; hit, surfPt = intersect(ray); if (!hit) continue;
while (true) { ...
// BSDFの重点的サンプリング fs, dir, dirPDF = surfPt.BSDF.sample(rnd01(), rnd01()); alpha *= fs * absDot(surfPt.n, dir) / dirPDF;
ray = Ray(surfPt.p, dir);
hit, surfPt = intersect(ray); if (!hit) break; ...
// Russian Roulette if (rnd01() >= ProbRR) break; alpha /= ProbRR; } }
}
// 光源にヒットした場合、寄与を蓄積 if (surfPt.isEmitting()) { cosLight = absDot(ray.dir, surfPt.n); dist2 = sqDistance(ray.org, surfPt.p); bsdfPDF = dirPDF; // 単位をbsdfPDFに合わせる。 lightPDF = surfPt.evalAreaPDF() * dist2 / cosLight; MISWeight = bsdfPDF / (bsdfPDF + lightPDF); contribution += alpha * MISWeight * surfPt.Le(-ray.dir); }
BSDF Sampling + MISウェイト
![Page 29: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/29.jpg)
DEPTH OF FIELD!被写界深度
![Page 30: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/30.jpg)
薄レンズモデルを用いたDoF表現
理論・手順の詳細はWEBページ参照 端的に述べると…
xpx0
x�1
x1
x0
xp x�1
シーン中の位置
センサー面 物面
レンズ上の1点 をサンプル、 ピクセル中の位置 に対応する物面上の点 に向かってレイトレース レンズ位置のサンプルを行っているのでPDF で寄与を割る pA(x0)
![Page 31: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/31.jpg)
実装すると…
ピンホール 薄レンズモデルによるDoF
![Page 32: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/32.jpg)
ちゃんとボケてるみたいだけど ピンホールと明るさ違うし、
レンズの大きさによって明るさ変わる…
現実のカメラと一緒 レンズが大きければ取り入れる光の量が増えて明るくなる
à画像の明るさを一定に保ちたいのなら センサーの感度を変更する必要がある
![Page 33: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/33.jpg)
センサーの感度を適切に設定すると…
ピンホール 薄レンズモデルによるDoF
![Page 34: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/34.jpg)
ちょっと待て
![Page 35: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/35.jpg)
ピンホールカメラは薄レンズモデルで レンズが極限に小さい場合と捉えることができる
àPDFの値が無限となるので、PDFで割ると結果はゼロ
レンズが大きい程画像が明るいのは当たり前 じゃあピンホールカメラの画像は真っ暗なのでは…?
ある意味正解
初歩的なパストレ等の実装では そもそもレンズ面のPDFで割ったりしていない
àPDFをキャンセルするだけの 無限のセンサー感度があるのと等しい
![Page 36: パストレーシング](https://reader034.vdocuments.site/reader034/viewer/2022042723/586f71541a28ab10258b4ee9/html5/thumbnails/36.jpg)
おしまい IBLとか色々話したかったけど そのうちWEBページに書きます...
http://www35.atpages.jp/shocker/memoRANDOM/CG/CG.php