Hi all,
I’m struggling a little with this one. Basically I am trying to get this obj file Simple.obj (115 Bytes) to look like what I have in the following picture. There is no .mtl files associated with the files I am looking at
I have tried using all sort of lighting (point , directional etc…) and different materials but they all look terrible. Reading up on this I believe it’s do with a mixture of things that I am doing wrong. so here are my questions
- Normals information in the obj. How do I check if there is this is present or not and what is the correct way to create these if there are not. I’m assuming without this no directional lighting will work and materials will not look right??
- What material should I use to get the effect ? If I wanted it to be more metallic looking what would I do?
- How do I get a bottom grid similar to what is in the picture. Is there something built in to threejs or do I need to load my own image?
- Should my light source position be coming from the same position as the camera?
- I also need to load stl files. Does it work in the same way with regards normals?
Thanks in advance
Thanks for the prompt response - very helpful
You are correct - the object is showing as black so I presume the normals are broken. Is there a way to recalculate them programmatically inside threejs without having to use Blender?
Thanks I’ll mark this as a solution and open it up again if I run into problems
Ok - So I installed blender and imported the obj file. without doing anything it looks pretty good in blender so I’m assuming it has normals . see this image
This is my code in threejs. (I pass the contents of the obj file as this.objtext)
var loader = new OBJLoader2();
loader.setLogging(true, true);
loader.setUseIndices(true);
loader.setDisregardNormals(false);
this.object = loader.parse(this.objtext);
this.dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
this.dirLight.position.set( -1, 0.75, 1 );
this.dirLight.name = "dirlight";
this.dirLight.castShadow = true;
this.scene.add( this.dirLight );
var material = new THREE.MeshStandardMaterial( {
color: 0Xcae1ff,
metalness: 0.1, // between 0 and 1
roughness: 0.75, // between 0 and 1
} );
this.object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material = material;
}
} );
this.scene.add(this.object);
The object still looks terrible. Any ideas what I am doing wrong? Am I loading in the material incorrectly?
Can you share a screenshot of what you mean by “terrible”, it’s a bit ambiguous ?
Yes, but normals can be flipped, which causes the geometry to look quite abstract. See this video (at 0:43) - toggle Face Orientation
in Blender and make sure the entire model is blue.
Great little video - it’s all coming as blue in blender which is good I believe?
Here is what I am getting with my code. Looks like it’s shading the inside but not the outside
I had attached the obj in the first post ( simple.obj). I’ve played around with it since my last post and it looks like it’s how I am lighting it is the problem as I’m getting better results now. Just not exactly sure how to get it more like the desired image I want it to be in the first post
I am using a DirectionalLight and it looks ok on certain views but I’m not sure if this is the best choice for what I am trying to achieve. I am assuming I’ll have to add more Directional lights if I want to use something like Orbitcontrols with it, as there will be no light on the opposite side of the view if the camera moves around to that side when using Orbitcontrols. Does adding more directional lights start creating it’s own problems with regards enabling shadowing in the scene etc.?
Is there a better way to approach lighting a scene in general? It seems very much try it and refine type approach. Maybe that’s just the way it is and experience is everything or possibly there is a more mathematical type approach??