Search code examples
three.jsreact-three-fiber

I want to improve the quality of the 3d object's material



First of all, please understand that I am not good at English.
I'm using react three fiber so hard. I uploaded the obj file using OBJLoader.
In this way, image A was rendered. But the quality is very, very bad...
I want to increase the quality like image B
I don't know if I matched the map of the material incorrectly
What should I do??
Thanks for sharing your wisdom

Image A: Initial

Image B: Final

const canvasRef = useRef(null);
const cameraControls = useRef<CameraControlsType | null>(null);
const [aoMap, map, normalMap, roughnessMap] = useLoader(THREE.TextureLoader, [
    `${process.env.PUBLIC_URL}/NT_NO061/Textures/T_NT_NO061_AO.png`,
    `${process.env.PUBLIC_URL}/NT_NO061/Textures/T_NT_NO061_D.png`,
    `${process.env.PUBLIC_URL}/NT_NO061/Textures/T_NT_NO061_N.png`,
    `${process.env.PUBLIC_URL}/NT_NO061/Textures/T_NT_NO061_R.png`
])
const scene = useLoader(OBJLoader, `${process.env.PUBLIC_URL}/NT_NO061/NT_NO061.obj`);
const {nodes, materials} = useGraph(scene);
const object3d = nodes[Object.keys(nodes)[0]];
const material = materials[Object.keys(materials)[0]];
material.aoMap = aoMap;
material.map = map;
material.normalMap = normalMap;
material.displacementMap = roughnessMap;
material.displacementScale = 0.1;

useEffect(() => {
    console.log('canvasRef', canvasRef)
}, [canvasRef])

const playVideo = () => {
    cameraControls.current?.reset(true);
    setTimeout(() => {
        cameraControls.current?.rotate(Math.PI, 0, true)
    }, 1000)
    setTimeout(() => {
        cameraControls.current?.rotate(Math.PI, 0, true)
    }, 2000)
}

return (
  <Wrapper>
      <Canvas
        ref={canvasRef}
        camera={{position: [3, 3, 3]}}
        onCreated={state => state.gl.setClearColor('black')}
      >
          <CameraControls ref={cameraControls} />
          <OrbitControls/>
          <pointLight
            color={'white'}
            intensisty={1}
            position={[10, 10, 10]}
          />
          <mesh
            position={[0, -2, 0]}
            geometry={object3d.geometry}
            material={material}
          />
      </Canvas>
      <div style={{ position: 'absolute', top: '0' }}>
          <button type={'button'} onClick={() => cameraControls.current?.rotate(Math.PI / 4, 0, true)}>
              rotate theta 45deg
          </button>
          <button type={'button'} onClick={() => cameraControls.current?.reset(true)}>
              reset
          </button>
          <button type={'button'} onClick={playVideo}>
              play video
          </button>
      </div>
  </Wrapper>
);

}


Solution

  • Let's find the differences between these 2 images first.

    Image A:

    Initial

    Image B:

    Desired

    The first difference I see here is that Image B is smooth, while Image A is composed of triangular faces. You can open this up in Blender and apply a Smooth modifier, or just manually increase the vertice count.

    The next thing I see is that Image B is shiny, with a mild reflection, while Image A is obsolete. You can use the roughness and metalness properties of three.js to change the way light reflects off of your mesh.

    That should do it~