23 Load(filesystem, asset_path);
65 MaterialTextureUvSet base_color_uv_set = MaterialTextureUvSet::Uv0;
66 MaterialTextureUvSet normal_uv_set = MaterialTextureUvSet::Uv0;
67 MaterialTextureUvSet orm_uv_set = MaterialTextureUvSet::Uv0;
68 MaterialTextureUvSet emissive_uv_set = MaterialTextureUvSet::Uv0;
69 MaterialTextureUvSet transmission_uv_set = MaterialTextureUvSet::Uv0;
70 MaterialTextureUvSet volume_thickness_uv_set = MaterialTextureUvSet::Uv0;
71 MaterialTextureUvSet specular_uv_set = MaterialTextureUvSet::Uv0;
72 MaterialTextureUvSet specular_color_uv_set = MaterialTextureUvSet::Uv0;
73 MaterialTextureUvSet clearcoat_uv_set = MaterialTextureUvSet::Uv0;
74 MaterialTextureUvSet clearcoat_roughness_uv_set = MaterialTextureUvSet::Uv0;
75 MaterialTextureUvSet clearcoat_normal_uv_set = MaterialTextureUvSet::Uv0;
76 MaterialTextureUvSet sheen_color_uv_set = MaterialTextureUvSet::Uv0;
77 MaterialTextureUvSet sheen_roughness_uv_set = MaterialTextureUvSet::Uv0;
78 MaterialTextureUvSet iridescence_uv_set = MaterialTextureUvSet::Uv0;
79 MaterialTextureUvSet iridescence_thickness_uv_set = MaterialTextureUvSet::Uv0;
95 glm::vec4 base_color_factor = glm::vec4(1.0f);
96 float metallic_factor = 0.0f;
97 float roughness_factor = 1.0f;
98 float normal_scale = 1.0f;
99 float occlusion_strength = 1.0f;
101 float transmission_factor = 0.0f;
102 float volume_thickness_factor = 0.0f;
103 float volume_attenuation_distance = 0.0f;
104 glm::vec3 emissive_factor = glm::vec3(0.0f);
105 float emissive_strength = 1.0f;
106 glm::vec3 volume_attenuation_color = glm::vec3(1.0f);
107 float specular_factor = 1.0f;
108 glm::vec3 specular_color_factor = glm::vec3(1.0f);
109 float clearcoat_factor = 0.0f;
110 float clearcoat_roughness_factor = 0.0f;
111 float clearcoat_normal_scale = 1.0f;
112 glm::vec3 sheen_color_factor = glm::vec3(0.0f);
113 float sheen_roughness_factor = 0.0f;
114 float iridescence_factor = 0.0f;
115 float iridescence_ior = 1.3f;
116 float iridescence_thickness_minimum = 100.0f;
117 float iridescence_thickness_maximum = 400.0f;
118 MaterialAlphaMode alpha_mode = MaterialAlphaMode::Opaque;
119 float alpha_cutoff = 0.5f;
120 bool double_sided =
false;
121 MaterialShadingModel shading_model = MaterialShadingModel::Lit;
123 friend Node& operator<<(
Node& node,
const Material& material)
125 node[
"baseColorTexture"] << material.base_color_texture;
126 node[
"normalTexture"] << material.normal_texture;
127 node[
"ormTexture"] << material.orm_texture;
128 node[
"emissiveTexture"] << material.emissive_texture;
129 node[
"transmissionTexture"] << material.transmission_texture;
130 node[
"volumeThicknessTexture"] << material.volume_thickness_texture;
131 node[
"specularTexture"] << material.specular_texture;
132 node[
"specularColorTexture"] << material.specular_color_texture;
133 node[
"clearcoatTexture"] << material.clearcoat_texture;
134 node[
"clearcoatRoughnessTexture"] << material.clearcoat_roughness_texture;
135 node[
"clearcoatNormalTexture"] << material.clearcoat_normal_texture;
136 node[
"sheenColorTexture"] << material.sheen_color_texture;
137 node[
"sheenRoughnessTexture"] << material.sheen_roughness_texture;
138 node[
"iridescenceTexture"] << material.iridescence_texture;
139 node[
"iridescenceThicknessTexture"] << material.iridescence_thickness_texture;
140 node[
"baseColorSampler"] << material.base_color_sampler;
141 node[
"normalSampler"] << material.normal_sampler;
142 node[
"ormSampler"] << material.orm_sampler;
143 node[
"emissiveSampler"] << material.emissive_sampler;
144 node[
"transmissionSampler"] << material.transmission_sampler;
145 node[
"volumeThicknessSampler"] << material.volume_thickness_sampler;
146 node[
"specularSampler"] << material.specular_sampler;
147 node[
"specularColorSampler"] << material.specular_color_sampler;
148 node[
"clearcoatSampler"] << material.clearcoat_sampler;
149 node[
"clearcoatRoughnessSampler"] << material.clearcoat_roughness_sampler;
150 node[
"clearcoatNormalSampler"] << material.clearcoat_normal_sampler;
151 node[
"sheenColorSampler"] << material.sheen_color_sampler;
152 node[
"sheenRoughnessSampler"] << material.sheen_roughness_sampler;
153 node[
"iridescenceSampler"] << material.iridescence_sampler;
154 node[
"iridescenceThicknessSampler"] << material.iridescence_thickness_sampler;
155 node[
"baseColorUvSet"] << material.base_color_uv_set;
156 node[
"normalUvSet"] << material.normal_uv_set;
157 node[
"ormUvSet"] << material.orm_uv_set;
158 node[
"emissiveUvSet"] << material.emissive_uv_set;
159 node[
"transmissionUvSet"] << material.transmission_uv_set;
160 node[
"volumeThicknessUvSet"] << material.volume_thickness_uv_set;
161 node[
"specularUvSet"] << material.specular_uv_set;
162 node[
"specularColorUvSet"] << material.specular_color_uv_set;
163 node[
"clearcoatUvSet"] << material.clearcoat_uv_set;
164 node[
"clearcoatRoughnessUvSet"] << material.clearcoat_roughness_uv_set;
165 node[
"clearcoatNormalUvSet"] << material.clearcoat_normal_uv_set;
166 node[
"sheenColorUvSet"] << material.sheen_color_uv_set;
167 node[
"sheenRoughnessUvSet"] << material.sheen_roughness_uv_set;
168 node[
"iridescenceUvSet"] << material.iridescence_uv_set;
169 node[
"iridescenceThicknessUvSet"] << material.iridescence_thickness_uv_set;
170 node[
"baseColorUvTransform"] << material.base_color_uv_transform;
171 node[
"normalUvTransform"] << material.normal_uv_transform;
172 node[
"ormUvTransform"] << material.orm_uv_transform;
173 node[
"emissiveUvTransform"] << material.emissive_uv_transform;
174 node[
"transmissionUvTransform"] << material.transmission_uv_transform;
175 node[
"volumeThicknessUvTransform"] << material.volume_thickness_uv_transform;
176 node[
"specularUvTransform"] << material.specular_uv_transform;
177 node[
"specularColorUvTransform"] << material.specular_color_uv_transform;
178 node[
"clearcoatUvTransform"] << material.clearcoat_uv_transform;
179 node[
"clearcoatRoughnessUvTransform"] << material.clearcoat_roughness_uv_transform;
180 node[
"clearcoatNormalUvTransform"] << material.clearcoat_normal_uv_transform;
181 node[
"sheenColorUvTransform"] << material.sheen_color_uv_transform;
182 node[
"sheenRoughnessUvTransform"] << material.sheen_roughness_uv_transform;
183 node[
"iridescenceUvTransform"] << material.iridescence_uv_transform;
184 node[
"iridescenceThicknessUvTransform"] << material.iridescence_thickness_uv_transform;
187 factorNode.set_type(NodeType::Array);
188 auto& factorProperties = factorNode.properties();
189 factorProperties.clear();
190 for (
int index = 0; index < 4; ++index)
193 componentNode << material.base_color_factor[index];
194 factorProperties.emplace_back(
"", std::move(componentNode));
196 node[
"baseColorFactor"] = std::move(factorNode);
197 node[
"metallicFactor"] << material.metallic_factor;
198 node[
"roughnessFactor"] << material.roughness_factor;
199 node[
"normalScale"] << material.normal_scale;
200 node[
"occlusionStrength"] << material.occlusion_strength;
201 node[
"ior"] << material.ior;
202 node[
"transmissionFactor"] << material.transmission_factor;
203 node[
"volumeThicknessFactor"] << material.volume_thickness_factor;
204 node[
"volumeAttenuationDistance"] << material.volume_attenuation_distance;
205 node[
"specularFactor"] << material.specular_factor;
206 node[
"clearcoatFactor"] << material.clearcoat_factor;
207 node[
"clearcoatRoughnessFactor"] << material.clearcoat_roughness_factor;
208 node[
"clearcoatNormalScale"] << material.clearcoat_normal_scale;
209 node[
"sheenRoughnessFactor"] << material.sheen_roughness_factor;
210 node[
"iridescenceFactor"] << material.iridescence_factor;
211 node[
"iridescenceIor"] << material.iridescence_ior;
212 node[
"iridescenceThicknessMinimum"] << material.iridescence_thickness_minimum;
213 node[
"iridescenceThicknessMaximum"] << material.iridescence_thickness_maximum;
214 node[
"alphaMode"] << material.alpha_mode;
215 node[
"alphaCutoff"] << material.alpha_cutoff;
216 node[
"doubleSided"] << material.double_sided;
217 node[
"shadingModel"] << material.shading_model;
220 emissiveNode.set_type(NodeType::Array);
221 auto& emissiveProperties = emissiveNode.properties();
222 emissiveProperties.clear();
223 for (
int index = 0; index < 3; ++index)
226 componentNode << material.emissive_factor[index];
227 emissiveProperties.emplace_back(
"", std::move(componentNode));
229 node[
"emissiveFactor"] = std::move(emissiveNode);
230 node[
"emissiveStrength"] << material.emissive_strength;
232 Node volumeAttenuationColorNode;
233 volumeAttenuationColorNode.set_type(NodeType::Array);
234 auto& volumeAttenuationColorProperties = volumeAttenuationColorNode.properties();
235 volumeAttenuationColorProperties.clear();
236 for (
int index = 0; index < 3; ++index)
239 componentNode << material.volume_attenuation_color[index];
240 volumeAttenuationColorProperties.emplace_back(
"", std::move(componentNode));
242 node[
"volumeAttenuationColor"] = std::move(volumeAttenuationColorNode);
244 Node specularColorNode;
245 specularColorNode.set_type(NodeType::Array);
246 auto& specularColorProperties = specularColorNode.properties();
247 specularColorProperties.clear();
248 for (
int index = 0; index < 3; ++index)
251 componentNode << material.specular_color_factor[index];
252 specularColorProperties.emplace_back(
"", std::move(componentNode));
254 node[
"specularColorFactor"] = std::move(specularColorNode);
257 sheenColorNode.set_type(NodeType::Array);
258 auto& sheenColorProperties = sheenColorNode.properties();
259 sheenColorProperties.clear();
260 for (
int index = 0; index < 3; ++index)
263 componentNode << material.sheen_color_factor[index];
264 sheenColorProperties.emplace_back(
"", std::move(componentNode));
266 node[
"sheenColorFactor"] = std::move(sheenColorNode);
270 friend const Node& operator>>(
const Node& node, Material& material)
272 if (node.has_property(
"baseColorTexture"))
274 node[
"baseColorTexture"] >> material.base_color_texture;
277 if (node.has_property(
"normalTexture"))
279 node[
"normalTexture"] >> material.normal_texture;
282 if (node.has_property(
"ormTexture"))
284 node[
"ormTexture"] >> material.orm_texture;
287 if (node.has_property(
"emissiveTexture"))
289 node[
"emissiveTexture"] >> material.emissive_texture;
292 if (node.has_property(
"transmissionTexture"))
294 node[
"transmissionTexture"] >> material.transmission_texture;
297 if (node.has_property(
"volumeThicknessTexture"))
299 node[
"volumeThicknessTexture"] >> material.volume_thickness_texture;
302 if (node.has_property(
"specularTexture"))
304 node[
"specularTexture"] >> material.specular_texture;
307 if (node.has_property(
"specularColorTexture"))
309 node[
"specularColorTexture"] >> material.specular_color_texture;
312 if (node.has_property(
"clearcoatTexture"))
314 node[
"clearcoatTexture"] >> material.clearcoat_texture;
317 if (node.has_property(
"clearcoatRoughnessTexture"))
319 node[
"clearcoatRoughnessTexture"] >> material.clearcoat_roughness_texture;
322 if (node.has_property(
"clearcoatNormalTexture"))
324 node[
"clearcoatNormalTexture"] >> material.clearcoat_normal_texture;
327 if (node.has_property(
"sheenColorTexture"))
329 node[
"sheenColorTexture"] >> material.sheen_color_texture;
332 if (node.has_property(
"sheenRoughnessTexture"))
334 node[
"sheenRoughnessTexture"] >> material.sheen_roughness_texture;
337 if (node.has_property(
"iridescenceTexture"))
339 node[
"iridescenceTexture"] >> material.iridescence_texture;
342 if (node.has_property(
"iridescenceThicknessTexture"))
344 node[
"iridescenceThicknessTexture"] >> material.iridescence_thickness_texture;
347 if (node.has_property(
"baseColorSampler"))
349 node[
"baseColorSampler"] >> material.base_color_sampler;
352 if (node.has_property(
"normalSampler"))
354 node[
"normalSampler"] >> material.normal_sampler;
357 if (node.has_property(
"ormSampler"))
359 node[
"ormSampler"] >> material.orm_sampler;
362 if (node.has_property(
"emissiveSampler"))
364 node[
"emissiveSampler"] >> material.emissive_sampler;
367 if (node.has_property(
"transmissionSampler"))
369 node[
"transmissionSampler"] >> material.transmission_sampler;
372 if (node.has_property(
"volumeThicknessSampler"))
374 node[
"volumeThicknessSampler"] >> material.volume_thickness_sampler;
377 if (node.has_property(
"specularSampler"))
379 node[
"specularSampler"] >> material.specular_sampler;
382 if (node.has_property(
"specularColorSampler"))
384 node[
"specularColorSampler"] >> material.specular_color_sampler;
387 if (node.has_property(
"clearcoatSampler"))
389 node[
"clearcoatSampler"] >> material.clearcoat_sampler;
392 if (node.has_property(
"clearcoatRoughnessSampler"))
394 node[
"clearcoatRoughnessSampler"] >> material.clearcoat_roughness_sampler;
397 if (node.has_property(
"clearcoatNormalSampler"))
399 node[
"clearcoatNormalSampler"] >> material.clearcoat_normal_sampler;
402 if (node.has_property(
"sheenColorSampler"))
404 node[
"sheenColorSampler"] >> material.sheen_color_sampler;
407 if (node.has_property(
"sheenRoughnessSampler"))
409 node[
"sheenRoughnessSampler"] >> material.sheen_roughness_sampler;
412 if (node.has_property(
"iridescenceSampler"))
414 node[
"iridescenceSampler"] >> material.iridescence_sampler;
417 if (node.has_property(
"iridescenceThicknessSampler"))
419 node[
"iridescenceThicknessSampler"] >> material.iridescence_thickness_sampler;
422 if (node.has_property(
"baseColorUvSet"))
424 node[
"baseColorUvSet"] >> material.base_color_uv_set;
427 if (node.has_property(
"normalUvSet"))
429 node[
"normalUvSet"] >> material.normal_uv_set;
432 if (node.has_property(
"ormUvSet"))
434 node[
"ormUvSet"] >> material.orm_uv_set;
437 if (node.has_property(
"emissiveUvSet"))
439 node[
"emissiveUvSet"] >> material.emissive_uv_set;
442 if (node.has_property(
"transmissionUvSet"))
444 node[
"transmissionUvSet"] >> material.transmission_uv_set;
447 if (node.has_property(
"volumeThicknessUvSet"))
449 node[
"volumeThicknessUvSet"] >> material.volume_thickness_uv_set;
452 if (node.has_property(
"specularUvSet"))
454 node[
"specularUvSet"] >> material.specular_uv_set;
457 if (node.has_property(
"specularColorUvSet"))
459 node[
"specularColorUvSet"] >> material.specular_color_uv_set;
462 if (node.has_property(
"clearcoatUvSet"))
464 node[
"clearcoatUvSet"] >> material.clearcoat_uv_set;
467 if (node.has_property(
"clearcoatRoughnessUvSet"))
469 node[
"clearcoatRoughnessUvSet"] >> material.clearcoat_roughness_uv_set;
472 if (node.has_property(
"clearcoatNormalUvSet"))
474 node[
"clearcoatNormalUvSet"] >> material.clearcoat_normal_uv_set;
477 if (node.has_property(
"sheenColorUvSet"))
479 node[
"sheenColorUvSet"] >> material.sheen_color_uv_set;
482 if (node.has_property(
"sheenRoughnessUvSet"))
484 node[
"sheenRoughnessUvSet"] >> material.sheen_roughness_uv_set;
487 if (node.has_property(
"iridescenceUvSet"))
489 node[
"iridescenceUvSet"] >> material.iridescence_uv_set;
492 if (node.has_property(
"iridescenceThicknessUvSet"))
494 node[
"iridescenceThicknessUvSet"] >> material.iridescence_thickness_uv_set;
497 if (node.has_property(
"baseColorUvTransform"))
499 node[
"baseColorUvTransform"] >> material.base_color_uv_transform;
502 if (node.has_property(
"normalUvTransform"))
504 node[
"normalUvTransform"] >> material.normal_uv_transform;
507 if (node.has_property(
"ormUvTransform"))
509 node[
"ormUvTransform"] >> material.orm_uv_transform;
512 if (node.has_property(
"emissiveUvTransform"))
514 node[
"emissiveUvTransform"] >> material.emissive_uv_transform;
517 if (node.has_property(
"transmissionUvTransform"))
519 node[
"transmissionUvTransform"] >> material.transmission_uv_transform;
522 if (node.has_property(
"volumeThicknessUvTransform"))
524 node[
"volumeThicknessUvTransform"] >> material.volume_thickness_uv_transform;
527 if (node.has_property(
"specularUvTransform"))
529 node[
"specularUvTransform"] >> material.specular_uv_transform;
532 if (node.has_property(
"specularColorUvTransform"))
534 node[
"specularColorUvTransform"] >> material.specular_color_uv_transform;
537 if (node.has_property(
"clearcoatUvTransform"))
539 node[
"clearcoatUvTransform"] >> material.clearcoat_uv_transform;
542 if (node.has_property(
"clearcoatRoughnessUvTransform"))
544 node[
"clearcoatRoughnessUvTransform"] >> material.clearcoat_roughness_uv_transform;
547 if (node.has_property(
"clearcoatNormalUvTransform"))
549 node[
"clearcoatNormalUvTransform"] >> material.clearcoat_normal_uv_transform;
552 if (node.has_property(
"sheenColorUvTransform"))
554 node[
"sheenColorUvTransform"] >> material.sheen_color_uv_transform;
557 if (node.has_property(
"sheenRoughnessUvTransform"))
559 node[
"sheenRoughnessUvTransform"] >> material.sheen_roughness_uv_transform;
562 if (node.has_property(
"iridescenceUvTransform"))
564 node[
"iridescenceUvTransform"] >> material.iridescence_uv_transform;
567 if (node.has_property(
"iridescenceThicknessUvTransform"))
569 node[
"iridescenceThicknessUvTransform"] >> material.iridescence_thickness_uv_transform;
572 if (node.has_property(
"baseColorFactor"))
574 const Node& factorNode = node[
"baseColorFactor"];
575 ASSERT(factorNode.type() == NodeType::Array,
"material baseColorFactor must be an array");
576 const auto& factorProperties = factorNode.properties();
577 ASSERT(factorProperties.size() >= 4,
"material baseColorFactor requires four components");
578 for (
int index = 0; index < 4; ++index)
580 factorProperties[index].second >> material.base_color_factor[index];
584 if (node.has_property(
"metallicFactor"))
586 node[
"metallicFactor"] >> material.metallic_factor;
589 if (node.has_property(
"roughnessFactor"))
591 node[
"roughnessFactor"] >> material.roughness_factor;
594 if (node.has_property(
"normalScale"))
596 node[
"normalScale"] >> material.normal_scale;
599 if (node.has_property(
"occlusionStrength"))
601 node[
"occlusionStrength"] >> material.occlusion_strength;
604 if (node.has_property(
"ior"))
606 node[
"ior"] >> material.ior;
609 if (node.has_property(
"transmissionFactor"))
611 node[
"transmissionFactor"] >> material.transmission_factor;
614 if (node.has_property(
"volumeThicknessFactor"))
616 node[
"volumeThicknessFactor"] >> material.volume_thickness_factor;
619 if (node.has_property(
"volumeAttenuationDistance"))
621 node[
"volumeAttenuationDistance"] >> material.volume_attenuation_distance;
624 if (node.has_property(
"specularFactor"))
626 node[
"specularFactor"] >> material.specular_factor;
629 if (node.has_property(
"clearcoatFactor"))
631 node[
"clearcoatFactor"] >> material.clearcoat_factor;
634 if (node.has_property(
"clearcoatRoughnessFactor"))
636 node[
"clearcoatRoughnessFactor"] >> material.clearcoat_roughness_factor;
639 if (node.has_property(
"clearcoatNormalScale"))
641 node[
"clearcoatNormalScale"] >> material.clearcoat_normal_scale;
644 if (node.has_property(
"sheenRoughnessFactor"))
646 node[
"sheenRoughnessFactor"] >> material.sheen_roughness_factor;
649 if (node.has_property(
"iridescenceFactor"))
651 node[
"iridescenceFactor"] >> material.iridescence_factor;
654 if (node.has_property(
"iridescenceIor"))
656 node[
"iridescenceIor"] >> material.iridescence_ior;
659 if (node.has_property(
"iridescenceThicknessMinimum"))
661 node[
"iridescenceThicknessMinimum"] >> material.iridescence_thickness_minimum;
664 if (node.has_property(
"iridescenceThicknessMaximum"))
666 node[
"iridescenceThicknessMaximum"] >> material.iridescence_thickness_maximum;
669 if (node.has_property(
"alphaMode"))
671 node[
"alphaMode"] >> material.alpha_mode;
674 if (node.has_property(
"alphaCutoff"))
676 node[
"alphaCutoff"] >> material.alpha_cutoff;
679 if (node.has_property(
"doubleSided"))
681 node[
"doubleSided"] >> material.double_sided;
684 if (node.has_property(
"shadingModel"))
686 node[
"shadingModel"] >> material.shading_model;
689 if (node.has_property(
"emissiveFactor"))
691 const Node& emissiveNode = node[
"emissiveFactor"];
692 ASSERT(emissiveNode.type() == NodeType::Array,
"material emissiveFactor must be an array");
693 const auto& emissiveProperties = emissiveNode.properties();
694 ASSERT(emissiveProperties.size() >= 3,
"material emissiveFactor requires three components");
695 for (
int index = 0; index < 3; ++index)
697 emissiveProperties[index].second >> material.emissive_factor[index];
701 if (node.has_property(
"emissiveStrength"))
703 node[
"emissiveStrength"] >> material.emissive_strength;
706 if (node.has_property(
"volumeAttenuationColor"))
708 const Node& volume_attenuation_color_node = node[
"volumeAttenuationColor"];
709 ASSERT(volume_attenuation_color_node.type() == NodeType::Array,
"material volumeAttenuationColor must be an array");
710 const auto& volume_attenuation_color_properties = volume_attenuation_color_node.properties();
711 ASSERT(volume_attenuation_color_properties.size() >= 3,
"material volumeAttenuationColor requires three components");
712 for (
int index = 0; index < 3; ++index)
714 volume_attenuation_color_properties[index].second >> material.volume_attenuation_color[index];
718 if (node.has_property(
"specularColorFactor"))
720 const Node& specular_color_node = node[
"specularColorFactor"];
721 ASSERT(specular_color_node.type() == NodeType::Array,
"material specularColorFactor must be an array");
722 const auto& specular_color_properties = specular_color_node.properties();
723 ASSERT(specular_color_properties.size() >= 3,
"material specularColorFactor requires three components");
724 for (
int index = 0; index < 3; ++index)
726 specular_color_properties[index].second >> material.specular_color_factor[index];
730 if (node.has_property(
"sheenColorFactor"))
732 const Node& sheen_color_node = node[
"sheenColorFactor"];
733 ASSERT(sheen_color_node.type() == NodeType::Array,
"material sheenColorFactor must be an array");
734 const auto& sheen_color_properties = sheen_color_node.properties();
735 ASSERT(sheen_color_properties.size() >= 3,
"material sheenColorFactor requires three components");
736 for (
int index = 0; index < 3; ++index)
738 sheen_color_properties[index].second >> material.sheen_color_factor[index];