示例#1
0
void sun_lightmap::add(sun_lightmap::rays& r, float raylen,
                       yaw_pitch dir2) const
{
    const vector half(0.5, 0.5, 0.5);
    for (int d(0); d < 6; ++d) {
        vector normal(dir_vector[d]);
        vector origin(half + normal * 0.6f);
        vector dir(from_spherical(dir2.x, dir2.y));
        float weight(dot_prod(dir, normal));
        if (weight > 0)
            r[d].add(voxel_raycast(origin, origin + dir * raylen), weight);
    }
}
ambient_occlusion_lightmap::rays
ambient_occlusion_lightmap::precalc (float ambient_raylen, unsigned int count) const
{
    rays result;
    vector center (0.5f, 0.5f, 0.5f);

    for (auto v : golden_spiral(count))
    {
        for (int i (0); i < 5; ++i)
        {
            vector normal (dir_vector[i]);

            // Weight is calculated according to Lambert's cosine law:
            // intensity = cos theta = a . b (for unit vectors)
            float weight (dot_prod(v, normal));
            if (weight <= 0)
                continue;

            // The ray's origin is set to somewhat above the center of the
            // surface.  (Not too close: this darkens corners too much.)
            auto origin (center + normal * 0.8f);
            auto dir (v * ambient_raylen);
            result[i].add(voxel_raycast(origin, origin + dir), weight);
        }
    }

    float max (0);
    for (int i(0); i < 5; ++i)
    {
        if (result[i].weight > max)
            max = result[i].weight;
    }

    max = 1.0f / max;
    for (int i(0); i < 5; ++i)
        result[i].multiply_weight(max);

    return result;
}