1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2018 Esteban Tovagliari, The appleseedhq Organization
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 
29 #pragma once
30 
31 // appleseed.foundation headers.
32 #include "foundation/core/concepts/noncopyable.h"
33 
34 // Boost headers.
35 #include "boost/filesystem/path.hpp"
36 
37 
38 namespace renderer
39 {
40 
41 //
42 // Base class for 2D albedo tables.
43 //
44 
45 class AlbedoTable2D
46   : public foundation::NonCopyable
47 {
48   public:
49     // Return the directional albedo.
50     float get_directional_albedo(const float cos_theta, const float roughness) const;
51 
52     // Return the average albedo.
53     float get_average_albedo(const float roughness) const;
54 
55     // Write the table to an OpenEXR image.
56     void write_table_to_image(const boost::filesystem::path& filename) const;
57 
58     // Write the table to a cpp array.
59     void write_table_to_cpp_array(
60         const boost::filesystem::path&  filename,
61         const char*                     array_name) const;
62 
63   protected:
64     AlbedoTable2D();
65 
66     explicit AlbedoTable2D(const float* table);
67 
68     ~AlbedoTable2D();
69 
70     size_t array_size() const;
71 
72     float dir_table(const size_t x , const size_t y) const;
73     float avg_table(const size_t x) const;
74 
75     const size_t    TableSize;
76     const size_t    TableHeight;
77 
78     float*          m_albedo_table;
79     float*          m_avg_table;
80     float*          m_data;
81 };
82 
83 
84 //
85 // Base class for 3D albedo tables.
86 //
87 
88 class AlbedoTable3D
89   : public foundation::NonCopyable
90 {
91   public:
92     // Return the directional albedo.
93     float get_directional_albedo(
94         const float eta,
95         const float roughness,
96         const float cos_theta) const;
97 
98     // Return the average albedo.
99     float get_average_albedo(const float eta, const float roughness) const;
100 
101     // Write the table to an OpenEXR image.
102     void write_table_to_image(const boost::filesystem::path& filename) const;
103 
104     // Write the table to a cpp array.
105     void write_table_to_cpp_array(
106         const boost::filesystem::path& filename,
107         const char*                    array_name) const;
108 
109   protected:
110     AlbedoTable3D(const float min_eta, const float max_eta);
111 
112     AlbedoTable3D(const float* table, const float min_eta, const float max_eta);
113 
114     ~AlbedoTable3D();
115 
116     void init();
117 
118     size_t array_size() const;
119 
120     float dir_table(const size_t x, const size_t y, const size_t z) const;
121     float& dir_table(const size_t x, const size_t y, const size_t z);
122 
123     float avg_table(const size_t x, const size_t y) const;
124     float& avg_table(const size_t x, const size_t y);
125 
126     const size_t    TableSize;
127 
128     float*          m_albedo_table;
129     float*          m_avg_table;
130     float*          m_data;
131 
132     const float     m_min_eta;
133     const float     m_max_eta;
134 };
135 
136 float average_albedo(
137     const size_t    table_size,
138     const float*    directional_albedo);
139 
140 }   // namespace renderer
141