Added gltf2 KHR_materials_ior support.

pull/4112/head
diharaw 2021-09-30 08:47:53 +01:00
parent d3276de47d
commit addd541251
8 changed files with 96 additions and 2 deletions

View File

@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* KHR_materials_clearcoat full
* KHR_materials_transmission full
* KHR_materials_volume full
* KHR_materials_ior full
*/
#ifndef GLTF2ASSET_H_INC
#define GLTF2ASSET_H_INC
@ -789,6 +790,13 @@ struct MaterialVolume {
void SetDefaults();
};
struct MaterialIOR {
float ior = 0.f;
MaterialIOR() { SetDefaults(); }
void SetDefaults();
};
//! The material appearance of a primitive.
struct Material : public Object {
//PBR metallic roughness properties
@ -817,6 +825,9 @@ struct Material : public Object {
//extension: KHR_materials_volume
Nullable<MaterialVolume> materialVolume;
//extension: KHR_materials_ior
Nullable<MaterialIOR> materialIOR;
//extension: KHR_materials_unlit
bool unlit;
@ -1107,6 +1118,7 @@ public:
bool KHR_materials_clearcoat;
bool KHR_materials_transmission;
bool KHR_materials_volume;
bool KHR_materials_ior;
bool KHR_draco_mesh_compression;
bool FB_ngon_encoding;
bool KHR_texture_basisu;

View File

@ -1228,6 +1228,16 @@ inline void Material::Read(Value &material, Asset &r) {
}
}
if (r.extensionsUsed.KHR_materials_ior) {
if (Value *curMaterialIOR = FindObject(*extensions, "KHR_materials_ior")) {
MaterialIOR ior;
ReadMember(*curMaterialIOR, "ior", ior.ior);
this->materialIOR = Nullable<MaterialIOR>(ior);
}
}
unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
}
}
@ -1280,6 +1290,11 @@ inline void MaterialVolume::SetDefaults() {
SetVector(attenuationColor, defaultAttenuationColor);
}
inline void MaterialIOR::SetDefaults() {
//KHR_materials_ior properties
ior = 1.5f;
}
namespace {
template <int N>
@ -1952,6 +1967,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
CHECK_EXT(KHR_materials_clearcoat);
CHECK_EXT(KHR_materials_transmission);
CHECK_EXT(KHR_materials_volume);
CHECK_EXT(KHR_materials_ior);
CHECK_EXT(KHR_draco_mesh_compression);
CHECK_EXT(KHR_texture_basisu);

View File

@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* KHR_materials_clearcoat: full
* KHR_materials_transmission: full
* KHR_materials_volume: full
* KHR_materials_ior: full
*/
#ifndef GLTF2ASSETWRITER_H_INC
#define GLTF2ASSETWRITER_H_INC

View File

@ -496,6 +496,20 @@ namespace glTF2 {
}
}
if (m.materialIOR.isPresent) {
Value materialIOR(rapidjson::Type::kObjectType);
MaterialIOR &ior = m.materialIOR.value;
if (ior.ior != 1.5f) {
WriteFloat(materialIOR, ior.ior, "ior", w.mAl);
}
if (!materialIOR.ObjectEmpty()) {
exts.AddMember("KHR_materials_ior", materialIOR, w.mAl);
}
}
if (!exts.ObjectEmpty()) {
obj.AddMember("extensions", exts, w.mAl);
}
@ -916,6 +930,10 @@ namespace glTF2 {
exts.PushBack(StringRef("KHR_materials_volume"), mAl);
}
if (this->mAsset.extensionsUsed.KHR_materials_ior) {
exts.PushBack(StringRef("KHR_materials_ior"), mAl);
}
if (this->mAsset.extensionsUsed.FB_ngon_encoding) {
exts.PushBack(StringRef("FB_ngon_encoding"), mAl);
}

View File

@ -704,6 +704,22 @@ bool glTF2Exporter::GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTra
return result || transmission.transmissionTexture.texture;
}
bool glTF2Exporter::GetMatVolume(const aiMaterial &mat, glTF2::MaterialVolume &volume) {
bool result = mat.Get(AI_MATKEY_VOLUME_THICKNESS_FACTOR, volume.thicknessFactor) != aiReturn_SUCCESS;
GetMatTex(mat, volume.thicknessTexture, AI_MATKEY_VOLUME_THICKNESS_TEXTURE);
result = result || mat.Get(AI_MATKEY_VOLUME_ATTENUATION_DISTANCE, volume.attenuationDistance);
result = result || GetMatColor(mat, volume.attenuationColor, AI_MATKEY_VOLUME_ATTENUATION_COLOR) != aiReturn_SUCCESS;
// Valid if any of these properties are available
return result || volume.thicknessTexture.texture;
}
bool glTF2Exporter::GetMatIOR(const aiMaterial &mat, glTF2::MaterialIOR &ior) {
return mat.Get(AI_MATKEY_IOR, ior.ior) == aiReturn_SUCCESS;
}
void glTF2Exporter::ExportMaterials() {
aiString aiName;
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
@ -824,6 +840,18 @@ void glTF2Exporter::ExportMaterials() {
mAsset->extensionsUsed.KHR_materials_transmission = true;
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
}
MaterialVolume volume;
if (GetMatVolume(mat, volume)) {
mAsset->extensionsUsed.KHR_materials_volume = true;
m->materialVolume = Nullable<MaterialVolume>(volume);
}
MaterialIOR ior;
if (GetMatIOR(mat, ior)) {
mAsset->extensionsUsed.KHR_materials_ior = true;
m->materialIOR = Nullable<MaterialIOR>(ior);
}
}
}
}

View File

@ -77,6 +77,8 @@ struct PbrSpecularGlossiness;
struct MaterialSheen;
struct MaterialClearcoat;
struct MaterialTransmission;
struct MaterialVolume;
struct MaterialIOR;
// Vec/matrix types, as raw float arrays
typedef float(vec2)[2];
@ -114,6 +116,8 @@ protected:
bool GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen);
bool GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat);
bool GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission);
bool GetMatVolume(const aiMaterial &mat, glTF2::MaterialVolume &volume);
bool GetMatIOR(const aiMaterial &mat, glTF2::MaterialIOR &ior);
void ExportMetadata();
void ExportMaterials();
void ExportMeshes();

View File

@ -351,6 +351,13 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
SetMaterialColorProperty(r, volume.attenuationColor, aimat, AI_MATKEY_VOLUME_ATTENUATION_COLOR);
}
// KHR_materials_ior
if (mat.materialIOR.isPresent) {
MaterialIOR &ior = mat.materialIOR.value;
aimat->AddProperty(&ior.ior, 1, AI_MATKEY_IOR);
}
return aimat;
} catch (...) {
delete aimat;

View File

@ -1037,14 +1037,22 @@ extern "C" {
// Volume
// ------------
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_volume
// Base percentage of light transmitted through the surface. 0.0 = Opaque, 1.0 = Fully transparent
// The thickness of the volume beneath the surface. If the value is 0 the material is thin-walled. Otherwise the material is a volume boundary.
#define AI_MATKEY_VOLUME_THICKNESS_FACTOR "$mat.volume.thicknessFactor", 0, 0
// Texture defining percentage of light transmitted through the surface.
// Texture that defines the thickness.
// Multiplied by AI_MATKEY_THICKNESS_FACTOR
#define AI_MATKEY_VOLUME_THICKNESS_TEXTURE aiTextureType_VOLUME, 0
// Density of the medium given as the average distance that light travels in the medium before interacting with a particle.
#define AI_MATKEY_VOLUME_ATTENUATION_DISTANCE "$mat.volume.attenuationDistance", 0, 0
// The color that white light turns into due to absorption when reaching the attenuation distance.
#define AI_MATKEY_VOLUME_ATTENUATION_COLOR "$mat.volume.attenuationColor", 0, 0
// IOR
// ------------
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_ior
// Index of Refraction.
#define AI_MATKEY_IOR "$mat.ior", 0, 0
// Emissive
// --------
#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0