Color Renderer::render(std::vector<PhotonMap::NearestPhoton>& nearestPhotons, Ray const& ray, int rayBounceCount) const {      
     Color radiance = Color::BLACK;
     
     float hitDistance; Scene::Sample hit;
     if (!scene()->hit(ray, hitDistance, hit)) {
         return radiance;
     }
     
     { // emitted radiance
         radiance += hit.emission * hit.emissionPower;
     }
     { // photon radiance
         Color photonRadiance = Color::BLACK; 
         auto nearestPhotonsEnd = photonMap().nearest(hit.position, nearestPhotons.begin(), nearestPhotons.end());
         Vector3f const& n = hit.normal;
         Vector3f v = -ray.direction;
         auto farthestPhotonIt = nearestPhotons.begin();
         float farthestPhotonSqrDistance = farthestPhotonIt->sqrDistance;
         for (auto& nearestPhoton : nearestPhotons) {
             Photon const& photon = *nearestPhoton.photon;
             Vector3f l = -photon.direction;
             float ln = dot(l, n);
             if (ln > 0.0f) {
                 photonRadiance += hit.diffuse * ln * photon.power;
                 Vector3f r = reflect(-l, n);
                 float rv = dot(r, v);
                 if (rv > 0.0f) {
                     photonRadiance += hit.specular * pow(rv, hit.specularPower) * photon.power;
                 }
             }
         }
         photonRadiance /= pi() * farthestPhotonSqrDistance * photonCount();
         radiance += photonRadiance;
     }
     { // reflected radiance
         if (rayBounceCount + 1 < maxRayBounceCount() && luminance(hit.specular) > 0.0f) {
             Ray reflectedRay;
             reflectedRay.origin = hit.position;
             reflectedRay.direction = reflect(ray.direction, hit.normal);
             reflectedRay.origin += reflectedRay.direction * 0.001f;
             radiance += hit.specular * render(nearestPhotons, reflectedRay, rayBounceCount + 1);
         }
     }
     { // transmitted radiance
         if (rayBounceCount + 1 < maxRayBounceCount() && luminance(hit.transmission) > 0.0f) {
             Ray transmittedRay;
             transmittedRay.origin = hit.position;
             if (dot(hit.normal, ray.direction) <= 0.0f) {
                 transmittedRay.direction = transmit(ray.direction, +hit.normal, 1.0f / hit.refractionIndex);
             } else {
                 transmittedRay.direction = transmit(ray.direction, -hit.normal, hit.refractionIndex / 1.0f);
             }
             transmittedRay.origin += transmittedRay.direction * 0.001f;
             if (!nan(sqrLength(transmittedRay.direction))) {
                 radiance += hit.transmission * render(nearestPhotons, transmittedRay, rayBounceCount + 1);
             }
         }
     }
     return radiance;
 }
Beispiel #2
0
 void Label::mouseMoveEvent(QMouseEvent* event) {
     if (m_mousePosition) {
         Point2i oldMousePosition = *m_mousePosition;
         *m_mousePosition = Point2i(event->pos().x(), event->pos().y());
         Vector2i displacement = *m_mousePosition - oldMousePosition;
         if (sqrLength(displacement) > 0) {
             emit mouseMoved(*m_mousePosition, displacement);
         }
     } else {
         m_mousePosition = new Point2i(event->pos().x(), event->pos().y());
         emit mouseEntered(*m_mousePosition);
     }
     event->accept();
 }
Beispiel #3
0
 //! Return length of vector.
 Type length() const
 {
     return (Type)std::sqrt( sqrLength() );
 }
    Photon Renderer::emitAndScatter(Random &random) {
        float currentRefractionIndex = 1.0;
        Scene::Sample sample;
        do {
            sample = scene()->uniformOnSurface(random);
        } while (luminance(sample.emission) * sample.emissionPower == 0.0f);
        float hitDistance; Scene::Sample hit;
        Ray ray;
        ray.origin = sample.position;
        do {
            ray.direction = random.cosineDirection(sample.normal);
        } while (!scene()->hit(ray, hitDistance, hit));
        Photon photon;
        photon.position = hit.position;
        photon.direction = ray.direction;
        photon.power = sample.emission * sample.emissionPower;
        while (true) {
            float action = random.uniformInRange01();

            float specularLuminance = luminance(hit.specular);
            if (action < specularLuminance) {
                Ray reflectedRay;
                reflectedRay.origin = hit.position;
                reflectedRay.direction = reflect(ray.direction, hit.normal);
                reflectedRay.origin += reflectedRay.direction * 0.001f;
                ray = reflectedRay;
                if (!scene()->hit(ray, hitDistance, hit)) {
                    photon.power = Color::BLACK;
                    break;
                }
                photon.position = hit.position;
                photon.direction = ray.direction;
                continue;
            } else {
                action -= specularLuminance;
            }

            float transmissionLuminance = luminance(hit.transmission);
            if (action < transmissionLuminance) {
                Ray transmittedRay;
                transmittedRay.origin = hit.position;
                if (dot(hit.normal, ray.direction) <= 0.0f) {
                    transmittedRay.direction = transmit(ray.direction, +hit.normal, 1.0f / hit.refractionIndex);
                } else {
                    transmittedRay.direction = transmit(ray.direction, -hit.normal, hit.refractionIndex / 1.0f);
                }
                transmittedRay.origin += transmittedRay.direction * 0.001f;
                ray = transmittedRay;
                if (nan(sqrLength(ray.direction)) || !scene()->hit(ray, hitDistance, hit)) {
                    photon.power = Color::BLACK;
                    break;
                }
                photon.position = hit.position;
                photon.direction = ray.direction;
                continue;
            } else {
                action -= transmissionLuminance;
            }

            // absorbtion;
            break;
        }
        return photon;
    }
Beispiel #5
0
float sqrDistance(const Vector4& a, const Vector4& b)
{
    return sqrLength(b - a);
}
Beispiel #6
0
 eF32 length() const
 {
     return eSqrt(sqrLength());
 }
 inline float length(Vector3f const& v) {
     return sqrt(sqrLength(v));
 }