Форум программистов, компьютерный форум, киберфорум
Программирование графики
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/35: Рейтинг темы: голосов - 35, средняя оценка - 4.83
1 / 1 / 0
Регистрация: 03.08.2014
Сообщений: 46

Расчет нормалей вертекса

15.12.2020, 15:57. Показов 8589. Ответов 50
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья, есть вопрос.

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

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

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

C
1
2
3
4
5
6
7
8
9
10
11
12
    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 создать куб, сохранить и посмотреть в сохраненный файл, но в него записались уже вычисленные нормали граней, а по вертексам данных нет.

Добавлено через 58 секунд
Вот эта библиотека, если что https://github.com/FabioRM/dsp... rc/dsp3D.c
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.12.2020, 15:57
Ответы с готовыми решениями:

Расчет нормалей для освещения
Никак не могу разобраться, как правильно рассчитывать нормали для освещения модели. Вот пример: // front face v =...

Как изменить позицию вертекса на меше?
К примеру, есть у меня Plane 5*5 точек, у всех параметр "Y" = 0, мне нужно сделать 13му вертексу "Y" = 2. Реализую на C#; ...

Карты нормалей
Доброго времени суток. Мне требуется шейдер, искажающий изображение таким образом, что он начинает выглядеть как сфера. Например тут...

50
Модератор
Эксперт Java
 Аватар для alecss131
2896 / 1402 / 412
Регистрация: 11.08.2017
Сообщений: 4,491
Записей в блоге: 2
17.01.2021, 15:42
Студворк — интернет-сервис помощи студентам
zheka1980, грубо говоря
В те времена, когда щейдеры еще только начали появляться, разработчики проводили вычисления освещения по модели Фонга в вершинном шейдере. Преимущество такого подхода заключалось в его большей производительности, так как обычно вершин гораздо меньше, чем фрагментов, и поэтому (дорогие) расчеты освещения выполняются реже. Однако вычисленное в вершинном шейдере значение цвета является точным только для этой вершины, а цвета окружающих её фрагментов получают путем интерполяции освещения соседних вершин. Поэтому, если не использовалось большое количество вершин, то освещение было не очень реалистичным: Если модель освещения Фонга реализована в вершинном шейдере, то она называется методом тонирования Гуро, а не Фонга. Обратите внимание, что из-за интерполяции освещение выглядит несколько шероховатым. Как видите, модель Фонга дает более сглаженные результаты освещения.
Название: 9.png
Просмотров: 142

Размер: 12.7 Кб
По сути отличий нету, только перенести код Фонга в вершинный шейдер
0
Модератор
Эксперт Java
 Аватар для alecss131
2896 / 1402 / 412
Регистрация: 11.08.2017
Сообщений: 4,491
Записей в блоге: 2
18.01.2021, 23:56
Вот нарисовал
Фонг

Гуро

Слева мой куб справа ваш
У вашего куба освещение тоже не очень)) Освещение самое базовое и простое, можно немного улучшить не повышая сложность
0
9987 / 2959 / 497
Регистрация: 05.10.2013
Сообщений: 8,111
Записей в блоге: 243
23.01.2021, 00:52
Цитата Сообщение от zheka1980 Посмотреть сообщение
P.S. Попытался в Blender создать куб, сохранить и посмотреть в сохраненный файл, но в него записались уже вычисленные нормали граней, а по вертексам данных нет.
Потому что вы сохранили его в режиме Flat, а для Gouraud нужно нажать кнопку Smooth

У меня Blender версии 2.67 и там не левой панели (T-panel) эти кнопки:

Название: 008953f3-efcd-4c29-a842-daa0f91b24f8.png
Просмотров: 103

Размер: 2.0 Кб

Цитата Сообщение от zheka1980 Посмотреть сообщение
Для этого в массив к каждому вертексу нужно добавить нормали. Именно к вертексу, а не к грани.
Нормаль - это вектор и поэтому для Flat он экспортируется в файл в одном экземпляре, потому что он одинаковый для всех вершин данной грани. Программа должна сама взять значение этого вектора и положить в массив с таким же индексом, что и массив координат вершин. Другими словами, модель состоит из треугольников и для Flat Blender экспортирует один вектор нормали для всего треугольника, но в железо, то есть на видео карту нужно отправить одинаковые по длине массивы координат вершин и нормалей. Даже для Flat для треугольника будет отправлено координаты трёх точек вершин и три нормали. Вершинный шейдер для треугольника сработает три раза и каждый раз он из массивов вершин и нормаль будет забирать по одной координате: (vx, vy, vz) и (nx, ny, nz).

Как смог постарался объяснить. Посмотрите этот ролик, который длиться меньше 4 минут, в нём наглядно показана разница между Flat и Gouraud. Вы увидите, что для Flat не одна нормаль на видеокарте, а уже программист отправил одинаковые нормали для каждой вершины:
Видео
0
1 / 1 / 0
Регистрация: 03.08.2014
Сообщений: 46
26.01.2021, 22:15  [ТС]
А вот это - это что, Фонг? Гуро? Я так понял, там угластые призмы, но каким-то образом сглажены. Это как-то за счет нормалей делается?
0
9987 / 2959 / 497
Регистрация: 05.10.2013
Сообщений: 8,111
Записей в блоге: 243
26.01.2021, 22:51
Цитата Сообщение от zheka1980 Посмотреть сообщение
Это как-то за счет нормалей делается?
Да, с помощью нормалей достигается сглаживание. Это игра с освещением. На видео выше стрелками показываются нормали. Когда нормали торчат перпендикулярно плоскости полигона (грани), то это Flat:

Название: e0672cc8-1b03-475f-9d41-e3172ed06302.png
Просмотров: 77

Размер: 22.3 Кб

Если в Blender нажать кнопку Smooth, то нормали соседних граней будут усреднены:

Название: 4dbdf676-7370-4f89-a300-7a6c5824878c.png
Просмотров: 75

Размер: 33.4 Кб

Вы можете кубик сделать Smooth, экспортировать в файл и посмотреть, как изменятся нормали по сравнению c Flat.

Цитата Сообщение от zheka1980 Посмотреть сообщение
А вот это - это что, Фонг? Гуро?
Фонг и Гуро - это модели освещения. Этим моделям освещения без разницы какую модель вы им отдадите: Flat или Smooth. Отличаются Гуро и Фонг тем, что для Гуро цвет считается для вертекса в вершинном шейдере, а для Фонг в фрагментном шейдере для каждого пикселя. Гуро менее требовательный, потому что вершинный шейдер срабатывает один раз для каждой вершины треугольника, а фрагментный получает интерполированное значение цвета между вершинами. А для Фонг расчёт цвета происходит в фрагментном шейдере, который срабатывает для каждого пикселя (лучше сказать - фрагмента). Фонг лучше по красоте, но хуже по производительности, хотя сейчас, учитывая мощность даже бюджетных ноутбуков, разница между Фонг и Гуро может быть пренебрежимо мала. Но если сделать Smooth, но, скорее всего, разницы между Фонг и Гуро не будет видно - я это не проверял, но по моей логике так должно быть, я только Фонг использую.

Для сравнения Фонг и Гуро.

На этой сфере с Гуро освещением затенение неровное, треугольники просматриваются: https://jsfiddle.net/8Observer8/edz9Lz8f/

Название: bf8f6e0f-ed77-42a3-9e8e-0ab972aba46a.png
Просмотров: 77

Размер: 13.4 Кб

А здесь сфера с Фонг освещением: https://jsfiddle.net/8Observer8/qzwyow4j/

Название: 022ca3eb-1d36-4e16-beba-92c6befefe86.png
Просмотров: 77

Размер: 15.3 Кб
0
9987 / 2959 / 497
Регистрация: 05.10.2013
Сообщений: 8,111
Записей в блоге: 243
26.01.2021, 23:15
zheka1980, попробуйте в Blender выбрать объект и нажать кнопку Smooth на панели слева. Нарисуйте объект с помощью библиотеки, которую вы используете, с включенным Гуро освещением и посмотрите, что получится. Обратите внимание, что Smooth работает не только в объектом режиме Blender, но и в режиме редактирования (Edit Mode), то есть можно выделять Face'ы и нажимать Smooth, а не делать весь объект сглаженным.
0
1 / 1 / 0
Регистрация: 03.08.2014
Сообщений: 46
21.02.2021, 21:47  [ТС]
Продолжаем одолевать 3D

Есть у меня 3D библиотека, настроил я ее, нарисовал кубик. Теперь хочу его покрутить (при помощи сенсорного экрана).

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

Я решил поступить по другому - вращать не объект, а перемещать камеру вокруг кубика. То есть точка прицела камеры всегда в координатах 0,0,0, а сама камера гуляет по поверхности сферы радиусом 10.

Иными словами - ведешь по экрану вверх-вниз - меняется зенитный угол, ведешь вправо-влево - меняется азимут.

Высчитываю по вот такой формуле

https://www.cyberforum.ru/cgi-bin/latex.cgi?\left\{\begin{matrix}x\:=\:r\:\sin\theta\:\cos\varphi \\y\:=\:r\:\sin\theta\:\sin\varphi \\z\:=\:r\:\cos\theta  \end{matrix}\right.



В коде это выглядит так:
Code
1
2
3
4
5
6
7
       azimuthal+=(float32_t)d_evt.getDeltaX()/495;  // Преобразуем  горизонтальный пробег пальца по экрану в приращение азимута
            zenital+=(float32_t)d_evt.getDeltaY()/445; // Преобразуем  вертикальные пробег пальца по экрану в приращение зенитного угла
            
 
            dsp3D_setCameraPosition(10*arm_sin_f32(zenital)*arm_cos_f32(azimuthal),
                                                  10*arm_sin_f32(zenital)*arm_sin_f32(azimuthal),
                                                  10*arm_cos_f32(zenital)); // Перемещаем камеру (при этом сама камера всегда смотрит в точку 0,0,0)
Вращение камеры почему-то неадекватное. Даже трудно описать в чем, но чем дальше поворачивается кубик, тем неадекватнее его реакция на движение.





проверял отладкой преобразование пробега пальца по экрану в параметры azimuthal и zenital - оно адекватное.

Саму камеру перемещал вверх-вниз, вправо-влево - тоже адекватно. Но она при этом движется во фронтальное плоскости перед объектом, что не соответствует желаемому. А желаемое - двигаться в пределах сферы, окружающей объект.



В упор не вижу ошибки, в чем она может быть?

взглянем, к примеру на формулу расчета Z - из нее вытекает, что Z зависит только от зенитного угла, но ведь это не так! Если камера, не меняя зенита, будет "водить хоровод" вокруг объекта, Z ведь должен меняться...
0
1 / 1 / 0
Регистрация: 03.08.2014
Сообщений: 46
22.02.2021, 08:54  [ТС]
Вот видео поведения куба
https://cloud.mail.ru/public/whtu/BXQvRUxSV

Добавлено через 42 минуты
Ага.... разница в том, что в моей библиотеке ось Z смотрит на экран, а в формуле - вверх. Переставил оси - вроде заработало почти как надо.   Только вот зенит почему-то работает только в пределах 0-180 градусов.... пытаешься заглянуть под объект, при пересечении 0 или 180 градусов начинается вращение  в обратную сторону. Это как побороть?
0
Модератор
Эксперт Java
 Аватар для alecss131
2896 / 1402 / 412
Регистрация: 11.08.2017
Сообщений: 4,491
Записей в блоге: 2
22.02.2021, 11:19
Цитата Сообщение от zheka1980 Посмотреть сообщение
Это как побороть?
Вместо углов Эйлера (или как их там) использовать другие способы вращения, а эти ограничения это увы часть их работы и не избавиться. Еще у них возможны шарнирные замки. Альтернатива например кватернионы
0
9987 / 2959 / 497
Регистрация: 05.10.2013
Сообщений: 8,111
Записей в блоге: 243
22.02.2021, 13:57
Я не совсем понял, что в конечном итоге должно получиться. Я писал недавно демку солнечной системы с поворотами камеры мышкой (зажатой кнопкой мыши) и пальцем для мобильных на WebGL: https://8observer8.github.io/W... index.html Примерно такое должно быть поведение камеры или другое?
0
1 / 1 / 0
Регистрация: 03.08.2014
Сообщений: 46
22.02.2021, 21:29  [ТС]
Ахахах, уписаться можно))))

Решил я понаблюдать за численными значениями координат - все нормально. Они меняются как надо.

А смена направления вращения - это ИЛЛЮЗИЯ! Камера при переходе через горизонт почему-то переворачивается на 180 градусов вокруг оси, соответствующей направлению взгляда. И кубик, который только что "падал" от нас, начинает на нас "заваливаться", но подставляя нам другую грань, а не ту, которая от нас уплывала.

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

ДРузья, я ноль в 3D графике. Вот список библиотечных функций, которые так или иначе формируют или определяют проекцию
C++
1
2
3
4
5
6
7
8
9
void dsp3D_vectorNormalTransform(float32_t *v, float32_t *m, float32_t *result);
void dsp3D_vectorCrossProduct(float32_t *a, float32_t *b, float32_t *v);
void dsp3D_vectorNorm(float32_t *a, float32_t *v);
void dsp3D_transformVertex(float32_t *v, float32_t *m, float32_t *tv);
void dsp3D_generateLookAtMatrixLH(float32_t *cameraPosition, float32_t *cameraTarget, float32_t *cameraUpVector, float32_t *m);
void dsp3D_generatePerspectiveFovMatrixLH(float32_t fov, float32_t aspect, float32_t znear, float32_t zfar, float32_t* m);
void dsp3D_generateRotationMatrix(float32_t yaw, float32_t pitch, float32_t roll, float32_t *m);
void dsp3D_generateTranslationMatrix(float32_t xaxis, float32_t yaxis, float32_t zaxis, float32_t *m);
void dsp3D_generateScalingMatrix(float32_t xaxis, float32_t yaxis, float32_t zaxis, float32_t *m);
Скажите, чем и как можно повернуть камеру вдоль оси ее взгляда, или повернуть мир (не объект, я пробовал, лажа выходит, а весь мир) вокруг камеры?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.02.2021, 21:29

Вычисление нормалей (c++)
Ребятушки, разъясните пожалуйста как правильно рассчитать нормали, после загрузки данных из .3ds файла. Вот собственно как я рассчитываю ...

Карта нормалей и ее данные
Всем привет. Вот тут пример. Здесь используется карта нормалей для создания подобного эффекта. Загвоздка вот в чем- в коде вершинного...

Генерация псевдослучайных нормалей
Здравствуйте На каждом шаге вычислений есть такие исходные данные N - нормаль к поверхности, может меняться плавно или скачком ...

Вычисление нормалей к вершинам
Собственно интересует вопрос: правильно ли я делаю это? Вот мои шаги: Пробегаюсь по всем индексам с шагом +3 Беру 3 точки,...

Экспорт нормалей из 3ds Max
Как нужно экспортировать нормали, чтобы при загрузке в программу (написанной на OpenGL) модель отображалась так же, как и в максе? Код...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
51
Ответ Создать тему
Новые блоги и статьи
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru