// Sample an exitant ray
Vec3f DirectionalLight::sampleExitantRay(
        const Scene& scene,
        const Vec2f& emissionVertexSample,
        const Vec2f& raySample,
        RaySample& exitantRaySample,
        float& emissionVertexPdf) const
{
    Vec3f center;
    float radius;
    boundingSphere(scene.getBBox(), center, radius);

    // Center of the disk
    center += m_IncidentDirection * radius;

    Vec2f pos2D = uniformSampleDisk(raySample, radius);

    auto originPdf = 1.f / (pi<float>() * radius * radius);
    emissionVertexPdf = 1.f;

    auto pdf = originPdf * emissionVertexPdf;

    auto matrix = frameY(center, m_IncidentDirection);
    auto rayOrigin = Vec3f(matrix * Vec4f(pos2D.x, 0, pos2D.y, 1.f));

    exitantRaySample = RaySample(Ray(rayOrigin, -m_IncidentDirection), pdf);

    return m_Le;
}
Exemple #2
0
    float PerspectiveCamera::generateRay(const Sample& sample, 
        RayDifferential* ray) const {
        float invXRes = mFilm->getInvXResolution();
        float invYRes = mFilm->getInvYResolution();
        float xNDC = +2.0f * sample.imageX * invXRes - 1.0f;
        float yNDC = -2.0f * sample.imageY * invYRes + 1.0f;
        float dxNDC = +2.0f * (sample.imageX + 1.0f) * invXRes - 1.0f;
        float dyNDC = -2.0f * (sample.imageY + 1.0f) * invYRes + 1.0f;
        // from NDC space to view space
        // xView = xNDC * zView * tan(fov / 2) * aspectRatio
        // yView = yNDC * zView * tan(fov / 2)
        // in projection matrix pro,
        // pro[0][0] = 1 / (tan(fov / 2) * aspectRatio)
        // pro[1][1] = 1 / (tan(fov / 2))
        float zView = 1.0f;
        float xView = xNDC / mProj[0][0];
        float yView = yNDC / mProj[1][1];
        Vector3 viewDir = Vector3(xView, yView, zView);

        float dxView = dxNDC / mProj[0][0];
        Vector3 dxViewDir(dxView, yView, zView);
        float dyView = dyNDC / mProj[1][1];
        Vector3 dyViewDir(xView, dyView, zView);

        if(mLensRadius == 0.0f) {
            // view space to world space
            ray->o = ray->dxOrigin = ray->dyOrigin = mPosition;
            ray->d = mOrientation * normalize(viewDir);
            ray->dxDir = mOrientation * normalize(dxViewDir);
            ray->dyDir = mOrientation * normalize(dyViewDir);
            
        } else {
            // perturb the ray direction for DOF effect
            float ft = mFocalDistance / viewDir.z;
            Vector3 pFocus = viewDir * ft;
            Vector3 pDxFocus = dxViewDir * ft;
            Vector3 pDyFocus = dyViewDir * ft;
            Vector2 lensSample = mLensRadius *
                uniformSampleDisk(sample.lensU1, sample.lensU2);
            Vector3 viewOrigin(lensSample.x, lensSample.y, 0.0f);
            ray->o = ray->dxOrigin = ray->dyOrigin = 
                mOrientation * viewOrigin + mPosition;
            ray->d = mOrientation * normalize(pFocus - viewOrigin);
            ray->dxDir = mOrientation * normalize(pDxFocus - viewOrigin);
            ray->dyDir = mOrientation * normalize(pDyFocus - viewOrigin);
        }
        ray->mint = 1e-3f;
        ray->maxt = INFINITY;
        ray->depth = 0;
        ray->hasDifferential = true;
        return 1.0f;
    }
Exemple #3
0
 Vector3 PerspectiveCamera::samplePosition(const Sample& sample,
     Vector3* surfaceNormal, float* pdfArea) const {
     Vector3 pCamera;
     if (mLensRadius > 0.0f) {
         Vector2 lensSample = mLensRadius *
             uniformSampleDisk(sample.lensU1, sample.lensU2);
         Vector3 viewOrigin(lensSample.x, lensSample.y, 0.0f);
         pCamera = mOrientation * viewOrigin + mPosition;
     } else {
         pCamera = mPosition;
     }
     if (pdfArea) {
         *pdfArea = mLensRadius > 0.0f ?
             1.0f / (mLensRadius * mLensRadius * PI) : 1.0f;
     }
     *surfaceNormal = getLook();
     return pCamera;
 }