ПрограммированиеФорум

Frustum Culling (Отсечение по пирамиде видимости) (комментарии)

Страницы: 1 2 Следующая »
#0
0:45, 28 июля 2016

Frustum Culling (Отсечение по пирамиде видимости) (комментарии)

Это сообщение сгенерировано автоматически.

#1
0:45, 28 июля 2016

Возник вопрос, вот по первой ссылке код:

 /* ЗАДНЯЯ плоскость */
   frustum[4][0] = clip[ 3] - clip[ 2];
   frustum[4][1] = clip[ 7] - clip[ 6];
   frustum[4][2] = clip[11] - clip[10];
   frustum[4][3] = clip[15] - clip[14]; 

   /* ПЕРЕДНЯЯ плоскость */
   frustum[5][0] = clip[ 3] + clip[ 2];
   frustum[5][1] = clip[ 7] + clip[ 6];
   frustum[5][2] = clip[11] + clip[10];
   frustum[5][3] = clip[15] + clip[14];

Третье число в каждой плоскости это параметр С с уравнения
Изображение
Когда я подставляю точку (0,0,30),  формуле if( frustum

[0] * x + frustum

[1] * y + frustum

[2] * z + frustum

[3] <= 0 ) всегда говорит что для передней плоскости все ок, точка перед ней, но про заднюю говорит что точка за ней.
Все потому что параметр С для противоположных плоскостей с разным знаком.

Проекционную матрицу считаю так:

auto aspectRatio = (float)realWidth / (float)realHeight;
  const float PI = 3.14159265359f;
  const float TORAD = PI / 180.0f;

  float fov = 45.0f;
  float nearZ = 0.1f;
  float farZ = 1000.0f;

  float t = 1.0f / tan(fov * TORAD * 0.5f);
  float nf = nearZ - farZ;
  _mProject = Mat4(
    t / aspectRatio, 0, 0, 0,
    0, -t, 0, 0,
    0, 0, (-nearZ - farZ) / nf, (2 * nearZ*farZ) / nf,
    0, 0, 1, 0);

Есть подозрения, что где-то я ошибся в матрице, но рендерит все обьекты нормально.

UPD: Проверил на листике, похоже пропустил минус на 10 елементе, вечером проверю...

#2
22:31, 28 июля 2016

Anders333
Советую выкинуть данную статью, и все ссылки в ней, по одной простой причине.
После вычисления проекции точки, посредством умножения ее на матрицу PROJ*MODEL, проверка ее попадания в пирамиду происходит одним выражением flag==0 и все!

// умножение вектора на матрицу
    r[0]=_invector[0]*_matrixa[0]+_invector[1]*_matrixa[4]+_invector[2]*_matrixa[8]+_invector[3]*_matrixa[12];
    r[1]=_invector[0]*_matrixa[1]+_invector[1]*_matrixa[5]+_invector[2]*_matrixa[9]+_invector[3]*_matrixa[13];
    r[2]=_invector[0]*_matrixa[2]+_invector[1]*_matrixa[6]+_invector[2]*_matrixa[10]+_invector[3]*_matrixa[14];
    r[3]=_invector[0]*_matrixa[3]+_invector[1]*_matrixa[7]+_invector[2]*_matrixa[11]+_invector[3]*_matrixa[15];
// интересующая нас часть про отсечение по пирамиде видимости для точки
    r[4]=-r[3]; // коэффициент указывающий на размеры среза пирамиды видимости в плоскости параллельной плоскости проекции пересекающей проецируемую точку.
    int flag=0;
    if (r[0]>r[3]) flag|=0x01; // правая плоскость
    if (r[1]>r[3]) flag|=0x02; // верхняя плоскость
    if (r[2]>r[3]) flag|=0x04; // дальняя плоскость
    if (r[0]<r[4]) flag|=0x10; // левая плоскость
    if (r[1]<r[4]) flag|=0x20; // нижняя плоскость
    if (r[2]<r[4]) flag|=0x40; // ближайшая плоскость

или
((r[0]>=r[4] && r[0]<=r[3]) && (r[1]>=r[4] && r[1]<=r[3]) && (r[2]>=r[4] && r[2]<=r[3]))

подробнее

#3
22:38, 28 июля 2016

Прошло ровно 11 лет с написания этой статьи, и вдруг внезапно появились комментарии. Откуда они берутся?

#4
23:00, 28 июля 2016

gammaker
Ж))
Меня больше заботит, удивляет, вводит в недоумение, нелепость данной статьи и высокая должность авторов подобного.
И с последствием влияния таких "кадров" приходиться бороться по сей день.

#5
23:38, 28 июля 2016

foxes
Там ровно то же самое, что и у тебя.

#6
23:57, 28 июля 2016

foxes
спасибо, я думал насчет проектирования, но с уравнениями плоскости меньше действий происходит, собственно меньше нагрузки на CPU.

В общем, с директ матрицами всё работало. А если создаю сам матрицу вида и проекции, получается фигня с плоскостью. Наверно прийдется всё-таки использовать проекцию точки=(

#7
1:17, 29 июля 2016

Blew_zc
> Там ровно то же самое, что и у тебя.
Там общее описание, говорящее о том что через вычисление плоскостей работает быстрее чем через проекцию, и куча ссылок на бредовые вычисления с 16 делениями. В общем то последние оптимизаторы это хорошо обрабатывают и незаметно для программиста приводят все к простой формуле о которой я говорю.

Вкратце отсечение вершины плоскостью это простое выражение:
dot(vertex-plane,normal)<0 отсечена. для пирамиды таких 6 - бессмысленных вычислений. Помимо этого нужно еще сами значения нормалей плоскостей вычислять.

И ни в одной из ссылок не говориться о том что достаточно умножить вершину на матрицу чтобы выполнить отсечение - а это всего 4 dot(vector,matrix(i)).

А в самой же статье делается акцент вот на чем:

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

Это совершенно обратное тому что я говорю. А говорю я, о том что вычисление проекции не только быстрее и проще но и равносильно вычислению с помощью плоскостей также как:
a-b=a-b+c*2-d*3+d-c*2+d*2...

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

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

Anders333
> А если создаю сам матрицу вида и проекции, получается фигня с плоскостью.
Для того чтобы выполнить отсечение через расчет проекции нет нужды в видовой матрице, нужна только проекционная и модельная, другие вычисления не нужны.

#8
1:53, 29 июля 2016

foxes
Уточнение. Это для OpenGL clip space пример. Для DirectX clip space нужно последнюю строчку:

if (r[2]<r[4]) flag|=0x40; // ближайшая плоскость

заменить на:

if (r[2]<0) flag|=0x40; // ближайшая плоскость
#9
1:59, 29 июля 2016

MrShoor
Да, или вычислять одинаковые проекционные матрицы для GL и DX в ручную для данного примера - ни каких проблем. Вообще разница между DX и GL это изменение мест слагаемых и названий, что создает путаницу Row/Coll хотя на низком уровне ориентация у матриц одинаковая.
по ссылке:
foxes
> Конечно там все замечательно написано но только про саму матрицу проекции. Для
> примера буду рассматривать OpenGL.

Anders333
> А если создаю сам матрицу вида и проекции, получается фигня с плоскостью.
Anders333
> _mProject = Mat4(
> t / aspectRatio, 0, 0, 0,
> 0, -t, 0, 0,
> 0, 0, (-nearZ - farZ) / nf, (2 * nearZ*farZ) / nf,
> 0, 0, 1, 0);
вот тут как раз за счет перепутанной ориентации Row/Coll (строка/столбец) может быть и не работает. Попробуй транспонировать.

Anders333
> но с уравнениями плоскости меньше действий происходит, собственно меньше
> нагрузки на CPU.
неа.

#10
8:25, 29 июля 2016

foxes
> Да, или вычислять одинаковые проекционные матрицы для GL и DX в ручную для
> данного примера - ни каких проблем. Вообще разница между DX и GL это изменение
> мест слагаемых и названий, что создает путаницу Row/Coll хотя на низком уровне
> ориентация у матриц одинаковая.
В инете вообще жесть, одни пишут что матрицы кроме транспонирования для ДХ и ОГЛ еще и способом отличаются.

> вот тут как раз за счет перепутанной ориентации Row/Coll (строка/столбец) может
> быть и не работает. Попробуй транспонировать.
Ну как мне обьяснили, можно люые матрицы поекции юзать. Я рендерю на Вулкане, а модельки импортирую с блендера, поэтому решил использовать матрицы как в ОГЛ. Да и рендерит прекрасно. Надо будет еще почитать про плоскости, а то немного непонятен принцып извлечения плоскостей с матрицы.
И спасибо за ссылку, ща почитаю.

foxes
> неа.
есть ОББ, у него 8 вершин. Для проецирования нужно 8 точек умножить на матрицу на. С плейнами для каждой точки надо произвести только 3 умножения и 4 суммирования.

#11
9:41, 29 июля 2016

Anders333
> С плейнами для каждой точки надо произвести только 3 умножения и 4
> суммирования.
Помножить на 6 забыл. Плоскостей же 6.

#12
10:48, 29 июля 2016

MrShoor
> Помножить на 6 забыл. Плоскостей же 6.
Блин, точно. Надо будет потестить сегодня на своих 2,5к обьектах, что быстрее получится, проецирование или проверка с плейнами.

#13
14:16, 29 июля 2016

Anders333
> Для проецирования нужно 8 точек умножить на матрицу на.
используй сферу - достаточно одного умножения на матрицу.
foxes
> dot(vertex-plane,normal)<0 отсечена. для пирамиды таких 6 - бессмысленных
> вычислений.
foxes
> достаточно умножить вершину на матрицу чтобы выполнить отсечение - а это всего
> 4 dot(vector,matrix(i)).

условия такие

    if ((r[0]-r[3])/proj.x.x>-radius) flag|=0x01; // правая плоскость
    if ((r[1]-r[3])/proj.y.y>-radius) flag|=0x02; // верхняя плоскость
    if ((r[2]-r[3])/proj.z.z>-radius) flag|=0x04; // дальняя плоскость
    if ((r[0]+r[3])/proj.x.x<radius) flag|=0x10; // левая плоскость
    if ((r[1]+r[3])/proj.y.y<radius) flag|=0x20; // нижняя плоскость
    if ((r[2]+r[3])/proj.z.z<radius) flag|=0x40; // ближайшая плоскость
#14
22:53, 29 июля 2016

foxes
Хочу сделать по сфере, но немного непонял про матрицу с нормалями плейнов внутри. Как туда нормали записать? Или это обычная матрица вида умноженная на проекционную?
Еще вопрос про эту матрицу, с которой плейны вытаскивают. У нее нормали в глобальной системе координат или переходят в локальную камеры?

Страницы: 1 2 Следующая »
ПрограммированиеФорум

Тема в архиве.