Vec3f TraceBase::volumePhaseSample(const Primitive &light, PathSampleGenerator &sampler, MediumSample &mediumSample, const Medium *medium, int bounce, const Ray &parentRay) { PhaseSample phaseSample; if (!mediumSample.phase->sample(sampler, parentRay.dir(), phaseSample)) return Vec3f(0.0f); Ray ray = parentRay.scatter(mediumSample.p, phaseSample.w, 0.0f); ray.setPrimaryRay(false); IntersectionTemporary data; IntersectionInfo info; Vec3f e = attenuatedEmission(sampler, light, medium, -1.0f, data, info, bounce, false, ray, nullptr); if (e == Vec3f(0.0f)) return Vec3f(0.0f); Vec3f phaseF = e*phaseSample.weight; phaseF *= SampleWarp::powerHeuristic(phaseSample.pdf, light.directPdf(_threadId, data, info, mediumSample.p)); return phaseF; }
Vec3f TraceBase::bsdfSample(const Primitive &light, SurfaceScatterEvent &event, const Medium *medium, int bounce, const Ray &parentRay) { event.requestedLobe = BsdfLobes::AllButSpecular; if (!event.info->bsdf->sample(event, false)) return Vec3f(0.0f); if (event.weight == 0.0f) return Vec3f(0.0f); Vec3f wo = event.frame.toGlobal(event.wo); if (!isConsistent(event, wo)) return Vec3f(0.0f); bool geometricBackside = (wo.dot(event.info->Ng) < 0.0f); medium = event.info->primitive->selectMedium(medium, geometricBackside); Ray ray = parentRay.scatter(event.info->p, wo, event.info->epsilon); ray.setPrimaryRay(false); IntersectionTemporary data; IntersectionInfo info; Vec3f e = attenuatedEmission(*event.sampler, light, medium, -1.0f, data, info, bounce, true, ray, nullptr); if (e == Vec3f(0.0f)) return Vec3f(0.0f); Vec3f bsdfF = e*event.weight; bsdfF *= SampleWarp::powerHeuristic(event.pdf, light.directPdf(_threadId, data, info, event.info->p)); return bsdfF; }