ボレロ村上 - ENiyGmaA Code

中3女子です。

Sprout.Darkroom でチェック模様のテクスチャを使ったレンダリング

Sprout.Darkroom は、constexpr ベースのコンパイルレイトレーシングライブラリです。
https://github.com/bolero-MURAKAMI/Sprout


Sprout.Darkroom は、特定のインタフェースのクラスをテクスチャマップやスペキュラマップとして
オブジェクトに設定する機能があります。


試しにチェック模様のテクスチャクラスを作ってみたので使ってみます。


床がチェック模様になっています。
模様の黒っぽい側には反射率も設定しているので、映り込みも表現されています。


下記がソースコードです。
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


次は、コンパイル時にテクスチャ画像ファイルを外部から読み込む機構を作っていく予定です。