Пример #1
0
    void weak_white_furnace_test(
        size_t                      num_runs,
        const float                 alpha_x,
        const float                 alpha_y,
        const float                 gamma,
        const float                 angle_step,
        WeakWhiteFurnaceTestResult& result)
    {
        result.m_min_G1 =  numeric_limits<float>::max();
        result.m_max_G1 = -numeric_limits<float>::max();
        result.m_min_result =  numeric_limits<float>::max();
        result.m_max_result = -numeric_limits<float>::max();

        MDF mdf;

        for (size_t i = 0; i < num_runs; ++i)
        {
            static const size_t Bases[] = { 2 };
            const Vector2f s = hammersley_sequence<float, 2>(Bases, num_runs, i);
            const Vector3f v = sample_hemisphere_uniform(s);
            const float G1 = mdf.G1(v, Vector3f(0.0f, 1.0, 0.0f), alpha_x, alpha_y, gamma);

            result.m_min_G1 = std::min(result.m_min_G1, G1);
            result.m_max_G1 = std::max(result.m_max_G1, G1);

            const float cos_thetha_o_4 = std::abs(4.0f * v.y);

            float integral = 0.0f;

            for (float theta = 0.0f; theta < Pi<float>(); theta += angle_step)
            {
                const float cos_theta = std::cos(theta);
                const float sin_theta = std::sin(theta);

                for (float phi = 0.0f; phi < TwoPi<float>(); phi += angle_step)
                {
                    const float cos_phi = std::cos(phi);
                    const float sin_phi = std::sin(phi);

                    const Vector3f l =
                        Vector3f::make_unit_vector(
                            cos_theta,
                            sin_theta,
                            cos_phi,
                            sin_phi);

                    const Vector3f h = normalize(v + l);

                    if (h.y > 0.0f)
                        integral += sin_theta * mdf.D(h, alpha_x, alpha_y, gamma) * G1 / cos_thetha_o_4;
                }
            }

            // Result should be 1.
            integral *= square(angle_step);

            result.m_min_result = std::min(result.m_min_result, integral);
            result.m_max_result = std::max(result.m_max_result, integral);
        }
    }
Пример #2
0
    void weak_white_furnace_test(
        size_t                          num_runs,
        const double                    alpha_x,
        const double                    alpha_y,
        const double                    angle_step,
        WeakWhiteFurnaceTestResult& result)
    {
        result.m_min_G1 =  numeric_limits<double>::max();
        result.m_max_G1 = -numeric_limits<double>::max();
        result.m_min_result =  numeric_limits<double>::max();
        result.m_max_result = -numeric_limits<double>::max();

        MDF mdf;

        for (size_t i = 0; i < num_runs; ++i)
        {
            static const size_t Bases[] = { 2 };
            const Vector2d s = hammersley_sequence<double, 2>(Bases, num_runs, i);
            const Vector3d v = sample_hemisphere_uniform(s);
            const double G1 = mdf.G1(v, Vector3d(0.0, 1.0, 0.0), alpha_x, alpha_y);

            result.m_min_G1 = std::min(result.m_min_G1, G1);
            result.m_max_G1 = std::max(result.m_max_G1, G1);

            const double cos_thetha_o_4 = std::abs(4.0 * v.y);

            double integral = 0.0;

            for (double theta = 0.0; theta < Pi<double>(); theta += angle_step)
            {
                const double cos_theta = std::cos(theta);
                const double sin_theta = std::sin(theta);

                for (double phi = 0.0; phi < TwoPi<double>(); phi += angle_step)
                {
                    const double cos_phi = std::cos(phi);
                    const double sin_phi = std::sin(phi);

                    const Vector3d l =
                        Vector3d::make_unit_vector(
                            cos_theta,
                            sin_theta,
                            cos_phi,
                            sin_phi);

                    const Vector3d h = normalize(v + l);

                    if (h.y > 0.0)
                        integral += sin_theta * mdf.D(h, alpha_x, alpha_y) * G1 / cos_thetha_o_4;
                }
            }

            // Result should be 1.
            integral *= square(angle_step);

            result.m_min_result = std::min(result.m_min_result, integral);
            result.m_max_result = std::max(result.m_max_result, integral);
        }
    }