Three.js: правильный способ setIndex/index для BufferGeometry?

Я пытаюсь установить UV-индексы для каждого лица в BufferGeometry.

Я начинаю с геометрии. Каждая грань моей геометрии имеет face.materialIndex, соответствующий UV-индексу. Я пытаюсь преобразовать это в BufferGeometry, а затем сопоставить face.materialIndex с BufferGeometry.

Вот что у меня есть до сих пор:

// Convert geometry > buffergeometry
const bufGeo = new BufferGeometry().fromGeometry( geometry );

// Get an array of all the original geometry's indices...
const faceIndices = geometry.faces.map( face => face.materialIndex );

// Build a new array with the indices...
const indices = new Uint16Array( faceIndices );

// Apply to the BufferGeometry
bufGeo.setIndex( new BufferAttribute( indices, 1 ) );

Прямо сейчас это, кажется, затирает мою сетку и заставляет ее вообще не рисоваться. Что я делаю не так?

Кстати, под капотом, когда Geometry преобразуется в BufferGeometry, Three.js помещает его в промежуточный формат, сначала называемый DirectGeometry. Это использовалось для копирования индексов, но оно было удалено по неизвестным причинам. коммит мистера Дуба. Прямо сейчас Three, похоже, полностью отбрасывает индексы при преобразовании Geo > BufGeo.

Я также пытался использовать код из этой фиксации (измененный для использования setIndex):

const indices = new Uint16Array( faceIndices.length * 3 );
bufGeo.addAttribute( 'index', new BufferAttribute( indices, 1 ).copyIndicesArray( faceIndices ) );

Но у меня та же проблема. Полученная сетка затирается.


person Andy Ray    schedule 16.07.2017    source источник
comment
пожалуйста, перестаньте добавлять тег webgl к этому вопросу. Ничто в этом вопросе не имеет ничего общего с WebGL. Это полностью вопрос three.js   -  person gman    schedule 17.07.2017
comment
никогда!! (буферы - довольно важная часть webgl)   -  person Andy Ray    schedule 17.07.2017
comment
Вы когда-нибудь находили решение? У меня точно такая же проблема, и я не могу найти никакой документации. Одна вещь, которая, кажется, работает, - это установка индексов в стандартный массив и передача этого права в setIndex (хотя этого нет ни в одной документации, это то, что делается в примерах). Однако тогда не представляется возможным обновить массив.   -  person JSideris    schedule 25.03.2018


Ответы (1)


Функция setIndex используется для указания индексов треугольников, которые ссылаются на буферы атрибутов вершин в BufferGeometry. В вашем примере вы устанавливаете массив индексов треугольника в массив, сгенерированный из materialIndex каждой грани.

MaterialIndex соответствует материалу для рендеринга этого треугольника из массива материалов, а не UV-индексу. Из документации Face3:

materialIndex — (необязательный) какой индекс массива материалов связать с гранью.

Очень возможно, что это materialIndex равно нулю для каждой грани, если вы не сделали что-то, чтобы изменить его, что объясняет, почему ваша модель перестает рисовать (вершины на гранях все одинаковые).

Эта строка - ваша проблема:

// Get an array of all the original geometry's indices... const faceIndices = geometry.faces.map( face => face.materialIndex );

Также может быть важно отметить, что вы получите 1/3 от количества элементов массива, необходимого для атрибута, сгенерировав массив таким образом, потому что на каждую грань приходится 3 вершины.

Возможные решения

  • Если вы хотите визуализировать каждое лицо с помощью другого материала, как соответствует materialIndex, я бы посмотрел на группы для BufferGeometry

  • Если вы действительно хотите сгенерировать собственные UV-координаты для BufferGeometry, я бы посмотрел на BufferAttributes и функцию BufferGeometry.addAttribute для добавления нового атрибута UV.

Надеюсь, это поможет!

person Garrett Johnson    schedule 24.05.2018