Spectrum sampleRay(Ray &ray, const Point2 &pixelSample, const Point2 &otherSample, Float timeSample) const { Point2 tmp = warp::squareToUniformDiskConcentric(otherSample) * m_apertureRadius; ray.time = sampleTime(timeSample); /* Compute the corresponding position on the near plane (in local camera space) */ Point nearP = m_sampleToCamera(Point( pixelSample.x * m_invResolution.x, pixelSample.y * m_invResolution.y, 0.0f)); /* Aperture position */ Point apertureP(tmp.x, tmp.y, 0.0f); /* Sampled position on the focal plane */ Point focusP = nearP * (m_focusDistance / nearP.z); /* Turn these into a normalized ray direction, and adjust the ray interval accordingly */ Vector d = normalize(focusP - apertureP); Float invZ = 1.0f / d.z; ray.mint = m_nearClip * invZ; ray.maxt = m_farClip * invZ; const Transform &trafo = m_worldTransform->eval(ray.time); ray.setOrigin(trafo.transformAffine(apertureP)); ray.setDirection(trafo(d)); return Spectrum(1.0f); }
Spectrum sampleRayDifferential(RayDifferential &ray, const Point2 &pixelSample, const Point2 &otherSample, Float timeSample) const { /* Record pixel index, added by Lifan */ ray.index.x = (int)std::floor(pixelSample.x); ray.index.y = (int)std::floor(pixelSample.y); Point2 tmp = warp::squareToUniformDiskConcentric(otherSample) * m_apertureRadius; ray.time = sampleTime(timeSample); /* Compute the corresponding position on the near plane (in local camera space) */ Point nearP = m_sampleToCamera(Point( pixelSample.x * m_invResolution.x, pixelSample.y * m_invResolution.y, 0.0f)); /* Aperture position */ Point apertureP(tmp.x, tmp.y, 0.0f); /* Sampled position on the focal plane */ Float fDist = m_focusDistance / nearP.z; Point focusP = nearP * fDist; Point focusPx = (nearP+m_dx) * fDist; Point focusPy = (nearP+m_dy) * fDist; /* Turn that into a normalized ray direction, and adjust the ray interval accordingly */ Vector d = normalize(focusP - apertureP); Float invZ = 1.0f / d.z; ray.mint = m_nearClip * invZ; ray.maxt = m_farClip * invZ; const Transform &trafo = m_worldTransform->eval(ray.time); ray.setOrigin(trafo.transformAffine(apertureP)); ray.setDirection(trafo(d)); ray.rxOrigin = ray.ryOrigin = ray.o; ray.rxDirection = trafo(normalize(Vector(focusPx - apertureP))); ray.ryDirection = trafo(normalize(Vector(focusPy - apertureP))); ray.hasDifferentials = true; return Spectrum(1.0f); }
Spectrum sampleDirect(DirectSamplingRecord &dRec, const Point2 &sample) const { const Transform &trafo = m_worldTransform->eval(dRec.time); /* Transform the reference point into the local coordinate system */ Point refP = trafo.inverse().transformAffine(dRec.ref); /* Check if it is outside of the clip range */ if (refP.z < m_nearClip || refP.z > m_farClip) { dRec.pdf = 0.0f; return Spectrum(0.0f); } /* Sample a position on the aperture (in local coordinates) */ Point2 tmp = warp::squareToUniformDiskConcentric(sample) * m_apertureRadius; Point apertureP(tmp.x, tmp.y, 0); /* Compute the normalized direction vector from the aperture position to the reference point */ Vector localD(refP - apertureP); Float dist = localD.length(), invDist = 1.0f / dist; localD *= invDist; Float value = importance(apertureP, localD, &dRec.uv); if (value == 0.0f) { dRec.pdf = 0.0f; return Spectrum(0.0f); } dRec.p = trafo.transformAffine(apertureP); dRec.d = (dRec.p - dRec.ref) * invDist; dRec.dist = dist; dRec.n = trafo(Vector(0.0f, 0.0f, 1.0f)); dRec.pdf = m_aperturePdf * dist*dist/(Frame::cosTheta(localD)); dRec.measure = ESolidAngle; /* intentionally missing a cosine factor wrt. the aperture disk (it is already accounted for in importance()) */ return Spectrum(value * invDist * invDist); }