|
1 /* |
|
2 * material.h: material and texture classes |
|
3 * |
|
4 * This file is part of Pyrit Ray Tracer. |
|
5 * |
|
6 * Copyright 2006, 2007, 2008 Radek Brich |
|
7 * |
|
8 * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
9 * of this software and associated documentation files (the "Software"), to deal |
|
10 * in the Software without restriction, including without limitation the rights |
|
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
12 * copies of the Software, and to permit persons to whom the Software is |
|
13 * furnished to do so, subject to the following conditions: |
|
14 * |
|
15 * The above copyright notice and this permission notice shall be included in |
|
16 * all copies or substantial portions of the Software. |
|
17 * |
|
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
24 * THE SOFTWARE. |
|
25 */ |
|
26 |
|
27 #ifndef MATERIAL_H |
|
28 #define MATERIAL_H |
|
29 |
|
30 #include "common.h" |
|
31 #include "vector.h" |
|
32 #include "noise.h" |
|
33 |
|
34 /** |
|
35 * perlin noise |
|
36 */ |
|
37 Float perlin(Float x, Float y, Float z); |
|
38 |
|
39 /** |
|
40 * general texture |
|
41 */ |
|
42 class Texture |
|
43 { |
|
44 public: |
|
45 virtual ~Texture() {}; |
|
46 virtual Colour evaluate(const Vector3 &point) = 0; |
|
47 }; |
|
48 |
|
49 /** |
|
50 * general colour map |
|
51 */ |
|
52 class ColourMap |
|
53 { |
|
54 public: |
|
55 virtual Colour map(const Float &val) = 0; |
|
56 }; |
|
57 |
|
58 /** |
|
59 * linear colour map |
|
60 * maps value lineary between two colours |
|
61 */ |
|
62 class LinearColourMap: public ColourMap |
|
63 { |
|
64 Colour col,cdiff; |
|
65 public: |
|
66 LinearColourMap(const Colour &clow, const Colour &chigh): |
|
67 col(clow), cdiff(chigh-clow) {}; |
|
68 Colour map(const Float &val) { return col + cdiff*val; }; |
|
69 }; |
|
70 |
|
71 /** |
|
72 * bound colour map |
|
73 * initialize with two arrays, bounds and colours, of same size |
|
74 * bounds must contain numbers between 0 and 1 in rising order, |
|
75 * last number should be larger than max 'val' |
|
76 * colours are mapped to slices between bounds (with zero being |
|
77 * implicit bottom bound) |
|
78 */ |
|
79 class BoundColourMap: public ColourMap |
|
80 { |
|
81 Float *bounds; |
|
82 Colour *colours; |
|
83 public: |
|
84 BoundColourMap(Float *abounds, Colour *acolours): |
|
85 bounds(abounds), colours(acolours) {}; |
|
86 Colour map(const Float &val) |
|
87 { |
|
88 Float *b = bounds; |
|
89 Colour *c = colours; |
|
90 while (val > *b) |
|
91 { |
|
92 b++; |
|
93 c++; |
|
94 } |
|
95 return *c; |
|
96 }; |
|
97 }; |
|
98 |
|
99 /** |
|
100 * general texture mapping |
|
101 */ |
|
102 class TextureMap |
|
103 { |
|
104 protected: |
|
105 Vector3 center; |
|
106 Float invsize; |
|
107 public: |
|
108 TextureMap(const Vector3 &acenter, const Float &size): |
|
109 center(acenter), invsize(1./size) {}; |
|
110 virtual void map(const Vector3 &point, Float &u, Float &v) = 0; |
|
111 }; |
|
112 |
|
113 /** |
|
114 * planar mapping |
|
115 */ |
|
116 class PlanarMap: public TextureMap |
|
117 { |
|
118 public: |
|
119 PlanarMap(const Vector3 &acenter, const Float &size): |
|
120 TextureMap(acenter, size) {}; |
|
121 void map(const Vector3 &point, Float &u, Float &v) |
|
122 { |
|
123 const Vector3 p = point - center; |
|
124 u = p.x*invsize; |
|
125 v = p.y*invsize; |
|
126 }; |
|
127 }; |
|
128 |
|
129 /** |
|
130 * cubic mapping |
|
131 */ |
|
132 class CubicMap: public TextureMap |
|
133 { |
|
134 public: |
|
135 CubicMap(const Vector3 &acenter, const Float &size): |
|
136 TextureMap(acenter, size) {}; |
|
137 void map(const Vector3 &point, Float &u, Float &v) |
|
138 { |
|
139 const Vector3 p = point - center; |
|
140 if (fabs(p.x) > fabs(p.y)) |
|
141 { |
|
142 if (fabs(p.x) > fabs(p.z)) |
|
143 { |
|
144 if (p.x < 0) |
|
145 u = -p.y; |
|
146 else |
|
147 u = p.y; |
|
148 v = p.z; |
|
149 } |
|
150 else |
|
151 { |
|
152 if (p.z < 0) |
|
153 u = -p.x; |
|
154 else |
|
155 u = p.x; |
|
156 v = p.y; |
|
157 } |
|
158 } |
|
159 else |
|
160 { |
|
161 if (fabs(p.y) > fabs(p.z)) |
|
162 { |
|
163 if (p.y < 0) |
|
164 u = -p.x; |
|
165 else |
|
166 u = p.x; |
|
167 v = p.z; |
|
168 } |
|
169 else |
|
170 { |
|
171 if (p.z < 0) |
|
172 u = -p.x; |
|
173 else |
|
174 u = p.x; |
|
175 v = p.y; |
|
176 } |
|
177 } |
|
178 u = u*invsize; |
|
179 v = v*invsize; |
|
180 }; |
|
181 }; |
|
182 |
|
183 /** |
|
184 * cylindrical mapping |
|
185 */ |
|
186 class CylinderMap: public TextureMap |
|
187 { |
|
188 public: |
|
189 CylinderMap(const Vector3 &acenter, const Float &size): |
|
190 TextureMap(acenter, size) {}; |
|
191 void map(const Vector3 &point, Float &u, Float &v) |
|
192 { |
|
193 const Vector3 p = point - center; |
|
194 u = ( M_PI + atan2(p.z, p.x) ) * invsize; |
|
195 v = p.y * invsize; |
|
196 }; |
|
197 }; |
|
198 |
|
199 /** |
|
200 * spherical mapping |
|
201 */ |
|
202 class SphereMap: public TextureMap |
|
203 { |
|
204 public: |
|
205 SphereMap(const Vector3 &acenter, const Float &size): |
|
206 TextureMap(acenter, size) {}; |
|
207 void map(const Vector3 &point, Float &u, Float &v) |
|
208 { |
|
209 const Vector3 p = point - center; |
|
210 u = ( M_PI + atan2(p.z, p.x) ) * invsize; |
|
211 v = acos(p.y / p.mag()) * invsize; |
|
212 }; |
|
213 }; |
|
214 |
|
215 /** |
|
216 * general 2D texture |
|
217 */ |
|
218 class Texture2D: public Texture |
|
219 { |
|
220 protected: |
|
221 TextureMap *map; |
|
222 public: |
|
223 Texture2D(TextureMap *amap): map(amap) {}; |
|
224 }; |
|
225 |
|
226 /** |
|
227 * 2D checkers texture |
|
228 */ |
|
229 class CheckersTexture: public Texture2D |
|
230 { |
|
231 ColourMap *colourmap; |
|
232 public: |
|
233 CheckersTexture(TextureMap *tmap, ColourMap *cmap): |
|
234 Texture2D(tmap), colourmap(cmap) {}; |
|
235 Colour evaluate(const Vector3 &point) |
|
236 { |
|
237 Float u,v, val; |
|
238 map->map(point, u,v); |
|
239 val = 0.5*(round(u - floor(u)) + round(v - floor(v))); |
|
240 return colourmap->map(val); |
|
241 }; |
|
242 }; |
|
243 |
|
244 /** |
|
245 * 3D perlin cloud texture |
|
246 */ |
|
247 class CloudTexture: public Texture |
|
248 { |
|
249 Float detail; |
|
250 ColourMap *colourmap; |
|
251 public: |
|
252 CloudTexture(const Float &adetail, ColourMap *cmap): |
|
253 detail(adetail), colourmap(cmap) {}; |
|
254 Colour evaluate(const Vector3 &point) |
|
255 { |
|
256 Float sum = 0.0; |
|
257 for (int i = 1; i < detail; i++) |
|
258 sum += fabs(perlin(point.x*i, point.y*i, point.z*i))/i; |
|
259 //Float value = sinf(point.x + sum)/2 + 0.5; |
|
260 return colourmap->map(sum); |
|
261 }; |
|
262 }; |
|
263 |
|
264 /** |
|
265 * material |
|
266 */ |
|
267 class Material |
|
268 { |
|
269 public: |
|
270 Colour colour; |
|
271 Texture *texture; |
|
272 Float ambient, diffuse, specular, shininess; // Phong constants |
|
273 Float reflectivity; // how much reflective is the surface |
|
274 Float transmissivity, refract_index; // part of light which can be refracted; index of refraction |
|
275 bool smooth; // triangle smoothing |
|
276 |
|
277 Material(const Colour &acolour): colour(acolour), texture(NULL), smooth(false) |
|
278 { |
|
279 ambient = 0.2; |
|
280 diffuse = 0.8; |
|
281 specular = 0.2; |
|
282 shininess = 0.5; |
|
283 reflectivity = 0.2; |
|
284 transmissivity = 0.0; |
|
285 refract_index = 1.3; |
|
286 } |
|
287 |
|
288 void setPhong(const Float amb, const Float dif, const Float spec, const Float shin) |
|
289 { ambient = amb; diffuse = dif; specular = spec; shininess = shin; }; |
|
290 void setReflectivity(const Float refl) { reflectivity = refl; }; |
|
291 void setTransmissivity(const Float trans, const Float rindex) |
|
292 { transmissivity = trans; refract_index = rindex; }; |
|
293 void setSmooth(bool sm) { smooth = sm; }; |
|
294 }; |
|
295 |
|
296 #endif |