THREE.js如何在3d房间模型中制作透明的前墙

时间:2017-09-15 11:48:25

标签: javascript three.js

我想在three.js中创建一个3d房间。我希望在旋转房间时,在摄像机视图前面的墙壁变得透明。

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

似乎解决方案是在材料中添加THREE.BackSide。

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

当房间充当单个THREE.BoxGeometry时,这确实很有效。 但就我而言,每个墙,天花板和地板都是单独的THREE.BoxGeometry对象。有没有办法在摄像机视图前隐藏它们或不渲染?

2 个答案:

答案 0 :(得分:4)

您希望根据某些条件隐藏网格。这是使用EventEmitter@Component({ selector: 'app-group-selector', template: ` <div> <label>Group</label> <select [(ngModel)]="name" (change)="onGroupChanged(name)"> <option *ngFor="let groupName of groupNames" [value]="groupName">{{groupName}}</option> </select> </div>` }) export class SharedComponent { @Output() selectedgroup: EventEmitter<string> = new EventEmitter<string>(); groupNames: string[]; // note new property here, to be used as ngModel name: string; constructor() { this.groupNames = ['A', 'B', 'C']; this.name = 'A'; } onGroupChanged(newvalue): void { console.log('from Shared:',newvalue); this.selectedgroup.emit(newvalue); } } 方法的完美用例。

onBeforeRender()

小提琴:http://jsfiddle.net/he6t10r8/

three.js r.87

答案 1 :(得分:0)

您可以使用光线投射来确定要关闭的墙。基本上,从相机拍摄光线,并设置它相交的墙的透明度。

有关简化案例,请参阅下面代码段中的updateWallTransparency_simple。它从相机中心发射光线,并设置相交墙的透明度。

但是,您可能会遇到一个字面角落案例,您可以从一个墙转换到另一个墙。您可以通过第二次光线投射来补偿这一点,但是您需要将两条光线偏离中心,因此在角落的情况下它们不会与同一墙壁相交。有关示例,请参阅下面代码段中的updateWallTransparency_corners

现在这是一个高度简化的案例。如果您的墙壁形状更复杂,您需要进行进一步检查以确定是否应隐藏某些墙壁。此外,如果您将相机倾斜太远,您会发现它会隐藏后墙。作为一个整体,这个问题还有很多需要考虑的问题,但这应该可以让你开始。

&#13;
&#13;
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();
      })
    })
  })
})();
&#13;
&#13;
&#13;