How to create metalic object imported from blender

Hello,

how to create metalic object imported from blender?

so the environnement is a garden + skybox created with blender and exported in gltf .

the metalic object have been created too with blender ( with metal at 1 roughness 0 ) but the object is black when is imported .

i ve read the solution is around envmap property but i dont understand what i have to do and i didn’t find any tutorial about how to create metallic object with three js .
thank you very much

Try loading your model in some other viewer first. Make sure the model looks right there.

gltf-viewer.donmccurdy.com/

Once you’ve done that, work on getting your code to look the same. You will always need to load an environment map with metallic objects. This is a good example for it: three.js examples

i try to add something like that

const generator = new THREE.PMREMGenerator( renderer );
const envMap = generator.fromScene( scene ,0 ,0.1,1300 );

              scene.environment = envMap.texture ; 
              generator.dispose();

but it doesn’t work as i wish . I understand that everything around material and light are very hard and complex , and probably i havent the good level yet . I need to learn and read lot of tutorial before to be able to do metalic objet .

thank

i have discovered why the bottom of object with metalic matérial are black , the top was strange , and found some plant on side .

it is because when i use to const envMap = generator.fromScene( scene ,0,0.1,1300 );

it is create an envMap like it was in the center of the world ( = 0 ,0 ,0 ) and not in the center of the object

but my scene i need is at 160 meter of altitude and my metallic objet is above 160 meter .

so how can i use PMREMGenerator to do like it is at the same position of my metallic object ?

thanks

Edit : i ve found a solution which is not the best practice but it is working . so i take the position of my metal objet , i translates all the scene like this objet is in the center of the world and after i do inverse translation .

var sphereTest  = scene.getObjectByName('spheretest');
            var metalx = sphereTest.position.x ;
            var metaly = sphereTest.position.y;
            var metalz = sphereTest.position.z;
             scene.translateX(-metalx);
             scene.translateY(-metaly);
             scene.translateZ(-metalz);
             
             
             
             const generator = new THREE.PMREMGenerator( renderer );
             const envMap = generator.fromScene( scene ,0,0.1,1300 );
             envMap.mapping = THREE.CubeRefractionMapping;;
            envMap.texture.encoding  = THREE.sRGBEEncoding ;
            sphereTest.material.envMap = envMap.texture; 
            sphereTest.material.envMapIntensity = 1 ;
        
              generator.dispose();
             scene.translateX(metalx);
             scene.translateY(metaly);
             scene.translateZ(metalz);
             
 see the result 

Edit 2 : i want to say that i dont really understand what i m doing , i try and see the result until something working . I ve just discovered that the line envMap.mapping = THREE.CubeRefractionMapping;
is not good , change Refraction by Reflection , no change , remove the line and get same result see the result without this line ( same result that above picture )

edit3 : it is very great , i have used a cube , apply quaternion and it look like a mirror which spinning . It is like envMap stay at the same position and the object3D can turn .
to simulate night i decrease intensity cube.material.envMapIntensity

Hey @donmccurdy, a lockdown project for you if the time allows is to add a test texture to test your UVs to this viewer one day. Something like this texture. (Ignore the KK)

hello ,

i ve tried now to do two envMap for two different object which are not next , but when i does create a second envMap2 , and assign it to the second object , even if all variable are different the first get the envMap of the second object .

question : how to assign two different envMap at two different object ?

thank

i ve found the solution and it was my fault because under blender i have assigned the same material for the two sphere , so when i have assigned the second envMap to the second sphere , it was like i assigned the same envMap to the first sphere . So the solution was under blender to duplicate material for the second sphere and it is working great , now the two sphere have their own envMap . It is marvellous !! see result

thank you very much for the help ( three js is very great ! )

Hey donmccurdy, I tried loading my model but it has the same problem, I loaded it up onto an online viewer and it looks totally fine. I had a look at the example but it uses a RGBELoader and the textures are in a seperate file.

But with mine the textures went straight onto the GLTF file because I used the principle shader BSDF node in blender. So the it’s just all in one in the GLTF file.

So I’m not sure why my model worked on the GLTF viewer online but not in my Three js project… What would be a way around this? thanks

You will have to use an environment map to get proper lighting on a PBR scene, this is what RGBELoader is for. The GLTF file does not provide an environment map.

@donmccurdy but my GLTF file has metallic properties from principled BSDF node (and material output node) I don’t have any other nodes.

If I look at that file in an online GLTF viewer it works fine, do I still have to do an evironment map for my Three js project then?

I also have no image textures or anything like that, just 1.0 metallic and 0.0 roughness material from the principled shader node

The model looks correct in online GLTF viewers because those viewers add their own environment maps. A metallic surface needs something to reflect, or it will look wrong. Without an environment there is nothing to reflect. You must include an environment map of some kind — whether it’s an external HDRI texture, THREE.RoomEnvironment, or generated on the fly from your scene. I would start with using RGBELoader.

Is there a way to use sky js as the environment map? because that is what I have surrounding my environment

Yes. It will be a bit more work to set up and more expensive than an HDRI texture, so I would advise doing the easier option with a texture first and making sure things look as you expect. You can see the example below for how to use THREE.CubeCamera to create an environment cubemap on the fly in the scene, and use that for the environment. If the sky isn’t changing then you don’t need to update the CubeCamera on every frame.

examples / webgl / materials / cubemap / dynamic

If you’re having trouble getting that to work I’d recommend starting a new thread with details. :slight_smile:

1 Like