Исправление нормалей в пользовательской геометрии капсулы threejs

Чтобы узнать немного больше о пользовательской геометрии в three.js, я попытался адаптировать пример капсульной геометрии Пола Бурка. .

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

  1. Нормали средней грани не ориентированы должным образом.
  2. По бокам есть жесткий шов. (EDIT: исправлено путем преднамеренного вычисления нормалей лица. обновленный код в сути)

И, может быть, один бонусный вопрос, который не давал мне покоя:

  1. Какой может быть общая стратегия добавления петель вершин в этот средний сегмент?

В целом я очень доволен геометрией, но кто-нибудь может подсказать, как решить эти проблемы? Я чувствую, что нормальной проблемой в среднем сегменте должна быть ориентация лиц, и вот соответствующий фрагмент построения лица:

  for(let i = 0; i <= N/2; i++){
    for(let j = 0; j < N; j++){
      let vec = new THREE.Vector4(
        i         * ( N + 1 ) +   j       ,
        i         * ( N + 1 ) + ( j + 1 ) ,
        ( i + 1 ) * ( N + 1 ) + ( j + 1 ) ,
        ( i + 1 ) * ( N + 1 ) +   j
      );

      let face_1 = new THREE.Face3(vec.x,vec.y,vec.z);
      let face_2 = new THREE.Face3(vec.x,vec.z,vec.w);

      geometry.faces.push(face_1);
      geometry.faces.push(face_2);
    }
  }

CapsuleGeometry.js


изображение нормальных проблем геометрии

геометрия в виде каркаса


person aceslowman    schedule 05.04.2018    source источник
comment
Верны ли нормали, если вы их явно вычисляете? Кроме того, что такое вершинная петля и что вы имеете в виду, добавляя их в средний сегмент?   -  person meowgoesthedog    schedule 05.04.2018
comment
@meowgoesthedog Мне только что удалось удалить шов, явно вычислив нормали, что оставляет проблему обратных нормалей в среднем сегменте. Под вершинными петлями я подразумеваю добавление дополнительных сегментов вдоль соединения между двумя крышками.   -  person aceslowman    schedule 06.04.2018


Ответы (1)


Затенение/нормальный шов здесь, потому что вы, вероятно, явно определили там жесткий край.

Когда вы запускаете свои циклы для создания вершин, вы, вероятно, дублируете начальную позицию. Если вы начнете с 0 и дойдете до 2PI, 0 == 2PI. Когда вы сплетаете треугольники, вы, вероятно, говорите последнему использовать 2PI вместо 0, и даже если они находятся в одном и том же положении, что касается треугольников, они указывают на разные вершины и, таким образом, не связаны.

for(let i = 0; i <= N/4; i++){ //change to i < N 
for(let j = 0; j <= N; j++){

Если вы скажете последнему треугольнику в цикле указывать на начальную вершину, вы создадите непрерывную поверхность, которую geometry.computeVertexNormals() можно сгладить.

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

person pailhead    schedule 05.04.2018
comment
Когда я экспериментировал с тем, что у вас есть, я не мог заставить его примириться с тем, что у меня было. Изменение на i ‹ N влияет на фи и нарушило конструкцию двух отдельных крышек. С учетом сказанного, я, возможно, неправильно реализовал ваш совет. Однако мне удалось удалить шов, вычислив нормали лица явно, по вашему совету использовать исходную сферу. Так что спасибо тебе! Теперь остаются только перевернутые нормали вдоль среднего сегмента. - person aceslowman; 06.04.2018
comment
Да, возможно, это не единственное, что нужно изменить, это было более иллюстративно. Пожалуйста, примите ответ, если он сработал :) - person pailhead; 06.04.2018