Vec3f TraceBase::volumeLightSample(PathSampleGenerator &sampler, MediumSample &mediumSample, const Primitive &light, const Medium *medium, int bounce, const Ray &parentRay) { LightSample lightSample; if (!light.sampleDirect(_threadId, mediumSample.p, sampler, lightSample)) return Vec3f(0.0f); Vec3f f = mediumSample.phase->eval(parentRay.dir(), lightSample.d); if (f == 0.0f) return Vec3f(0.0f); Ray ray = parentRay.scatter(mediumSample.p, lightSample.d, 0.0f); ray.setPrimaryRay(false); IntersectionTemporary data; IntersectionInfo info; Vec3f e = attenuatedEmission(sampler, light, medium, lightSample.dist, data, info, bounce, false, ray, nullptr); if (e == 0.0f) return Vec3f(0.0f); Vec3f lightF = f*e/lightSample.pdf; if (!light.isDirac()) lightF *= SampleWarp::powerHeuristic(lightSample.pdf, mediumSample.phase->pdf(parentRay.dir(), lightSample.d)); return lightF; }
Vec3f TraceBase::lightSample(const Primitive &light, SurfaceScatterEvent &event, const Medium *medium, int bounce, const Ray &parentRay, Vec3f *transmittance) { LightSample sample; if (!light.sampleDirect(_threadId, event.info->p, *event.sampler, sample)) return Vec3f(0.0f); event.wo = event.frame.toLocal(sample.d); if (!isConsistent(event, sample.d)) return Vec3f(0.0f); bool geometricBackside = (sample.d.dot(event.info->Ng) < 0.0f); medium = event.info->primitive->selectMedium(medium, geometricBackside); event.requestedLobe = BsdfLobes::AllButSpecular; Vec3f f = event.info->bsdf->eval(event, false); if (f == 0.0f) return Vec3f(0.0f); Ray ray = parentRay.scatter(event.info->p, sample.d, event.info->epsilon); ray.setPrimaryRay(false); IntersectionTemporary data; IntersectionInfo info; Vec3f e = attenuatedEmission(*event.sampler, light, medium, sample.dist, data, info, bounce, true, ray, transmittance); if (e == 0.0f) return Vec3f(0.0f); Vec3f lightF = f*e/sample.pdf; if (!light.isDirac()) lightF *= SampleWarp::powerHeuristic(sample.pdf, event.info->bsdf->pdf(event)); return lightF; }