Sprout.Darkroom でチェック模様のテクスチャを使ったレンダリング
Sprout.Darkroom は、constexpr ベースのコンパイル時レイトレーシングライブラリです。
https://github.com/bolero-MURAKAMI/Sprout
Sprout.Darkroom は、特定のインタフェースのクラスをテクスチャマップやスペキュラマップとして
オブジェクトに設定する機能があります。
試しにチェック模様のテクスチャクラスを作ってみたので使ってみます。
-
- out.png
床がチェック模様になっています。
模様の黒っぽい側には反射率も設定しているので、映り込みも表現されています。
下記がソースコードです。
gcc 4.7.0 20111126 (experimental) でコンパイルしています。
一度にレンダリングしようとするとメモリが足りないので、
8x8のタイル分割された画像を生成する darkroom.cpp を、darkroom.sh から
連続してコンパイル→実行→画像連結しています。
-
- darkroom.cpp
#ifndef DARKROOM_TOTAL_WIDTH #define DARKROOM_TOTAL_WIDTH 8 #endif #ifndef DARKROOM_TOTAL_HEIGHT #define DARKROOM_TOTAL_HEIGHT DARKROOM_TOTAL_WIDTH #endif #ifndef DARKROOM_TILE_WIDTH #define DARKROOM_TILE_WIDTH DARKROOM_TOTAL_WIDTH #endif #ifndef DARKROOM_TILE_HEIGHT #define DARKROOM_TILE_HEIGHT DARKROOM_TOTAL_HEIGHT #endif #ifndef DARKROOM_OFFSET_X #define DARKROOM_OFFSET_X 0 #endif #ifndef DARKROOM_OFFSET_Y #define DARKROOM_OFFSET_Y 0 #endif #define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION #include <cstddef> #include <cmath> #include <iostream> #include <sprout/config.hpp> #include <sprout/darkroom.hpp> SPROUT_STATIC_CONSTEXPR std::size_t total_width = DARKROOM_TOTAL_WIDTH; SPROUT_STATIC_CONSTEXPR std::size_t total_height = DARKROOM_TOTAL_HEIGHT; SPROUT_STATIC_CONSTEXPR std::size_t tile_width = DARKROOM_TILE_WIDTH; SPROUT_STATIC_CONSTEXPR std::size_t tile_height = DARKROOM_TILE_HEIGHT; SPROUT_STATIC_CONSTEXPR std::size_t offset_x = DARKROOM_OFFSET_X; SPROUT_STATIC_CONSTEXPR std::size_t offset_y = DARKROOM_OFFSET_Y; int main() { using namespace sprout::darkroom; SPROUT_STATIC_CONSTEXPR auto object = sprout::make_tuple( objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::x, -10.0, materials::make_uniform_material_image( colors::rgb_f(1.0, 0.0, 0.0), 0.0 ) ), objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::x, 10.0, materials::make_uniform_material_image( colors::rgb_f(0.0, 1.0, 0.0), 0.0 ) ), objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::y, -3.0, materials::make_plaid_material_image( colors::rgb_f(1.0, 1.0, 1.0), colors::rgb_f(0.25, 0.25, 0.5), 0.0, 0.5 ) ), objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::y, 7.0, materials::make_uniform_material_image( colors::rgb_f(1.0, 1.0, 1.0), 0.0 ) ), objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::z, 12.0, materials::make_uniform_material_image( colors::rgb_f(1.0, 1.0, 1.0), 0.75 ) ), objects::make_aa_plane( sprout::darkroom::objects::aa_plane_direction::z, -2.0, materials::make_uniform_material_image( colors::rgb_f(1.0, 1.0, 1.0), 0.75 ) ), objects::make_sphere( coords::vector3d(-5.0, 1.0, 7.0), 3.0, materials::make_uniform_material_image( colors::rgb_f(1.0, 0.75, 0.75), 0.75 ) ), objects::make_sphere( coords::vector3d(1.25, 1.0, 6.0), 1.0, materials::make_uniform_material_image( colors::rgb_f(0.75, 0.75, 1.0), 0.2 ) ) ); SPROUT_STATIC_CONSTEXPR auto light = lights::make_point_light( coords::vector3d(7.0, 6.0, 4.0), colors::rgb_f(10.0, 10.0, 10.0) ); SPROUT_STATIC_CONSTEXPR auto camera = cameras::make_simple_camera( std::sqrt(3.0) / 2 ); SPROUT_STATIC_CONSTEXPR auto renderer = renderers::whitted_style(); SPROUT_STATIC_CONSTEXPR auto raytracer = tracers::raytracer<>(); typedef pixels::color_pixels<tile_width, tile_height>::type image_type; SPROUT_STATIC_CONSTEXPR auto image = pixels::generate<image_type>( raytracer, renderer, camera, object, light, offset_x, offset_y, total_width, total_height ); std::cout << "P3" << std::endl << image[0].size() << ' ' << image.size() << std::endl << 255 << std::endl ; for (auto i = image.begin(), last = image.end(); i != last; ++i) { auto const& line = *i; for (auto j = line.begin(), last = line.end(); j != last; ++j) { auto const& pixel = *j; std::cout << unsigned(colors::r(pixel)) << ' ' << unsigned(colors::g(pixel)) << ' ' << unsigned(colors::b(pixel)) << std::endl ; } } }
materials::make_plaid_material_image が、チェック模様クラスを生成する部分です。
-
- darkroom.sh
#!/bin/bash TARGET_DIR=darkroom mkdir -p $TARGET_DIR TOTAL_WIDTH=512 TOTAL_HEIGHT=512 TILE_WIDTH=8 TILE_HEIGHT=8 for ((y=0; y<TOTAL_HEIGHT; y+=TILE_HEIGHT)); do for ((x=0; x<TOTAL_WIDTH; x+=TILE_WIDTH)); do mkdir -p $TARGET_DIR/$y/ binname=$x.$y.out g++ -o $binname -std=gnu++0x \ -I/home/boleros/git/sprout \ -DDARKROOM_TOTAL_WIDTH=$TOTAL_WIDTH \ -DDARKROOM_TOTAL_HEIGHT=$TOTAL_HEIGHT \ -DDARKROOM_TILE_WIDTH=$TILE_WIDTH \ -DDARKROOM_TILE_HEIGHT=$TILE_HEIGHT \ -DDARKROOM_OFFSET_X=$x \ -DDARKROOM_OFFSET_Y=$y \ darkroom.cpp && ./$binname > $TARGET_DIR/$y/$x.ppm rm $binname done; pushd $TARGET_DIR/$y/ convert +append $(ls *.ppm | sort -n) ../$y.ppm popd done; pushd $TARGET_DIR convert -append $(ls *.ppm | sort -n) out.ppm popd
次は、コンパイル時にテクスチャ画像ファイルを外部から読み込む機構を作っていく予定です。