Tatooine
direct_volume.h
Go to the documentation of this file.
1#ifndef TATOOINE_RENDERING_DIRECT_VOLUME_H
2#define TATOOINE_RENDERING_DIRECT_VOLUME_H
3//==============================================================================
4#include <omp.h>
8//==============================================================================
9namespace tatooine::rendering {
10//==============================================================================
11template <arithmetic DistOnRay, arithmetic CameraReal, arithmetic AABBReal,
12 regular_invocable<vec<AABBReal, 3>> DomainCheck, typename Shader>
15 DomainCheck&& domain_check, DistOnRay const distance_on_ray,
16 Shader&& shader) {
17 using pos_type = vec<AABBReal, 3>;
18 using viewdir_t = vec<CameraReal, 3>;
19 using color_t = std::invoke_result_t<Shader, pos_type, viewdir_t>;
21 using alpha_t = typename color_t::value_type;
22 static_assert(static_vec<color_t> && color_t::num_components() == 4,
23 "Shader must return a vector with 4 components.");
25 linspace<CameraReal>{0.0, cam.plane_width() - 1, cam.plane_width()},
26 linspace<CameraReal>{0.0, cam.plane_height() - 1, cam.plane_height()}};
27 auto& rendering =
28 rendered_image.template insert_vertex_property<rgb_t>("rendering");
29 auto const bg_color = rgb_t::ones();
30
31 std::vector<std::tuple<ray<CameraReal, 3>, AABBReal, size_t, size_t>> rays;
32 for (size_t y = 0; y < cam.plane_height(); ++y) {
33 for (size_t x = 0; x < cam.plane_width(); ++x) {
34 rendering(x, y) = bg_color;
35 auto r = cam.ray(x, y);
36 r.normalize();
37 if (auto const i = aabb.check_intersection(r); i) {
38 rays.push_back(std::tuple{r, i->t, x, y});
39 }
40 }
41 }
42#pragma omp parallel for
43 for (size_t i = 0; i < rays.size(); ++i) {
44 auto const [r, t, x, y] = rays[i];
45 auto accumulated_color = rgb_t::zeros();
46 auto accumulated_alpha = alpha_t(0);
47 auto cur_t = t;
48 pos_type cur_pos = r(cur_t);
49 if (!aabb.is_inside(cur_pos)) {
50 cur_t += 1e-6;
51 cur_pos = r(cur_t);
52 }
53
54 while (aabb.is_inside(cur_pos) && accumulated_alpha < 0.95) {
55 if (domain_check(cur_pos)) {
56 auto const rgba = shader(cur_pos, r.direction());
57 auto const rgb = vec{rgba(0), rgba(1), rgba(2)};
58 auto const alpha = rgba(3);
59 accumulated_color += (1 - accumulated_alpha) * alpha * rgb;
60 accumulated_alpha += (1 - accumulated_alpha) * alpha;
61 }
62 cur_t += distance_on_ray;
63 cur_pos = r(cur_t);
64 }
65 rendering(x, y) = accumulated_color * accumulated_alpha +
66 bg_color * (1 - accumulated_alpha);
67 }
68 return rendered_image;
69}
70// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71// template <arithmetic TReal, arithmetic Min, arithmetic Max,
72// arithmetic DistOnRay, arithmetic CameraReal, arithmetic AABBReal,
73// typename S, typename SReal, regular_invocable<SReal> ColorScale,
74// regular_invocable<SReal> AlphaScale>
75// auto direct_volume(
76// camera<CameraReal> const& cam,
77// axis_aligned_bounding_box<AABBReal, 3> const& aabb,
78// scalarfield<S, SReal, 3> const& s, TReal const t, Min const min,
79// Max const max, DistOnRay const distance_on_ray, ColorScale&& color_scale,
80// AlphaScale&& alpha_scale,
81// std::invoke_result_t<ColorScale, SReal> const& bg_color = {}) {
82// return direct_volume(
83// cam, aabb, [&](auto const& x) { return s(x, t); },
84// [&](auto const& x) { return s.in_domain(x, t); }, min, max,
85// distance_on_ray, std::forward<ColorScale>(color_scale),
86// std::forward<AlphaScale>(alpha_scale), bg_color);
87//}
90// template <arithmetic Min, arithmetic Max, arithmetic DistOnRay,
91// arithmetic CameraReal, typename Grid, typename ValueType,
92// bool HasNonConstReference, regular_invocable<double> ColorScale,
93// regular_invocable<double> AlphaScale>
94// auto direct_volume(
95// camera<CameraReal> const& cam,
96// typed_grid_vertex_property_interface<Grid, ValueType,
97// HasNonConstReference> const& prop,
98// Min const min, Max const max, DistOnRay const distance_on_ray,
99// ColorScale&& color_scale, AlphaScale&& alpha_scale,
100// std::invoke_result_t<ColorScale, ValueType> const& bg_color = {}) {
101// auto sampler = prop.template sampler<interpolation::cubic>();
102// return direct_volume(
103// cam, prop.grid().bounding_box(),
104// [&](auto const& x) { return sampler(x); },
105// [](auto const&) { return true; }, min, max, distance_on_ray,
106// std::forward<ColorScale>(color_scale),
107// std::forward<AlphaScale>(alpha_scale), bg_color);
108//}
109//==============================================================================
110} // namespace tatooine::rendering
111//==============================================================================
112#endif
Definition: rectilinear_grid.h:38
Definition: camera.h:312
Definition: tensor_concepts.h:23
Definition: camera.h:12
auto direct_volume(camera< CameraReal > const &cam, axis_aligned_bounding_box< AABBReal, 3 > const &aabb, DomainCheck &&domain_check, DistOnRay const distance_on_ray, Shader &&shader)
Definition: direct_volume.h:13
Definition: axis_aligned_bounding_box.h:103
auto constexpr is_inside(pos_type const &p) const
Definition: axis_aligned_bounding_box.h:191
auto check_intersection(ray_type const &r, Real const =0) const -> optional_intersection_type override
Definition: axis_aligned_bounding_box.h:33
Definition: linspace.h:26
Definition: vec.h:12