1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

[sprout.darkroom] implemented refraction

This commit is contained in:
bolero-MURAKAMI 2013-12-06 01:57:31 +09:00
parent 8e3c426684
commit 8e306168da
8 changed files with 197 additions and 37 deletions

View file

@ -117,6 +117,14 @@ namespace sprout {
sprout::darkroom::colors::b(lhs) * rhs sprout::darkroom::colors::b(lhs) * rhs
); );
} }
template<typename Color, typename Fac, typename... Tail>
inline SPROUT_CONSTEXPR Color
mul(Color const& lhs, Fac const& rhs, Tail const&... tail) {
return sprout::darkroom::colors::mul(
sprout::darkroom::colors::mul(lhs, rhs),
tail...
);
}
// //
// add // add
// //
@ -130,6 +138,14 @@ namespace sprout {
sprout::darkroom::colors::b(lhs) + sprout::darkroom::colors::b(rhs) sprout::darkroom::colors::b(lhs) + sprout::darkroom::colors::b(rhs)
); );
} }
template<typename Color1, typename Color2, typename... Tail>
inline SPROUT_CONSTEXPR Color1
add(Color1 const& lhs, Color2 const& rhs, Tail const&... tail) {
return sprout::darkroom::colors::add(
sprout::darkroom::colors::add(lhs, rhs),
tail...
);
}
// //
// filter // filter
// //
@ -143,6 +159,14 @@ namespace sprout {
sprout::darkroom::colors::b(lhs) * sprout::darkroom::colors::b(rhs) sprout::darkroom::colors::b(lhs) * sprout::darkroom::colors::b(rhs)
); );
} }
template<typename Color1, typename Color2, typename... Tail>
inline SPROUT_CONSTEXPR Color1
filter(Color1 const& lhs, Color2 const& rhs, Tail const&... tail) {
return sprout::darkroom::colors::filter(
sprout::darkroom::colors::filter(lhs, rhs),
tail...
);
}
// //
// rgb_f_to_rgb // rgb_f_to_rgb

View file

@ -59,6 +59,17 @@ namespace sprout {
return sprout::darkroom::coords::vector3d_t(x, y, z); return sprout::darkroom::coords::vector3d_t(x, y, z);
} }
//
// is_zero
//
template<typename Vector>
inline SPROUT_CONSTEXPR bool
is_zero(Vector const& vec) {
return sprout::darkroom::coords::x(vec) == 0
&& sprout::darkroom::coords::y(vec) == 0
&& sprout::darkroom::coords::z(vec) == 0
;
}
// //
// length_sq // length_sq
// //
@ -204,6 +215,37 @@ namespace sprout {
sprout::darkroom::coords::scale(nor, sprout::darkroom::coords::dot(incid, nor) * 2) sprout::darkroom::coords::scale(nor, sprout::darkroom::coords::dot(incid, nor) * 2)
); );
} }
//
// refract
//
namespace detail {
template<typename Incident, typename Normal, typename Refraction, typename InNor, typename K>
inline SPROUT_CONSTEXPR Incident
refract_impl_1(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t, K const& k) {
return k < 0 ? sprout::tuples::remake<Incident>(incid, 0, 0, 0)
: sprout::darkroom::coords::sub(
sprout::darkroom::coords::scale(incid, eta),
sprout::darkroom::coords::scale(nor, eta * t * sprout::sqrt(k))
)
;
}
template<typename Incident, typename Normal, typename Refraction, typename InNor>
inline SPROUT_CONSTEXPR Incident
refract_impl(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t) {
return sprout::darkroom::coords::detail::refract_impl_1(
incid, nor, eta,
t, 1 - eta * eta * (1 - t * t)
);
}
} // namespace detail
template<typename Incident, typename Normal, typename Refraction>
inline SPROUT_CONSTEXPR Incident
refract(Incident const& incid, Normal const& nor, Refraction const& eta) {
return sprout::darkroom::coords::detail::refract_impl(
incid, nor, eta,
sprout::darkroom::coords::dot(incid, nor)
);
}
} // namespace coords } // namespace coords
} // namespace darkroom } // namespace darkroom
} // namespace sprout } // namespace sprout

View file

@ -8,6 +8,7 @@
#ifndef SPROUT_DARKROOM_INTERSECTS_INTERSECTION_HPP #ifndef SPROUT_DARKROOM_INTERSECTS_INTERSECTION_HPP
#define SPROUT_DARKROOM_INTERSECTS_INTERSECTION_HPP #define SPROUT_DARKROOM_INTERSECTS_INTERSECTION_HPP
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/tuple/tuple.hpp> #include <sprout/tuple/tuple.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
@ -89,7 +90,7 @@ namespace sprout {
} }
template< template<
typename T, typename T,
typename sprout::enabler_if<sprout::darkroom::intersects::has_is_from_inside<T>::value>::type = sprout::enabler typename sprout::enabler_if<sprout::darkroom::intersects::has_is_from_inside<typename std::decay<T>::type>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR auto inline SPROUT_CONSTEXPR auto
is_from_inside(T&& t) is_from_inside(T&& t)
@ -100,7 +101,7 @@ namespace sprout {
} }
template< template<
typename T, typename T,
typename sprout::enabler_if<!sprout::darkroom::intersects::has_is_from_inside<T>::value>::type = sprout::enabler typename sprout::enabler_if<!sprout::darkroom::intersects::has_is_from_inside<typename std::decay<T>::type>::value>::type = sprout::enabler
> >
inline SPROUT_CONSTEXPR typename sprout::darkroom::access::element<5, sprout::darkroom::intersects::intersection>::type inline SPROUT_CONSTEXPR typename sprout::darkroom::access::element<5, sprout::darkroom::intersects::intersection>::type
is_from_inside(T&&) is_from_inside(T&&)

View file

@ -79,14 +79,8 @@ namespace sprout {
inter, inter,
sprout::darkroom::objects::intersect( sprout::darkroom::objects::intersect(
objs, objs,
sprout::darkroom::rays::make_ray( sprout::darkroom::rays::make_detached_ray(
sprout::darkroom::coords::add( sprout::darkroom::intersects::point_of_intersection(inter),
sprout::darkroom::coords::scale(
dir_,
sprout::numeric_limits<unit_type>::epsilon() * 256
),
sprout::darkroom::intersects::point_of_intersection(inter)
),
dir_ dir_
) )
) )

View file

@ -83,14 +83,8 @@ namespace sprout {
direction, direction,
sprout::darkroom::objects::intersect( sprout::darkroom::objects::intersect(
objs, objs,
sprout::darkroom::rays::make_ray( sprout::darkroom::rays::make_detached_ray(
sprout::darkroom::coords::add( sprout::darkroom::intersects::point_of_intersection(inter),
sprout::darkroom::coords::scale(
direction,
sprout::numeric_limits<unit_type>::epsilon() * 256
),
sprout::darkroom::intersects::point_of_intersection(inter)
),
direction direction
) )
) )

View file

@ -110,12 +110,15 @@ namespace sprout {
} }
template<typename Ray, typename Vec> template<typename Ray, typename Vec>
SPROUT_CONSTEXPR typename intersection<Ray>::type SPROUT_CONSTEXPR typename intersection<Ray>::type
intersect_6(Ray const& ray, zwo_type const& zwo, drei_type const& drei, Vec const& normal) const { intersect_6(Ray const& ray, zwo_type const& zwo, drei_type const& drei,bool is_from_inside, Vec const& normal) const {
return typename intersection<Ray>::type( return typename intersection<Ray>::type(
sprout::tuples::get<zw::does_intersect>(zwo), sprout::tuples::get<zw::does_intersect>(zwo),
sprout::tuples::get<zw::distance>(zwo), sprout::tuples::get<zw::distance>(zwo),
sprout::tuples::get<dr::point_of_intersection>(drei), sprout::tuples::get<dr::point_of_intersection>(drei),
sprout::tuples::get<dr::normal>(drei), is_from_inside
? sprout::darkroom::coords::negate(normal)
: normal
,
sprout::darkroom::materials::calculate_material( // ! Spherical sprout::darkroom::materials::calculate_material( // ! Spherical
mat_, mat_,
sprout::atan2( sprout::atan2(
@ -133,7 +136,7 @@ namespace sprout {
) )
/ sprout::math::half_pi<unit_type>() / sprout::math::half_pi<unit_type>()
), ),
sprout::darkroom::coords::dot(normal, sprout::darkroom::rays::direction(ray)) > 0 is_from_inside
); );
} }
template<typename Ray> template<typename Ray>
@ -143,6 +146,7 @@ namespace sprout {
ray, ray,
zwo, zwo,
drei, drei,
sprout::darkroom::coords::dot(sprout::tuples::get<dr::normal>(drei), sprout::darkroom::rays::direction(ray)) > 0,
sprout::tuples::get<dr::normal>(drei) sprout::tuples::get<dr::normal>(drei)
); );
} }

View file

@ -9,6 +9,7 @@
#define SPROUT_DARKROOM_RAYS_RAY_HPP #define SPROUT_DARKROOM_RAYS_RAY_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/tuple/tuple.hpp> #include <sprout/tuple/tuple.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
#include <sprout/darkroom/access/access.hpp> #include <sprout/darkroom/access/access.hpp>
@ -63,6 +64,32 @@ namespace sprout {
sprout::darkroom::coords::scale(sprout::darkroom::rays::direction(ray), dist) sprout::darkroom::coords::scale(sprout::darkroom::rays::direction(ray), dist)
); );
} }
//
// detach_position
//
template<typename Position, typename Direction>
inline SPROUT_CONSTEXPR Position
detach_position(Position const& pos, Direction const& dir) {
return sprout::darkroom::coords::add(
pos,
sprout::darkroom::coords::resize(
dir,
sprout::numeric_limits<typename sprout::darkroom::access::unit<Direction>::type>::epsilon() * 256
)
);
}
//
// make_detached_ray
//
template<typename Position, typename Direction>
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Position, Direction>
make_detached_ray(Position const& pos, Direction const& dir) {
return sprout::darkroom::rays::make_ray(
sprout::darkroom::rays::detach_position(pos, dir),
dir
);
}
} // namespace rays } // namespace rays
} // namespace darkroom } // namespace darkroom
} // namespace sprout } // namespace sprout

View file

@ -43,7 +43,7 @@ namespace sprout {
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer, Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max, std::size_t depth_max,
Direction const& reflect_dir Direction const& new_dir
) const ) const
{ {
return sprout::darkroom::renderers::calculate<Color>( return sprout::darkroom::renderers::calculate<Color>(
@ -51,19 +51,8 @@ namespace sprout {
camera, objs, lights, camera, objs, lights,
sprout::tuples::remake<Ray>( sprout::tuples::remake<Ray>(
ray, ray,
sprout::darkroom::coords::add( sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir),
sprout::darkroom::intersects::point_of_intersection(inter), new_dir
sprout::darkroom::coords::scale(
reflect_dir,
sprout::numeric_limits<typename sprout::darkroom::access::unit<Direction>::type>::epsilon() * 256
)
// ???
// sprout::darkroom::coords::scale(
// sprout::darkroom::intersects::normal(inter),
// sprout::numeric_limits<typename sprout::darkroom::access::unit<Direction>::type>::epsilon() * 256
// )
),
reflect_dir
), ),
depth_max - 1 depth_max - 1
); );
@ -102,6 +91,80 @@ namespace sprout {
} }
}; };
// //
// whitted_transparent
//
class whitted_transparent {
private:
template<
typename Color,
typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer,
typename Direction
>
SPROUT_CONSTEXPR Color
color_1(
Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max,
Direction const& new_dir
) const
{
return !sprout::darkroom::coords::is_zero(new_dir)
? sprout::darkroom::renderers::calculate<Color>(
renderer,
camera, objs, lights,
sprout::tuples::remake<Ray>(
ray,
sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir),
new_dir
),
depth_max - 1
)
: sprout::tuples::make<Color>(0, 0, 0)
;
}
public:
template<
typename Color,
typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer
>
SPROUT_CONSTEXPR Color
operator()(
Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max
) const
{
typedef typename std::decay<
decltype(sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter)))
>::type alpha_type;
typedef typename std::decay<
decltype(sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter)))
>::type refraction_type;
return depth_max > 0
&& sprout::darkroom::intersects::does_intersect(inter)
&& sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter))
> sprout::numeric_limits<alpha_type>::epsilon()
&& sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter))
> sprout::numeric_limits<refraction_type>::epsilon()
? color_1<Color>(
camera, objs, lights,
ray, inter, renderer,
depth_max,
sprout::darkroom::coords::refract(
sprout::darkroom::rays::direction(ray),
sprout::darkroom::intersects::normal(inter),
sprout::darkroom::intersects::is_from_inside(inter)
? 1 / sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter))
: sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter))
)
)
: sprout::tuples::make<Color>(0, 0, 0)
;
}
};
//
// whitted_style // whitted_style
// //
template<typename InfinityColor = sprout::darkroom::renderers::direction_gradation> template<typename InfinityColor = sprout::darkroom::renderers::direction_gradation>
@ -115,18 +178,24 @@ namespace sprout {
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
color_3( color_3(
Ray const& ray, Intersection const& inter, Ray const& ray, Intersection const& inter,
Color const& diffuse_color, Color const& mirror_color Color const& diffuse_color, Color const& mirror_color, Color const& transparent_color
) const ) const
{ {
return sprout::darkroom::intersects::does_intersect(inter) return sprout::darkroom::intersects::does_intersect(inter)
? sprout::darkroom::colors::add( ? sprout::darkroom::colors::add(
sprout::darkroom::colors::mul( sprout::darkroom::colors::mul(
diffuse_color, diffuse_color,
1 - sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) 1
- sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter))
- sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter))
), ),
sprout::darkroom::colors::mul( sprout::darkroom::colors::mul(
mirror_color, mirror_color,
sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter))
),
sprout::darkroom::colors::mul(
transparent_color,
sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter))
) )
) )
: sprout::darkroom::renderers::calculate_infinity<Color>(infinity_color_, sprout::darkroom::rays::direction(ray)) : sprout::darkroom::renderers::calculate_infinity<Color>(infinity_color_, sprout::darkroom::rays::direction(ray))
@ -148,6 +217,11 @@ namespace sprout {
ray, inter, ray, inter,
diffuse_color, diffuse_color,
sprout::darkroom::renderers::whitted_mirror().template operator()<Color>( sprout::darkroom::renderers::whitted_mirror().template operator()<Color>(
camera, objs, lights,
ray, inter, *this,
depth_max
),
sprout::darkroom::renderers::whitted_transparent().template operator()<Color>(
camera, objs, lights, camera, objs, lights,
ray, inter, *this, ray, inter, *this,
depth_max depth_max