Я создаю процедурную сетку на основе кривой, и размер сетки уменьшается по всей кривой, как вы видите ниже.
И проблема в том, что UV изменяется зигзагообразно при изменении размера (он отлично работает, когда размер сетки одинаков по всей кривой).
Vertices.Add(R);
Vertices.Add(L);
UVs.Add(new Vector2(0f, (float)id / count));
UVs.Add(new Vector2(1f, (float)id / count));
start = Vertices.Count - 4;
Triangles.Add(start + 0);
Triangles.Add(start + 2);
Triangles.Add(start + 1);
Triangles.Add(start + 1);
Triangles.Add(start + 2);
Triangles.Add(start + 3);
mesh.vertices = Vertices.ToArray();
//mesh.normals = normales;
mesh.uv = UVs.ToArray();
mesh.triangles = Triangles.ToArray();
Как я могу это исправить?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
источник
источник
id
иcount
? Что делаетUVs.ToArray()
? Как вы загружаете вершины и координаты текстуры на карту?id
это индекс текущего сегмента из всех перемычек вдоль полосы, где ихcount
общее количество.List<T>.ToArray()
возвращает типизированный массив всех записей в списке (поэтому здесь, аVector2[]
). Эти буферы данных становятся доступными для системы рендеринга, назначая ихMesh
экземпляруmesh
в последних нескольких строках. Но ничто из этого не является особенно интересной частью кода: как выбираются точки вершин. Эти детали было бы более полезно увидеть. ;)count
самом деле это вершины, а не полигоны или наоборот. Просто убедиться, что все, что мы думаем, происходит на самом деле.Ответы:
Типичное УФ-картирование - это то, что называется аффинным преобразованием . Это означает, что отображение каждого треугольника между трехмерным пространством и текстурным пространством может включать в себя вращение, перемещение, масштабирование / сдвиг и наклон (т. Е. Все, что мы можем сделать с однородным умножением матриц)
Суть аффинных преобразований в том, что они однородны по всей своей области - вращение, перемещение, масштабирование и перекос, которые мы применяем к текстуре около вершины A, совпадает с тем, что мы применяем около вершины B внутри любого одного треугольника. Линии, параллельные в одном пространстве, будут отображаться на параллельные линии в другом, никогда не сходясь / не расходясь.
Но постепенное сужение, которое вы пытаетесь применить, не является равномерным - это сопоставление параллельных линий в текстуре со сходящимися линиями в сетке. Это означает, что масштаб текстуры, измеряемой по всей полосе, непрерывно меняется при движении вниз по полосе. Это больше, чем могут точно представить аффинные преобразования 2D UV-картирования: интерполяция 2D UV-координат между смежными вершинами даст один согласованный масштаб по всему краю, даже по диагональному краю, который должен уменьшаться в масштабе при перемещении вниз по полосе. Это несоответствие - то, что создает этот трогательный зигзаг.
Эта проблема возникает всякий раз, когда мы хотим отобразить прямоугольник на трапецию - параллельные стороны к сходящимся сторонам: просто нет аффинного преобразования, которое делает это, поэтому мы должны приблизить его кусочно, приводя к видимым швам.
Для большинства целей вы можете минимизировать эффект, добавив больше геометрии. Увеличение количества делений по длине полосы и разделение полосы на два или более сегмента вдоль ее ширины с диагоналями треугольников, расположенных в виде рисунка "елочкой", может сделать эффект гораздо менее заметным. Это всегда будет присутствовать до некоторой степени, пока мы используем аффинные преобразования.
Но есть способ обойти это. Мы можем использовать тот же трюк, который мы используем для 3D-рендеринга, чтобы рисовать трапеции в перспективе при заданных прямоугольных стенах и полах: мы используем проективные координаты !
Аффинное текстурирование:
Проективное текстурирование:
Для этого нам нужно добавить третью координату uv (uvw) и изменить наши шейдеры.
Учитывая масштабный коэффициент в каждой точке (скажем, равный ширине вашей полосы в этом месте), вы можете построить 3D-проективную координату uvw из вашей обычной 2D-координаты uv следующим образом:
Чтобы применить эти 3D-координаты uvw к вашей сетке, вам нужно использовать Mesh.SetUVs перегрузки Vector3 (int channel, List uvs)
И обязательно измените структуру ввода вашего шейдера так, чтобы он ожидал трехмерную текстурную координату (показанную здесь с помощью неосвещенного шейдера по умолчанию):
Вам также необходимо вырезать макрос TRANSFORM_TEX в вершинном шейдере, так как он ожидает 2D uv:
Наконец, чтобы вернуться к 2D-координате текстуры для выборки текстуры, вы просто делите на третью координату в своем фрагментном шейдере :
Поскольку мы сделали эту трехмерную координату uvw из нашей желаемой 2D-координаты умножением на одно и то же число, две операции отменяются, и мы возвращаемся к нашей первоначальной желаемой 2D-координате, но теперь с нелинейной интерполяцией между вершинами. : D
Важно делать это деление на фрагмент, а не на вершинный шейдер. Если это сделано для каждой вершины, то мы вернулись к линейной интерполяции результирующих координат вдоль каждого ребра, и мы потеряли нелинейность, которую мы пытались ввести с проективной координатой!
источник