[42cursurs]Ray Tracing in One Weekend 12-Defocus Blur


最後の機能はBlur効果を作ることです.ブルーレイは画像をぼかした効果です.原文は、反映しようとする現実のカメラで発生する現象を説明している.しかし、これはすべて実現したわけではないので、目標Blurのために必要なものだけを用意します.
  • Blu-ray、すなわちぼかし画像の効果が実現されます.
  • ブルーレイを実現するために、一部の現実的なカメラ構造を実現する.
  • A Thin Lens Approximation


    これは実際のカメラモデルの画像です.私たちはそこに必要な一部しか採用していません.
    Figure 17: Camera lens model
    次のイメージのように現れます.
    Figure 18: Camera focus plane
    Blur効果自体は、最終的には画像をぼかしているだけです.
    1.固定された光源をレンズから出射するように、一定の範囲内でランダムに出射する光線を選択します.
    2.光線の方向ベクトルは同じなので、光源が固定されていると、その点の近くにある点に接触します.
    3.このように関係のない箇所と、本来触れているものの色を塗ったものを混ぜ合わせると、モザイクのようにイメージがぼやけてしまいます.
    このアイデアでブルーレイ効果を実現します.

    Generating Sample Rays


    Blurの光源の半径をランダムに変更するほど、Blurを強くすることができます.

    vec3.h

    vec3 random_in_unit_disk() {
        while (true) {
            auto p = vec3(random_double(-1,1), random_double(-1,1), 0);
            if (p.length_squared() >= 1) continue;
            return p;
        }
    }

    camera.h

    class camera {
        public:
            camera(
                point3 lookfrom,
                point3 lookat,
                vec3   vup,
                double vfov, // vertical field-of-view in degrees
                double aspect_ratio,
                double aperture,
                double focus_dist
            ) {
                auto theta = degrees_to_radians(vfov);
                auto h = tan(theta/2);
                auto viewport_height = 2.0 * h;
                auto viewport_width = aspect_ratio * viewport_height;
    
                w = unit_vector(lookfrom - lookat);
                u = unit_vector(cross(vup, w));
                v = cross(w, u);
    
                origin = lookfrom;
                horizontal = focus_dist * viewport_width * u;
                vertical = focus_dist * viewport_height * v;
                lower_left_corner = origin - horizontal/2 - vertical/2 - focus_dist*w;
    
                lens_radius = aperture / 2;
            }
    
    
            ray get_ray(double s, double t) const {
                vec3 rd = lens_radius * random_in_unit_disk();
                vec3 offset = u * rd.x() + v * rd.y();
    
                return ray(
                    origin + offset,
                    lower_left_corner + s*horizontal + t*vertical - origin - offset
                );
            }
    
        private:
            point3 origin;
            point3 lower_left_corner;
            vec3 horizontal;
            vec3 vertical;
            vec3 u, v, w;
            double lens_radius;
    };

    main.cc

    point3 lookfrom(3,3,2);
    point3 lookat(0,0,-1);
    vec3 vup(0,1,0);
    auto dist_to_focus = (lookfrom-lookat).length();
    auto aperture = 2.0;
    
    camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus);
    以下の画像を出力します.Blur効果がビューポートに近づくほど、Blur効果は弱くなります.物体がビューポートに近づくほど、光線が前後に接触する物体をランダムに生成する誤差が小さくなるからです.
    Image 20: Spheres with depth-of-field