AABB getAABB() const { AABB bounds; bounds.expandBy(m_sampleToCamera(Point(0, 0, 0))); bounds.expandBy(m_sampleToCamera(Point(1, 1, 0))); return m_worldTransform->getSpatialBounds(bounds); }
Spectrum sampleDirection(DirectionSamplingRecord &dRec, PositionSamplingRecord &pRec, const Point2 &sample, const Point2 *extra) const { const Transform &trafo = m_worldTransform->eval(pRec.time); Point samplePos(sample.x, sample.y, 0.0f); if (extra) { /* The caller wants to condition on a specific pixel position */ samplePos.x = (extra->x + sample.x) * m_invResolution.x; samplePos.y = (extra->y + sample.y) * m_invResolution.y; } pRec.uv = Point2(samplePos.x * m_resolution.x, samplePos.y * m_resolution.y); /* Compute the corresponding position on the near plane (in local camera space) */ Point nearP = m_sampleToCamera(samplePos); nearP.x = nearP.x * (m_focusDistance / nearP.z); nearP.y = nearP.y * (m_focusDistance / nearP.z); nearP.z = m_focusDistance; Point apertureP = trafo.inverse().transformAffine(pRec.p); /* Turn that into a normalized ray direction */ Vector d = normalize(nearP - apertureP); dRec.d = trafo(d); dRec.measure = ESolidAngle; dRec.pdf = m_normalization / (d.z * d.z * d.z); return Spectrum(1.0f); }
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); }
void configure() { PerspectiveCamera::configure(); const Vector2i &filmSize = m_film->getSize(); const Vector2i &cropSize = m_film->getCropSize(); const Point2i &cropOffset = m_film->getCropOffset(); Vector2 relSize((Float) cropSize.x / (Float) filmSize.x, (Float) cropSize.y / (Float) filmSize.y); Point2 relOffset((Float) cropOffset.x / (Float) filmSize.x, (Float) cropOffset.y / (Float) filmSize.y); /** * These do the following (in reverse order): * * 1. Create transform from camera space to [-1,1]x[-1,1]x[0,1] clip * coordinates (not taking account of the aspect ratio yet) * * 2+3. Translate and scale to shift the clip coordinates into the * range from zero to one, and take the aspect ratio into account. * * 4+5. Translate and scale the coordinates once more to account * for a cropping window (if there is any) */ m_cameraToSample = Transform::scale(Vector(1.0f / relSize.x, 1.0f / relSize.y, 1.0f)) * Transform::translate(Vector(-relOffset.x, -relOffset.y, 0.0f)) * Transform::scale(Vector(-0.5f, -0.5f*m_aspect, 1.0f)) * Transform::translate(Vector(-1.0f, -1.0f/m_aspect, 0.0f)) * Transform::perspective(m_xfov, m_nearClip, m_farClip); m_sampleToCamera = m_cameraToSample.inverse(); /* Position differentials on the near plane */ m_dx = m_sampleToCamera(Point(m_invResolution.x, 0.0f, 0.0f)) - m_sampleToCamera(Point(0.0f)); m_dy = m_sampleToCamera(Point(0.0f, m_invResolution.y, 0.0f)) - m_sampleToCamera(Point(0.0f)); /* Precompute some data for importance(). Please look at that function for further details */ Point min(m_sampleToCamera(Point(0, 0, 0))), max(m_sampleToCamera(Point(1, 1, 0))); m_imageRect.reset(); m_imageRect.expandBy(Point2(min.x, min.y) / min.z); m_imageRect.expandBy(Point2(max.x, max.y) / max.z); m_normalization = 1.0f / m_imageRect.getVolume(); /* Clip-space transformation for OpenGL */ m_clipTransform = Transform::translate( Vector((1-2*relOffset.x)/relSize.x - 1, -(1-2*relOffset.y)/relSize.y + 1, 0.0f)) * Transform::scale(Vector(1.0f / relSize.x, 1.0f / relSize.y, 1.0f)); m_aperturePdf = 1 / (M_PI * m_apertureRadius * m_apertureRadius); }
void configure() { ProjectiveCamera::configure(); const Vector2i &filmSize = m_film->getSize(); const Vector2i &cropSize = m_film->getCropSize(); const Point2i &cropOffset = m_film->getCropOffset(); Vector2 relSize((Float) cropSize.x / (Float) filmSize.x, (Float) cropSize.y / (Float) filmSize.y); Point2 relOffset((Float) cropOffset.x / (Float) filmSize.x, (Float) cropOffset.y / (Float) filmSize.y); /** * These do the following (in reverse order): * * 1. Create transform from camera space to [-1,1]x[-1,1]x[0,1] clip * coordinates (not taking account of the aspect ratio yet) * * 2+3. Translate and scale to shift the clip coordinates into the * range from zero to one, and take the aspect ratio into account. * * 4+5. Translate and scale the coordinates once more to account * for a cropping window (if there is any) */ m_cameraToSample = Transform::scale(Vector(1.0f / relSize.x, 1.0f / relSize.y, 1.0f)) * Transform::translate(Vector(-relOffset.x, -relOffset.y, 0.0f)) * Transform::scale(Vector(-0.5f, -0.5f*m_aspect, 1.0f)) * Transform::translate(Vector(-1.0f, -1.0f/m_aspect, 0.0f)) * Transform::orthographic(m_nearClip, m_farClip); m_sampleToCamera = m_cameraToSample.inverse(); /* Position differentials on the near plane */ m_dx = m_sampleToCamera(Point(m_invResolution.x, 0.0f, 0.0f)) - m_sampleToCamera(Point(0.0f)); m_dy = m_sampleToCamera(Point(0.0f, m_invResolution.y, 0.0f)) - m_sampleToCamera(Point(0.0f)); /* Clip-space transformation for OpenGL */ m_clipTransform = Transform::translate( Vector((1-2*relOffset.x)/relSize.x - 1, -(1-2*relOffset.y)/relSize.y + 1, 0.0f)) * Transform::scale(Vector(1.0f / relSize.x, 1.0f / relSize.y, 1.0f)); const Transform &trafo = m_worldTransform->eval(0.0f); m_invSurfaceArea = 1.0f / ( trafo(m_sampleToCamera(Vector(1, 0, 0))).length() * trafo(m_sampleToCamera(Vector(0, 1, 0))).length()); m_scale = trafo(Vector(0, 0, 1)).length(); }
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); }