22 Load(filesystem, asset_path);
63 MaterialTextureUvSet base_color_uv_set = MaterialTextureUvSet::Uv0;
64 MaterialTextureUvSet normal_uv_set = MaterialTextureUvSet::Uv0;
65 MaterialTextureUvSet orm_uv_set = MaterialTextureUvSet::Uv0;
66 MaterialTextureUvSet emissive_uv_set = MaterialTextureUvSet::Uv0;
67 MaterialTextureUvSet transmission_uv_set = MaterialTextureUvSet::Uv0;
68 MaterialTextureUvSet volume_thickness_uv_set = MaterialTextureUvSet::Uv0;
69 MaterialTextureUvSet specular_uv_set = MaterialTextureUvSet::Uv0;
70 MaterialTextureUvSet specular_color_uv_set = MaterialTextureUvSet::Uv0;
71 MaterialTextureUvSet clearcoat_uv_set = MaterialTextureUvSet::Uv0;
72 MaterialTextureUvSet clearcoat_roughness_uv_set = MaterialTextureUvSet::Uv0;
73 MaterialTextureUvSet clearcoat_normal_uv_set = MaterialTextureUvSet::Uv0;
74 MaterialTextureUvSet sheen_color_uv_set = MaterialTextureUvSet::Uv0;
75 MaterialTextureUvSet sheen_roughness_uv_set = MaterialTextureUvSet::Uv0;
76 MaterialTextureUvSet iridescence_uv_set = MaterialTextureUvSet::Uv0;
77 MaterialTextureUvSet iridescence_thickness_uv_set = MaterialTextureUvSet::Uv0;
93 glm::vec4 base_color_factor = glm::vec4(1.0f);
94 float metallic_factor = 0.0f;
95 float roughness_factor = 1.0f;
96 float normal_scale = 1.0f;
97 float occlusion_strength = 1.0f;
99 float transmission_factor = 0.0f;
100 float volume_thickness_factor = 0.0f;
101 float volume_attenuation_distance = 0.0f;
102 glm::vec3 emissive_factor = glm::vec3(0.0f);
103 float emissive_strength = 1.0f;
104 glm::vec3 volume_attenuation_color = glm::vec3(1.0f);
105 float specular_factor = 1.0f;
106 glm::vec3 specular_color_factor = glm::vec3(1.0f);
107 float clearcoat_factor = 0.0f;
108 float clearcoat_roughness_factor = 0.0f;
109 float clearcoat_normal_scale = 1.0f;
110 glm::vec3 sheen_color_factor = glm::vec3(0.0f);
111 float sheen_roughness_factor = 0.0f;
112 float iridescence_factor = 0.0f;
113 float iridescence_ior = 1.3f;
114 float iridescence_thickness_minimum = 100.0f;
115 float iridescence_thickness_maximum = 400.0f;
116 MaterialAlphaMode alpha_mode = MaterialAlphaMode::Opaque;
117 float alpha_cutoff = 0.5f;
118 bool double_sided =
false;
119 MaterialShadingModel shading_model = MaterialShadingModel::Lit;
121 friend Node& operator<<(
Node& node,
const Material& material)
123 node[
"baseColorTexture"] << material.base_color_texture;
124 node[
"normalTexture"] << material.normal_texture;
125 node[
"ormTexture"] << material.orm_texture;
126 node[
"emissiveTexture"] << material.emissive_texture;
127 node[
"transmissionTexture"] << material.transmission_texture;
128 node[
"volumeThicknessTexture"] << material.volume_thickness_texture;
129 node[
"specularTexture"] << material.specular_texture;
130 node[
"specularColorTexture"] << material.specular_color_texture;
131 node[
"clearcoatTexture"] << material.clearcoat_texture;
132 node[
"clearcoatRoughnessTexture"] << material.clearcoat_roughness_texture;
133 node[
"clearcoatNormalTexture"] << material.clearcoat_normal_texture;
134 node[
"sheenColorTexture"] << material.sheen_color_texture;
135 node[
"sheenRoughnessTexture"] << material.sheen_roughness_texture;
136 node[
"iridescenceTexture"] << material.iridescence_texture;
137 node[
"iridescenceThicknessTexture"] << material.iridescence_thickness_texture;
138 node[
"baseColorSampler"] << material.base_color_sampler;
139 node[
"normalSampler"] << material.normal_sampler;
140 node[
"ormSampler"] << material.orm_sampler;
141 node[
"emissiveSampler"] << material.emissive_sampler;
142 node[
"transmissionSampler"] << material.transmission_sampler;
143 node[
"volumeThicknessSampler"] << material.volume_thickness_sampler;
144 node[
"specularSampler"] << material.specular_sampler;
145 node[
"specularColorSampler"] << material.specular_color_sampler;
146 node[
"clearcoatSampler"] << material.clearcoat_sampler;
147 node[
"clearcoatRoughnessSampler"] << material.clearcoat_roughness_sampler;
148 node[
"clearcoatNormalSampler"] << material.clearcoat_normal_sampler;
149 node[
"sheenColorSampler"] << material.sheen_color_sampler;
150 node[
"sheenRoughnessSampler"] << material.sheen_roughness_sampler;
151 node[
"iridescenceSampler"] << material.iridescence_sampler;
152 node[
"iridescenceThicknessSampler"] << material.iridescence_thickness_sampler;
153 node[
"baseColorUvSet"] << material.base_color_uv_set;
154 node[
"normalUvSet"] << material.normal_uv_set;
155 node[
"ormUvSet"] << material.orm_uv_set;
156 node[
"emissiveUvSet"] << material.emissive_uv_set;
157 node[
"transmissionUvSet"] << material.transmission_uv_set;
158 node[
"volumeThicknessUvSet"] << material.volume_thickness_uv_set;
159 node[
"specularUvSet"] << material.specular_uv_set;
160 node[
"specularColorUvSet"] << material.specular_color_uv_set;
161 node[
"clearcoatUvSet"] << material.clearcoat_uv_set;
162 node[
"clearcoatRoughnessUvSet"] << material.clearcoat_roughness_uv_set;
163 node[
"clearcoatNormalUvSet"] << material.clearcoat_normal_uv_set;
164 node[
"sheenColorUvSet"] << material.sheen_color_uv_set;
165 node[
"sheenRoughnessUvSet"] << material.sheen_roughness_uv_set;
166 node[
"iridescenceUvSet"] << material.iridescence_uv_set;
167 node[
"iridescenceThicknessUvSet"] << material.iridescence_thickness_uv_set;
168 node[
"baseColorUvTransform"] << material.base_color_uv_transform;
169 node[
"normalUvTransform"] << material.normal_uv_transform;
170 node[
"ormUvTransform"] << material.orm_uv_transform;
171 node[
"emissiveUvTransform"] << material.emissive_uv_transform;
172 node[
"transmissionUvTransform"] << material.transmission_uv_transform;
173 node[
"volumeThicknessUvTransform"] << material.volume_thickness_uv_transform;
174 node[
"specularUvTransform"] << material.specular_uv_transform;
175 node[
"specularColorUvTransform"] << material.specular_color_uv_transform;
176 node[
"clearcoatUvTransform"] << material.clearcoat_uv_transform;
177 node[
"clearcoatRoughnessUvTransform"] << material.clearcoat_roughness_uv_transform;
178 node[
"clearcoatNormalUvTransform"] << material.clearcoat_normal_uv_transform;
179 node[
"sheenColorUvTransform"] << material.sheen_color_uv_transform;
180 node[
"sheenRoughnessUvTransform"] << material.sheen_roughness_uv_transform;
181 node[
"iridescenceUvTransform"] << material.iridescence_uv_transform;
182 node[
"iridescenceThicknessUvTransform"] << material.iridescence_thickness_uv_transform;
185 factorNode.set_type(NodeType::Array);
186 auto& factorProperties = factorNode.properties();
187 factorProperties.clear();
188 for (
int index = 0; index < 4; ++index)
191 componentNode << material.base_color_factor[index];
192 factorProperties.emplace_back(
"", std::move(componentNode));
194 node[
"baseColorFactor"] = std::move(factorNode);
195 node[
"metallicFactor"] << material.metallic_factor;
196 node[
"roughnessFactor"] << material.roughness_factor;
197 node[
"normalScale"] << material.normal_scale;
198 node[
"occlusionStrength"] << material.occlusion_strength;
199 node[
"ior"] << material.ior;
200 node[
"transmissionFactor"] << material.transmission_factor;
201 node[
"volumeThicknessFactor"] << material.volume_thickness_factor;
202 node[
"volumeAttenuationDistance"] << material.volume_attenuation_distance;
203 node[
"specularFactor"] << material.specular_factor;
204 node[
"clearcoatFactor"] << material.clearcoat_factor;
205 node[
"clearcoatRoughnessFactor"] << material.clearcoat_roughness_factor;
206 node[
"clearcoatNormalScale"] << material.clearcoat_normal_scale;
207 node[
"sheenRoughnessFactor"] << material.sheen_roughness_factor;
208 node[
"iridescenceFactor"] << material.iridescence_factor;
209 node[
"iridescenceIor"] << material.iridescence_ior;
210 node[
"iridescenceThicknessMinimum"] << material.iridescence_thickness_minimum;
211 node[
"iridescenceThicknessMaximum"] << material.iridescence_thickness_maximum;
212 node[
"alphaMode"] << material.alpha_mode;
213 node[
"alphaCutoff"] << material.alpha_cutoff;
214 node[
"doubleSided"] << material.double_sided;
215 node[
"shadingModel"] << material.shading_model;
218 emissiveNode.set_type(NodeType::Array);
219 auto& emissiveProperties = emissiveNode.properties();
220 emissiveProperties.clear();
221 for (
int index = 0; index < 3; ++index)
224 componentNode << material.emissive_factor[index];
225 emissiveProperties.emplace_back(
"", std::move(componentNode));
227 node[
"emissiveFactor"] = std::move(emissiveNode);
228 node[
"emissiveStrength"] << material.emissive_strength;
230 Node volumeAttenuationColorNode;
231 volumeAttenuationColorNode.set_type(NodeType::Array);
232 auto& volumeAttenuationColorProperties = volumeAttenuationColorNode.properties();
233 volumeAttenuationColorProperties.clear();
234 for (
int index = 0; index < 3; ++index)
237 componentNode << material.volume_attenuation_color[index];
238 volumeAttenuationColorProperties.emplace_back(
"", std::move(componentNode));
240 node[
"volumeAttenuationColor"] = std::move(volumeAttenuationColorNode);
242 Node specularColorNode;
243 specularColorNode.set_type(NodeType::Array);
244 auto& specularColorProperties = specularColorNode.properties();
245 specularColorProperties.clear();
246 for (
int index = 0; index < 3; ++index)
249 componentNode << material.specular_color_factor[index];
250 specularColorProperties.emplace_back(
"", std::move(componentNode));
252 node[
"specularColorFactor"] = std::move(specularColorNode);
255 sheenColorNode.set_type(NodeType::Array);
256 auto& sheenColorProperties = sheenColorNode.properties();
257 sheenColorProperties.clear();
258 for (
int index = 0; index < 3; ++index)
261 componentNode << material.sheen_color_factor[index];
262 sheenColorProperties.emplace_back(
"", std::move(componentNode));
264 node[
"sheenColorFactor"] = std::move(sheenColorNode);
268 friend const Node& operator>>(
const Node& node, Material& material)
270 if (node.has_property(
"baseColorTexture"))
272 node[
"baseColorTexture"] >> material.base_color_texture;
275 if (node.has_property(
"normalTexture"))
277 node[
"normalTexture"] >> material.normal_texture;
280 if (node.has_property(
"ormTexture"))
282 node[
"ormTexture"] >> material.orm_texture;
285 if (node.has_property(
"emissiveTexture"))
287 node[
"emissiveTexture"] >> material.emissive_texture;
290 if (node.has_property(
"transmissionTexture"))
292 node[
"transmissionTexture"] >> material.transmission_texture;
295 if (node.has_property(
"volumeThicknessTexture"))
297 node[
"volumeThicknessTexture"] >> material.volume_thickness_texture;
300 if (node.has_property(
"specularTexture"))
302 node[
"specularTexture"] >> material.specular_texture;
305 if (node.has_property(
"specularColorTexture"))
307 node[
"specularColorTexture"] >> material.specular_color_texture;
310 if (node.has_property(
"clearcoatTexture"))
312 node[
"clearcoatTexture"] >> material.clearcoat_texture;
315 if (node.has_property(
"clearcoatRoughnessTexture"))
317 node[
"clearcoatRoughnessTexture"] >> material.clearcoat_roughness_texture;
320 if (node.has_property(
"clearcoatNormalTexture"))
322 node[
"clearcoatNormalTexture"] >> material.clearcoat_normal_texture;
325 if (node.has_property(
"sheenColorTexture"))
327 node[
"sheenColorTexture"] >> material.sheen_color_texture;
330 if (node.has_property(
"sheenRoughnessTexture"))
332 node[
"sheenRoughnessTexture"] >> material.sheen_roughness_texture;
335 if (node.has_property(
"iridescenceTexture"))
337 node[
"iridescenceTexture"] >> material.iridescence_texture;
340 if (node.has_property(
"iridescenceThicknessTexture"))
342 node[
"iridescenceThicknessTexture"] >> material.iridescence_thickness_texture;
345 if (node.has_property(
"baseColorSampler"))
347 node[
"baseColorSampler"] >> material.base_color_sampler;
350 if (node.has_property(
"normalSampler"))
352 node[
"normalSampler"] >> material.normal_sampler;
355 if (node.has_property(
"ormSampler"))
357 node[
"ormSampler"] >> material.orm_sampler;
360 if (node.has_property(
"emissiveSampler"))
362 node[
"emissiveSampler"] >> material.emissive_sampler;
365 if (node.has_property(
"transmissionSampler"))
367 node[
"transmissionSampler"] >> material.transmission_sampler;
370 if (node.has_property(
"volumeThicknessSampler"))
372 node[
"volumeThicknessSampler"] >> material.volume_thickness_sampler;
375 if (node.has_property(
"specularSampler"))
377 node[
"specularSampler"] >> material.specular_sampler;
380 if (node.has_property(
"specularColorSampler"))
382 node[
"specularColorSampler"] >> material.specular_color_sampler;
385 if (node.has_property(
"clearcoatSampler"))
387 node[
"clearcoatSampler"] >> material.clearcoat_sampler;
390 if (node.has_property(
"clearcoatRoughnessSampler"))
392 node[
"clearcoatRoughnessSampler"] >> material.clearcoat_roughness_sampler;
395 if (node.has_property(
"clearcoatNormalSampler"))
397 node[
"clearcoatNormalSampler"] >> material.clearcoat_normal_sampler;
400 if (node.has_property(
"sheenColorSampler"))
402 node[
"sheenColorSampler"] >> material.sheen_color_sampler;
405 if (node.has_property(
"sheenRoughnessSampler"))
407 node[
"sheenRoughnessSampler"] >> material.sheen_roughness_sampler;
410 if (node.has_property(
"iridescenceSampler"))
412 node[
"iridescenceSampler"] >> material.iridescence_sampler;
415 if (node.has_property(
"iridescenceThicknessSampler"))
417 node[
"iridescenceThicknessSampler"] >> material.iridescence_thickness_sampler;
420 if (node.has_property(
"baseColorUvSet"))
422 node[
"baseColorUvSet"] >> material.base_color_uv_set;
425 if (node.has_property(
"normalUvSet"))
427 node[
"normalUvSet"] >> material.normal_uv_set;
430 if (node.has_property(
"ormUvSet"))
432 node[
"ormUvSet"] >> material.orm_uv_set;
435 if (node.has_property(
"emissiveUvSet"))
437 node[
"emissiveUvSet"] >> material.emissive_uv_set;
440 if (node.has_property(
"transmissionUvSet"))
442 node[
"transmissionUvSet"] >> material.transmission_uv_set;
445 if (node.has_property(
"volumeThicknessUvSet"))
447 node[
"volumeThicknessUvSet"] >> material.volume_thickness_uv_set;
450 if (node.has_property(
"specularUvSet"))
452 node[
"specularUvSet"] >> material.specular_uv_set;
455 if (node.has_property(
"specularColorUvSet"))
457 node[
"specularColorUvSet"] >> material.specular_color_uv_set;
460 if (node.has_property(
"clearcoatUvSet"))
462 node[
"clearcoatUvSet"] >> material.clearcoat_uv_set;
465 if (node.has_property(
"clearcoatRoughnessUvSet"))
467 node[
"clearcoatRoughnessUvSet"] >> material.clearcoat_roughness_uv_set;
470 if (node.has_property(
"clearcoatNormalUvSet"))
472 node[
"clearcoatNormalUvSet"] >> material.clearcoat_normal_uv_set;
475 if (node.has_property(
"sheenColorUvSet"))
477 node[
"sheenColorUvSet"] >> material.sheen_color_uv_set;
480 if (node.has_property(
"sheenRoughnessUvSet"))
482 node[
"sheenRoughnessUvSet"] >> material.sheen_roughness_uv_set;
485 if (node.has_property(
"iridescenceUvSet"))
487 node[
"iridescenceUvSet"] >> material.iridescence_uv_set;
490 if (node.has_property(
"iridescenceThicknessUvSet"))
492 node[
"iridescenceThicknessUvSet"] >> material.iridescence_thickness_uv_set;
495 if (node.has_property(
"baseColorUvTransform"))
497 node[
"baseColorUvTransform"] >> material.base_color_uv_transform;
500 if (node.has_property(
"normalUvTransform"))
502 node[
"normalUvTransform"] >> material.normal_uv_transform;
505 if (node.has_property(
"ormUvTransform"))
507 node[
"ormUvTransform"] >> material.orm_uv_transform;
510 if (node.has_property(
"emissiveUvTransform"))
512 node[
"emissiveUvTransform"] >> material.emissive_uv_transform;
515 if (node.has_property(
"transmissionUvTransform"))
517 node[
"transmissionUvTransform"] >> material.transmission_uv_transform;
520 if (node.has_property(
"volumeThicknessUvTransform"))
522 node[
"volumeThicknessUvTransform"] >> material.volume_thickness_uv_transform;
525 if (node.has_property(
"specularUvTransform"))
527 node[
"specularUvTransform"] >> material.specular_uv_transform;
530 if (node.has_property(
"specularColorUvTransform"))
532 node[
"specularColorUvTransform"] >> material.specular_color_uv_transform;
535 if (node.has_property(
"clearcoatUvTransform"))
537 node[
"clearcoatUvTransform"] >> material.clearcoat_uv_transform;
540 if (node.has_property(
"clearcoatRoughnessUvTransform"))
542 node[
"clearcoatRoughnessUvTransform"] >> material.clearcoat_roughness_uv_transform;
545 if (node.has_property(
"clearcoatNormalUvTransform"))
547 node[
"clearcoatNormalUvTransform"] >> material.clearcoat_normal_uv_transform;
550 if (node.has_property(
"sheenColorUvTransform"))
552 node[
"sheenColorUvTransform"] >> material.sheen_color_uv_transform;
555 if (node.has_property(
"sheenRoughnessUvTransform"))
557 node[
"sheenRoughnessUvTransform"] >> material.sheen_roughness_uv_transform;
560 if (node.has_property(
"iridescenceUvTransform"))
562 node[
"iridescenceUvTransform"] >> material.iridescence_uv_transform;
565 if (node.has_property(
"iridescenceThicknessUvTransform"))
567 node[
"iridescenceThicknessUvTransform"] >> material.iridescence_thickness_uv_transform;
570 if (node.has_property(
"baseColorFactor"))
572 const Node& factorNode = node[
"baseColorFactor"];
573 ASSERT(factorNode.type() == NodeType::Array,
"material baseColorFactor must be an array");
574 const auto& factorProperties = factorNode.properties();
575 ASSERT(factorProperties.size() >= 4,
"material baseColorFactor requires four components");
576 for (
int index = 0; index < 4; ++index)
578 factorProperties[index].second >> material.base_color_factor[index];
582 if (node.has_property(
"metallicFactor"))
584 node[
"metallicFactor"] >> material.metallic_factor;
587 if (node.has_property(
"roughnessFactor"))
589 node[
"roughnessFactor"] >> material.roughness_factor;
592 if (node.has_property(
"normalScale"))
594 node[
"normalScale"] >> material.normal_scale;
597 if (node.has_property(
"occlusionStrength"))
599 node[
"occlusionStrength"] >> material.occlusion_strength;
602 if (node.has_property(
"ior"))
604 node[
"ior"] >> material.ior;
607 if (node.has_property(
"transmissionFactor"))
609 node[
"transmissionFactor"] >> material.transmission_factor;
612 if (node.has_property(
"volumeThicknessFactor"))
614 node[
"volumeThicknessFactor"] >> material.volume_thickness_factor;
617 if (node.has_property(
"volumeAttenuationDistance"))
619 node[
"volumeAttenuationDistance"] >> material.volume_attenuation_distance;
622 if (node.has_property(
"specularFactor"))
624 node[
"specularFactor"] >> material.specular_factor;
627 if (node.has_property(
"clearcoatFactor"))
629 node[
"clearcoatFactor"] >> material.clearcoat_factor;
632 if (node.has_property(
"clearcoatRoughnessFactor"))
634 node[
"clearcoatRoughnessFactor"] >> material.clearcoat_roughness_factor;
637 if (node.has_property(
"clearcoatNormalScale"))
639 node[
"clearcoatNormalScale"] >> material.clearcoat_normal_scale;
642 if (node.has_property(
"sheenRoughnessFactor"))
644 node[
"sheenRoughnessFactor"] >> material.sheen_roughness_factor;
647 if (node.has_property(
"iridescenceFactor"))
649 node[
"iridescenceFactor"] >> material.iridescence_factor;
652 if (node.has_property(
"iridescenceIor"))
654 node[
"iridescenceIor"] >> material.iridescence_ior;
657 if (node.has_property(
"iridescenceThicknessMinimum"))
659 node[
"iridescenceThicknessMinimum"] >> material.iridescence_thickness_minimum;
662 if (node.has_property(
"iridescenceThicknessMaximum"))
664 node[
"iridescenceThicknessMaximum"] >> material.iridescence_thickness_maximum;
667 if (node.has_property(
"alphaMode"))
669 node[
"alphaMode"] >> material.alpha_mode;
672 if (node.has_property(
"alphaCutoff"))
674 node[
"alphaCutoff"] >> material.alpha_cutoff;
677 if (node.has_property(
"doubleSided"))
679 node[
"doubleSided"] >> material.double_sided;
682 if (node.has_property(
"shadingModel"))
684 node[
"shadingModel"] >> material.shading_model;
687 if (node.has_property(
"emissiveFactor"))
689 const Node& emissiveNode = node[
"emissiveFactor"];
690 ASSERT(emissiveNode.type() == NodeType::Array,
"material emissiveFactor must be an array");
691 const auto& emissiveProperties = emissiveNode.properties();
692 ASSERT(emissiveProperties.size() >= 3,
"material emissiveFactor requires three components");
693 for (
int index = 0; index < 3; ++index)
695 emissiveProperties[index].second >> material.emissive_factor[index];
699 if (node.has_property(
"emissiveStrength"))
701 node[
"emissiveStrength"] >> material.emissive_strength;
704 if (node.has_property(
"volumeAttenuationColor"))
706 const Node& volume_attenuation_color_node = node[
"volumeAttenuationColor"];
707 ASSERT(volume_attenuation_color_node.type() == NodeType::Array,
"material volumeAttenuationColor must be an array");
708 const auto& volume_attenuation_color_properties = volume_attenuation_color_node.properties();
709 ASSERT(volume_attenuation_color_properties.size() >= 3,
"material volumeAttenuationColor requires three components");
710 for (
int index = 0; index < 3; ++index)
712 volume_attenuation_color_properties[index].second >> material.volume_attenuation_color[index];
716 if (node.has_property(
"specularColorFactor"))
718 const Node& specular_color_node = node[
"specularColorFactor"];
719 ASSERT(specular_color_node.type() == NodeType::Array,
"material specularColorFactor must be an array");
720 const auto& specular_color_properties = specular_color_node.properties();
721 ASSERT(specular_color_properties.size() >= 3,
"material specularColorFactor requires three components");
722 for (
int index = 0; index < 3; ++index)
724 specular_color_properties[index].second >> material.specular_color_factor[index];
728 if (node.has_property(
"sheenColorFactor"))
730 const Node& sheen_color_node = node[
"sheenColorFactor"];
731 ASSERT(sheen_color_node.type() == NodeType::Array,
"material sheenColorFactor must be an array");
732 const auto& sheen_color_properties = sheen_color_node.properties();
733 ASSERT(sheen_color_properties.size() >= 3,
"material sheenColorFactor requires three components");
734 for (
int index = 0; index < 3; ++index)
736 sheen_color_properties[index].second >> material.sheen_color_factor[index];