首页 > 解决方案 > Three.js:如何将“diffuseMap”和“roughnessMap”改为“cubeMap”?

问题描述

这是我想使用的代码:

var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;

var mouseX = 0,
  mouseY = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

var object;

init();
animate();

function init() {
  container = document.createElement("div");
  container.className = "object";
  document.body.appendChild(container);

  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    2000
  );
  camera.position.z = 250;

  // scene

  scene = new THREE.Scene();
  scene.add(camera);

  // manager
  function loadModel() {
    THREE.DefaultLoadingManager.onLoad = function() {
      pmremGenerator.dispose();
    };

    // -----------------

    function loadObjectAndAndEnvMap() {

      const textureLoader = new THREE.TextureLoader();
      const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
      const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');

      object.traverse(function(child) {
        //This allow us to check if the children is an instance of the Mesh constructor
        if (child instanceof THREE.Mesh) {
          child.material = new THREE.MeshStandardMaterial({
            color: "#555",
            roughness: 1.0,
            metalness: 0.5,
            envMapIntensity: 5.0
          });

          child.material.envMap = newEnvMap;
          child.material.map = diffuseMap;
          child.material.roughnessMap = roughnessMap;
          child.material.needsUpdate = true;

          //Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
        }
      });
      object.position.y = -90;
      scene.add(object);
    }

    const pmremGenerator = new THREE.PMREMGenerator(renderer);
    pmremGenerator.compileEquirectangularShader();

    new THREE.EXRLoader()
      .setDataType(THREE.UnsignedByteType)
      .load(
        "https://threejs.org/examples/textures/piz_compressed.exr",
        function(texture) {
          exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
          exrBackground = exrCubeRenderTarget.texture;
          newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;

          loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded

          texture.dispose();
        }
      );

    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.outputEncoding = THREE.sRGBEncoding;
  }

  var manager = new THREE.LoadingManager(loadModel);

  manager.onProgress = function(item, loaded, total) {
    console.log(item, loaded, total);
  };


  var loader = new THREE.OBJLoader(manager);
  loader.load(
    "https://threejs.org/examples/models/obj/female02/female02.obj",
    function(obj) {
      object = obj;
    }
  );

  //

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  document.addEventListener("mousemove", onDocumentMouseMove, false);

  //

  window.addEventListener("resize", onWindowResize, false);
}

function onWindowResize() {
  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
}

function onDocumentMouseMove(event) {
  mouseX = (event.clientX - windowHalfX) / 2;
  mouseY = (event.clientY - windowHalfY) / 2;
}

//

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  camera.position.x += (mouseX - camera.position.x) * 0.05;
  camera.position.y += (-mouseY - camera.position.y) * 0.05;

  camera.lookAt(scene.position);

  scene.background = exrBackground;
  renderer.toneMappingExposure = 1.0;
  renderer.render(scene, camera);
}
body {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/examples/js/loaders/EXRLoader.js"></script>

而不是现有的材料,我想要像这里这样的金属材料。

为此,我尝试删除diffuseMapandroughnessMap并添加cubeMap.

那是我不工作的结果:

var container;
var camera, scene, renderer;
let newEnvMap;
let torusMesh, planeMesh;

var mouseX = 0,
  mouseY = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

var object;

init();
animate();

function init() {
  container = document.createElement("div");
  container.className = "object";
  document.body.appendChild(container);

  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    2000
  );
  camera.position.z = 250;

  // scene

  scene = new THREE.Scene();
  scene.add(camera);

  // manager
  function loadModel() {
    THREE.DefaultLoadingManager.onLoad = function() {
      pmremGenerator.dispose();
    };

    // -----------------

    function loadObjectAndAndEnvMap() {

      const textureLoader = new THREE.TextureLoader();

      textureLoader.load('https://threejs.org/examples/textures/2294472375_24a3b8ef46_o.jpg', function(texture) {

        texture.encoding = THREE.sRGBEncoding;
        texture.mapping = THREE.EquirectangularReflectionMapping;

        init(texture);
        animate();

      });


      object.traverse(function(child) {
        //This allow us to check if the children is an instance of the Mesh constructor
        if (child instanceof THREE.Mesh) {
          child.material = new THREE.MeshStandardMaterial({
            color: "#555",
            roughness: 1.0,
            metalness: 0.5,
            envMapIntensity: 5.0
          });

          child.material.envMap = newEnvMap;
          child.material.needsUpdate = true;

          //Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
        }
      });
      object.position.y = -90;
      scene.add(object);
    }

    const pmremGenerator = new THREE.PMREMGenerator(renderer);
    pmremGenerator.compileEquirectangularShader();


    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.outputEncoding = THREE.sRGBEncoding;
  }

  var manager = new THREE.LoadingManager(loadModel);

  manager.onProgress = function(item, loaded, total) {
    console.log(item, loaded, total);
  };


  var loader = new THREE.OBJLoader(manager);
  loader.load(
    "https://threejs.org/examples/models/obj/female02/female02.obj",
    function(obj) {
      object = obj;
    }
  );

  //

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  document.addEventListener("mousemove", onDocumentMouseMove, false);

  //

  window.addEventListener("resize", onWindowResize, false);
}

function onWindowResize() {
  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
}

function onDocumentMouseMove(event) {
  mouseX = (event.clientX - windowHalfX) / 2;
  mouseY = (event.clientY - windowHalfY) / 2;
}

//

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  camera.position.x += (mouseX - camera.position.x) * 0.05;
  camera.position.y += (-mouseY - camera.position.y) * 0.05;

  camera.lookAt(scene.position);

  renderer.toneMappingExposure = 1.0;
  renderer.render(scene, camera);
}
body {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/examples/js/loaders/OBJLoader.js"></script>

最后背景应该是透明的,只有 OBJ 对象应该是可见的。

有人可以帮我吗?会很高兴的!

标签: javascriptthree.js

解决方案


您无需进行太多更改即可使其成为金属:

child.material = new THREE.MeshStandardMaterial({
  color: "#555",
  roughness: 0.0, // <- roughness 0
  metalness: 1.0, // <- metalness 1
  envMapIntensity: 1.0
});

child.material.envMap = newEnvMap;

// Then you only need the envMap, remove the other stuff
//child.material.map = diffuseMap;
//child.material.roughnessMap = roughnessMap;
//child.material.needsUpdate = true;

最后,如果您不想要背景,请将其从渲染循环中删除:

//scene.background = exrBackground;

现场演示:

var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;

var mouseX = 0,
  mouseY = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

var object;

init();
animate();

function init() {
  container = document.createElement("div");
  container.className = "object";
  document.body.appendChild(container);

  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    2000
  );
  camera.position.z = 250;

  // scene

  scene = new THREE.Scene();
  scene.add(camera);

  // manager
  function loadModel() {
    THREE.DefaultLoadingManager.onLoad = function() {
      pmremGenerator.dispose();
    };

    // -----------------

    function loadObjectAndAndEnvMap() {

      const textureLoader = new THREE.TextureLoader();
      const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
      const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');

      object.traverse(function(child) {
        //This allow us to check if the children is an instance of the Mesh constructor
        if (child instanceof THREE.Mesh) {
          child.material = new THREE.MeshStandardMaterial({
            color: "#555",
            roughness: 0.0,
            metalness: 1.0,
            envMapIntensity: 5.0
          });

          child.material.envMap = newEnvMap;
          //child.material.map = diffuseMap;
          //child.material.roughnessMap = roughnessMap;
          //child.material.needsUpdate = true;

          //Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
        }
      });
      object.position.y = -90;
      scene.add(object);
    }

    const pmremGenerator = new THREE.PMREMGenerator(renderer);
    pmremGenerator.compileEquirectangularShader();

    new THREE.EXRLoader()
      .setDataType(THREE.UnsignedByteType)
      .load(
        "https://threejs.org/examples/textures/piz_compressed.exr",
        function(texture) {
          exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
          exrBackground = exrCubeRenderTarget.texture;
          newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;

          loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded

          texture.dispose();
        }
      );

    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.outputEncoding = THREE.sRGBEncoding;
  }

  var manager = new THREE.LoadingManager(loadModel);

  manager.onProgress = function(item, loaded, total) {
    console.log(item, loaded, total);
  };


  var loader = new THREE.OBJLoader(manager);
  loader.load(
    "https://threejs.org/examples/models/obj/female02/female02.obj",
    function(obj) {
      object = obj;
    }
  );

  //

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  document.addEventListener("mousemove", onDocumentMouseMove, false);

  //

  window.addEventListener("resize", onWindowResize, false);
}

function onWindowResize() {
  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
}

function onDocumentMouseMove(event) {
  mouseX = (event.clientX - windowHalfX) / 2;
  mouseY = (event.clientY - windowHalfY) / 2;
}

//

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  camera.position.x += (mouseX - camera.position.x) * 0.05;
  camera.position.y += (-mouseY - camera.position.y) * 0.05;

  camera.lookAt(scene.position);

  //scene.background = exrBackground;
  renderer.toneMappingExposure = 1.0;
  renderer.render(scene, camera);
}
body {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.125.2/examples/js/loaders/EXRLoader.js"></script>


推荐阅读