Incompatible usage of the Collada transparency value
authorGaia Clary <gaia.clary@machinimatrix.org>
Mon, 22 Jul 2019 16:57:44 +0000 (18:57 +0200)
committerGaia Clary <gaia.clary@machinimatrix.org>
Mon, 22 Jul 2019 17:03:56 +0000 (19:03 +0200)
Some external tools seem to have issues with the definition
of Collada <transparency> - a float value in range (0,1).
However it is possible to use the <transparent> color as a container
for the <transparency> value. This seems to be a more reliable
method to export transparency values from Blender PBSDF Shaders.

The relevant documentation is in the collada 1.14 reference manual,
page 7-5 about the usage of transparent and transparency.

This fix makes export and import of the <transparency>
and <transparent> values more convenient and more reliable.

Reviewers: brecht, jesterking

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D5305

release/datafiles/locale
release/scripts/addons
release/scripts/addons_contrib
source/blender/collada/EffectExporter.cpp
source/blender/collada/Materials.cpp

index 0f771b0f380a1ae21d859416043c6119f66e40c9..6625026f62f492dd677f5f29c68b9d70c96fb34b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0f771b0f380a1ae21d859416043c6119f66e40c9
+Subproject commit 6625026f62f492dd677f5f29c68b9d70c96fb34b
index aa3366b7805bbe4d1afee890bda81b6d91bd47be..979298511916b25ec97bb22feb1c06cc9fbc86dd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit aa3366b7805bbe4d1afee890bda81b6d91bd47be
+Subproject commit 979298511916b25ec97bb22feb1c06cc9fbc86dd
index 0aa23a4d6177bed4c12392c81d0b767a8b35fe61..b4fce25e94ec139554e821f58bbada3384b13afa 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0aa23a4d6177bed4c12392c81d0b767a8b35fe61
+Subproject commit b4fce25e94ec139554e821f58bbada3384b13afa
index a784776d34209c7e0f3ec2c6572328142d522105..80f84738f6e0119033c6d14d6aaff05a24f1c145 100644 (file)
@@ -102,7 +102,12 @@ void EffectsExporter::set_shader_type(COLLADASW::EffectProfile &ep, Material *ma
 void EffectsExporter::set_transparency(COLLADASW::EffectProfile &ep, Material *ma)
 {
   double alpha = bc_get_alpha(ma);
-  ep.setTransparency(alpha, false, "alpha");
+  if (alpha < 1) {
+    // workaround use <transparent> to avoid wrong handling of <transparency> by other tools
+    COLLADASW::ColorOrTexture cot = bc_get_cot(0, 0, 0, alpha);
+    ep.setTransparent(cot, false, "alpha");
+    ep.setOpaque(COLLADASW::EffectProfile::A_ONE);
+  }
 }
 
 void EffectsExporter::set_diffuse_color(COLLADASW::EffectProfile &ep, Material *ma)
@@ -134,7 +139,9 @@ void EffectsExporter::set_reflective(COLLADASW::EffectProfile &ep, Material *ma)
 void EffectsExporter::set_reflectivity(COLLADASW::EffectProfile &ep, Material *ma)
 {
   double reflectivity = bc_get_reflectivity(ma);
-  ep.setReflectivity(reflectivity, false, "specular");
+  if (reflectivity > 0.0) {
+    ep.setReflectivity(reflectivity, false, "specular");
+  }
 }
 
 void EffectsExporter::set_emission(COLLADASW::EffectProfile &ep, Material *ma)
index d8a0f06c12b893b4ccabcc350d95310bd0d68340..e1d5b2e9d5c2df521057b94387c4548912329ccb 100644 (file)
@@ -168,13 +168,37 @@ void MaterialNode::set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode,
                              COLLADAFW::ColorOrTexture &cot,
                              COLLADAFW::FloatOrParam &val)
 {
+  /*  Handling the alpha value according to the Collada 1.4 reference guide
+   *  see page 7-5 Determining Transparency (Opacity)
+   */
+
   if (effect == nullptr) {
     return;
   }
 
   if (cot.isColor() || !cot.isValid()) {
-    COLLADAFW::Color col = (cot.isValid()) ? cot.getColor() : COLLADAFW::Color(1, 1, 1, 1);
-    float alpha = val.getFloatValue() * col.getAlpha();  // Assuming A_ONE opaque mode
+    // transparent_cot is either a color or not defined
+
+    float transparent_alpha;
+    if (cot.isValid()) {
+      COLLADAFW::Color col = cot.getColor();
+      transparent_alpha = col.getAlpha();
+    }
+    else {
+      // no transparent color defined
+      transparent_alpha = 1;
+    }
+
+    float transparency_alpha = val.getFloatValue();
+    if (transparency_alpha < 0) {
+      // transparency is not defined
+      transparency_alpha = 1;  // set to opaque
+    }
+
+    float alpha = transparent_alpha * transparency_alpha;
+    if (mode == COLLADASW::EffectProfile::RGB_ZERO) {
+      alpha = 1 - alpha;
+    }
 
     bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Alpha");
     ((bNodeSocketValueFloat *)socket->default_value)->value = alpha;
@@ -182,7 +206,6 @@ void MaterialNode::set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode,
   else if (cot.isTexture()) {
     int locy = -300 * (node_map.size() - 2);
     add_texture_node(cot, -300, locy, "Alpha");
-    // TODO: Connect node
   }
 }