diff --git a/CHANGES.md b/CHANGES.md index 04f991beb..85d1cf3f0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,9 +1,13 @@ Change Log ========== ### Next Release + ##### Additions :tada: * Switch CI builds to GitHub actions [#264](https://github.com/KhronosGroup/COLLADA2GLTF/pull/264) +##### Fixes :wrench: +* Fixed spec/glossiness extension export [#156](https://github.com/KhronosGroup/COLLADA2GLTF/issues/156) + ### v2.1.5 - 2019-05-22 ##### Additions :tada: diff --git a/GLTF/src/GLTFMaterial.cpp b/GLTF/src/GLTFMaterial.cpp index 93ac69498..1f785ba2d 100755 --- a/GLTF/src/GLTFMaterial.cpp +++ b/GLTF/src/GLTFMaterial.cpp @@ -11,17 +11,17 @@ GLTF::Material::Material() { GLTF::Material::~Material() { - if (values) { - delete[] values->ambient; - delete[] values->diffuse; - delete[] values->emission; - delete[] values->specular; - delete[] values->shininess; - delete[] values->transparency; - - delete values; - values = nullptr; - } + if (values) { + delete[] values->ambient; + delete[] values->diffuse; + delete[] values->emission; + delete[] values->specular; + delete[] values->shininess; + delete[] values->transparency; + + delete values; + values = nullptr; + } } bool GLTF::Material::hasTexture() { @@ -172,10 +172,10 @@ void GLTF::MaterialPBR::Texture::writeJSON(void* writer, GLTF::Options* options) GLTF::MaterialPBR::MetallicRoughness::~MetallicRoughness() { - delete baseColorTexture; - delete metallicRoughnessTexture; + delete baseColorTexture; + delete metallicRoughnessTexture; - // baseColorFactor is stored in this->values + // baseColorFactor is stored in this->values } void GLTF::MaterialPBR::MetallicRoughness::writeJSON(void* writer, GLTF::Options* options) { @@ -213,10 +213,12 @@ void GLTF::MaterialPBR::MetallicRoughness::writeJSON(void* writer, GLTF::Options GLTF::MaterialPBR::SpecularGlossiness::~SpecularGlossiness() { - delete diffuseTexture; - delete specularGlossinessTexture; + delete diffuseTexture; + delete specularGlossinessTexture; + delete specularFactor; + delete glossinessFactor; - // diffuseFactor, specularFactor, glossinessFactor are stored in this->values + // diffuseFactor is stored in this->values } void GLTF::MaterialPBR::SpecularGlossiness::writeJSON(void* writer, GLTF::Options* options) { @@ -569,10 +571,10 @@ GLTF::Material* GLTF::MaterialCommon::getMaterial(std::vectortechnique == Technique::BLINN) { fragmentLightingBlock += "\ - vec3 h = normalize(l + viewDir);\n\ - float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n"; + vec3 h = normalize(l + viewDir);\n\ + float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n"; } else { // PHONG fragmentLightingBlock += "\ - vec3 reflectDir = reflect(-l, normal);\n\ - float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n"; + vec3 reflectDir = reflect(-l, normal);\n\ + float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n"; } } fragmentLightingBlock += "\ - specularLight += u_" + lightBaseName + "Color * specularIntensity;\n\ - }\n"; + specularLight += u_" + lightBaseName + "Color * specularIntensity;\n\ + }\n"; } } @@ -717,23 +719,23 @@ attribute vec4 a_weight;\n"; if (nonAmbientLights.size() == 0 && this->technique != Technique::CONSTANT) { fragmentLightingBlock += "\ - vec3 l = vec3(0.0, 0.0, 1.0);\n\ - diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal, l), 0.); \n"; + vec3 l = vec3(0.0, 0.0, 1.0);\n\ + diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal, l), 0.); \n"; if (hasSpecular) { if (this->technique == Technique::BLINN) { fragmentLightingBlock += "\ - vec3 h = normalize(l + viewDir);\n\ - float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n"; + vec3 h = normalize(l + viewDir);\n\ + float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n"; } else { // PHONG fragmentLightingBlock += "\ - vec3 reflectDir = reflect(-l, normal);\n\ - float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n"; + vec3 reflectDir = reflect(-l, normal);\n\ + float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n"; } fragmentLightingBlock += "\ - specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n"; + specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n"; } } @@ -756,9 +758,9 @@ void main(void) {\n"; fragmentShaderSource += " vec3 normal = normalize(v_normal);\n"; if (doubleSided || options->doubleSided) { fragmentShaderSource += "\ - if (gl_FrontFacing == false)\n\ - {\n\ - normal = -normal;\n\ + if (gl_FrontFacing == false)\n\ + {\n\ + normal = -normal;\n\ }\n"; } } @@ -826,8 +828,8 @@ void main(void) {\n"; colorCreationBlock += " color += ambient * ambientLight;\n"; } fragmentShaderSource += "\ - vec3 viewDir = -normalize(v_position);\n\ - vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n"; + vec3 viewDir = -normalize(v_position);\n\ + vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n"; // Add in light computations fragmentShaderSource += fragmentLightingBlock; @@ -882,13 +884,13 @@ std::string GLTF::MaterialCommon::getTechniqueKey(GLTF::Options* options) { GLTF::MaterialPBR::~MaterialPBR() { - delete metallicRoughness; - delete specularGlossiness; + delete metallicRoughness; + delete specularGlossiness; - delete normalTexture; - delete occlusionTexture; - delete emissiveTexture; - delete emissiveFactor; + delete normalTexture; + delete occlusionTexture; + delete emissiveTexture; + delete emissiveFactor; } GLTF::MaterialPBR::MaterialPBR() { @@ -920,12 +922,12 @@ GLTF::MaterialPBR* GLTF::MaterialCommon::getMaterialPBR(GLTF::Options* options) } } - if (values->emission) { - if (values->emission[3] < 1.0) { - hasTransparency = true; - } - material->emissiveFactor = new float[3]{ values->emission[0], values->emission[1], values->emission[2] }; - } + if (values->emission) { + if (values->emission[3] < 1.0) { + hasTransparency = true; + } + material->emissiveFactor = new float[3]{ values->emission[0], values->emission[1], values->emission[2] }; + } if (values->emissionTexture) { GLTF::MaterialPBR::Texture* texture = new GLTF::MaterialPBR::Texture(); texture->texCoord = values->emissionTexCoord; @@ -941,24 +943,50 @@ GLTF::MaterialPBR* GLTF::MaterialCommon::getMaterialPBR(GLTF::Options* options) material->occlusionTexture = texture; } - if (options->specularGlossiness) { - if (values->specular) { - if (values->specular[3] < 1.0) { - hasTransparency = true; - } - material->specularGlossiness->specularFactor = values->specular; + float specularIntensity = 1.0; + if (values->specular) { + if (values->specular[3] < 1.0) { + hasTransparency = true; + } + // Compute specular intensity as luminance of the specular color. + float opacity = values->specular[3]; + specularIntensity = values->specular[0] * opacity * 0.2125 + + values->specular[1] * opacity * 0.7154 + + values->specular[2] * opacity * 0.0721; + } + + float roughnessFactor = 1.0; + if (values->shininess) { + // Transform from 0-1000 range to 0-1 range. Then invert. + roughnessFactor = values->shininess[0] / 1000.0; + roughnessFactor = 1 - roughnessFactor; + // Clamp to 0.0-1.0 range. + if (roughnessFactor < 0) { + roughnessFactor = 0; + } else if (roughnessFactor > 1) { + roughnessFactor = 1; } + } + + // Low specular intensity values should produce a rough material even if shininess is high. + if (specularIntensity < 0.1) { + roughnessFactor *= (1.0 - specularIntensity); + } + if (roughnessFactor < 1.0) { + material->metallicRoughness->roughnessFactor = roughnessFactor; + } + + if (options->specularGlossiness) { + // Specular factor is based on metallic factor, which when converting from Blinn-Phong is always zero. + material->specularGlossiness->specularFactor = new float[4]{ 0.0, 0.0, 0.0, 1.0 }; if (values->specularTexture) { GLTF::MaterialPBR::Texture* texture = new GLTF::MaterialPBR::Texture(); texture->texCoord = values->specularTexCoord; texture->texture = values->specularTexture; material->specularGlossiness->specularGlossinessTexture = texture; } - if (values->shininess) { - if (values->shininess[0] > 1.0) { - values->shininess[0] = 1.0; - } - material->specularGlossiness->glossinessFactor = values->shininess; + if (roughnessFactor < 1.0) { + material->specularGlossiness->glossinessFactor = new float[1]{ 1.0f - roughnessFactor }; } }