パストレーシング

36
パストレーシング 渡部 心 @Shocker_0x15 レイトレ合宿3!!! 2015/08/29-30 https://sites.google.com/site/raytracingcamp3/ PATH TRACING

Upload: shin-watanabe

Post on 06-Jan-2017

3.861 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: パストレーシング

パストレーシング

渡部 心 @Shocker_0x15

レイトレ合宿3!!! 2015/08/29-30 https://sites.google.com/site/raytracingcamp3/

PATH TRACING

Page 2: パストレーシング

レンダリング方程式 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: パストレーシング

入射方向を確率的にサンプル、光源に当たれば寄与を計算 視点から光輸送経路をトレース

Page 4: パストレーシング

入射方向のサンプリング

Diffuse BSDF Glossy BSDF Specular BSDF

どの方向も似たような値 鏡面反射方向の 周囲に大きな値

鏡面反射方向以外の 値はゼロ

少なくともBSDFが大きな値を持つ方向を 多くサンプルするのが望ましいàBSDFの重点的サンプリング

Page 5: パストレーシング

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: パストレーシング

入射方向を確率的にサンプル、光源に当たれば寄与がとれる 視点から光輸送経路をトレース

なかなか当たらない!(特に光源が小さいとき)

Page 7: パストレーシング

NEXT EVENT ESTIMATION!

Page 8: パストレーシング

NEXT EVENT ESTIMATION

光源上の点を明示的にサンプル、視線経路と接続する

Page 9: パストレーシング

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: パストレーシング

???

Page 11: パストレーシング

// 光源上の点を明示的にサンプリングして現在の点と接続 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: パストレーシング

...無い cos項ひとつだし距離二乗も無い

Lo(x, ��o) = Le(x, ��o) +�

S2Li(x, ��i)fs(x, ��i, ��o) |�n · ��i| d��i

Page 13: パストレーシング

単位の話

Page 14: パストレーシング

確率に単位は無いが確率密度(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: パストレーシング

位置に関するサンプリングでは レンダリング方程式の形が若干変わる

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: パストレーシング

BSDFのサンプリング Next Event Estimation

ただしNext Event Estimationが逆効果になることも...

Page 17: パストレーシング

MULTIPLE IMPORTANCE SAMPLING!多重重点的サンプリング

Page 18: パストレーシング

Light

光沢BSDF

BSDFの寄与に沿った重点的サンプリング

BSDF寄与に沿って入射方向サンプル:高い確率で高い寄与 à低い分散(光源が良い場所にあれば)

�C� =1N

N�

i=1

f(x̄i)pBSDF (x̄i)

Page 19: パストレーシング

Light

拡散BSDF

BSDFの寄与に沿った重点的サンプリング

BSDF寄与に沿って入射方向サンプル:低い確率で高い寄与 à高い分散(たまにしか当たらないため)

�C� =1N

N�

i=1

f(x̄i)pBSDF (x̄i)

Page 20: パストレーシング

Light

拡散BSDF

光源上の位置の重点的サンプリング

光源上の位置をサンプルして接続:高い確率で高い寄与 à低い分散(BSDFの値が比較的一様であれば)

�C� =1N

N�

i=1

f(x̄i)plight(x̄i)

Page 21: パストレーシング

Light

光沢BSDF

光源上の位置の重点的サンプリング

光源上の位置をサンプルして接続:低い確率で高い寄与 à高い分散(BSDFの値が非一様なため)

�C� =1N

N�

i=1

f(x̄i)plight(x̄i)

Page 22: パストレーシング

光源面のサンプリング BSDFのサンプリング n  VEACH, E. 1997. Robust Monte Carlo methods for light transport simulation. PhD thesis, Stanford, CA, USA.!

Page 23: パストレーシング

多重重点的サンプリング

�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: パストレーシング

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: パストレーシング

バランスヒューリスティック:要するに

BSDF 「パス持ってきたよ」

「推定結果に自信のほどは」

BSDF 「3」

「lightが仮にこのパスつくったなら自信は」

light 「8」

「じゃあBSDFが持ってきたパスの重みは  3 / (3 + 8)ってことで」

light 「パス持ってきたよ」

「推定結果に自信のほどは」

light 「8」

「BSDFが仮にこのパスつくったなら自信は」

BSDF 「3」

「じゃあlightが持ってきたパスの重みは  8 / (3 + 8)ってことで」

Page 26: パストレーシング

MISによるウェイト配分 Multiple Importance Sampling n  VEACH, E. 1997. Robust Monte Carlo methods for light transport simulation. PhD thesis, Stanford, CA, USA.!

Page 27: パストレーシング

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: パストレーシング

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: パストレーシング

DEPTH OF FIELD!被写界深度

Page 30: パストレーシング

薄レンズモデルを用いたDoF表現

理論・手順の詳細はWEBページ参照 端的に述べると…

xpx0

x�1

x1

x0

xp x�1

シーン中の位置

センサー面 物面

レンズ上の1点 をサンプル、 ピクセル中の位置 に対応する物面上の点 に向かってレイトレース レンズ位置のサンプルを行っているのでPDF    で寄与を割る pA(x0)

Page 31: パストレーシング

実装すると…

ピンホール 薄レンズモデルによるDoF

Page 32: パストレーシング

ちゃんとボケてるみたいだけど ピンホールと明るさ違うし、

レンズの大きさによって明るさ変わる…

現実のカメラと一緒 レンズが大きければ取り入れる光の量が増えて明るくなる

à画像の明るさを一定に保ちたいのなら センサーの感度を変更する必要がある

Page 33: パストレーシング

センサーの感度を適切に設定すると…

ピンホール 薄レンズモデルによるDoF

Page 34: パストレーシング

ちょっと待て

Page 35: パストレーシング

ピンホールカメラは薄レンズモデルで レンズが極限に小さい場合と捉えることができる

àPDFの値が無限となるので、PDFで割ると結果はゼロ

レンズが大きい程画像が明るいのは当たり前 じゃあピンホールカメラの画像は真っ暗なのでは…?

ある意味正解

初歩的なパストレ等の実装では そもそもレンズ面のPDFで割ったりしていない

àPDFをキャンセルするだけの 無限のセンサー感度があるのと等しい

Page 36: パストレーシング

おしまい IBLとか色々話したかったけど そのうちWEBページに書きます...

http://www35.atpages.jp/shocker/memoRANDOM/CG/CG.php