新しい機能を全て使ったシーン

全ての機能を一つのシーンにまとめよう。さらに全体に広がる薄い霧と表面下反射 (クリアコート層) を持つ青い球も追加する (表面下反射は直接実装していないが、拡散マテリアルを誘電体マテリアルで包んだものが表面下反射を起こすマテリアルに等しい)。このレンダラの最大の制限はシャドウレイがないことだが、これと引き換えに集光模様と表面下散乱が手に入っている。これは諸刃の剣の設計判断だ。

hittable_list final_scene() {
  hittable_list boxes1;
  auto ground =
    make_shared<lambertian>(make_shared<solid_color>(0.48, 0.83, 0.53));

  const int boxes_per_side = 20;
  for (int i = 0; i < boxes_per_side; i++) {
    for (int j = 0; j < boxes_per_side; j++) {
      auto w = 100.0;
      auto x0 = -1000.0 + i*w;
      auto z0 = -1000.0 + j*w;
      auto y0 = 0.0;
      auto x1 = x0 + w;
      auto y1 = random_double(1,101);
      auto z1 = z0 + w;

      boxes1.add(make_shared<box>(point3(x0,y0,z0), point3(x1,y1,z1), ground));
    }
  }

  hittable_list objects;

  objects.add(make_shared<bvh_node>(boxes1, 0, 1));

  auto light = make_shared<diffuse_light>(make_shared<solid_color>(7, 7, 7));
  objects.add(make_shared<xz_rect>(123, 423, 147, 412, 554, light));

  auto center1 = point3(400, 400, 200);
  auto center2 = center1 + vec3(30,0,0);
  auto moving_sphere_material =
    make_shared<lambertian>(make_shared<solid_color>(0.7, 0.3, 0.1));
  objects.add(make_shared<moving_sphere>(
    center1, center2, 0, 1, 50, moving_sphere_material));

  objects.add(make_shared<sphere>(
    point3(260, 150, 45), 50, make_shared<dielectric>(1.5)));
  objects.add(make_shared<sphere>(
    point3(0, 150, 145), 50, make_shared<metal>(color(0.8, 0.8, 0.9), 10.0)));

  auto boundary = make_shared<sphere>(
    point3(360,150,145), 70, make_shared<dielectric>(1.5));
  objects.add(boundary);
  objects.add(make_shared<constant_medium>(
    boundary, 0.2, make_shared<solid_color>(0.2, 0.4, 0.9)));
  boundary = make_shared<sphere>(
    point3(0, 0, 0), 5000, make_shared<dielectric>(1.5));
  objects.add(make_shared<constant_medium>(
    boundary, .0001, make_shared<solid_color>(1,1,1)));

  auto emat = make_shared<lambertian>(
    make_shared<image_texture>("earthmap.jpg"));
  objects.add(make_shared<sphere>(point3(400,200,400), 100, emat));
  auto pertext = make_shared<noise_texture>(0.1);
  objects.add(make_shared<sphere>(
    point3(220,280,300), 80, make_shared<lambertian>(pertext)));

  hittable_list boxes2;
  auto white = make_shared<lambertian>(make_shared<solid_color>(.73, .73, .73));
  int ns = 1000;
  for (int j = 0; j < ns; j++) {
    boxes2.add(make_shared<sphere>(point3::random(0,165), 10, white));
  }

  objects.add(make_shared<translate>(
    make_shared<rotate_y>(
      make_shared<bvh_node>(boxes2, 0.0, 1.0), 15),
      vec3(-100,270,395)
    )
  );

  return objects;
}
リスト 2.69 [main.cc] 最後のシーン

\(1\) ピクセルごとに \(10{,}000\) レイを放てば次の画像が得られる:

図 2.30:
最後のシーン

さぁクールな画像を自分で作ってみよ! 発展的な文献やここで紹介しなかった機能は https://in1weekend.blogspot.com/ にまとめてある。質問やコメント、クールな画像は ptrshrl@gmail.com まで送ってほしい。

広告