Merge pull request #4112 from diharaw/master
[GLTF2] Add read and write support for KHR_materials_volume and KHR_materials_ior extensions.pull/4079/head^2
commit
f81d7c0b3e
|
@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* KHR_materials_sheen full
|
* KHR_materials_sheen full
|
||||||
* KHR_materials_clearcoat full
|
* KHR_materials_clearcoat full
|
||||||
* KHR_materials_transmission full
|
* KHR_materials_transmission full
|
||||||
|
* KHR_materials_volume full
|
||||||
|
* KHR_materials_ior full
|
||||||
*/
|
*/
|
||||||
#ifndef GLTF2ASSET_H_INC
|
#ifndef GLTF2ASSET_H_INC
|
||||||
#define GLTF2ASSET_H_INC
|
#define GLTF2ASSET_H_INC
|
||||||
|
@ -713,6 +715,7 @@ const vec3 defaultEmissiveFactor = { 0, 0, 0 };
|
||||||
const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 };
|
const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 };
|
||||||
const vec3 defaultSpecularFactor = { 1, 1, 1 };
|
const vec3 defaultSpecularFactor = { 1, 1, 1 };
|
||||||
const vec3 defaultSheenFactor = { 0, 0, 0 };
|
const vec3 defaultSheenFactor = { 0, 0, 0 };
|
||||||
|
const vec3 defaultAttenuationColor = { 1, 1, 1 };
|
||||||
|
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
Ref<Texture> texture;
|
Ref<Texture> texture;
|
||||||
|
@ -777,6 +780,23 @@ struct MaterialTransmission {
|
||||||
float transmissionFactor = 0.f;
|
float transmissionFactor = 0.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MaterialVolume {
|
||||||
|
float thicknessFactor = 0.f;
|
||||||
|
TextureInfo thicknessTexture;
|
||||||
|
float attenuationDistance = 0.f;
|
||||||
|
vec3 attenuationColor;
|
||||||
|
|
||||||
|
MaterialVolume() { SetDefaults(); }
|
||||||
|
void SetDefaults();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaterialIOR {
|
||||||
|
float ior = 0.f;
|
||||||
|
|
||||||
|
MaterialIOR() { SetDefaults(); }
|
||||||
|
void SetDefaults();
|
||||||
|
};
|
||||||
|
|
||||||
//! The material appearance of a primitive.
|
//! The material appearance of a primitive.
|
||||||
struct Material : public Object {
|
struct Material : public Object {
|
||||||
//PBR metallic roughness properties
|
//PBR metallic roughness properties
|
||||||
|
@ -803,6 +823,12 @@ struct Material : public Object {
|
||||||
//extension: KHR_materials_transmission
|
//extension: KHR_materials_transmission
|
||||||
Nullable<MaterialTransmission> materialTransmission;
|
Nullable<MaterialTransmission> materialTransmission;
|
||||||
|
|
||||||
|
//extension: KHR_materials_volume
|
||||||
|
Nullable<MaterialVolume> materialVolume;
|
||||||
|
|
||||||
|
//extension: KHR_materials_ior
|
||||||
|
Nullable<MaterialIOR> materialIOR;
|
||||||
|
|
||||||
//extension: KHR_materials_unlit
|
//extension: KHR_materials_unlit
|
||||||
bool unlit;
|
bool unlit;
|
||||||
|
|
||||||
|
@ -1091,6 +1117,8 @@ public:
|
||||||
bool KHR_materials_sheen;
|
bool KHR_materials_sheen;
|
||||||
bool KHR_materials_clearcoat;
|
bool KHR_materials_clearcoat;
|
||||||
bool KHR_materials_transmission;
|
bool KHR_materials_transmission;
|
||||||
|
bool KHR_materials_volume;
|
||||||
|
bool KHR_materials_ior;
|
||||||
bool KHR_draco_mesh_compression;
|
bool KHR_draco_mesh_compression;
|
||||||
bool FB_ngon_encoding;
|
bool FB_ngon_encoding;
|
||||||
bool KHR_texture_basisu;
|
bool KHR_texture_basisu;
|
||||||
|
|
|
@ -1215,6 +1215,29 @@ inline void Material::Read(Value &material, Asset &r) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r.extensionsUsed.KHR_materials_volume) {
|
||||||
|
if (Value *curMaterialVolume = FindObject(*extensions, "KHR_materials_volume")) {
|
||||||
|
MaterialVolume volume;
|
||||||
|
|
||||||
|
ReadMember(*curMaterialVolume, "thicknessFactor", volume.thicknessFactor);
|
||||||
|
ReadTextureProperty(r, *curMaterialVolume, "thicknessTexture", volume.thicknessTexture);
|
||||||
|
ReadMember(*curMaterialVolume, "attenuationDistance", volume.attenuationDistance);
|
||||||
|
ReadMember(*curMaterialVolume, "attenuationColor", volume.attenuationColor);
|
||||||
|
|
||||||
|
this->materialVolume = Nullable<MaterialVolume>(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1260,6 +1283,18 @@ inline void MaterialSheen::SetDefaults() {
|
||||||
sheenRoughnessFactor = 0.f;
|
sheenRoughnessFactor = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void MaterialVolume::SetDefaults() {
|
||||||
|
//KHR_materials_volume properties
|
||||||
|
thicknessFactor = 0.f;
|
||||||
|
attenuationDistance = INFINITY;
|
||||||
|
SetVector(attenuationColor, defaultAttenuationColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MaterialIOR::SetDefaults() {
|
||||||
|
//KHR_materials_ior properties
|
||||||
|
ior = 1.5f;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
|
@ -1931,6 +1966,8 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
|
||||||
CHECK_EXT(KHR_materials_sheen);
|
CHECK_EXT(KHR_materials_sheen);
|
||||||
CHECK_EXT(KHR_materials_clearcoat);
|
CHECK_EXT(KHR_materials_clearcoat);
|
||||||
CHECK_EXT(KHR_materials_transmission);
|
CHECK_EXT(KHR_materials_transmission);
|
||||||
|
CHECK_EXT(KHR_materials_volume);
|
||||||
|
CHECK_EXT(KHR_materials_ior);
|
||||||
CHECK_EXT(KHR_draco_mesh_compression);
|
CHECK_EXT(KHR_draco_mesh_compression);
|
||||||
CHECK_EXT(KHR_texture_basisu);
|
CHECK_EXT(KHR_texture_basisu);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* KHR_materials_sheen: full
|
* KHR_materials_sheen: full
|
||||||
* KHR_materials_clearcoat: full
|
* KHR_materials_clearcoat: full
|
||||||
* KHR_materials_transmission: full
|
* KHR_materials_transmission: full
|
||||||
|
* KHR_materials_volume: full
|
||||||
|
* KHR_materials_ior: full
|
||||||
*/
|
*/
|
||||||
#ifndef GLTF2ASSETWRITER_H_INC
|
#ifndef GLTF2ASSETWRITER_H_INC
|
||||||
#define GLTF2ASSETWRITER_H_INC
|
#define GLTF2ASSETWRITER_H_INC
|
||||||
|
|
|
@ -474,6 +474,42 @@ namespace glTF2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m.materialVolume.isPresent) {
|
||||||
|
Value materialVolume(rapidjson::Type::kObjectType);
|
||||||
|
|
||||||
|
MaterialVolume &volume = m.materialVolume.value;
|
||||||
|
|
||||||
|
if (volume.thicknessFactor != 0.f) {
|
||||||
|
WriteFloat(materialVolume, volume.thicknessFactor, "thicknessFactor", w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteTex(materialVolume, volume.thicknessTexture, "thicknessTexture", w.mAl);
|
||||||
|
|
||||||
|
if (volume.attenuationDistance != INFINITY) {
|
||||||
|
WriteFloat(materialVolume, volume.attenuationDistance, "attenuationDistance", w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteVec(materialVolume, volume.attenuationColor, "attenuationColor", defaultAttenuationColor, w.mAl);
|
||||||
|
|
||||||
|
if (!materialVolume.ObjectEmpty()) {
|
||||||
|
exts.AddMember("KHR_materials_volume", materialVolume, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
if (!exts.ObjectEmpty()) {
|
||||||
obj.AddMember("extensions", exts, w.mAl);
|
obj.AddMember("extensions", exts, w.mAl);
|
||||||
}
|
}
|
||||||
|
@ -890,6 +926,14 @@ namespace glTF2 {
|
||||||
exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
|
exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->mAsset.extensionsUsed.KHR_materials_volume) {
|
||||||
|
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) {
|
if (this->mAsset.extensionsUsed.FB_ngon_encoding) {
|
||||||
exts.PushBack(StringRef("FB_ngon_encoding"), mAl);
|
exts.PushBack(StringRef("FB_ngon_encoding"), mAl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -704,6 +704,22 @@ bool glTF2Exporter::GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTra
|
||||||
return result || transmission.transmissionTexture.texture;
|
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_REFRACTI, ior.ior) == aiReturn_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void glTF2Exporter::ExportMaterials() {
|
void glTF2Exporter::ExportMaterials() {
|
||||||
aiString aiName;
|
aiString aiName;
|
||||||
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||||
|
@ -824,6 +840,18 @@ void glTF2Exporter::ExportMaterials() {
|
||||||
mAsset->extensionsUsed.KHR_materials_transmission = true;
|
mAsset->extensionsUsed.KHR_materials_transmission = true;
|
||||||
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ struct PbrSpecularGlossiness;
|
||||||
struct MaterialSheen;
|
struct MaterialSheen;
|
||||||
struct MaterialClearcoat;
|
struct MaterialClearcoat;
|
||||||
struct MaterialTransmission;
|
struct MaterialTransmission;
|
||||||
|
struct MaterialVolume;
|
||||||
|
struct MaterialIOR;
|
||||||
|
|
||||||
// Vec/matrix types, as raw float arrays
|
// Vec/matrix types, as raw float arrays
|
||||||
typedef float(vec2)[2];
|
typedef float(vec2)[2];
|
||||||
|
@ -114,6 +116,8 @@ protected:
|
||||||
bool GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen);
|
bool GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen);
|
||||||
bool GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat);
|
bool GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat);
|
||||||
bool GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission);
|
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 ExportMetadata();
|
||||||
void ExportMaterials();
|
void ExportMaterials();
|
||||||
void ExportMeshes();
|
void ExportMeshes();
|
||||||
|
|
|
@ -341,6 +341,23 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
|
||||||
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_TRANSMISSION_TEXTURE);
|
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_TRANSMISSION_TEXTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KHR_materials_volume
|
||||||
|
if (mat.materialVolume.isPresent) {
|
||||||
|
MaterialVolume &volume = mat.materialVolume.value;
|
||||||
|
|
||||||
|
aimat->AddProperty(&volume.thicknessFactor, 1, AI_MATKEY_VOLUME_THICKNESS_FACTOR);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, volume.thicknessTexture, aimat, AI_MATKEY_VOLUME_THICKNESS_TEXTURE);
|
||||||
|
aimat->AddProperty(&volume.attenuationDistance, 1, AI_MATKEY_VOLUME_ATTENUATION_DISTANCE);
|
||||||
|
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_REFRACTI);
|
||||||
|
}
|
||||||
|
|
||||||
return aimat;
|
return aimat;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
delete aimat;
|
delete aimat;
|
||||||
|
|
|
@ -1028,6 +1028,19 @@ extern "C" {
|
||||||
// Multiplied by AI_MATKEY_TRANSMISSION_FACTOR
|
// Multiplied by AI_MATKEY_TRANSMISSION_FACTOR
|
||||||
#define AI_MATKEY_TRANSMISSION_TEXTURE aiTextureType_TRANSMISSION, 0
|
#define AI_MATKEY_TRANSMISSION_TEXTURE aiTextureType_TRANSMISSION, 0
|
||||||
|
|
||||||
|
// Volume
|
||||||
|
// ------------
|
||||||
|
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_volume
|
||||||
|
// 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 that defines the thickness.
|
||||||
|
// Multiplied by AI_MATKEY_THICKNESS_FACTOR
|
||||||
|
#define AI_MATKEY_VOLUME_THICKNESS_TEXTURE aiTextureType_TRANSMISSION, 1
|
||||||
|
// 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
|
||||||
|
|
||||||
// Emissive
|
// Emissive
|
||||||
// --------
|
// --------
|
||||||
#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0
|
#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0
|
||||||
|
|
Loading…
Reference in New Issue