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)
Но опять же, есть много способов сделать это. Вы можете просто сделать другую сцену и визуализировать цвета вершин. Вы можете сделать материал переопределения и визуализировать цвета вершин. Много параметров, много перестановок.