constexpr ã¬ã¤ãã¬ã¼ã·ã³ã°
ããã¯ãSprout.Darkroom ã©ã¤ãã©ãªã® constexpr ã¬ã¤ãã¬ã¼ãµã¼ã§ã¬ã³ããªã³ã°ããç»åã§ãã
ç»åãµã¤ãºã¯ 512Ã512 pixelã
ãã¡ããç»ç´ ãã¼ã¿ã¯ãã¹ã¦ã³ã³ãã¤ã«æã«çæããããã¡ã¤ã«åºåã®ã¿ãå®è¡æã«è¡ãªããã¦ãã¾ãã
å
æºã¯æåå³å´ã«ãããæåã®éè²ããã£ãçãã奥ã®èµ¤è²ããã£ãçã¸è½ã¡ãå½±ãã
åå°ã«ããçå½¢ã®æ ãè¾¼ã¿ã確èªã§ããã¨æãã¾ãã
ã¬ã¤ãã¬ã¼ã·ã³ã°ã®åºæ¬çãªã¢ã«ã´ãªãºã ã¯ã¨ã¦ãã·ã³ãã«ã§ãã
è¦ç¹ããåãã¯ã»ã«ãéãå
ç·ãé£ã°ãã¦ããã¯ãã«ã ãªãã¸ã§ã¯ãã¨äº¤å·®ããé¨åã®æ¡æ£å
ã¨åå°å
ã®æåãå¾ãã ãã§ãã
ãã¦ãã§ã¯ãã® Sprout.Darkroom ã constexpr ã§ã©ãå®è£
ããã¦ãããè¦ã¦ãããã¨ã«ãã¾ãããã
ã¨ã¦ãæå¿«ã§è§£ããããå®è£
ã§ãã
ãªã Sprout.Darkroom ã¯æªã éçºéä¸ã®ã©ã¤ãã©ãªã§ãããæ±ãããªãã¸ã§ã¯ãã¨ãã¦çããå®è£
ãã¦ããªãã£ããã
é¢æ°ãã¯ã©ã¹ã®ã¤ã³ã¿ãã§ã¼ã¹ã¯ä»å¾å¤æ´ãããå¯è½æ§ããããã¨ããäºæ¿ãã ããã
ã¾ãã使ç¨ããã¦ãããã¯ããã¯ã constexpr èªä½ã®ä»æ§ã«ã¤ãã¦ã¯ã
ååºã®ãä¸ï¼å¥³åã§ãããã constexprããä¸éãèªãã§ããç¨åº¦ã®ç¥èãåæã¨ãããã¨ãäºããæããã¦ããã¾ãã
ã©ã¤ãã©ãªè¨è¨ã«ã¤ãã¦
Sprout.Darkroom ã¯ãã³ã³ã»ãããã¼ã¹ã®è¨è¨ã«ãªã£ã¦ãã¾ãã
ã³ã³ã»ãããã¼ã¹ã¨ã¯ãBoost.Fusion ã Boost.Geometry ã®ããã«ã
åã決ãæã¡ãããç¶æ¿é¢ä¿ãè¦æ±ãããã¨ãªããå¿
è¦ãªæä½ã«ãã£ã¦åã®æºããã¹ãè¦ä»¶ã決å®ãã¾ãã
ã¦ã¼ã¶ãæ©è½ãæ¡å¼µãããå ´åã«ã¯ãç¹æ®åããªã¼ãã¼ãã¼ãã«ãã£ã¦è¡ãªããã¨ã«ãªãã¾ãã
ã¨ããã§ãç¶æ¿é¢ä¿ã«ããä»®æ³é¢æ°ãã¼ã¹ã®åä½ã«ã¹ã¿ãã¤ãºã¯ constexpr ã§ã¯ä½¿ãã¾ããã
ãªããªãã°ãä»®æ³é¢æ°ãæã¤ã¯ã©ã¹ã¯éãªãã©ã«åã§ããã
éãªãã©ã«åã®ãªãã¸ã§ã¯ãã¯ã³ã³ãã¤ã«æå®æ°ã¨ãã¦æ±ããªãããã§ãã
ãã®ãããã³ã³ã»ãããã¼ã¹ã®è¨è¨ã¯ãconstexpr ã©ã¤ãã©ãªã®è¨è¨ã«æ¬ ãããªããã®ã ã¨è¨ãã¾ãã
è¨ã£ã¦ãã¾ãã°ããããã®è¨äºã®çµè«é¨åã§ãã
ããã ãç¥ã£ã¦ããã ããã°çµæ§ã§ãã
ãä¸ï¼å¥³åã§ãããã constexprãã§ã¯åã
ã®é¢æ°ãã¯ã©ã¹ã® constexpr åã«ã¤ãã¦è¨åãã¾ãããã
大ããªæ¬ãã¨ãã¦ã® constexpr ã©ã¤ãã©ãªãè¨è¨ããå ´åã¯ããããããã¨ãèããå¿
è¦ãããã¾ãã
以éã¯å®è£
ãã¤ãã¤ãã¨è¦ã¦ããã ãã§ãã
é·ãã®ã§ã³ã¼ãé¨åã¯èªã¿é£ã°ãã¦ãçµæ§ã§ãã
ãã¼ã¿åã®ã¢ã¯ã»ã¹
ã¾ãã¯æ±ããã¼ã¿åã«ã¤ãã¦å®ç¾©ãã¾ãã
æãåºæ¬çãªã®ã¯ãã¯ãã«ãã«ã©ã¼ã§ãããã
ç¹å¾´çãªã®ã¯ãããããããããè¤æ°ã®æåãæã¤ãã¨ã§ãã
- ï¼æ¬¡å ãã¯ãã« (x, y, z)
- RBGã«ã©ã¼ (r, g, b)
ãã®ãããªãã¼ã¿æ§é ã¯å
¸åçãªã¿ãã«ã§ããã¨è¦ãªãã¾ãã
namespace access { // // element // template<std::size_t I, typename T> struct element : public sprout::tuples::tuple_element<I, T> {}; // // size // template<typename T> struct size : public sprout::tuples::tuple_size<T> {}; // // unit // template<typename T> struct unit : public sprout::darkroom::access::element<0, T> {}; // // get // template<std::size_t I, typename T> SPROUT_CONSTEXPR auto get( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::tuples::get<I>(sprout::forward<T>(t)))) -> decltype(sprout::tuples::get<I>(sprout::forward<T>(t))) { return sprout::tuples::get<I>(sprout::forward<T>(t)); } } // namespace access
element ã¯ãã¤ã³ããã¯ã¹ I ã®è¦ç´ ã®åãè¿ãã¡ã¿é¢æ°ã§ãã
size
unit
get ã¯ãT ã®ã¤ã³ããã¯ã¹ I ã®è¦ç´ ãè¿ã constexpr é¢æ°ã§ãã
ããã¦ã¼ã¶ãå¥ã®èªåã®ã¯ã©ã¹ããã¯ãã«åãã«ã©ã¼åã¨ãã¦æ±ãããå ´åã
ãããããªã¼ãã¼ãã¼ããããã¨ã§ã¢ãããã§ãã¾ãã
ãªã SPROUT_CONSTEXPR ã SPROUT_NOEXCEPT_EXPR ã¯ããããã constexpr ã noexcept ã«ç½®æããã¾ãã
RGBã«ã©ã¼
namespace colors { // // r // g // b // template<typename T> SPROUT_CONSTEXPR auto r( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<0>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto g( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<1>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto b( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<2>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<2>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<2>(sprout::forward<T>(t)); } // // rgb // rgb_f // typedef sprout::tuples::tuple<std::uint8_t, std::uint8_t, std::uint8_t> rgb; typedef sprout::tuples::tuple<double, double, double> rgb_f; // // mul // template<typename Color, typename Fac> SPROUT_CONSTEXPR inline Color mul(Color const& lhs, Fac const& rhs) { return sprout::tuples::remake_clone<Color>( lhs, sprout::darkroom::colors::r(lhs) * rhs, sprout::darkroom::colors::g(lhs) * rhs, sprout::darkroom::colors::b(lhs) * rhs ); } // // add // template<typename Color1, typename Color2> SPROUT_CONSTEXPR inline Color1 add(Color1 const& lhs, Color2 const& rhs) { return sprout::tuples::remake_clone<Color1>( lhs, sprout::darkroom::colors::r(lhs) + sprout::darkroom::colors::r(rhs), sprout::darkroom::colors::g(lhs) + sprout::darkroom::colors::g(rhs), sprout::darkroom::colors::b(lhs) + sprout::darkroom::colors::b(rhs) ); } // // filter // template<typename Color1, typename Color2> SPROUT_CONSTEXPR inline Color1 filter(Color1 const& lhs, Color2 const& rhs) { return sprout::tuples::remake_clone<Color1>( lhs, sprout::darkroom::colors::r(lhs) * sprout::darkroom::colors::r(rhs), sprout::darkroom::colors::g(lhs) * sprout::darkroom::colors::g(rhs), sprout::darkroom::colors::b(lhs) * sprout::darkroom::colors::b(rhs) ); } // // rgb_f_to_rgb // template<typename RGB, typename RGB_F> SPROUT_CONSTEXPR inline RGB rgb_f_to_rgb(RGB_F const& col) { typedef typename sprout::darkroom::access::unit<RGB>::type unit_type; return sprout::tuples::make_clone<RGB>( sprout::darkroom::colors::r(col) < 0 ? std::numeric_limits<unit_type>::min() : sprout::darkroom::colors::r(col) > 1 ? std::numeric_limits<unit_type>::max() : sprout::darkroom::colors::r(col) * std::numeric_limits<unit_type>::max() , sprout::darkroom::colors::g(col) < 0 ? std::numeric_limits<unit_type>::min() : sprout::darkroom::colors::g(col) > 1 ? std::numeric_limits<unit_type>::max() : sprout::darkroom::colors::g(col) * std::numeric_limits<unit_type>::max() , sprout::darkroom::colors::b(col) < 0 ? std::numeric_limits<unit_type>::min() : sprout::darkroom::colors::b(col) > 1 ? std::numeric_limits<unit_type>::max() : sprout::darkroom::colors::b(col) * std::numeric_limits<unit_type>::max() ); } } // namespace colors
rgb åã¯ãåè¦ç´ 8 bit ã® RGBã«ã©ã¼ã§ããã¬ã³ããªã³ã°ãããç»ç´ ã«ã¯ãé常ãã®åã使ããã¾ãã
rgb_f åã¯ãåè¦ç´ ãæµ®åå°æ°ç¹æ°ã® RGBã«ã©ã¼ã§ããã«ã©ã¼æ¼ç®ã§ä½¿ç¨ããã¾ãã
æµ®åå°æ°ç¹æ°ãèªç¶ã«ä½¿ããã®ã¯ãconstexpr ã® TMP ã«å¯¾ãã大ããªå©ç¹ã§ãã
r, g, b ãããããã¿ãã«ã® 0, 1, 2 è¦ç´ ç®ã¨ãã¦ãã¾ãã
ãã¡ããä»ã®åã使ãããå ´åã¯ããããããªã¼ãã¼ãã¼ãããå¿
è¦ãããã¾ãã
mul, add, filter ã¨ãã£ãã«ã©ã¼æ¼ç®ãå®ç¾©ããã¦ãã¾ãã
ãã¯ãã«
namespace coords { // // x // y // z // template<typename T> SPROUT_CONSTEXPR auto x( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<0>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto y( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<1>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto z( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<2>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<2>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<2>(sprout::forward<T>(t)); } // // vector3d // typedef sprout::tuples::tuple<double, double, double> vector3d; // // length_sq // template<typename Vector> SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit<Vector>::type length_sq(Vector const& vec) { return sprout::darkroom::coords::x(vec) * sprout::darkroom::coords::x(vec) + sprout::darkroom::coords::y(vec) * sprout::darkroom::coords::y(vec) + sprout::darkroom::coords::z(vec) * sprout::darkroom::coords::z(vec) ; } // // length // template<typename Vector> SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit<Vector>::type length(Vector const& vec) { using std::sqrt; return sqrt(sprout::darkroom::coords::length_sq(vec)); } // // add // template<typename Vector1, typename Vector2> SPROUT_CONSTEXPR inline Vector1 add(Vector1 const& lhs, Vector2 const& rhs) { return sprout::tuples::remake_clone<Vector1>( lhs, sprout::darkroom::coords::x(lhs) + sprout::darkroom::coords::x(rhs), sprout::darkroom::coords::y(lhs) + sprout::darkroom::coords::y(rhs), sprout::darkroom::coords::z(lhs) + sprout::darkroom::coords::z(rhs) ); } // // sub // template<typename Vector1, typename Vector2> SPROUT_CONSTEXPR inline Vector1 sub(Vector1 const& lhs, Vector2 const& rhs) { return sprout::tuples::remake_clone<Vector1>( lhs, sprout::darkroom::coords::x(lhs) - sprout::darkroom::coords::x(rhs), sprout::darkroom::coords::y(lhs) - sprout::darkroom::coords::y(rhs), sprout::darkroom::coords::z(lhs) - sprout::darkroom::coords::z(rhs) ); } // // scale // template<typename Vector, typename Fac> SPROUT_CONSTEXPR inline Vector scale(Vector const& lhs, Fac const& rhs) { return sprout::tuples::remake_clone<Vector>( lhs, sprout::darkroom::coords::x(lhs) * rhs, sprout::darkroom::coords::y(lhs) * rhs, sprout::darkroom::coords::z(lhs) * rhs ); } // // dot // template<typename Vector> SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit<Vector>::type dot(Vector const& lhs, Vector const& rhs) { return sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::x(rhs) + sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::y(rhs) + sprout::darkroom::coords::z(lhs) * sprout::darkroom::coords::z(rhs) ; } // // normalize // namespace detail { template<typename Vector> SPROUT_CONSTEXPR inline Vector normalize_impl( Vector const& vec, typename sprout::darkroom::access::unit<Vector>::type const& len ) { return sprout::tuples::remake_clone<Vector>( vec, sprout::darkroom::coords::x(vec) / len, sprout::darkroom::coords::y(vec) / len, sprout::darkroom::coords::z(vec) / len ); } } // namespace detail template<typename Vector> SPROUT_CONSTEXPR inline Vector normalize(Vector const& vec) { return sprout::darkroom::coords::detail::normalize_impl( vec, sprout::darkroom::coords::length(vec) ); } // // reflect // template<typename Incident, typename Normal> SPROUT_CONSTEXPR inline Incident reflect(Incident const& incid, Normal const& nor) { return sprout::darkroom::coords::sub( incid, sprout::darkroom::coords::scale(nor, sprout::darkroom::coords::dot(incid, nor) * 2) ); } // // normal_to_color // template<typename Color, typename Normal> SPROUT_CONSTEXPR Color normal_to_color(Normal const& nor) { return sprout::tuples::make_clone<Color>( 0.5 + sprout::darkroom::coords::x(nor) * 0.5, 0.5 + sprout::darkroom::coords::y(nor) * 0.5, 0.5 + sprout::darkroom::coords::z(nor) * 0.5 ); } } // namespace coords
vector3d ã¯ãæµ®åå°æ°ç¹æ°ã«ããï¼æ¬¡å
ãã¯ãã«ã§ãã
x, y, z ãããããã¿ãã«ã® 0, 1, 2 è¦ç´ ç®ã¨ãã¦ãã¾ãã
ä»ã®åã使ãããå ´åã¯ããããããªã¼ãã¼ãã¼ãããå¿
è¦ãããã¾ãã
length, add, sub, scale, dot, normalize, reflect ãªã©ã®ãã¯ãã«æ¼ç®ãå®ç¾©ããã¦ãã¾ãã
ãªã normalize ã¯ããã¯ãã«ãåä½ãã¯ãã«ï¼== é·ã 1.0 ã®ãã¯ãã«ï¼ã«ç´ããã®ã§ãã
å ç·
namespace rays { // // position // direction // template<typename T> SPROUT_CONSTEXPR auto position( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<0>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto direction( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<1>(sprout::forward<T>(t)); } // // make_ray // template<typename Position, typename Direction> SPROUT_CONSTEXPR sprout::tuples::tuple<Position, Direction> make_ray(Position const& pos, Direction const& dir) { return sprout::tuples::make_tuple(pos, dir); } // // ray // typedef sprout::tuples::tuple<sprout::darkroom::coords::vector3d, sprout::darkroom::coords::vector3d> ray; // // point_of_intersection // template<typename Ray, typename Distance> SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit<Ray>::type point_of_intersection(Ray const& ray, Distance const& dist) { return sprout::darkroom::coords::add( sprout::darkroom::rays::position(ray), sprout::darkroom::coords::scale(sprout::darkroom::rays::direction(ray), dist) ); } } // namespace ray
ray ã¯ãposition (åç¹ããã®ä½ç½®) 㨠direction (æ¹åã示ãåä½ãã¯ãã«) ã®çµã§ãã
point_of_intersection ã¯ãå ç·ãããè·é¢ã§ãªãã¸ã§ã¯ãã«äº¤å·®ããã¨ãã®ã交差ä½ç½®ã示ããã¯ãã«ãè¿ãã¾ãã
ãããªã¢ã«
namespace materials { // // color // reflection // template<typename T> SPROUT_CONSTEXPR auto color( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<0>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto reflection( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<1>(sprout::forward<T>(t)); } // // calc_color // calc_reflection // template<typename Image, typename Position, typename Normal> SPROUT_CONSTEXPR auto calc_color(Image&& t, Position const&, Normal const&) SPROUT_NOEXCEPT -> decltype(t) { return t; } template<typename Image, typename Position, typename Normal> SPROUT_CONSTEXPR auto calc_reflection(Image&& t, Position const&, Normal const&) SPROUT_NOEXCEPT -> decltype(t) { return t; } // // calc_material // template<typename Material, typename Position, typename Normal> SPROUT_CONSTEXPR auto calc_material(Material const& mat, Position const& pos, Normal const& nor) -> decltype(sprout::tuples::make_tuple( sprout::darkroom::materials::calc_color(sprout::darkroom::materials::color(mat), pos, nor), sprout::darkroom::materials::calc_reflection(sprout::darkroom::materials::reflection(mat), pos, nor) )) { return sprout::tuples::make_tuple( sprout::darkroom::materials::calc_color(sprout::darkroom::materials::color(mat), pos, nor), sprout::darkroom::materials::calc_reflection(sprout::darkroom::materials::reflection(mat), pos, nor) ); } // // make_material_image // template<typename ColorImage, typename ReflectionImage> SPROUT_CONSTEXPR sprout::tuples::tuple<ColorImage, ReflectionImage> make_material_image(ColorImage const& col, ReflectionImage const& ref) { return sprout::tuples::make_tuple(col, ref); } // // material // typedef sprout::tuples::tuple<sprout::darkroom::colors::rgb_f, double> material; } // namespace materials
material ã¯ããªãã¸ã§ã¯ãã®ä»»æã®ä½ç½®ã«é¢é£ä»ããããã«ã©ã¼æåã¨åå°æåã§ãã
ãªããééãå±æã«ã¤ãã¦ã¯å®è£
ããã¦ãã¾ããã
ColorImage ã ReflectionImage ã¯ããªãã¸ã§ã¯ãã«é¢é£ä»ãããåæåãè¨ç®ããå
ã¨ãªããã®ã
ã¤ã¾ãåºå®ã«ã©ã¼ããã¯ã¹ãã£ããããã¹ããã¥ã©ãããã®ãã¨ã§ãã
calc_color, calc_reflection ã¯ãããã ColorImage ã ReflectionImage ããæåãè¨ç®ãããã®ã§ãã
ããã§ã¯åºå®ã«ã©ã¼ãåºå®å¤ã®åå°çã®ã¿å®ç¾©ããã¦ãã¾ãã
ãã¯ã¹ãã£ããããªã©ã®å®è£
ã®éã«ã¯ãããããªã¼ãã¼ãã¼ãããã¾ãã
å ç·ã¨ãªãã¸ã§ã¯ãã®äº¤å·®
namespace intersects { // // does_intersect // distance // point_of_intersection // normal // material // template<typename T> SPROUT_CONSTEXPR auto does_intersect( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<0>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto distance( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<1>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto point_of_intersection( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<2>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<2>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<2>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto normal( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<3>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<3>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<3>(sprout::forward<T>(t)); } template<typename T> SPROUT_CONSTEXPR auto material( T&& t ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<4>(sprout::forward<T>(t)))) -> decltype(sprout::darkroom::access::get<4>(sprout::forward<T>(t))) { return sprout::darkroom::access::get<4>(sprout::forward<T>(t)); } // // make_intersection // template<typename Distance, typename Point, typename Normal, typename Material> SPROUT_CONSTEXPR sprout::tuples::tuple<bool, Distance, Point, Normal, Material> make_intersection(bool b, Distance const& dist, Point const& p, Normal const& nor, Material const& mat) { return sprout::tuples::make_tuple(b, dist, p, nor, mat); } // // intersection // typedef sprout::tuples::tuple< bool, double, sprout::darkroom::coords::vector3d, sprout::darkroom::coords::vector3d, sprout::darkroom::materials::material > intersection; } // namespace intersects
å
ç·ã¨ãªãã¸ã§ã¯ãã®äº¤å·®å¤å®ã«ä½¿ããã¾ãã
does_intersect - 交差ããã
distance - 交差ç¹ã¾ã§ã®è·é¢
point_of_intersection - 交差ç¹ã®ä½ç½®
normal - 交差ç¹ã®æ³ç·ãã¯ãã«
material - 交差ç¹ã®ãããªã¢ã«
intersection ã¯ãããã®ã¿ãã«ã§ããã交差å¤å®é¢æ°ã®è¿å¤ã«ãªãã¾ãã
交差å¤å®
namespace objects { // // intersect // template<typename Object, typename Ray> SPROUT_CONSTEXPR inline typename Object::template intersection<Ray>::type intersect(Object const& obj, Ray const& ray) { return obj.intersect(ray); } // // intersect_list // namespace detail { template<std::size_t N> struct intersect_list_impl { private: template<typename Objects, typename Ray, typename A, typename B> SPROUT_CONSTEXPR typename sprout::darkroom::access::unit<Objects>::type ::template intersection<Ray>::type comp(A const& a, B const& b) const { return sprout::darkroom::intersects::does_intersect(a) && sprout::darkroom::intersects::does_intersect(b) ? sprout::darkroom::intersects::distance(a) < sprout::darkroom::intersects::distance(b) ? a : b : sprout::darkroom::intersects::does_intersect(a) ? a : b ; } public: template<typename Objects, typename Ray> SPROUT_CONSTEXPR typename sprout::darkroom::access::unit<Objects>::type ::template intersection<Ray>::type operator()(Objects const& objs, Ray const& ray) const { return comp<Objects, Ray>( sprout::darkroom::objects::intersect(sprout::darkroom::access::get<N>(objs), ray), intersect_list_impl<N - 1>()(objs, ray) ); } }; template<> struct intersect_list_impl<0> { public: template<typename Objects, typename Ray> SPROUT_CONSTEXPR typename sprout::darkroom::access::unit<Objects>::type ::template intersection<Ray>::type operator()(Objects const& objs, Ray const& ray) const { return sprout::darkroom::objects::intersect(sprout::darkroom::access::get<0>(objs), ray); } }; } // namespace detail template<typename Objects, typename Ray> SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit<Objects>::type ::template intersection<Ray>::type intersect_list(Objects const& objs, Ray const& ray) { return sprout::darkroom::objects::detail::intersect_list_impl< sprout::darkroom::access::size<Objects>::value - 1 >()(objs, ray); } } // namespace objects
intersect ã¯ãå
ç·ã¨ãªãã¸ã§ã¯ãã®äº¤å·®å¤å®ãè¡ã constexpr é¢æ°ã§ãã
å®è£
ã¯ã渡ããããªãã¸ã§ã¯ãã¯ã©ã¹ã® intersect ã¡ã³ãé¢æ°ãå¼ã³åºãã ãã§ãã
ãã¡ããã¦ã¼ã¶ãæããªãã°ãããããªã¼ãã¼ãã¼ããã¦ã«ã¹ã¿ãã¤ãºå¯è½ã§ãã
intersect_list ã¯ãè¤æ°ã®ãªãã¸ã§ã¯ãã®ãªã¹ãï¼ã¿ãã«ï¼ã«ã¤ãã¦äº¤å·®å¤å®ãè¡ãã
æãå
ç·ã®å§ç¹ã«è¿ãï¼æåã«äº¤å·®ããï¼äº¤å·®çµæãè¿ãã¾ãã
çãªãã¸ã§ã¯ã
namespace objects { // // basic_sphere // template<typename Material, typename Position = sprout::darkroom::coords::vector3d> class basic_sphere { public: typedef Material material_type; typedef Position position_type; typedef typename sprout::darkroom::access::unit<position_type>::type unit_type; typedef unit_type radius_type; public: template<typename Ray> struct intersection { typedef sprout::tuples::tuple< bool, unit_type, position_type, position_type, decltype(sprout::darkroom::materials::calc_material( std::declval<material_type const&>(), std::declval<position_type const&>(), std::declval<position_type const&>() )) > type; }; private: typedef sprout::tuples::tuple<int, bool, unit_type> zwo_type; typedef sprout::tuples::tuple<position_type, position_type> drei_type; struct zw { SPROUT_STATIC_CONSTEXPR std::size_t hit_side = 0; SPROUT_STATIC_CONSTEXPR std::size_t does_intersect = 1; SPROUT_STATIC_CONSTEXPR std::size_t distance = 2; }; struct dr { SPROUT_STATIC_CONSTEXPR std::size_t point_of_intersection = 0; SPROUT_STATIC_CONSTEXPR std::size_t normal = 1; }; private: position_type pos_; radius_type rad_; material_type mat_; private: template<typename Ray> SPROUT_CONSTEXPR zwo_type zweitens_2( Ray const& ray, unit_type const& i1, unit_type const& i2, int hit_side, bool does_intersect ) const { return zwo_type( hit_side, does_intersect, hit_side < 0 ? i2 : hit_side > 0 ? i1 : -1 ); } template<typename Ray> SPROUT_CONSTEXPR zwo_type zweitens_1( Ray const& ray, unit_type const& i1, unit_type const& i2 ) const { return zweitens_2( ray, i1, i2, i2 > 0 ? i1 < 0 ? -1 : 1 : 0 , i2 > 0 ); } template<typename Ray> SPROUT_CONSTEXPR zwo_type zweitens( Ray const& ray, bool neg, unit_type const& b, unit_type const& det ) const { return neg ? zweitens_1(ray, b - det, b + det) : zwo_type(0, false, -1) ; } template<typename Ray> SPROUT_CONSTEXPR drei_type drittens_1( Ray const& ray, typename sprout::darkroom::access::unit<Ray>::type point_of_intersection ) const { return drei_type( point_of_intersection, sprout::darkroom::coords::normalize( sprout::darkroom::coords::sub(point_of_intersection, pos_) ) ); } template<typename Ray> SPROUT_CONSTEXPR drei_type drittens( Ray const& ray, bool neg, unit_type const& distance ) const { return neg ? drittens_1(ray, sprout::darkroom::rays::point_of_intersection(ray, distance)) : drei_type( sprout::tuples::make_clone<position_type>(0, 0, 0), sprout::tuples::make_clone<position_type>(1, 1, 1) ) ; } template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_5( Ray const& ray, zwo_type const& zwo, drei_type const& drei ) const { return typename intersection<Ray>::type( sprout::tuples::get<zw::does_intersect>(zwo), sprout::tuples::get<zw::distance>(zwo), sprout::tuples::get<dr::point_of_intersection>(drei), sprout::tuples::get<dr::normal>(drei), sprout::darkroom::materials::calc_material( mat_, sprout::tuples::get<dr::point_of_intersection>(drei), sprout::tuples::get<dr::normal>(drei) ) ); } template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_4( Ray const& ray, zwo_type const& zwo ) const { return intersect_5( ray, zwo, drittens( ray, sprout::tuples::get<zw::does_intersect>(zwo), sprout::tuples::get<zw::distance>(zwo) ) ); } template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_3( Ray const& ray, unit_type const& b, unit_type const& det_sq ) const { using std::sqrt; return intersect_4( ray, zweitens( ray, det_sq > 0, b, sqrt(det_sq) ) ); } template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_2( Ray const& ray, position_type const& v, unit_type const& b ) const { return intersect_3( ray, b, b * b - sprout::darkroom::coords::length_sq(v) + rad_ * rad_ ); } template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_1( Ray const& ray, position_type const& v ) const { return intersect_2( ray, v, -sprout::darkroom::coords::dot(v, sprout::darkroom::rays::direction(ray)) ); } public: SPROUT_CONSTEXPR basic_sphere( position_type const& pos, radius_type rad, material_type const& mat ) : pos_(pos) , rad_(rad) , mat_(mat) {}; template<typename Ray> SPROUT_CONSTEXPR typename intersection<Ray>::type intersect(Ray const& ray) const { return intersect_1( ray, sprout::darkroom::coords::sub(sprout::darkroom::rays::position(ray), pos_) ); } }; // // make_sphere // template<typename Material, typename Position, typename Radius> SPROUT_CONSTEXPR inline sprout::darkroom::objects::basic_sphere<Material, Position> make_sphere(Position const& pos, Radius const& rad, Material const& mat) { return sprout::darkroom::objects::basic_sphere<Material, Position>(pos, rad, mat); } } // namespace objects
basic_sphere ã¯çã表ç¾ãããªãã¸ã§ã¯ãã§ãå
ç·ã¨ã®äº¤å·®å¤å®ãè¡ã intersect ã¡ã³ãé¢æ°ãæã¡ã¾ãã
éã«è¨ãã°ãintersect ã ãæã£ã¦ããã°ãªãã¸ã§ã¯ãã¯ã©ã¹ã¨ãã¦å®ç¾©ã§ããã¨ãããã¨ã§ãã
ç¶æ¿é¢ä¿ãªã©ã¯è¦æ±ããã¾ãããä»®æ³é¢æ°ãæã¤å¿
è¦ã¯ããã¾ããã
ãããã³ã³ã»ãããã¼ã¹ã©ã¤ãã©ãªã®ç¹å¾´ã¨è¨ãã¾ãã
è¨ç®å¼ã«ã¤ãã¦ã¯ãæ°å¦ã§ç´ç·ã¨çã®äº¤ç¹ãæ±ããã®ã¨åãã§ãã
constexpr é¢æ°ã®å¶ç´ããé常ã«åããé£ããªã£ã¦ãã¾ãã
constexpr ããå¼·åãªè¡¨ç¾åãæã£ã¦ããªããå®è£
ãåä»ãªã®ã¯ãã®ç¹ã«å°½ããã¨æãã¾ãã
ç¹å æº
namespace lights { // // basic_point_light // template< typename Position = sprout::darkroom::coords::vector3d, typename Color = sprout::darkroom::colors::rgb_f > class basic_point_light { public: typedef Position position_type; typedef typename sprout::darkroom::access::unit<position_type>::type unit_type; typedef Color color_type; private: position_type pos_; color_type col_; private: template<typename Intersection> SPROUT_CONSTEXPR color_type shade_4( Intersection const& inter, unit_type const& intensity ) const { return sprout::tuples::remake_clone<color_type>( col_, sprout::darkroom::colors::r(col_) * sprout::darkroom::colors::r( sprout::darkroom::materials::color( sprout::darkroom::intersects::material(inter) ) ) * intensity , sprout::darkroom::colors::g(col_) * sprout::darkroom::colors::g( sprout::darkroom::materials::color( sprout::darkroom::intersects::material(inter) ) ) * intensity , sprout::darkroom::colors::b(col_) * sprout::darkroom::colors::b( sprout::darkroom::materials::color( sprout::darkroom::intersects::material(inter) ) ) * intensity ); } template<typename Intersection, typename LightRayIntersection> SPROUT_CONSTEXPR color_type shade_3( Intersection const& inter, position_type const& diff, position_type const& direction, LightRayIntersection const& light_ray_inter ) const { return shade_4( inter, !sprout::darkroom::intersects::does_intersect(light_ray_inter) || sprout::darkroom::intersects::distance(light_ray_inter) > sprout::darkroom::coords::length(diff) || sprout::darkroom::intersects::distance(light_ray_inter) < std::numeric_limits<unit_type>::epsilon() ? NS_SSCRISK_CEL_OR_SPROUT_DETAIL::max( std::numeric_limits<unit_type>::epsilon(), sprout::darkroom::coords::dot( direction, sprout::darkroom::intersects::normal(inter) ) / (sprout::darkroom::coords::length(diff) + 1) ) : 0 ); } template<typename Intersection, typename Objects> SPROUT_CONSTEXPR color_type shade_2( Intersection const& inter, Objects const& objs, position_type const& diff, position_type const& direction ) const { return shade_3( inter, diff, direction, sprout::darkroom::objects::intersect_list( objs, sprout::darkroom::rays::make_ray( sprout::darkroom::coords::add( sprout::darkroom::coords::scale( direction, std::numeric_limits<unit_type>::epsilon() * 256 ), sprout::darkroom::intersects::point_of_intersection(inter) ), direction ) ) ); } template<typename Intersection, typename Objects> SPROUT_CONSTEXPR color_type shade_1( Intersection const& inter, Objects const& objs, position_type const& diff ) const { return shade_2( inter, objs, diff, sprout::darkroom::coords::normalize(diff) ); } public: SPROUT_CONSTEXPR basic_point_light( position_type const& pos, color_type const& col ) : pos_(pos) , col_(col) {} template<typename Intersection, typename Objects> SPROUT_CONSTEXPR color_type operator()(Intersection const& inter, Objects const& objs) const { return shade_1( inter, objs, sprout::darkroom::coords::sub( pos_, sprout::darkroom::intersects::point_of_intersection(inter) ) ); } }; // // make_point_light // template<typename Position, typename Color> SPROUT_CONSTEXPR inline sprout::darkroom::lights::basic_point_light<Position, Color> make_point_light(Position const& pos, Color const& col) { return sprout::darkroom::lights::basic_point_light<Position, Color>(pos, col); } } // namespace lights
basic_point_light ã¯ç¹å
æºã表ç¾ãã¾ãã
ç¹å
æºã¯ãããä¸ç¹ããæ¾ãããå
æºã§ãããå
æºããã®è·é¢ã«ãã£ã¦æ¸è¡°ããã¨ããç¹å¾´ãæã¡ã¾ãã
operator() ã¯ãªãã¸ã§ã¯ãã®ãªã¹ãã¨äº¤å·®çµæãã¨ãã交差ä½ç½®ã®é°å½±ãè¨ç®ãã¾ãã
ãã®é°å½±ãé常 diffuse ï¼æ¡æ£å
ï¼æåã¨ãã¦ä½¿ããã¾ãã
交差ç¹ããå
æºã¾ã§ã®ãã¯ãã«ãã·ã£ãã¦ãã¹ãã¬ã¤ã¨è¨ãããããéä¸ã§ä»ã®ãªãã¸ã§ã¯ãã¨äº¤å·®ããªãããã§ãã¯ãã¾ãã
ãã交差ãã¦ããããä»ã®ãªãã¸ã§ã¯ãã«ãã£ã¦å
ãé®è½ããã¦ãããã¨ã«ãªãããã®é¨åã¯å½±ã«ãªãã¾ãã
ã«ã¡ã©
namespace cameras { template<typename Unit = double> class basic_simple_camera { public: typedef Unit unit_type; typedef sprout::tuples::tuple<unit_type, unit_type, unit_type> position_type; typedef sprout::tuples::tuple<position_type, position_type> ray_type; private: unit_type far_plane_; public: SPROUT_CONSTEXPR explicit basic_simple_camera( unit_type const& far_plane ) : far_plane_(far_plane) {} SPROUT_CONSTEXPR ray_type operator()(unit_type const& u, unit_type const& v) const { return ray_type( position_type(0, 0, 0), sprout::darkroom::coords::normalize(position_type(u, v, far_plane_)) ); } }; // // make_simple_camera // template<typename Unit> SPROUT_CONSTEXPR inline sprout::darkroom::cameras::basic_simple_camera<Unit> make_simple_camera(Unit const& far_plane) { return sprout::darkroom::cameras::basic_simple_camera<Unit>(far_plane); } } // namespace cameras
ã«ã¡ã©ã«ãã£ã¦è¦³æ¸¬è
ã®è¦ç¹ã決å®ããã¾ãã
basic_simple_camera ã¯æãåç´ãªå®ç¹ã«ã¡ã©ã§ãã£ã¦ã常ã«åç¹ãã z æ¹åã«åãã¾ãã
far_plane ã®å¤ã¯ç»è§ã®æè¿åã®è·é¢ã§ããã
è¦ç¹ï¼åç¹ï¼ãããã®è·é¢ã®ä½ç½®ã«ã¬ã³ããªã³ã°ããç©å½¢ãç½®ããã¨ã«ãªãã¾ãã
ã¬ã³ãã©
namespace renderers { // // whitted_mirror // class whitted_mirror { private: template< typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Intersection, typename Tracer, typename Direction > SPROUT_CONSTEXPR Color color_1( Camera const& camera, Objects const& objs, Lights const& lights, Ray const& ray, Intersection const& inter, Tracer const& tracer, std::size_t depth_max, Direction const& reflect_dir ) const { return tracer.template operator()<Color>( camera, objs, lights, sprout::tuples::remake_clone<Ray>( ray, sprout::darkroom::coords::add( sprout::darkroom::intersects::point_of_intersection(inter), sprout::darkroom::coords::scale( reflect_dir, std::numeric_limits<typename sprout::darkroom::access::unit<Direction>::type>::epsilon() * 256 ) // !!! // sprout::darkroom::coords::scale( // sprout::darkroom::intersects::normal(inter), // std::numeric_limits<typename sprout::darkroom::access::unit<Direction>::type>::epsilon() * 256 // ) ), reflect_dir ), depth_max - 1 ); } public: template< typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Intersection, typename Tracer > SPROUT_CONSTEXPR Color operator()( Camera const& camera, Objects const& objs, Lights const& lights, Ray const& ray, Intersection const& inter, Tracer const& tracer, std::size_t depth_max ) const { typedef typename std::decay< decltype(sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter))) >::type reflection_type; return depth_max > 0 && sprout::darkroom::intersects::does_intersect(inter) && sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) > std::numeric_limits<reflection_type>::epsilon() ? color_1<Color>( camera, objs, lights, ray, inter, tracer, depth_max, sprout::darkroom::coords::reflect( sprout::darkroom::rays::direction(ray), sprout::darkroom::intersects::normal(inter) ) ) : sprout::tuples::make_clone<Color>(0, 0, 0) ; } }; // // whitted_style // class whitted_style { private: template< typename Color, typename Ray, typename Intersection > SPROUT_CONSTEXPR Color color_3( Ray const& ray, Intersection const& inter, Color const& diffuse_color, Color const& mirror_color ) const { return sprout::darkroom::intersects::does_intersect(inter) ? sprout::darkroom::colors::add( sprout::darkroom::colors::mul( diffuse_color, 1 - sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) ), sprout::darkroom::colors::mul( sprout::darkroom::colors::filter( sprout::darkroom::materials::color(sprout::darkroom::intersects::material(inter)), mirror_color ), sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) ) ) : sprout::darkroom::coords::normal_to_color<Color>(sprout::darkroom::rays::direction(ray)) ; } template< typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Intersection > SPROUT_CONSTEXPR Color color_2( Camera const& camera, Objects const& objs, Lights const& lights, Ray const& ray, std::size_t depth_max, Intersection const& inter, Color const& diffuse_color ) const { return color_3<Color>( ray, inter, diffuse_color, sprout::darkroom::renderers::whitted_mirror().template operator()<Color>( camera, objs, lights, ray, inter, *this, depth_max ) ); } template< typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Intersection > SPROUT_CONSTEXPR Color color_1( Camera const& camera, Objects const& objs, Lights const& lights, Ray const& ray, std::size_t depth_max, Intersection const& inter ) const { return color_2<Color>( camera, objs, lights, ray, depth_max, inter, lights.template operator()(inter, objs) ); } public: template< typename Color, typename Camera, typename Objects, typename Lights, typename Ray > SPROUT_CONSTEXPR Color operator()( Camera const& camera, Objects const& objs, Lights const& lights, Ray const& ray, std::size_t depth_max ) const { return color_1<Color>( camera, objs, lights, ray, depth_max, sprout::darkroom::objects::intersect_list(objs, ray) ); } }; } // namespace renderers
æãåç´ãªãã©ã¼åå°ã®ã¢ãã«ã®å®è£
ã§ãã
ãã¬ãã«ä¿æ°ãå±æã¯å
¨ãèæ
®ãã¦ãã¾ããã
diffuseï¼æ¡æ£å
ï¼æå㨠mirrorï¼åå°å
ï¼æåãããããªã¢ã«ã®ã¹ããã¥ã©å¤ã«å¿ãã¦è¶³ãåããã¾ãã
åå°å
æåã¯ãåå°ããå
ã«ã¤ãã¦å帰çã«è¨ç®ããã¾ãã
ãªãã¸ã§ã¯ãã®é
ç½®ã«ãã£ã¦ã¯ä½åº¦ãä½åº¦ãåå°ããã®ã§ãé常åå°æ·±åº¦ã®éçãè¨å®ãã¾ãã
ã¬ã¤ãã¬ã¼ãµã¼
namespace tracers { // // raytracer // template<typename Color = sprout::darkroom::colors::rgb_f> class raytracer { public: typedef Color color_type; public: template< typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit > SPROUT_CONSTEXPR color_type operator()( Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, Unit const& x, Unit const& y, Unit const& width, Unit const& height, std::size_t depth_max = 8 ) const { return renderer.template operator()<color_type>( camera, objs, lights, camera.template operator()( static_cast<typename Camera::unit_type>(x) / width - 0.5, static_cast<typename Camera::unit_type>(y) / height - 0.5 ), depth_max ); } }; } // namespace tracers
raytracer ã¯ãã¬ã³ãã©ãã·ã¼ã³æ§æè¦ç´ ããã¨ã«ãããç»ç´ ã«å¯¾ããã¬ã¤ãã¬ã¼ã¹ãéå§ãã¾ãã
å¦çã®å®éã«ã¤ãã¦ã¯ãã¬ã³ãã©ã®å®è£
ã«å§è²ããã¾ãã
ãã¯ã»ã«çæ
namespace pixels { // // generate // namespace detail { template< typename Pixels, typename RayTracer, typename Renderer, typename Camera, typename Objects, typename Lights, std::ptrdiff_t... XIndexes > SPROUT_CONSTEXPR inline typename sprout::fixed_container_traits<Pixels>::value_type generate_impl_line( RayTracer const& raytracer, Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type x , typename sprout::fixed_container_traits<Pixels>::size_type y, typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type width , typename sprout::fixed_container_traits<Pixels>::size_type height, std::size_t depth_max, sprout::index_tuple<XIndexes...> ) { typedef typename sprout::fixed_container_traits<Pixels>::value_type pixel_line_type; typedef typename sprout::fixed_container_traits<pixel_line_type>::value_type pixel_type; return sprout::make_clone<pixel_line_type>( sprout::darkroom::colors::rgb_f_to_rgb<pixel_type>( raytracer.template operator()( renderer, camera, objs, lights, x + XIndexes, y, width, height, depth_max ) )... ); } template< typename Pixels, typename RayTracer, typename Renderer, typename Camera, typename Objects, typename Lights, std::ptrdiff_t... YIndexes > SPROUT_CONSTEXPR inline Pixels generate_impl( RayTracer const& raytracer, Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type x , typename sprout::fixed_container_traits<Pixels>::size_type y, typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type width , typename sprout::fixed_container_traits<Pixels>::size_type height, std::size_t depth_max, sprout::index_tuple<YIndexes...> ) { return sprout::make_clone<Pixels>( sprout::darkroom::pixels::detail::generate_impl_line<Pixels>( raytracer, renderer, camera, objs, lights, x, y + YIndexes, width, height, depth_max, typename sprout::index_range< 0, sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::fixed_size >::type() )... ); } } // namespace detail template< typename Pixels, typename RayTracer, typename Renderer, typename Camera, typename Objects, typename Lights > SPROUT_CONSTEXPR inline Pixels generate( RayTracer const& raytracer, Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type x = 0 , typename sprout::fixed_container_traits<Pixels>::size_type y = 0 , typename sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::size_type width = sprout::fixed_container_traits< typename sprout::fixed_container_traits<Pixels>::value_type >::fixed_size , typename sprout::fixed_container_traits<Pixels>::size_type height = sprout::fixed_container_traits<Pixels>::fixed_size , std::size_t depth_max = 8 ) { return sprout::darkroom::pixels::detail::generate_impl<Pixels>( raytracer, renderer, camera, objs, lights, x, y, width, height, depth_max, typename sprout::index_range< 0, sprout::fixed_container_traits<Pixels>::fixed_size >::type() ); } // // color_pixels // template<std::size_t Width, std::size_t Height, typename Color = sprout::darkroom::colors::rgb> struct color_pixels { public: typedef sprout::array< sprout::array<Color, Width>, Height > type; }; } // namespace pixels
ç»åã¤ã¡ã¼ã¸ã¯ããã¯ã»ã«åã®ï¼æ¬¡å
é
åã¨ãã¦è¡¨ç¾ããã¾ãã
generate é¢æ°ã«ãã£ã¦ãåã
ã®ãã¯ã»ã«ã«ã¤ãã¦ã¬ã¤ãã¬ã¼ã¹ãå®è¡ããã¾ãã
ãã㧠index_tuple ã¤ãã£ãªã ãç¨ãããã¦ãã¾ãã
ç¹°ãè¿ãå¦çãå帰ç¡ãã«æ¸ãã¾ãã
ç´ æ´ãããã§ããã
ã¦ã¼ã¶ã³ã¼ã
- darkroom.cpp
// // DARKROOM_TOTAL_WIDTH // DARKROOM_TOTAL_HEIGHT // #ifndef DARKROOM_TOTAL_WIDTH #define DARKROOM_TOTAL_WIDTH 32 #endif #ifndef DARKROOM_TOTAL_HEIGHT #define DARKROOM_TOTAL_HEIGHT DARKROOM_TOTAL_WIDTH #endif // // DARKROOM_TILE_WIDTH // DARKROOM_TILE_HEIGHT // #ifndef DARKROOM_TILE_WIDTH #define DARKROOM_TILE_WIDTH DARKROOM_TOTAL_WIDTH #endif #ifndef DARKROOM_TILE_HEIGHT #define DARKROOM_TILE_HEIGHT DARKROOM_TOTAL_HEIGHT #endif // // DARKROOM_OFFSET_X // DARKROOM_OFFSET_Y // #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 <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_sphere( coords::vector3d(-1.0, -0.5, 5.0), 1.0, materials::make_material_image( colors::rgb_f(1.0, 0.75, 0.75), 0.2 ) ), objects::make_sphere( coords::vector3d(0.5, 0.5, 3.5), 1.0, materials::make_material_image( colors::rgb_f(0.75, 0.75, 1.0), 0.2 ) ), objects::make_sphere( coords::vector3d(0.5, -0.5, 3.0), 0.5, materials::make_material_image( colors::rgb_f(1.0, 1.0, 1.0), 0.75 ) ) ); SPROUT_STATIC_CONSTEXPR auto light = lights::make_point_light( coords::vector3d(1.0, 0.5, 1.0), colors::rgb_f(3.0, 3.0, 3.0) ); SPROUT_STATIC_CONSTEXPR auto camera = cameras::make_simple_camera(1.0); 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 ; } } }
ãããæåã®æ¹ã§ç¤ºããç»åã®ã¬ã³ããªã³ã°ã«ä½¿ã£ãã³ã¼ãã§ãã
ãã®ããã«ãã¦ã¼ã¶ã³ã¼ãã§ä½¿ãã¶ãã«ã¯ãreturn æï¼ã¤ããæ¸ããªãã¨ãã£ãå¶ç´ããªãã®ã§ã
ã¦ã¼ã¶ã¯ç¶ºéºãªã³ã¼ããæ¸ããã¨ãã§ãã¾ãã
æå¾ã®é¨åã§æ¨æºåºåã« ppm å½¢å¼ã§æ¸ãåºãã¦ãã¾ãã
å®è¡æã«åºåå
ããã¡ã¤ã«ã«ããã°ãppm å½¢å¼ã®ãã¡ã¤ã«ãåºåããããã¨ã«ãªãã¾ãã
ã·ã§ã«
- darkroom.sh
#!/bin/bash TARGET_DIR=supertrace mkdir -p $TARGET_DIR TOTAL_WIDTH=512 TOTAL_HEIGHT=512 TILE_WIDTH=32 TILE_HEIGHT=32 -I/home/boleros/git/sprout -I/home/boleros/git/cel-export -I/usr/include/opencv -lml -lcvaux -lhighgui -lcv -lcxcore -I/home/boleros/pub darkroom.cpp 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; echo "" > $TARGET_DIR/$2.done; echo "joining..." pushd $TARGET_DIR convert -append $(ls *.ppm | sort -n) darkroom.ppm popd
512Ã512 pixcel ã®ç»ç´ ãä¸æ°ã«çæãããã¨ããã°ã
ããããã©ããªã«ã¡ã¢ãªãç©ãã§ãã¦ãã³ã³ãã¤ã©ãè½ã¡ã¾ãã
darkroom.sh ã§ã¯ããã¯ãå¤ãå¤ãã¤ã¤é£ç¶çã« darkroom.cpp ãã³ã³ãã¤ã«ãã¾ãã
16Ã16 pixcel æ¯ã®ã¿ã¤ã«ã¨ãã¦ç»åãçæãããããçµåã㦠512Ã512 pixcel ã®ç»åã¨ãã¦ãã¾ãã
ã¾ã¨ã
以ä¸ãããã Sprout.Darkroom ã®å®è£ ã®å ¨è²ã§ãã
æ£ç´ããã¾ãã®ï¼constexpr ã®å¶éããæ¥ãï¼å®è£
ã®æ±ãã«ãconstexpr ã«åæ°ãããã人ãããããããã¾ããã
ãããã constexpr ã®ä»æ§èªä½ãããããç¨éãæ³å®ãããã®ã§ã¯ãªãã¨ãããã¨ãããã¾ãã
ããããªãããconstexpr ã¯é常ã®ã·ã³ãã«ãªä½¿ç¨ã«ããã¦ã¯ TMP ããã¯ãã«ããã³ã³ãã¤ã«æè¨ç®ã
ããè¯ãç½®ãæãããã¨ã®åºæ¥ãé常ã«ä½¿ããããéå
·ã§ãããã¨ã¯ç¢ºãã§ãã
ãã®ä¸ã§ã³ã³ãã¤ã«æã«æ´ã«è²ã
éãã§ã¿ããã¨ãã C++er ã«ã¨ã£ã¦ã¯ã
constexpr ã¯ãã®ä¸ãªãå¯è½æ§ãç§ããéå
·ã§ããã¨ãããã¨ãè¨ããã¨æãã¾ãã
!!! Let's constexpr !!!