Ejemplo n.º 1
0
Float MISWeight(const Scene &scene, Vertex *lightSubpath, Vertex *cameraSubpath,
                Vertex &sampled, int s, int t, const Distribution1D &lightPdf) {
    if (s + t == 2) return 1.0f;
    Float sum = 0.f;
    // Determine connection vertices
    Vertex *qs = s > 0 ? &lightSubpath[s - 1] : nullptr,
           *pt = t > 0 ? &cameraSubpath[t - 1] : nullptr,
           *qsMinus = s > 1 ? &lightSubpath[s - 2] : nullptr,
           *ptMinus = t > 1 ? &cameraSubpath[t - 2] : nullptr;

    // Temporarily update vertex properties for current strategy
    ScopedAssign<Vertex> s0;
    ScopedAssign<bool> s1, s2;
    ScopedAssign<Float> s3, s4, s5, s6;
    if (s == 1 || t == 1)
        s0 = ScopedAssign<Vertex>((s == 1) ? qs : pt, sampled);
    if (qs) {
        s1 = ScopedAssign<bool>(&qs->delta, false),
        s3 = ScopedAssign<Float>(&qs->pdfRev, pt->Pdf(scene, ptMinus, *qs));
    }
    if (qsMinus)
        s5 =
            ScopedAssign<Float>(&qsMinus->pdfRev, qs->Pdf(scene, pt, *qsMinus));
    if (pt) {
        s2 = ScopedAssign<bool>(&pt->delta, false);
        s4 = ScopedAssign<Float>(
            &pt->pdfRev, s > 0 ? qs->Pdf(scene, qsMinus, *pt)
                               : pt->PdfLightOrigin(scene, *ptMinus, lightPdf));
    }
    if (ptMinus)
        s6 = ScopedAssign<Float>(&ptMinus->pdfRev,
                                 s > 0 ? pt->Pdf(scene, qs, *ptMinus)
                                       : pt->PdfLight(scene, *ptMinus));

    // Consider hypothetical connection strategies along the camera subpath
    auto p = [](float f) -> float { return f != 0 ? f : 1.0f; };
    Float ratio = 1.0f;
    for (int i = t - 1; i > 0; --i) {
        ratio *= p(cameraSubpath[i].pdfRev) / p(cameraSubpath[i].pdfFwd);
        if (!cameraSubpath[i].delta && !cameraSubpath[i - 1].delta)
            sum += ratio;
    }

    // Consider hypothetical connection strategies along the light subpath
    ratio = 1.0f;
    for (int i = s - 1; i >= 0; --i) {
        ratio *= p(lightSubpath[i].pdfRev) / p(lightSubpath[i].pdfFwd);
        bool delta_lightvertex =
            i > 0 ? lightSubpath[i - 1].delta : lightSubpath[0].IsDeltaLight();
        if (!lightSubpath[i].delta && !delta_lightvertex) sum += ratio;
    }
    return 1.f / (1.f + sum);
}
Ejemplo n.º 2
0
Float MISWeight(const Scene &scene, Vertex *lightVertices,
                Vertex *cameraVertices, Vertex &sampled, int s, int t,
                const Distribution1D &lightPdf,
                const std::unordered_map<const Light *, size_t> &lightToIndex) {
    if (s + t == 2) return 1;
    Float sumRi = 0;
    // Define helper function _remap0_ that deals with Dirac delta functions
    auto remap0 = [](Float f) -> Float { return f != 0 ? f : 1; };

    // Temporarily update vertex properties for current strategy

    // Look up connection vertices and their predecessors
    Vertex *qs = s > 0 ? &lightVertices[s - 1] : nullptr,
           *pt = t > 0 ? &cameraVertices[t - 1] : nullptr,
           *qsMinus = s > 1 ? &lightVertices[s - 2] : nullptr,
           *ptMinus = t > 1 ? &cameraVertices[t - 2] : nullptr;

    // Update sampled vertex for $s=1$ or $t=1$ strategy
    ScopedAssignment<Vertex> a1;
    if (s == 1)
        a1 = {qs, sampled};
    else if (t == 1)
        a1 = {pt, sampled};

    // Mark connection vertices as non-degenerate
    ScopedAssignment<bool> a2, a3;
    if (pt) a2 = {&pt->delta, false};
    if (qs) a3 = {&qs->delta, false};

    // Update reverse density of vertex $\pt{}_{t-1}$
    ScopedAssignment<Float> a4;
    if (pt)
        a4 = {&pt->pdfRev, s > 0 ? qs->Pdf(scene, qsMinus, *pt)
                                 : pt->PdfLightOrigin(scene, *ptMinus, lightPdf,
                                                      lightToIndex)};

    // Update reverse density of vertex $\pt{}_{t-2}$
    ScopedAssignment<Float> a5;
    if (ptMinus)
        a5 = {&ptMinus->pdfRev, s > 0 ? pt->Pdf(scene, qs, *ptMinus)
                                      : pt->PdfLight(scene, *ptMinus)};

    // Update reverse density of vertices $\pq{}_{s-1}$ and $\pq{}_{s-2}$
    ScopedAssignment<Float> a6;
    if (qs) a6 = {&qs->pdfRev, pt->Pdf(scene, ptMinus, *qs)};
    ScopedAssignment<Float> a7;
    if (qsMinus) a7 = {&qsMinus->pdfRev, qs->Pdf(scene, pt, *qsMinus)};

    // Consider hypothetical connection strategies along the camera subpath
    Float ri = 1;
    for (int i = t - 1; i > 0; --i) {
        ri *=
            remap0(cameraVertices[i].pdfRev) / remap0(cameraVertices[i].pdfFwd);
        if (!cameraVertices[i].delta && !cameraVertices[i - 1].delta)
            sumRi += ri;
    }

    // Consider hypothetical connection strategies along the light subpath
    ri = 1;
    for (int i = s - 1; i >= 0; --i) {
        ri *= remap0(lightVertices[i].pdfRev) / remap0(lightVertices[i].pdfFwd);
        bool deltaLightvertex = i > 0 ? lightVertices[i - 1].delta
                                      : lightVertices[0].IsDeltaLight();
        if (!lightVertices[i].delta && !deltaLightvertex) sumRi += ri;
    }
    return 1 / (1 + sumRi);
}