Slide 27
Slide 27 text
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;
if (surfPt.isEmitting())
contribution += alpha * surfPt.Le(-ray.dir);
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[m^-2]に合わせる。
bsdfPDF = surfPt.BSDF.evalDirectionalPDF(shadowDir, -ray.dir) *
cosLight / dist2;
MISWeight = lightPDF / (bsdfPDF + lightPDF);
contribution += alpha * MISWeight *
fs * lightSurfPt.Le(-shadowDir) *
G / lightPDF;
}
/FYU&WFOU&TUJNBUJPO.*4ΣΠτ