Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557

Матрица тени

04.01.2018, 15:10. Показов 2103. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Кто разобрался с построением матрицы тени, обьясните принип построение или литературу на матчасть.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* Create a matrix that will project the desired shadow. */
void
shadowMatrix(GLfloat shadowMat[4][4],
  GLfloat groundplane[4],
  GLfloat lightpos[4])
{
  GLfloat dot;
 
  /* Find dot product between light position vector and ground plane normal. */
  dot = groundplane[X] * lightpos[X] +
    groundplane[Y] * lightpos[Y] +
    groundplane[Z] * lightpos[Z] +
    groundplane[W] * lightpos[W];
 
  shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
  shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
  shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
  shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
 
  shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
  shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
  shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
  shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
 
  shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
  shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
  shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
  shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
 
  shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
  shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
  shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
  shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
 
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.01.2018, 15:10
Ответы с готовыми решениями:

Изучаем тени
Здравствуйте Не секрет что нахождение каких-то базовых исходников в инете сейчас основной метод обучения/познания который используют...

Тени в 2D-игре
Visual C++ 10, OpenGL, и вся подобная бурда. Я пытался сделать тень следующим образом: ставил ClearColor в черный и у Quad'ов повышал...

Тени от объектов
На скриншоте из данного примера объекты отбрасывают тень. http://fabiensanglard.net/shadowmapping/index.php При запуске у себя на...

14
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
05.01.2018, 10:50
Эта бандура проецирует вертексы объекта (бросающего тень) на плоскость с нормалью groundplane и проходящую через точку (0, 0, 0). Делитель dot засунут в w

Популярно мнение что, мол, "матрица скрывает кучу вычислений", ну и значит пользоваться матрицами хорошо. Это не всегда так, напр в данном случае запись в векторах намного короче и понятнее.
C++
1
v -= lightpos * dot(lightpos, v) / dot(lightpos, groundplane);
где
lightpos - позиция источника
groundplane - нормаль к плоскости
v - проецируемый вертекс (в той же СК что и lightpos и groundplane)

Если теперь вынести v влево и домножить на делитель - получим бадягу выше. Позтому если у Вас шейдера то проще обойтись без матрицы, да и возможностей куда больше. Напр источник может быть и точечным, можно провериться что тени нет и.т.п.

Не по теме:

ASDFD12, может лучше конкретно сказать что надо? А то "разобрался - не разобрался" - здесь Ваня называет это "теорией" :)



Добавлено через 22 минуты
Виноват, маленько насвистел, верно так
C++
1
v -= lightpos * dot(v, groundplane) / dot(lightpos, groundplane);
Т.е. расстояние от вертекса до плоскости деленное на косинус нормали с лучом
1
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.01.2018, 13:24  [ТС]
Цитата Сообщение от Igor3D Посмотреть сообщение
ASDFD12, может лучше конкретно сказать что надо?
конкретно и сказал. чистая теория. Оба варианта одинаковы - скалярное произведение не зависит от порядка умножения.
Спасибо за уравнение.

Добавлено через 1 час 0 минут
Уравнение не правильное.
0
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
06.01.2018, 14:44
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Уравнение не правильное.
Обоснуйте

Хотя.. а зачем? Это ж все "теория", кому она нужна?
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.01.2018, 16:54  [ТС]
По сути вы формирует координаты проекцированой вершины как сумму текущих координат вершины + масштабированиый вектор позиции света, думаю ясно что это не правильно )

Добавлено через 1 час 48 минут
Вы видимо привели уравнение для параллельного источника света, а в матрице из примера - точечный
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.01.2018, 22:18  [ТС]
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.01.2018, 22:23  [ТС]
С виду все правильно а с матрицей в примере не совпадает
0
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
07.01.2018, 06:55
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Вы видимо привели уравнение для параллельного источника света, а в матрице из примера - точечный
Точечный источник матрицей НЕ делается, т.к. перспективное преобразование НЕ линейно.

Не по теме:

А как же матрица проекции??? И.т.п. Это заблуждение очень популярно, долго рассказывать :)

Цитата Сообщение от ASDFD12 Посмотреть сообщение
С виду все правильно а с матрицей в примере не совпадает
Ну давайте помотаем нитки (на матрицу).

// исходная формула
v -= lightpos * dotProduct(v, groundplane) / dotProduct(lightpos, groundplane);

// перепишем так
float dot = dotProduct(lightpos, groundplane); // этот скаляр от v не зависит
v_projected = v - lightpos * dotProduct(v, groundplane) / dot;

// теперь для каждой компонентны (x, y, z)
// распишем для x
v_projected.x = v.x - lightpos,x * (v.x * groundplane.x + v.y * groundplane.y + v.z * groundplane.z) / dot;

v_projected.x = v.x * (1 - lightpos.x * groundplane.x / dot) +
v.y * (-lightpos.x * groundplane.y) / dot +
v.z * (-lightpos.x * groundplane.z) / dot;

// Строка матрицы для x
(1 - lightpos.x * groundplane.x / dot)
(-lightpos.x * groundplane.y) / dot
(-lightpos.x * groundplane.z) / dot;

// Теперь dot засунем в w как общий делитель и помножим строку на dot
dot - lightpos.x * groundplane.x
-lightpos.x * groundplane.y
-lightpos.x * groundplane.z

Оно?

Добавлено через 6 минут
Цитата Сообщение от ASDFD12 Посмотреть сообщение
По сути вы формирует координаты проекцированой вершины как сумму текущих координат вершины + масштабированиый вектор позиции света, думаю ясно что это не правильно )
А вот мне неясно, объясните
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
07.01.2018, 10:59  [ТС]
Цитата Сообщение от Igor3D Посмотреть сообщение
Оно?
Оно.
Цитата Сообщение от Igor3D Посмотреть сообщение
А вот мне неясно, объясните
Логика была такая. Картину проецирования представляю как на рисунке в посте выше.
C++
1
2
3
4
5
6
7
8
v -= lightpos * dotProduct(v, groundplane) / dotProduct(lightpos, groundplane);
v - вектор.
lightpos - вектор
dotProduct(v, groundplane)  - число
dotProduct(lightpos, groundplane) - число
v= v -lightpos * число / число;
v = v + k* lightpos;
 на выходе сумма текущей координат вершины + масштабированный вектор позиции света
В чем заблуждение, по картинке выше никак не выйдет v = v + k* lightpos?
0
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
07.01.2018, 12:07
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Логика была такая. Картину проецирования представляю как на рисунке в посте выше.
C++
1
2
3
lightpos - вектор   // верно
dotProduct(v, groundplane) - число  // НЕ верно
dotProduct(lightpos, groundplane) - число  // верно
В чем заблуждение, по картинке выше никак не выйдет v = v + k* lightpos?
k - не константа, оно тоже зависит от v
1
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
07.01.2018, 23:45  [ТС]
Igor3D, все же проверил вашу формулу по реальных координатах - не совпадает. Было бы отлично, если вы привели картинку, хотя бы набросок в Paint , как расположены ваши вектора и как из их сложения получается проекция.
C++
1
2
3
lightpos - вектор   // верно
dotProduct(v, groundplane) - скаляр зависящий от v
dotProduct(lightpos, groundplane) - скаляр
Проверил для случая двумерного пространства
0
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
08.01.2018, 02:16
ASDFD12, все там работает.
Эта формула это обычное пересечение луча с плоскостью.

Берем для наглядности функцию:
C++
1
2
3
4
5
6
7
8
9
10
11
12
bool intersect ( const Plane& plane, const Ray& ray, float& t )
{
    float numer = - (plane.getDist () + ( ray.getOrg () & plane.getNormal () ) );
    float denom = ray.getDir () & plane.getNormal ();
 
    if ( fabs ( denom ) < EPS )
        return false;
        
    t = numer / denom;
 
    return true;
}
Тут :
- ray.getOrg() - начало луча, совпадает с положением источника сета.
- ray.getDir() - направление луча, вычисляем как (V - L), должно быть нормализовано.
- plane.getNormal() - нормаль к плоскости, должна быть нормализована.
- plane.getDist() - четвертый параметр плоскости, кратчайшее расстояние от начала координат.
- знаком & обозначена операция DOT().

После выполнения функции получаем параметр t, это расстояние от начала луча до точки пересечения.
Искомую точку пересечения получаем так - v1 = ray.getOrg() + ray.getDir() * t;
0
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
08.01.2018, 06:09
Цитата Сообщение от ASDFD12 Посмотреть сообщение
не совпадает
Не понял чем не нравится v' (13.3, 6.89)? Чем это неверно (ну или с чем сравнивали)? Повторюсь k - скаляр (не вектор) но зависящий от v. Т.е. для одного v будет одна прямая, для другого - уже другая. Но все они параллельны вектору lightpos и каждая проходит через вектекс(v). На предыдущем рисунке было правильно
Цитата Сообщение от _Develop Посмотреть сообщение
Эта формула это обычное пересечение луча с плоскостью.
Да, азы. Но их надо понимать очень хорошо. Вот неск вопросиков, пусть товарищи потренируются
v -= lightpos * dot(v, groundplane) / dot(lightpos, groundplane);
1) умножим groundplane на любое ненулевое число (положительное или отрицательное). Что изменится и почему?

2) это ур-е для плоскости проходящей через начало координат (0, 0, 0). Как сделать для плоскости проходящей через заданную точку p?

3) что нужно изменить чтобы получить проекцию точечного источника? Как записать матрицу для него?

Пока такие задачки не научитесь свободно решать - все эти примеры, либки и.т.п. - мертвому припарка
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
08.01.2018, 10:45  [ТС]
теперь все ясно. Я в посте выше привел решение для (не параллельного) точечного источника света spot light (лучи расходятся конусом) и любой плоскости задаваемой коефициентами уравнения плоскости, что четко видно на картинке - никакого параллельного вектору позиции света переноса вертекса там не наблюдается. И вторая картинка тоже для точечного источника. А мне демонстрируют элементарнейшую формулу где лучи параллельны вектору позиции света да еще и плоскость через начало координат проходит) не плохо. По картинке вроде бы все же видно.
По сути задача стояла центральное проектирование на произвольную плоскость. Центр проекцирование в точке света.

Добавлено через 8 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
все эти примеры, либки и.т.п
тут не понял. какие еще примеры либки))

Добавлено через 10 минут
вопрос решен - в первой картинке PF - функция позиции вертекса - внеся зависимости в матрицу все совпадает.
0
1958 / 814 / 114
Регистрация: 01.10.2012
Сообщений: 4,748
Записей в блоге: 2
09.01.2018, 15:36
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Я в посте выше привел решение для (не параллельного) точечного источника света spot light (лучи расходятся конусом)
Для точечного источника не существует матрицы тени "одной на всех". Т.е. выписать ее для конкретного вертекса - пожалуйста (все то же самое только от lightpos отнять v). Но для другого вертекса матрица будет уже другая. На вашем первом рисунке PF зависит от вертекса, т.е. она не константа и в матрице быть не может.

Цитата Сообщение от ASDFD12 Посмотреть сообщение
вопрос решен - в первой картинке PF - функция позиции вертекса - внеся зависимости в матрицу все совпадает.
Вносите хоть какие зависимости - все равно общей матрицы не получите, для точечного ее не существует в природе
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.01.2018, 15:36
Помогаю со студенческими работами здесь

добавление тени
Народ помогите, как сюда тень добавить? unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes,...

Тени в opengl
Несколько дней уже лажу по гуглам пытаюсь освоить тени, но как то рассматриваются примеры которые в моем случае не очень подходящие да и не...

Не рисуются все тени
Добрый вечер! Нужно изобразить цилиндр, конус и шар, а также их тени, которые они отбрасывают. Вот кусок кода, который отрисовывает...

Проекционные тени в OpenGL
Всем доброго времени суток. Я пытался реализовать рисование теней в OpenGL, как показано в статье...

OpenGL шейдеры и тени
Всем привет! Сегодня первый день осваиваю OpenGL, надо сделать это в сжатые сроки, задача из универа дана =\ Короче, мне нужно считать...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru