3.JS如何在3D房间模型中制作透明前壁



我想在三室中做一个3D室。我想要在摄像机视图前的墙壁在我旋转房间时变得透明。

这是我需要的示例:http://jsfiddle.net/tp2f2oo4/

似乎解决方案正在向材料添加三个。

var material2 = new THREE.MeshPhongMaterial( {
    color: 0xffffff, 
    transparent: false,
    side: THREE.BackSide
} );

的确,当房间充当单个三个盒子测度时,这是完美的选择但是就我而言,每个墙壁,天花板和地板都是单独的三个盒子测度对象。有什么方法可以隐藏它们或不呈现在摄像机视图的前面?

您想根据某种条件隐藏网格。这是使用onBeforeRender()onAfterRender()方法的完美用例。

// callbacks
var onBeforeRender = function() {
    var v = new THREE.Vector3();
    return function onBeforeRender( renderer, scene, camera, geometry, material, group ) {
        // this is one way. adapt to your use case.
        if ( v.subVectors( camera.position, this.position ).dot( this.userData.normal ) < 0 ) {
            geometry.setDrawRange( 0, 0 ); // it is too late to set visible = false, so do this, instead
        }
    };
}();
var onAfterRender = function( renderer, scene, camera, geometry, material, group ) {
    geometry.setDrawRange( 0, Infinity );
};
// mesh
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 10 );
mesh.rotation.set( 0, 0, 0 );
scene.add( mesh );
mesh.userData.normal = new THREE.Vector3( 0, 0, - 1 );
mesh.onBeforeRender = onBeforeRender;
mesh.onAfterRender = onAfterRender;

小提琴:http://jsfiddle.net/3qh815xa/

三。r.114

您可以使用射线铸造来确定要关闭哪些墙。基本上,从相机射击射线,并设置其相交的墙壁的透明度。

有关简化的情况,请参见下面的摘要中的updateWallTransparency_simple。它从相机的中心发射了一条光线,并设置了相交墙的透明度。

但是,您可能会遇到一个字面的角案件,在那里您从一堵墙过渡到另一堵墙。您可以使用第二个射线播放来补偿这一点,但是您需要将两条光线从中心取代,因此在角落的情况下它们不会相交相同的墙壁。有关示例,请参见下图中的updateWallTransparency_corners

现在这是一个高度简化的情况。如果您的墙壁形状更为复杂,则需要进行进一步的检查,以查看某些墙壁是否应该隐藏。另外,如果您的相机太远,您会注意到它会使后壁隐藏起来。整个问题还有很多要考虑的问题,但这应该使您开始。

var renderer, scene, camera, controls, stats;
var WIDTH = window.innerWidth,
  HEIGHT = window.innerHeight,
  FOV = 35,
  NEAR = 1,
  FAR = 1000,
  degrad = (Math.PI / 180),
  walls = [];
var raycaster = null,
  coords = null;
function updateWallTransparency_simple() {
  // reset all walls. You can optimize this by storing which ones are transparent/not
  walls.forEach(function(wall) {
    wall.material.opacity = 1;
  });
  raycaster.setFromCamera(coords, camera);
  var intersects = raycaster.intersectObjects(walls);
  if (intersects && intersects.length > 0) {
    intersects[0].object.material.opacity = 0.25;
  }
}
function updateWallTransparency_corners() {
  // reset all walls. You can optimize this by storing which ones are transparent/not
  walls.forEach(function(wall) {
    wall.material.opacity = 1;
  });
  coords.set(-0.1, 0);
  raycaster.setFromCamera(coords, camera);
  var intersects = raycaster.intersectObjects(walls);
  if (intersects && intersects.length > 0) {
    intersects[0].object.material.opacity = 0.25;
  }
  coords.set(0.1, 0);
  raycaster.setFromCamera(coords, camera);
  var intersects = raycaster.intersectObjects(walls);
  if (intersects && intersects.length > 0) {
    intersects[0].object.material.opacity = 0.25;
  }
}
function populateScene() {
  var geo = new THREE.BoxBufferGeometry(20, 20, 0.1),
    mat = new THREE.MeshPhongMaterial({
      color: "darkred",
      transparent: true,
      opacity: 1
    });
  var mesh = new THREE.Mesh(geo, mat);
  mesh.position.set(0, 0, -10);
  mesh.name = "backWall";
  scene.add(mesh);
  mesh.updateMatrixWorld(true);
  walls.push(mesh);
  mesh = new THREE.Mesh(geo, mat.clone());
  mesh.name = "frontWall";
  mesh.position.set(0, 0, 10);
  scene.add(mesh);
  mesh.updateMatrixWorld(true);
  walls.push(mesh);
  mesh = new THREE.Mesh(geo, mat.clone());
  mesh.name = "leftWall";
  mesh.position.set(-10, 0, 0);
  mesh.rotation.set(0, (Math.PI / 180) * 90, 0);
  scene.add(mesh);
  mesh.updateMatrixWorld(true);
  walls.push(mesh);
  mesh = new THREE.Mesh(geo, mat.clone());
  mesh.name = "rightWall";
  mesh.position.set(10, 0, 0);
  mesh.rotation.set(0, (Math.PI / 180) * 90, 0);
  scene.add(mesh);
  mesh.updateMatrixWorld(true);
  walls.push(mesh);
  geo = new THREE.BoxBufferGeometry(50, 0.1, 50),
    mat = new THREE.MeshPhongMaterial({
      color: "green"
    });
  mesh = new THREE.Mesh(geo, mat);
  mesh.position.set(0, -10, 0);
  mesh.name = "ground";
  scene.add(mesh);
  geo = new THREE.TorusKnotBufferGeometry(2, 0.5, 100, 16),
    mat = new THREE.MeshPhongMaterial({
      color: "blue"
    });
  mesh = new THREE.Mesh(geo, mat);
  mesh.name = "insideObject";
  scene.add(mesh);
}
function init() {
  document.body.style.backgroundColor = "lightBlue";
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  document.body.appendChild(renderer.domElement);
  document.body.style.overflow = "hidden";
  document.body.style.margin = "0";
  document.body.style.padding = "0";
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
  camera.position.z = 50;
  scene.add(camera);
  controls = new THREE.OrbitControls(camera);
  controls.enableZoom = false;
  controls.enablePan = false;
  controls.maxPolarAngle = Math.PI / 2;
  var light = new THREE.PointLight(0xffffff, 1, Infinity);
  camera.add(light);
  light = new THREE.HemisphereLight(0xffffbb, 0x00ff00, 1);
  scene.add(light);
  stats = new Stats();
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.top = '0';
  document.body.appendChild(stats.domElement);
  resize();
  window.onresize = resize;
  populateScene();
  raycaster = new THREE.Raycaster();
  coords = new THREE.Vector3();
  animate();
}
function resize() {
  WIDTH = window.innerWidth;
  HEIGHT = window.innerHeight;
  if (renderer && camera && controls) {
    renderer.setSize(WIDTH, HEIGHT);
    camera.aspect = WIDTH / HEIGHT;
    camera.updateProjectionMatrix();
  }
}
function render() {
  renderer.render(scene, camera);
}
function animate() {
  requestAnimationFrame(animate);
  //updateWallTransparency_simple();
  updateWallTransparency_corners();
  render();
  stats.update();
}
function threeReady() {
  init();
}
(function() {
  function addScript(url, callback) {
    callback = callback || function() {};
    var script = document.createElement("script");
    script.addEventListener("load", callback);
    script.setAttribute("src", url);
    document.head.appendChild(script);
  }
  addScript("https://threejs.org/build/three.js", function() {
    addScript("https://threejs.org/examples/js/controls/OrbitControls.js", function() {
      addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
        threeReady();
      })
    })
  })
})();

最新更新