UV отображение процедурного цилиндра в Unity

#unity3d #mesh #uv-mapping #procedural

#unity-игровой движок #сетка #uv-отображение #процедурный

Вопрос:

У меня есть метод, который создает цилиндр на основе переменных, содержащих высоту, радиус и количество сторон.

Сетка отлично генерируется с любым количеством сторон, однако я действительно затрудняюсь понять, как это должно быть отображено UV.

Каждая сторона цилиндра представляет собой квадрат, состоящий из двух треугольников. Треугольники имеют общие вершины.

Я думаю, что размещение uv-кода правильное, однако я понятия не имею, какие значения будут подходящими? Прямо сейчас текстура растянута / искривлена со всех сторон сетки. Пожалуйста, помогите мне разобраться в этом.

 private void _CreateSegmentSides(float height)
{
    if(m_Sides > 2) { 
        float           angleStep   = 360.0f / (float) m_Sides;
        BranchSegment   seg         = new BranchSegment(m_NextID  );
        Quaternion      rotation    = Quaternion.Euler(0.0f, angleStep, 0.0f);

        int index_tr = 0, index_tl = 3, index_br = 2, index_bl = 1;
        float u0 = (float)1 / (float) m_Sides;
        int max = m_Sides - 1;

        // Make first triangles.
        seg.vertexes.Add(rotation * (new Vector3(m_Radius, height, 0f)));
        seg.vertexes.Add(rotation * (new Vector3(m_Radius, 0f, 0f)));
        seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 1]);
        seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 3]);

        // Add triangle indices.
        seg.triangles.Add(index_tr);    // 0
        seg.triangles.Add(index_bl);    // 1
        seg.triangles.Add(index_br);    // 2
        seg.triangles.Add(index_tr);    // 0
        seg.triangles.Add(index_br);    // 2
        seg.triangles.Add(index_tl);    // 3

        seg.uv.Add(new Vector2(0, 0));
        seg.uv.Add(new Vector2(0, u0));
        seg.uv.Add(new Vector2(u0, u0));
        seg.uv.Add(new Vector2(u0, 0));

        for (int i = 0; i < max; i  )
        {
            seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 2]);      // new vertex

            seg.triangles.Add(seg.vertexes.Count - 1);  // new vertex
            seg.triangles.Add(seg.vertexes.Count - 2);  // shared
            seg.triangles.Add(seg.vertexes.Count - 3);  // shared

            seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 2]);      // new vertex

            seg.triangles.Add(seg.vertexes.Count - 3);  // shared
            seg.triangles.Add(seg.vertexes.Count - 2);  // shared
            seg.triangles.Add(seg.vertexes.Count - 1);  // new vertex

            // How should I set up the variables for this part??
            // I know they are not supposed to be zero.
            if (i % 2 == 0) {
                seg.uv.Add(new Vector2(0, 0));
                seg.uv.Add(new Vector2(0, u0));
            } else {
                seg.uv.Add(new Vector2(u0, u0));
                seg.uv.Add(new Vector2(u0, 0));
            }
        }
        m_Segments.Add(seg);
    }
    else
    {
        Debug.LogWarning("Too few sides in the segment.");
    }
}
  

Редактировать: Добавлены изображения

Вот как выглядит цилиндр (односторонние треугольники):

введите описание изображения здесь

Вот как должен выглядеть один и тот же шейдер (на плоской плоскости):

введите описание изображения здесь

Правка 2: Изображения в виде каркаса

введите описание изображения здесь
введите описание изображения здесь

Комментарии:

1. Не могли бы вы предоставить картинку?

2. @Menyus добавил фотографии

3. Можете ли вы также предоставить изображения с затенением каркас?

4. @Menyus добавил фотографии каркаса

Ответ №1:

Итак, ваш каркас в порядке (вы связали только каркас, но я попросил заштрихованный каркас: это заштрихованный каркас, но он в порядке).

Причина, по которой ваша текстура выглядит так, заключается в том, что она пытается выровнять ваше изображение по любой высоте, чтобы оно могло хорошо смотреться на цилиндре высотой 1 м, но выглядело бы растянутым на цилиндре высотой 1000 м, поэтому вам действительно нужно динамически выровнять эту uv-карту.

Например, для цилиндра высотой 1 м текстура подходит, потому что она рассчитана на размер 1×1: введите описание изображения здесь

Пример для текстуры цилиндра высотой 2 м, растянутого из-за удвоения размера длины 2×1:

введите описание изображения здесь

Итак, что вы можете сделать, это если вы создаете цилиндр всегда одинаковой высоты, вы можете просто настроить его внутри Unity, в свойствах текстуры, которые называются tiling, просто увеличьте размер x или y вашей текстуры и не забудьте заставить текстуру повторяться. Также ваша крышка цилиндра должна выглядеть следующим образом (это не обязательно, но да):

введите описание изображения здесь

Комментарии:

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

2. Можете ли вы также опубликовать непрозрачный заштрихованный каркас? 🙂 (возможно, ответит только в воскресенье вечером в банкомате gf parents)

3. У меня нет каркасного шейдера для режима воспроизведения. И я не могу выбрать как заштрихованный, так и каркасный для редактора, у меня нет опции для обоих одновременно. Однако у вас есть и заштрихованный, и каркасный элементы. Это просто вопрос о том, как вычислять UV-координаты для каждого шага цикла.

4. С помощью shaded wireframe я мог видеть, что вы имеете в виду под «странно скорректированным», кстати (заштрихованный каркас): [1]: i.stack.imgur.com/3FnzI.jpg , это на вкладке «Просмотр сцены»

5. У меня нет такой опции в Unity версии 2018.8f1 (hdrp). Говоря о странном растяжении, я имею в виду, что он должен выглядеть точно так же, как плоскость на картинке, с той же четкостью соотношения сторон. Теперь я использую вершины в uv-координатах, и это выглядит лучше, но все еще что-то не так. Должен быть четкий способ сделать это