Collada, Gltf, converters and shaders

Hi,

I have been experimenting a bit with different workflows to import 3D models in Cesium but I can’t find the best approach yet. I would not mind reading some sort of advanced tutorial on the subject (a bit like https://cesiumjs.org/2014/12/15/glTF-Tips-for-Artists/ but more detailed on the technical aspects)

I am particularly curious to know if the Gltf converter is (or will be) able to handle Collada “Techniques” in order to have out-of-the box specular lighting and/or reflection and bump mappings, etc.

If not directly available from the converter, I would also like to read about the best way to implement custom shaders in Cesium and apply them to some material used by a model: I am not a 3D programmer but could probably work my way around writing my own shaders if given some introductions to it.

Also, among the issues I have with the current converter:

  • I see inconsistencies in the results I get from the online converter and the stand alone converter.
  • Transparent textures (png) are not well handled by the online converter if only referenced (url set in DAE file): they need to be “dropped” in the online converter along with the DAE file in order to work properly.
  • A lot of inconsistencies in the way normals are handled:
  • Inverted normals no matter what.
  • Smoothing groups sometimes do not work no matter how the model is being processed (3DSmax, Blender, Sketchup, converted to simple mesh, pre-comp normals, etc.)
  • Often caused by the use of mirror cloning in 3D editing software (I suspect the vertices order to be responsible here)
    Many thanks,

Xavier

I am particularly curious to know if the Gltf converter is (or will be) able to handle Collada “Techniques” in order to have out-of-the box specular lighting and/or reflection and bump mappings, etc.

Right now the converter only uses profile_COMMON. This does support specular lighting.

**For bump mapping you would need a custom shader in another profile (eg. ****profile_GLSL, **profile_GLES), which isn’t currently supported. There aren’t any near term plans to implement these, as there aren’t really any good COLLADA exporters for these other profiles.

If not directly available from the converter, I would also like to read about the best way to implement custom shaders in Cesium and apply them to some material used by a model: I am not a 3D programmer but could probably work my way around writing my own shaders if given some introductions to it.

We don’t have robust support for this at the Cesium level. You can however get a material and change the values of a uniform. Take a look at https://cesiumjs.org/Cesium/Build/Documentation/Model.html#getMaterial.

If you need to do large things that require shader and uniform changes then probably the best way to do this would be to patch the model and shaders that are exported from the converter. You can find the glTF spec at https://github.com/KhronosGroup/glTF/blob/master/specification/README.md. It’s not incredibly difficult but it does take some understanding of the spec.

For simple changes you could just modify the shaders. For more advanced things that require additional uniforms you would need add a uniform to a technique and material and change the shader to use it. For things that require textures likebump mapping, you would have to also add an image and texture along with the uniform changes.

I see inconsistencies in the results I get from the online converter and the stand alone converter.

The online converter uses the standalone converter as part of a bigger conversion pipeline, so there will be some differences. Can you provide example models that are causing you issues.?

Transparent textures (png) are not well handled by the online converter if only referenced (url set in DAE file): they need to be “dropped” in the online converter along with the DAE file in order to work properly.

In order to make something transparent we need to know if the texture has transparency or not. It’s not a matter of simply using the texture with transparency. We need to enable blending and disable backface culling in the glTF technique.

A lot of inconsistencies in the way normals are handled:

Can you share an example?

Hi Tom,

Thanks for the extensive reply.

I will look into modifying the glTF shaders. If I could only add some specular lighting, that would already be really cool. If anybody has some pointer there, I am more that happy to hear about it.

When it come to problems with the converter, I attach a model (zip file) that gives some trouble. No matter what I try, the normals always are wrong. I reversed them, unified them, put the model through various transformation to try and fix it. I exported the DAE file from 3DS Max “OpenCollada”, from Sketchup and from Blender. In every case, the normals are wrong.

Also attached, some screenshots of what I see in the converted ouput: when normals are exported with the Collada model, they appear to be wrongly calculated, as if they were perpendicular to what they should be. The model looks black (and many people reported that problem), but it is just that it is wrongly lit.

The zip contains DAE, 3DS Max and Blender files + textures.

I will keep investigating but this is a real problem as many of the models I use have similar issues.

Thanks,

Xavier.

gondola.zip (813 KB)

I did a little messing around with it and it seems to have something to do with double sided lighting and the winding order.

Double sided lighting is for cases like the basket so we can show the inside and outside of the basket without duplicating geometry. All that happens in the shader is that it inverts the normal if the triangle is backfacing. Double sided lighting isn’t part of the Collada spec so it is enabled with an extra tag

<double_sided>1</double_sided>

Collada requires counter clockwise winding order. I think that your triangles are being output with clockwise winding order, so the shader thinks the front is the back and the back is the front, so the normals are always going in the wrong direction. You may want to look for options in your modeling packages to see if you can set the winding order. The exporters should know that collada requires CCW winding but most Collada exporters aren’t always robust.

Hi Tom,

Thanks for the feedback, I believe you found the right explanation. My files used to be exported from 3DS Max and were working fine in the Google Earth plugin. It must have had a specific implementation to handle this double_sided technique.

I found some sort of workflow that fixes it:

  • Import DAE model in Blender

  • Reverse badly behaved normals

  • Export as DAE

  • Import in Sketchup 8

  • Apply smoothing

  • Export with “triangulate all faces” and “export double side faces”

The last option, if I am correct, is simply duplicating the geometry for double sided faces.

“Triangulate all faces” is necessary to preserve smoothing settings.

Note: you can not directly reverse the normals in Sketchup if there is some UV mapping involved: it scrambles the UVs.

Still, what surprises me is that the Collada file can contain the normals. Then, renderers and converters should not bother about vertex winding order. Perhaps the glTF converter or Cesium could deal with this?

Also, when exchanging big 3D files over http, it could make sense to support something like double_sided faces in order to save geometry and weight.

Cheers,

Xavier.

I think you misunderstood what I was saying. The converter handles the double sided tags correctly, so you shouldn’t need to duplicate the geometry. I’m looking at other viewers and what you were seeing was correct according to the Collada spec. The problem appears to be that the model was exported with an incorrect winding order. This was most likely the fault of the Collada exporter.

During rendering normal have nothing to do with what is front facing or back facing, that is the winding order. Modeling package may mask this fact. They are used only for lighting calculations and can be effected by various things like bump mapping, etc. What would you do if you had a triangle with vertex normals pointing in completely opposite directions, which way is the front and which is the back? There would be no way to tell.

Winding order is used to calculate the surface normal of the triangle and then sets the gl_FrontFacing boolean in the shader to true if we are looking at the front of the triangle and false if we are looking at the back. That way if we want double sided lighting we can can just invert the normal if we are looking at the back.

The converter just adds this to the shader to get double sided to work

if (gl_FrontFacing == false) normal = -normal;

For this model we just need the front face (based on CCW winding order) and the normals to match and it should work fine. You may want to have a look at https://www.frictionalgames.com/forum/thread-9114.html for tips on exporting Collada from Blender.