В Unity процедурно генерирую меш локации, однако мне нужен угол затенения от векторов, а не от граней, восьмой час рою в дебрях интернета, и за это время нашел только пару мелких деталей по необходимой теме, в итоге плюнул и методом тыка выяснил что мне нужно делать, однако то что у меня получилось и дало результат довольно тяжеловато в выполнении, я конечно и не рассчитывал получить моментальную загрузку, но работать в редакторе стало невозможно, когда сцена загружается секунд тридцать при тысяче полигонов (проверял зависимость быстродействия от количества полигонов, результат удручающий) , вместо двух-трех на полноценной локации без выполнения этой функции.
В общем ищу способы либо удалить этот говнокод и использовать нормальный, продуманный разработчиками Unity функционал для такого же результата, либо облегчить то что есть. Во втором варианте по идее можно использовать Linq, он как минимум должен быстрее выполнятся чем цикл в цикле для поиска похожих координат вершин, но я с этим совершенно не знаком и пока не разобрался с документацией чтобы получить нужный результат, поэтому обращаюсь за помощью.
Сделал скриншоты для понимания необходимого действия и на второй экран вывел код.
void SmoothingNormalsNotOptimize() /// Не оптимизированное сглаживание нормалей
{
List<int> verticesNumber = new List<int>(); // создать лист с индексами повторяющихся вершин
Vector3[] ns = chunkMesh.normals; // создать список с углами нормалей и заполнить его имеющимися нормалями
for(int vertList1 = 0; vertList1 < chunkMesh.vertices.Length; vertList1++) // цикл переборки вершин
{
verticesNumber.Add(vertList1); // добавить индекс проверяемой вершины в список
for(int vertList2 = 0; vertList2 < chunkMesh.vertices.Length; vertList2++) // второй цикл переборки вершин
{
if(vertList2 != vertList1 && chunkMesh.vertices[vertList2] == chunkMesh.vertices[verticesNumber[0]]) // проверить не является ли сравниваемая вершина проверяемой и одинаковы ли координаты с проверяемой
{
verticesNumber.Add(vertList2); // если равна, то добавить её в список
}
}
if(verticesNumber.Count > 1) // если список индексов одинаковых координат вершине содержит больше одной вершины
{
Vector3 newVector = new Vector3(); // создать новый верктор для усредненой нормали
/// Найти среднее арифметическое нормалей на стыке граней
for(int n = 0; n < verticesNumber.Count; n++) // цикл переборки количества одинаковых вершин
{
newVector.x += ns[verticesNumber[n]].x; // приплюсовать направление меша по X
newVector.y += ns[verticesNumber[n]].y; // приплюсовать направление меша по Y
newVector.z += ns[verticesNumber[n]].z; // приплюсовать направление меша по Z
}
newVector.x = newVector.x / verticesNumber.Count; // разделить значение X на количество одинаковых нормалей
newVector.y = newVector.y / verticesNumber.Count; // разделить значение Y на количество одинаковых нормалей
newVector.z = newVector.z / verticesNumber.Count; // разделить значение Z на количество одинаковых нормалей
for(int un = 0; un < verticesNumber.Count; un++) // цикл переборки количества одинаковых вершин
{
ns[verticesNumber[un]] = newVector; // изменить координаты в списке по индексу на усредненное значение
}
}
verticesNumber.Clear(); // очистить список с индексами одинаковых вершин
}
chunkMesh.normals = ns; // заменить список нормалей в меше на измененный
}