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