forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Unity (http://forum.boolean.name/forumdisplay.php?f=144)
-   -   Smooth Shading для программно созданного mesh (http://forum.boolean.name/showthread.php?t=19302)

Evgen 11.07.2014 13:57

Smooth Shading для программно созданного mesh
 
Программно создаю mesh, т.е. через код.
В результате получается, то что справа.
А мне нужно чтобы нормали были размыты как слева.



Картинка не моя. Взято отсюда:

Mr_F_ 11.07.2014 14:24

Ответ: Smooth Shading для программно созданного mesh
 
у тебя скорее всего каждый треугольник имеет свои, не соединённые с соседними, вертексы. автогенератор нормалей считает это за разрыв.

Evgen 11.07.2014 15:22

Ответ: Smooth Shading для программно созданного mesh
 
Может быть... но мне нужно для одной вершины разные UV координаты текстуры.
То есть получается несколько вершин в одной точке...
Значит наверно нужно пересчитывать но как...
Грубо говоря делаю Tiled Terrain

Igor 11.07.2014 15:53

Ответ: Smooth Shading для программно созданного mesh
 
У совпадающих вершин нормали тоже совпадать должны.

Mr_F_ 11.07.2014 18:35

Ответ: Smooth Shading для программно созданного mesh
 
Цитата:

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

Evgen 14.07.2014 15:05

Ответ: Smooth Shading для программно созданного mesh
 
Вложений: 1
Цитата:

Сообщение от Igor (Сообщение 284162)
У совпадающих вершин нормали тоже совпадать должны.

Практика показывает, что нет...

Evgen 14.07.2014 15:06

Ответ: Smooth Shading для программно созданного mesh
 
Цитата:

Сообщение от Mr_F_ (Сообщение 284168)
тогда тебе нужно нормали самому считать.
находишь на каждый треугольник нормаль, а потом для каждого вертекса усредняешь нормали стыкующихся с ним (по позиции) треугольников.

Это целая история, но рано или поздно придется делать.

Evgen 14.07.2014 16:56

Ответ: Smooth Shading для программно созданного mesh
 
Пока что так.
Код:

Vector3[] normals = new Vector3[mesh.normals.Length];
for(int n=0;n<mesh.normals.Length;n++){
        normals[n] = new Vector3(0,0,1);                                                                                                       
}
mesh.normals = normals;

Поверхность освещается равномерно. Не реалистично, зато ребер не видно.

Mr_F_ 14.07.2014 17:00

Ответ: Smooth Shading для программно созданного mesh
 
Цитата:

Поверхность освещается равномерно. Не реалистично, зато ребер не видно.
лол, тебе не нужны для этого нормали, просто unlit шейдер заюзай тогда

Igor 14.07.2014 19:13

Ответ: Smooth Shading для программно созданного mesh
 
Цитата:

Практика показывает, что нет...
В той системе отсчёта, в которой рассчитывается освещение, нормали просто обязаны совпадать для совпадающий вершин- иначе с разных сторон от ребра будет разная яркость. Собственно, на картинке справа это видно

Evgen 15.07.2014 10:52

Ответ: Smooth Shading для программно созданного mesh
 
Вложений: 1
Цитата:

Сообщение от Mr_F_ (Сообщение 284249)
unlit шейдер заюзай тогда

Не знал...

Цитата:

Сообщение от Igor (Сообщение 284256)
В той системе отсчёта, в которой рассчитывается освещение, нормали просто обязаны совпадать для совпадающий вершин- иначе с разных сторон от ребра будет разная яркость. Собственно, на картинке справа это видно

Все равно что-то он не то считает, если вручную усреднить нормали результат гораздо лучше.

Все оказалось не так сложно... Делаю усреднение нормалей между вершинами у которых совпадают координаты. Алгоритм не оптимальный по скорости, но работает.

Код:

// smooth normals for light
Vector3[] normals = mesh.normals;
Vector3[] vertices = mesh.vertices;
for(int n=0;n<vertices.Length;n++){
        Vector3 norm = mesh.normals[n];
        int q=1;
        for(int c=0;c<vertices.Length;c++){
                if(vertices[c]==vertices[n] && c!=n){
                        norm += mesh.normals[c];
                        q++;
                }
        }
        norm=norm/q;
        normals[n]=norm;
}
mesh.normals = normals;

Осталось только устранить швы между соседними mesh'ами, но это уже немного другая история.

P.s. более быстрая версия
Код:

// smooth normals for light
Vector3[] inputnormals=mesh.normals;
Vector3[] outputnormals=new Vector3[mesh.normals.Length];
Vector3[] vertices = mesh.vertices;
int[] stack = new int[1000];
for(int n=0;n<outputnormals.Length;n++){
        if(outputnormals[n]==Vector3.zero){
                Vector3 norm = inputnormals[n];
                int q=1;
                for(int c=0;c<outputnormals.Length;c++){
                        if(vertices[c]==vertices[n] && c!=n){
                                norm += inputnormals[c];
                                stack[q]=c;
                                q++;
                        }
                }
                norm=norm/q;
                outputnormals[n]=norm;
                for(int s=0;s<q;s++)outputnormals[stack[s]]=norm;
        }
}
mesh.normals = outputnormals;



Часовой пояс GMT +4, время: 09:28.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot