Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как вычислить нормаль к вертексу? 
:(
    Опции темы
=Женек=
Дата 15.12.2020, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Друзья, есть вопрос. 

Есть библиотека 3d, простенькая. В ней есть функция - грузишь модель, представлющую собой массив, состоящий из вершин, индексов граней, нормалей и цвета, она эту модель отрисовывает.

Массив я создал - забил в него вертексы, назначил их граням, в режиме Wireframe рисует отлично. Хочу теперь запустить имеющуюся функцию отрисовки в режиме Flat и Gouraud.

Для этого в массив к каждому вертексу нужно добавить нормали. Именно к вертексу, а не к грани. ДЛя вычисления нормали к грани там есть своя функция, но для этого в нее нужно ввести нормали вертексов.

Код

    float32_t vertex_norm_a[3];
    float32_t vertex_norm_b[3];
    float32_t vertex_norm_c[3];
..............................
                vertex_norm_a[0] = dsp3dModel[2 + b * 6 + 3]; //   нормаль задается 3 числами
        vertex_norm_a[1] = dsp3dModel[2 + b * 6 + 4];//    заранее, при создании модели
        vertex_norm_a[2] = dsp3dModel[2 + b * 6 + 5];//    забитыми в массив


------------------------
// а потом вычисляется нормаль к грани
    dsp3D_calculateFaceNormal(vertex_norm_a, vertex_norm_b, vertex_norm_c, matrix_worldView, face_norm);




А как вычислить нормали к вертексам? 

Подвопрос: задает ли вершина нормаль? Или для ее расчета необходимы данные о всех трех ребрах, образующих грань?

P.S. Попытался в Blender создать куб, сохранить и посмотреть в сохраненный файл, но в него записались уже вычисленные нормали граней, а по вертексам данных нет.

[size="1"][color="grey"]Добавлено через 58 секунд[/color][/size]
Вот эта библиотека, если что   https://github.com/FabioRM/dsp3D/blob/master/src/dsp3D.c

Это сообщение отредактировал(а) =Женек= - 15.12.2020, 17:20
PM MAIL   Вверх
Alexeis
Дата 15.12.2020, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



=Женек=, в простейшем случае нормаль к вершине, это среднее арифметическое нормалей ко всем полигонам, которые содержат эту вершину. Такие нормали используют для сглаживания при расчете освещения. Но если нужно нарисовать резкую границу, то обычно вершину добавляют в 2 разных набора полигонов и соответственно в каждом из них она будет иметь свое значение нормали. Т.е. она дважды попадет в список вершин.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
=Женек=
Дата 15.12.2020, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Цитата(Alexeis @  15.12.2020,  16:09 Найти цитируемый пост)
это среднее арифметическое нормалей ко всем полигонам, которые содержат эту вершину

А откуда ж я возьму нормаль к полигонам, если нормаль к вертексу мне как раз для того и нужна, чтобы эту нормаль к полигону расчитать?

Смотрите.
Есть функция dsp3D_renderFlat(float32_t * dsp3dModel)     -   вот тут https://github.com/FabioRM/dsp3D/blob/master/src/dsp3D.c

Она в процессе работы читает из dsp3dModel вертексы, индексы граней и нормали ВЕРТЕКСОВ. После чего на основании нормалей ВЕРТЕКСОВ рассчитывает нормали ГРАНЕЙ:

Код

dsp3D_calculateFaceNormal(vertex_norm_a, vertex_norm_b, vertex_norm_c, matrix_worldView, face_norm);


A массив vertex_norm_a она заполняет из dsp3dModel.

Вертексы в dsp3dModel я забил руками.
Грани из вертексов я тоже слепил руками.
Но этого хватает только для режима WireFrame. Для того чтобы идти дальше, мне необходимы нормали ВЕРТЕКСОВ.
Как их посчитать, если даны координаты вертексов (ну и архитектура граней тоже).

Это сообщение отредактировал(а) =Женек= - 15.12.2020, 18:58
PM MAIL   Вверх
Alexeis
Дата 20.12.2020, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



=Женек=, ну блин, нормаль к полигону это школьная программа. Векторное произведение 2х векторов дает вектор перпендикулярный плоскости этих 2х векторов. Берем любые 3 точки полигона, вычисляем вектора, вычитая из конца начало, перемножаем вектора, получаем вектор нормали, нормализуем его разделив координаты на длину вектора, которая вычисляется по теореме Пифагора.




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
=Женек=
Дата 27.12.2020, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Я может что-то не так делаю
Вот координаты 8 вершин куба и его нормали
Код

//         VERTEXES  
//   coords    normals
 1, 1, 1,     0, 0, 1, // 0        
 1, 1,-1,     0,-1, 0, // 1            
 1,-1, 1,    -1, 0,0, // 2   
 1,-1,-1,     0, 0,-1, // 3    
-1, 1, 1,     1, 0, 0, // 4 
-1, 1,-1,     0, 1, 0, // 5        
-1,-1, 1,     0, 0, 0, // 6            
-1,-1,-1,     0, 0, 0, // 7 


Черный экран.
Скажите, если нормаль неверна, то будет неправильное освещение? Или вообще не будет визуализации? Неужели я во всех 8 нормалях ошибся?
PM MAIL   Вверх
Alexeis
Дата 3.1.2021, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
=Женек=
Дата 6.1.2021, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Код

Лучше начать с рабочего примера, чтобы было с чем сравнить. 


Нету его! И до автора библиотеки не достучаться


PM MAIL   Вверх
=Женек=
Дата 10.1.2021, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Вы были правы - причина черноты в другом.
Я поковырялся в коде и нашел вот что

Код

void dsp3D_drawPointDepthBuffer(int32_t x, int32_t y, float32_t z, color32_t color)
{
    if((x > -1) && (x < SCREEN_WIDTH) && (y > -1) && (y < SCREEN_HEIGHT))
    {
        int32_t index = (x + y * SCREEN_WIDTH) * 4;

        if(dsp3D_LL_readFromDepthBuffer(index) < z)  // вот тут засада - условие всегда выполняется и функция прерывается
            return;

        dsp3D_LL_writeToDepthBuffer(index, z);  //  а вот это 
        dsp3D_LL_drawPoint(x, y, color);//  и вот это не вызывается.
    }
}


Я в комментариях в коде написал что к чему.
Так вот, если я убираю эту проверку, то получаю вот такое видео  https://cloud.mail.ru/public/DGUX/TZoRw7stw 
Не обращайте внимание на тормоза, это поправимо.

Геометрия правильная, видно, что освещение не такое, и некоторые грани не освещены, потому что я нормали расставил наугад.
Но объясните мне, для чего нужна функция  dsp3D_LL_writeToDepthBuffer ?
Она пуста, потому что я должен сам туда ввести низкоуровневый код. К примеру функция dsp3D_LL_drawPoint тоже пуста, в нее я ввел свою функцию SetPixel(x,y,color)
А что нужно писать в dsp3D_LL_writeToDepthBuffer?



PM MAIL   Вверх
kurlyak
Дата 25.2.2021, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 7.11.2007

Репутация: 1
Всего: 3



Если надо нормаль к вертексу могу дать псевдокод где три вершины треугольника v1, v2, v3.

Код

vector3 edge1,edge2,normal;

edge1 = v2 - v1;
edge2 = v3 - v1;

edge1 = Vec3Normalize(edge1);
edge2 = Vec3Normalize(edge2);

normal = Vec3Cross(edge1, edge2);

normal = Vec3Normalize(normal);


А потом как писалось в ответе усреднить три нормали.

Это сообщение отредактировал(а) kurlyak - 25.2.2021, 16:36
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.1430 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.