예제 #1
0
        void compute_radiance(
            InputEvaluator&     input_evaluator,
            const Transformd&   light_transform,
            const Vector3d&     axis,
            const Vector3d&     outgoing,
            Spectrum&           radiance) const
        {
            const Vector3d up = light_transform.vector_to_parent(m_up);
            const Vector3d v = -axis;
            const Vector3d u = normalize(cross(up, v));
            const Vector3d n = cross(v, u);

            const double cos_theta = dot(outgoing, axis);
            assert(cos_theta > m_cos_outer_half_angle);

            const Vector3d d = outgoing / cos_theta - axis;
            const float x = static_cast<float>(dot(d, u) * m_rcp_screen_half_size);
            const float y = static_cast<float>(dot(d, n) * m_rcp_screen_half_size);
            const Vector2f uv(0.5f * (x + 1.0f), 0.5f * (y + 1.0f));

            const InputValues* values = input_evaluator.evaluate<InputValues>(m_inputs, uv);
            radiance = values->m_intensity;
            radiance *= static_cast<float>(values->m_intensity_multiplier);

            if (cos_theta < m_cos_inner_half_angle)
            {
                radiance *=
                    static_cast<float>(
                        smoothstep(m_cos_outer_half_angle, m_cos_inner_half_angle, cos_theta));
            }
        }
        double get_autofocus_focal_distance(const Intersector& intersector) const
        {
            // The autofocus considers the scene at the middle of the shutter interval.
            const float time = get_shutter_middle_time();
            const Transformd transform = m_transform_sequence.evaluate(time);

            // Create a ray that goes through the center of the lens.
            ShadingRay ray;
            ray.m_org = transform.get_local_to_parent().extract_translation();
            ray.m_dir = normalize(transform.vector_to_parent(-ndc_to_camera(m_autofocus_target)));
            ray.m_tmin = 0.0;
            ray.m_tmax = numeric_limits<double>::max();
            ray.m_time =
                ShadingRay::Time::create_with_normalized_time(
                    0.5f,
                    get_shutter_open_time(),
                    get_shutter_close_time());
            ray.m_flags = VisibilityFlags::ProbeRay;
            ray.m_depth = 0;

            // Trace the ray.
            ShadingPoint shading_point;
            intersector.trace(ray, shading_point);

            if (shading_point.hit())
            {
                // Hit: compute the focal distance.
                const Vector3d v = shading_point.get_point() - ray.m_org;
                const double af_focal_distance = -transform.vector_to_local(v).z;

                RENDERER_LOG_INFO(
                    "camera \"%s\": autofocus sets focal distance to %f (using camera position at time=%.1f).",
                    get_path().c_str(),
                    af_focal_distance,
                    ray.m_time.m_absolute);

                return af_focal_distance;
            }
            else
            {
                // Miss: focus at infinity.
                RENDERER_LOG_INFO(
                    "camera \"%s\": autofocus sets focal distance to infinity (using camera position at time=%.1f).",
                    get_path().c_str(),
                    ray.m_time.m_absolute);

                return 1.0e38;
            }
        }