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);
	}
Example #2
0
	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);
	}