I'm trying establish why I can't smooth shade geometry loaded with OBJLoader.
var loader = new THREE.OBJLoader(manager);
loader.load('/manmodel/js/man.obj', function (object, materials) {
console.log(object);
console.log(materials);
man = object;
man.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals( true );
child.material = new THREE.MeshPhongMaterial({
color: 'white',
shading: THREE.SmoothShading // <----------- THIS IS THE PROBLEM
});
}
});
man.position.y = -10;
scene.add(man);
});
This is the result:
If I remove the line computeFaceNormals() the model renders the same. If I remove computeVertexNormals( true ) the object renders with no lighting (black) - so I know this is doing something.
If I change the color attribute of the MeshPhongMaterial in this code, the color changes, so I also know that this is working.
I have tried to use the vertex and normal helpers to establish what the problem is, but they fail because with BufferGeometry the faces and verticices are not stored as arrays.
I have also tried modifying the man.obj file to change the 's' values from 'off' to 1. This did nothing.
As I will be loading several .obj files for different human figures, generated in Blender, and each is currently around 2MB, I prefer to do the shading on the browser than to 'bake' it into the file if this would increase file size.
THE QUESTION(s): Am I missing something here? OR, Is there a way to load the .obj file as standard Geometry, compute the normals, apply the shading, and then save as BufferGeometry?
ps. I may also need the normals for ray tracing further down the line.
If we want to use the most recent loader (r73), we can also convert the
BufferGeometry
to aGeometry
, and then back!The only caveat is that I had to merge the vertices before computing the vertex normals. I'm guessing that converting from the buffers messes with the triangles, so we gotta merge them before anything.
The most recent version of ObjLoader parses the .obj to a BufferGeometry for performance reasons. If you look back through the history on GitHub you can find the previous version which parses to Geometry:
https://github.com/mrdoob/three.js/blob/a321ba05f02ae3a1586a4060a53f5ad63b90729b/examples/js/loaders/OBJLoader.js
Load your .obj using this and you can then manipulate the Geometry until you have it as you need it, then create a new BufferGeometry and load the Geometry into it using BufferGeometry.fromGeometry(geometry) in order to get the performance. I have this working nicely.