2014-10-28 4 views
4

Я пытаюсь установить, почему я не могу сгладить геометрию тени, загруженную OBJLoader.THREE.js OBJLoader - загрузка в геометрию, управление, затем сохранение в BufferGeometry

var loader = new THREE.OBJLoader(manager); 
loader.load('/manmodel/js/man.obj', function (object, materials) { 
    console.log(object); 
    console.log(materials); 
    man = object; 
    man.traverse(function (child) { 
     if (child instanceof THREE.Mesh) { 
      child.geometry.computeFaceNormals(); 
      child.geometry.computeVertexNormals(true); 
      child.material = new THREE.MeshPhongMaterial({ 
       color: 'white', 
       shading: THREE.SmoothShading // <----------- THIS IS THE PROBLEM 
      }); 
     } 
    }); 
    man.position.y = -10; 
    scene.add(man); 
}); 

Это результат:

apparently Flat Shading

Если я удалить computeFaceNormals строки() модель делает то же самое. Если я удаляю computeVertexNormals (true), объект отображается без освещения (черный) - поэтому я знаю, что это что-то делает.

Если я изменяю атрибут цвета MeshPhongMaterial в этом коде, цвет меняется, поэтому я также знаю, что это работает.

Я попытался использовать верхушку и обычных помощников, чтобы установить, в чем проблема, но они не работают, потому что с BufferGeometry лица и вертицы не хранятся в виде массивов.

Я также попытался изменить файл man.obj, чтобы изменить значения 's' от 'off' до 1. Это ничего не делало.

Как я буду загружать несколько файлов .obj для разных человеческих фигур, сгенерированных в Blender, и каждый из них в настоящее время составляет около 2 МБ, я предпочитаю делать затенение в браузере, чем «испечь» его в файл, если это будет увеличить размер файла.

ВОПРОС: Я что-то упустил? OR, Есть ли способ загрузить файл .obj в качестве стандартной геометрии, вычислить нормали, применить затенение, а затем сохранить в качестве BufferGeometry?

пс. Мне также могут понадобиться нормали для трассировки лучей дальше по линии.

ответ

6

Последняя версия ObjLoader анализирует значение .obj на BufferGeometry по соображениям производительности. Если оглянуться назад через историю на GitHub вы можете найти предыдущую версию, которая разбирает к Geometry:

https://github.com/mrdoob/three.js/blob/a321ba05f02ae3a1586a4060a53f5ad63b90729b/examples/js/loaders/OBJLoader.js

Загрузите .obj, используя это, а затем вы можете управлять геометрией, пока вы не имеете его, как вам это нужно , затем создайте новую BufferGeometry и загрузите геометрию в нее с помощью BufferGeometry.fromGeometry (geometry), чтобы получить производительность. У меня это хорошо работает.

4

Если мы хотим использовать самый последний загрузчик (r73), мы также можем преобразовать BufferGeometry в Geometry, а затем обратно!

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

var geometry = new THREE.Geometry().fromBufferGeometry(child.geometry); 
geometry.computeFaceNormals(); 
geometry.mergeVertices(); 
geometry.computeVertexNormals(); 
child.geometry = new THREE.BufferGeometry().fromGeometry(geometry); 
Смежные вопросы