mmp / pbrt-v2

Source code for the version of pbrt described in the second edition of "Physically Based Rendering"
http://pbrt.org
990 stars 343 forks source link

UniformSampleSphere in AmbientOcclusionIntegrator::Li #58

Closed matt77hias closed 6 years ago

matt77hias commented 7 years ago

Shouldn't the AmbientOcclusionIntegrator::Li method use uniform cosine weighted sphere/hemisphere sampling or at least take the cosine factor separately into account in case of uniform sphere/hemisphere sampling?

Possible fix:

// AmbientOcclusionIntegrator Method Definitions
Spectrum AmbientOcclusionIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Intersection &isect,
        const Sample *sample, RNG &rng, MemoryArena &arena) const {

    const BSDF *bsdf = isect.GetBSDF(ray, arena);
    const Point &p = bsdf->dgShading.p;
    const Normal n = Faceforward(isect.dg.nn, -ray.d);

    const uint32_t scramble[2] = { rng.RandomUInt(), rng.RandomUInt() };
    float u[2];
    int nClear = 0;
    for (int i = 0; i < nSamples; ++i) {
        Sample02(i, scramble, u);

        const Vector axis_w = (Vector) n;
        const Vector axis_u = Cross((abs(axis_w.x) > 0.1f ? Vector(0.0f, 1.0f, 0.0f) : Vector(1.0f, 0.0f, 0.0f)), axis_w);
        const Vector axis_v = Cross(axis_w, axis_u);
        const Vector sample_d = CosineSampleHemisphere(u[0], u[1]);
        const Vector d = (sample_d.x * axis_u + sample_d.y * axis_v + sample_d.z * axis_w);

        const Ray r(p, d, .01f, maxDist);
        if (!scene->IntersectP(r)) ++nClear;
        ray.scount += r.count;
        ray.tcount += r.rcount;
    }
    return Spectrum(float(nClear) / float(nSamples));
}
mmp commented 6 years ago

The pbrt-v3 AO integrator does cos sampling by default (and has a control to choose)! Marking will not fix for v2.