VTK  9.1.0
Material.h
Go to the documentation of this file.
1#pragma once
2
3#include "vtkLogger.h"
4
5#include "../Types.h"
6#include "OSPRayMDL.h"
7#include "Texture.h"
8
9#include <VisRTX.h>
10#include <cassert>
11#include <set>
12#include <sstream>
13#include <string>
14
15namespace RTW
16{
17 class Material : public Object
18 {
19 friend class Geometry;
20
21 public:
22 Material(const std::string& type) : Object(RTW_MATERIAL), type(type)
23
24 {
25 VisRTX::Context* rtx = VisRTX_GetContext();
26
27 /*
28 * Basic material
29 */
30 if (this->type == "obj" || this->type == "luminous")
31 {
32 this->material = rtx->CreateBasicMaterial();
33 }
34
35 /*
36 * MDL material
37 */
38 else
39 {
40 //OSPRay 2.0 name backward compatibility.
41 if (this->type == "alloy")
42 this->type = "Alloy";
43 else if (this->type == "carPaint")
44 this->type = "CarPaint";
45 else if (this->type == "glass")
46 this->type = "Glass";
47 else if (this->type == "metal")
48 this->type = "Metal";
49 else if (this->type == "metallicPaint")
50 this->type = "MetallicPaint";
51 else if (this->type == "obj")
52 this->type = "OBJMaterial";
53 else if (this->type == "principled")
54 this->type = "Principled";
55 else if (this->type == "thinGlass")
56 this->type = "ThinGlass";
57
58 const std::string materialname = "::ospray::" + this->type;
59 try
60 {
61 this->material = rtx->CreateMDLMaterial(materialname.c_str(), (char*)OSPRay_mdl, (uint32_t) sizeof(OSPRay_mdl), 0, nullptr, VisRTX::CompilationType::INSTANCE);
62 }
63 catch(const std::exception&)
64 {
65 vtkLogF(ERROR, "VisRTX Error: CreateMDLMaterial failed! Falling back to BasicMaterial.");
66 this->material = nullptr;
67 }
68 if (!this->material)
69 {
70 this->material = rtx->CreateBasicMaterial();
71 }
72 }
73 assert(this->material != nullptr);
74 }
75
77 {
78 this->material->Release();
79 }
80
81 void Commit() override
82 {
83 assert(this->material != nullptr);
84
85 /*
86 * OBJMaterial (Basic material)
87 */
88 if (this->type == "obj" && this->material->GetType() == VisRTX::MaterialType::BASIC)
89 {
90 VisRTX::BasicMaterial* basicMaterial = dynamic_cast<VisRTX::BasicMaterial*>(this->material);
91 assert(basicMaterial);
92 if (!basicMaterial)
93 {
94 return;
95 }
96
97 //this->PrintAllParameters();
98
99 basicMaterial->SetDiffuse(this->GetVec3f({ "kd", "Kd" }, VisRTX::Vec3f(0.8f, 0.8f, 0.8f)));
100 basicMaterial->SetSpecular(this->GetVec3f({ "ks", "Ks" }, VisRTX::Vec3f(0.0f, 0.0f, 0.0f)));
101 basicMaterial->SetShininess(this->GetFloat({ "ns", "Ns" }, 10.0f));
102 basicMaterial->SetOpacity(this->GetFloat({ "d", "alpha" }, 1.0f));
103 basicMaterial->SetTransparencyFilter(this->GetVec3f({ "tf", "Tf" }, VisRTX::Vec3f(0.0f, 0.0f, 0.0f)));
104
105 Texture* diffuseTex = this->GetObject<Texture>({ "map_Kd", "map_kd" });
106 if (diffuseTex)
107 basicMaterial->SetDiffuseTexture(diffuseTex->texture);
108
109 Texture* specularTex = this->GetObject<Texture>({ "map_Ks", "map_ks" });
110 if (specularTex)
111 basicMaterial->SetSpecularTexture(specularTex->texture);
112
113 Texture* shininessTex = this->GetObject<Texture>({ "map_Ns", "map_ns" });
114 if (shininessTex)
115 basicMaterial->SetShininessTexture(shininessTex->texture);
116
117 Texture* opacityTex = this->GetObject<Texture>({ "map_d", "map_alpha" });
118 if (opacityTex)
119 basicMaterial->SetOpacityTexture(opacityTex->texture);
120
121 Texture* bumpTex = this->GetObject<Texture>({ "map_Bump", "map_bump" });
122 if (bumpTex)
123 basicMaterial->SetBumpMapTexture(bumpTex->texture);
124 }
125
126 /*
127 * Luminous (Basic material)
128 */
129 else if (this->type == "luminous" && this->material->GetType() == VisRTX::MaterialType::BASIC)
130 {
131 VisRTX::BasicMaterial* basicMaterial = dynamic_cast<VisRTX::BasicMaterial*>(this->material);
132 assert(basicMaterial);
133 if (!basicMaterial)
134 {
135 return;
136 }
137 basicMaterial->SetEmissive(this->GetVec3f({ "color" }, VisRTX::Vec3f(0.0f, 0.0f, 0.0f)));
138 basicMaterial->SetLuminosity(this->GetFloat({ "intensity" }, 0.0f));
139 }
140
141 /*
142 * Others (MDL material)
143 */
144 else if (this->material->GetType() == VisRTX::MaterialType::MDL)
145 {
146 VisRTX::MDLMaterial* mdlMaterial = dynamic_cast<VisRTX::MDLMaterial*>(this->material);
147 assert(mdlMaterial);
148 if (!mdlMaterial)
149 {
150 return;
151 }
152
153 std::set<std::string> ospparams_current = this->GetAllParameters();
154
155#define PRINT_MATERIAL_PARAMETERS 0
156#if PRINT_MATERIAL_PARAMETERS
157 static std::set<std::string> mdltypes_printed;
158 if (mdltypes_printed.find(this->type) == mdltypes_printed.end())
159 {
160 std::vector<std::string> availableParams;
161 for (uint32_t i = 0; i < mdlMaterial->GetParameterCount(); ++i)
162 {
163 availableParams.push_back(mdlMaterial->GetParameterName(i));
164 }
165
166 for (const auto &parameter : availableParams)
167 {
168 std::string parameterType;
169 switch (mdlMaterial->GetParameterType(parameter.c_str()))
170 {
171 case VisRTX::ParameterType::NONE:
172 parameterType = "none"; break;
173 case VisRTX::ParameterType::COLOR:
174 parameterType = "color"; break;
175 case VisRTX::ParameterType::DOUBLE:
176 parameterType = "double"; break;
177 case VisRTX::ParameterType::FLOAT:
178 parameterType = "float"; break;
179 case VisRTX::ParameterType::INT:
180 parameterType = "int"; break;
181 case VisRTX::ParameterType::BOOL:
182 parameterType = "bool"; break;
183 case VisRTX::ParameterType::TEXTURE:
184 parameterType = "texture"; break;
185 }
186 std::stringstream logStrBuf;
187 logStrBuf << "(mdl) " << this->type << ": " << parameterType << " " << parameter;
188 vtkLogF(INFO, "%s", logStrBuf.str().c_str());
189 }
190 mdltypes_printed.insert(this->type);
191 }
192
193
194 static std::set<std::string> ospparams_printed;
195
196 for (auto param : ospparams_current)
197 {
198 std::string complete = this->type + ": " + param;
199 if (ospparams_printed.find(complete) == ospparams_printed.end())
200 {
201 vtkLogF(INFO, "(osp) %s", complete.c_str());
202 ospparams_printed.insert(complete);
203 }
204 }
205#endif //PRINT_MATERIAL_PARAMETERS
206
207#define WARN_NOT_IMPLEMENTED() vtkLogF(WARNING, "Warning: type \"%s\" not implemented (Material: %s, %s)", paramType.c_str(), this->type.c_str(), paramName.c_str());
208
209 for (const std::string &param : ospparams_current)
210 {
211 std::string paramType, paramName;
212 {
213 std::istringstream iss(param);
214 iss >> paramType;
215 iss >> paramName;
216 }
217
218 //getters for osp materials require a vector of names
219 std::vector<std::string> names;
220 names.push_back(paramName);
221
222 //rename parameters if needed (osp name -> mdl name)
223
224 static const std::map<std::pair<std::string, std::string>, std::string> renameMap
225 {
226 { { "obj", "map_kd" }, "map_Kd"},
227 { { "obj", "map_bump" }, "map_Bump"},
228 { { "Glass", "etaInside" }, "eta"},
229 { { "obj", "alpha" }, "d"},
230 { { "ThinGlass", "transmission" }, "attenuationColor"}
231 };
232
233 // explicit renames first
234 auto rename_it = renameMap.find(std::make_pair(this->type, paramName));
235 if (rename_it != renameMap.end())
236 {
237 paramName = rename_it->second;
238 }
239 else
240 {
241 //replace "...Map" with "map_..."
242 const std::string ospSuffix = "Map";
243 const std::string mdlPrefix = "map_";
244 if (paramName.length() >= ospSuffix.length()
245 && paramName.compare(paramName.length() - ospSuffix.length(),
246 ospSuffix.length(), ospSuffix) == 0)
247 {
248 std::string name =
249 paramName.substr(0, paramName.length() - ospSuffix.length());
250 paramName = mdlPrefix + name;
251 }
252 }
253
254 //exceptions first, e.g. spectra; then handle parameters by type
255 if (paramName == std::string("ior") && paramType == std::string("object"))
256 {
257 Data* iorData = this->GetObject<Data>(names);
258 assert(iorData->GetElementDataType() == RTW_VEC3F);
259
260 if (iorData->GetElementDataType() != RTW_VEC3F)
261 {
262 vtkLogF(ERROR, "Error: unexpected data type in ior object");
263 return;
264 }
265
266 const unsigned n_input = iorData->GetNumElements();
267
268 const VisRTX::Vec3f *input = (const VisRTX::Vec3f*)iorData->GetData();
269
270 static const unsigned spectrum_size = 8;
271 static const float wavelength_begin = 430.f;
272 static const float wavelength_spacing = 35.f;
273
274 float eta[spectrum_size], k[spectrum_size];
275
276 //subsample ior array
277 unsigned iinput = 0u, iprev = 0u;
278 for (unsigned iwl = 0u; iwl < spectrum_size; iwl++)
279 {
280 const float currentwl = wavelength_begin + (float)iwl * wavelength_spacing;
281 for (; iinput < n_input - 1 && input[iinput].x < currentwl; ++iinput)
282 {
283 iprev = iinput;
284 }
285 if (input[iprev].x == input[iinput].x)
286 {
287 eta[iwl] = input[iprev].y;
288 k[iwl] = input[iprev].z;
289 }
290 else
291 {
292 const float t = (currentwl - input[iprev].x) / (input[iinput].x - input[iprev].x);
293 eta[iwl] = (1.f - t) * input[iprev].y + t * input[iinput].y;
294 k[iwl] = (1.f - t) * input[iprev].z + t * input[iinput].z;
295 }
296 }
297
298 //response functions
299 static const float response_sRGB_r[spectrum_size] =
300 {
301 0.0598548,
302 -0.0234574,
303 -0.220138,
304 -0.238902,
305 0.316327,
306 0.738315,
307 0.323302,
308 0.0446981
309 };
310
311 static const float response_sRGB_g[spectrum_size] =
312 {
313 -0.0567346,
314 -0.0160361,
315 0.223861,
316 0.531185,
317 0.337221,
318 0.0149718,
319 -0.0296053,
320 -0.00486239
321 };
322
323 static const float response_sRGB_b[spectrum_size] =
324 {
325 0.420693,
326 0.616597,
327 0.0796766,
328 -0.0496266,
329 -0.0473149,
330 -0.0167536,
331 -0.00295686,
332 -0.000314818
333 };
334
335 //apply response functions to convert to RGB
336 VisRTX::Vec3f eta3(0.f, 0.f, 0.f), k3(0.f, 0.f, 0.f);
337 for (unsigned iwl = 0u; iwl < spectrum_size; ++iwl)
338 {
339 VisRTX::Vec3f response(response_sRGB_r[iwl], response_sRGB_g[iwl], response_sRGB_b[iwl]);
340
341 eta3.x += response.x * eta[iwl];
342 eta3.y += response.y * eta[iwl];
343 eta3.z += response.z * eta[iwl];
344 k3.x += response.x * k[iwl];
345 k3.y += response.y * k[iwl];
346 k3.z += response.z * k[iwl];
347 }
348
349 mdlMaterial->SetParameterColor("eta", eta3);
350 mdlMaterial->SetParameterColor("k", k3);
351 }
352 else if (paramType == std::string("string"))
353 {
354 std::string ospParam = this->GetString(names);
356 }
357 else if (paramType == std::string("object"))
358 {
359 Texture* ospParam = this->GetObject<Texture>(names);
360 if (ospParam)
361 {
362 mdlMaterial->SetParameterTexture(paramName.c_str(), ospParam->texture);
363 }
364 else
365 {
366 vtkLogF(WARNING, "Object \"%s\" of material type \"%s\" is not a texture.", paramName.c_str(), this->type.c_str());
367 }
368 }
369 else if (paramType == std::string("int1"))
370 {
371 int ospParam = this->GetInt(names);
372
373 if (mdlMaterial->GetParameterType(paramName.c_str()) == VisRTX::ParameterType::BOOL)
374 {
375 mdlMaterial->SetParameterBool(paramName.c_str(), ospParam > 0);
376 }
377 else
378 {
379 mdlMaterial->SetParameterInt(paramName.c_str(), ospParam);
380 }
381 }
382 else if (paramType == std::string("float1"))
383 {
384 float ospParam = this->GetFloat(names);
385
386 if (mdlMaterial->GetParameterType(paramName.c_str()) == VisRTX::ParameterType::BOOL)
387 {
388 mdlMaterial->SetParameterBool(paramName.c_str(), ospParam > 0.0f);
389 }
390 else
391 {
392 mdlMaterial->SetParameterFloat(paramName.c_str(), ospParam);
393 }
394 }
395 else if (paramType == std::string("float2"))
396 {
397 VisRTX::Vec2f ospParam = this->GetVec2f(names);
399 }
400 else if (paramType == std::string("int3"))
401 {
402 VisRTX::Vec3i ospParam = this->GetVec3i(names);
404 }
405 else if (paramType == std::string("float3"))
406 {
407 VisRTX::Vec3f ospParam = this->GetVec3f(names);
408 mdlMaterial->SetParameterColor(paramName.c_str(), ospParam);
409 }
410 else if (paramType == std::string("float4"))
411 {
412 VisRTX::Vec4f ospParam = this->GetVec4f(names);
414 }
415 else
416 {
418 }
419 }
420
421 mdlMaterial->Compile();
422 }
423 }
424
425 private:
426 std::string type;
427 VisRTX::Material* material = nullptr;
428 };
429 }
#define WARN_NOT_IMPLEMENTED()
unsigned char OSPRay_mdl[]
Definition: OSPRayMDL.h:6
@ RTW_VEC3F
Definition: Types.h:182
@ RTW_MATERIAL
Definition: Types.h:144
Definition: Data.h:10
size_t GetNumElements() const
Definition: Data.h:116
RTWDataType GetElementDataType() const
Definition: Data.h:136
void * GetData() const
Definition: Data.h:146
Material(const std::string &type)
Definition: Material.h:22
void Commit() override
Definition: Material.h:81
int32_t GetInt(const std::vector< std::string > &ids, int32_t defaultValue=0, bool *found=nullptr) const
Definition: Object.h:116
const std::string GetString(const std::vector< std::string > &ids, const std::string &defaultValue="", bool *found=nullptr) const
Definition: Object.h:61
VisRTX::Vec2f GetVec2f(const std::vector< std::string > &ids, const VisRTX::Vec2f &defaultValue=VisRTX::Vec2f(), bool *found=nullptr) const
Definition: Object.h:167
std::set< std::string > GetAllParameters() const
Definition: Object.h:274
VisRTX::Vec3i GetVec3i(const std::vector< std::string > &ids, const VisRTX::Vec3i &defaultValue=VisRTX::Vec3i(), bool *found=nullptr) const
Definition: Object.h:184
float GetFloat(const std::vector< std::string > &ids, float defaultValue=0.0f, bool *found=nullptr) const
Definition: Object.h:133
VisRTX::Vec4f GetVec4f(const std::vector< std::string > &ids, const VisRTX::Vec4f &defaultValue=VisRTX::Vec4f(), bool *found=nullptr) const
Definition: Object.h:218
VisRTX::Vec3f GetVec3f(const std::vector< std::string > &ids, const VisRTX::Vec3f &defaultValue=VisRTX::Vec3f(), bool *found=nullptr) const
Definition: Object.h:201
Definition: Backend.h:6
#define vtkLogF(verbosity_name,...)
Add to log given the verbosity level.
Definition: vtkLogger.h:484