Как объявить "маскирующий" материал, используя A-Frame.js

Я пытаюсь сделать сцену, где есть "дыра в стене".

Для этого требуется плоскость с удаленным квадратом, а затем материал, примененный к плоскости со следующими свойствами:

  1. Невидимый для камеры
  2. Скрывает любые другие объекты от рендеринга, которые находятся за ним

Вот пример этого с three.js, но как я могу сделать это с синтаксисом материала a-frame?

1 ответ

Решение

Маска".

Взглянув на пример с дырой в ящик, чтобы создать иллюзию, Ли создает две коробки.
1) Коробка, которая находится "в яме"
2) Немного большая невидимая коробка без верха - чтобы скрыть первую. Верхняя часть убрана, чтобы работать как "дыра", через которую вы можете видеть первую коробку

Как это можно сделать в THREE.js

Клоакинг делается путем предотвращения рендеринга второго блока любого цвета. Из примера Ли:

 let material = new THREE.MeshBasicMaterial({
      colorWrite: false;
 })

В документе указано, что этот флаг можно использовать для создания невидимых объектов, скрывающих других.

Как это можно сделать в рамке

Боюсь, вы не можете просто сделать материал "плащ" в рамке. colorWrite собственность не выставлена ​​в material составная часть.

То, что я думаю, самый простой способ - это создание cloak компонент, который создаст второе поле в THREE.js:

AFRAME.registerComponent('cloak', {
    init: function() {
      let geometry = new THREE.BoxGeometry(1, 1, 1)
      geometry.faces.splice(4, 2) // cut out the top faces 
      let material = new THREE.MeshBasicMaterial({
         colorWrite: false
      })
      let mesh = new THREE.Mesh(geometry, material)
      mesh.scale.set(1.1, 1.1, 1.1)
      this.el.object3D.add(mesh)
    }
})

и используйте это так:

<a-box material="src: myPic.png; side: back;" cloak>

Проверьте это в этом коде. С маркером HIRO вы должны получить такую ​​дыру:

Использование моделей или других объектов в качестве "плащей"

Здесь нам нужно применить colorWrite=false магия для каждого узла / потомка модели.

init: function() {
  // make sure the model is loaded first
  this.el.addEventListener('model-loaded', e=>{
    let mesh = this.el.getObject3D('mesh') // grab the mesh
    if (mesh === undefined) return;        // return if no mesh :(
    mesh.traverse(function(node) {         // traverse through and apply settings
      if (node.isMesh && node.material) {  // make sure the element can be a cloak
        node.material.colorWrite = false
        node.material.needsUpdate = true;
      }
    });
  })
}

Также убедитесь, что плащ отображается перед элементами, которые требуют маскировки:

<a-marker>
  <a-entity gltf-model="#wall-with-a-hole" cloak-component></a-entity>
  <!-- the other stuff that needs to be cloaked-->
</a-marker
Другие вопросы по тегам