Last active
March 25, 2016 05:40
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void LightTracer::splatFilmT1(const ScenePtr& scene, const Sample& sample, | |
const RNG& rng, std::vector<PathVertex>& pathVertices, | |
ImageTile* tile) const { | |
const vector<Light*>& lights = scene->getLights(); | |
if (lights.size() == 0) { | |
return; | |
} | |
// get the camera point | |
const CameraPtr camera = scene->getCamera(); | |
Vector3 nCamera; | |
float pdfCamera; | |
Vector3 pCamera = camera->samplePosition(sample, &nCamera, &pdfCamera); | |
PathVertex cVertex(Color(1.0f / pdfCamera), pCamera, | |
nCamera, camera.get()); | |
// get the light point | |
float pickLightPdf; | |
float pickSample = sample.u1D[mPickLightSampleIndexes[0].offset][0]; | |
int lightIndex = mPowerDistribution->sampleDiscrete( | |
pickSample, &pickLightPdf); | |
const Light* light = lights[lightIndex]; | |
LightSample ls(sample, mLightSampleIndexes[0], 0); | |
Vector3 nLight; | |
float pdfLightArea; | |
Vector3 pLight = light->samplePosition(scene, ls, &nLight, | |
&pdfLightArea); | |
pathVertices[0] = PathVertex( | |
Color(1.0f / (pdfLightArea * pickLightPdf)), | |
pLight, nLight, light); | |
float pdfLightDirection; | |
BSDFSample bs(sample, mBSDFSampleIndexes[0], 0); | |
Vector3 dir = light->sampleDirection( | |
nLight, bs.uDirection[0], bs.uDirection[1], &pdfLightDirection); | |
Color throughput = pathVertices[0].throughput * | |
absdot(nLight, dir) / pdfLightDirection; | |
Ray ray(pLight, dir, 1e-3f); | |
// start building a path from light by bouncing around the scene | |
int lightVertex = 1; | |
while (lightVertex < mMaxPathLength) { | |
float epsilon; | |
Intersection isect; | |
if (!scene->intersect(ray, &epsilon, &isect)) { | |
break; | |
} | |
const Fragment& frag = isect.fragment; | |
pathVertices[lightVertex] = PathVertex(throughput, isect); | |
BSDFSample bs(sample, mBSDFSampleIndexes[lightVertex], 0); | |
lightVertex += 1; | |
Vector3 wo = -normalize(ray.d); | |
Vector3 wi; | |
float pdfW; | |
Color f = isect.getMaterial()->sampleBSDF(frag, wo, bs, | |
&wi, &pdfW, BSDFAll, NULL, BSDFImportance); | |
if (f == Color::Black || pdfW == 0.0f) { | |
break; | |
} | |
throughput *= f * absdot(wi, frag.getNormal()) / pdfW; | |
ray = Ray(frag.getPosition(), wi, epsilon); | |
} | |
// evaluate path contribution Cs,1 | |
for (int s = 1; s <= lightVertex; ++s) { | |
const PathVertex& pv = pathVertices[s - 1]; | |
const Vector3& pvPos = pv.fragment.getPosition(); | |
Vector3 filmPixel = camera->worldToScreen( | |
pv.fragment.getPosition(), pCamera); | |
if (filmPixel == Camera::sInvalidPixel) { | |
continue; | |
} | |
// occlude test | |
Vector3 pv2Cam(pCamera - pvPos); | |
float occludeDistance = length(pv2Cam); | |
float epsilon = 1e-3f * occludeDistance; | |
Ray occludeRay(pvPos, normalize(pv2Cam), | |
epsilon, occludeDistance - epsilon); | |
if (scene->intersect(occludeRay)) { | |
continue; | |
} | |
Color fsL; | |
Vector3 wo = normalize(pCamera - pvPos); | |
if (s > 1) { | |
Vector3 wi = | |
normalize(pathVertices[s - 2].fragment.getPosition() - pvPos); | |
Color f = pv.material->bsdf(pv.fragment, wo, wi, | |
BSDFAll, BSDFImportance); | |
fsL = f * light->evalL(pLight, nLight, | |
pathVertices[1].fragment.getPosition()); | |
} else { | |
fsL = pv.light->evalL(pLight, nLight, pCamera); | |
} | |
float fsE = camera->evalWe(pCamera, pvPos); | |
float G = absdot(pv.fragment.getNormal(), wo) * absdot(nCamera, wo) / | |
squaredLength(pvPos - pCamera); | |
Color pathContribution = fsL * fsE * G * | |
pv.throughput * cVertex.throughput; | |
tile->addSample(filmPixel.x, filmPixel.y, pathContribution); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment