ID рендеринг + диффузный рендеринг в THREE.js

Я пытаюсь использовать onBeforeRender для добавления функции переопределения материала id в моем приложении THREEjs. Это довольно распространенная функция для рендеринга приложений, и я хотел бы иметь возможность использовать scene.overrideMaterial для этого, но из моих исследований кажется, что я собираюсь развернуть свое собственное.

Мой подход заключается в следующем.

Когда я создаю объекты:

...
      m.onBeforeRender = function (){
        if(Renderer._renderID){
            this.material = new THREE.MeshBasicMaterial(this.userData.idColor.getHex());
            this.material.needsUpdate = true;

            // Attempt at using a shader material
            //this.material = Renderer._idMat;
            //this.material.uniforms.idColor.value = this.userData.idColor;
            //this.material.uniforms.needsUpdate = true;
        }
      }
      m.onAfterRender = function (){
            if(Renderer._renderID){
                this.material = this.userData.material;
            }
      }
...

В моем цикле рендеринга:

...
        var idTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
        Renderer._renderID = true;
        Renderer._renderer.render(Renderer._scene, Renderer._camera, idTarget);
        Renderer._renderID = false;
...

Прямо сейчас буфер id и диффузный буфер визуализируются с диффузным материалом.

Любая помощь приветствуется. Пожалуйста, дайте мне знать, если потребуется дополнительная информация, я буду обновлять этот пост.

1 ответ

Three.js имеет официальный пример выбора gpu, который можно увидеть здесь.

Похоже, они визуализируют вещи в двух разных сценах и с вершинными цветами. Это не плохой подход, и я не согласен с комментарием и вашим закомментированным кодом. Изменение униформы - не единственный способ добиться этого, официальный пример использует цвета вершин и объединяет все геометрии.

Есть много способов снять шкуру с этой кошки.

Вы должны во что бы то ни стало избегать создания новых материалов в тесных петлях.

Это плохо плохо

  m.onBeforeRender = function (){
    if(Renderer._renderID){
        this.material = new THREE.MeshBasicMaterial(this.userData.idColor.getHex()); //just a big NO
        this.material.needsUpdate = true; //no it doesnt! it's a new material it has this true by default

Чтобы добиться чего-то подобного, или вашего собственного пользовательского переопределения:

const myMesh = new Mesh()
myMesh.myMaterials = [
  someRenderMaterial,
  someIDMaterial,
]

scene.traverse(o=>{if(o.myMaterials) o.material = o.myMaterials[1]})
renderer.render(scene,camera)

scene.traverse(o=>{if(o.myMaterials) o.material = o.myMaterials[0]})
renderer.render(scene,camera)

Но опять же, есть много способов сделать это. Вы можете просто сделать другую сцену и визуализировать цвета вершин. Вы можете сделать материал переопределения и визуализировать цвета вершин. Много параметров, много перестановок.

Другие вопросы по тегам