Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Нормали, полигоны и FOV (http://www.flasher.ru/forum/showthread.php?t=126000)

gloomyBrain 07.06.2009 17:21

Нормали, полигоны и FOV
 
http://game4b.narod.ru/normals.JPG
Вот, собственно, и вопрос =)
Если считать, что полигон виден, если его нормаль направлена в сторону камеры - все вроде бы понятно... НО!
с учетом FOV получается, что полигон (3) должен быть виден и при определенной сонаправленности нормалей камеры и полигона
Вопрос: как задать условие отображения полигона???

ЗЫ
делал так - брал камеру, создавал ее матрицу, получал обратную и ее (обратную) применял ко всем точкам полигонов. После этого высчитывал нормали полигонов
Далее с помощью Matrix3D.deltaTransformVector() проецировал нормаль на плоскость экрана.
когда камера направлена точно на центр полигона - все как надо, но если полигон находится в крайней части экрана - ... незнаю что и делать
заранее спасибо

ЗЗЫ
это не про papervision3D, я свой движок пытаюсь писать =))

alekslitvinenk 07.06.2009 17:37

Полигон 3 у Вас не должен быть виден, его нормаль направлена в другое полупространство.

gloomyBrain 07.06.2009 18:27

ну ок, если бы он был повернут чуть меньше - факт в том, что его нормаль направлена В ОДНУ сторону с нормалью камеры, НО он должен быть виден по смыслу
http://game4b.narod.ru/normals2.JPG

alekslitvinenk 07.06.2009 19:15

зачем вам делать периферийное искажение ?
не усложняте так все себе...

gloomyBrain 07.06.2009 19:20

Я готов выслушать правильный способ =)
как сделать перспективное искажение, не сталкиваясь с подобной проблемой теста на отображение полигона???

alekslitvinenk 07.06.2009 19:52

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

Stargazer 07.06.2009 22:04

Мне тоже интересен этот вопрос, потому что благодаря нему я понял, почему у меня в самописном 3д иногда промелькивали ненужные плоскости.
Есть ли простой способ определить видимость? Или, действительно, нужно вычислять в 2 этапа?

silin 07.06.2009 22:18

а такой способ не проходит ?
я не совсем в теме, но если правильно понял там берeтся локальный треугольник и потому в какую сторону он 'закручен' в глобальных координатах делается вывод видна ли плоскость, выглядит просто и надежно
вот еще пост с комментами по нему

MonkDead 08.06.2009 01:45

Что надо сделать:
1) Рассчитать угол обзора по отношению к области вывода
Код AS3:

var halfWidth:Number = viewPort.width / 2;
var halfHeight:Number = viewPort.height / 2;
var focalLength:Number - фокальный радиус(расстояние);
var angle:Number = focalLength / Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight + focalLength * focalLength);

2) Сравнить нормаль камеры с нормалью полигона, скалярным произведением и сравнить с углом области вывода;
Код AS3:

if(dots(нормаль камеры и полигона) < angle)
{
    // Полигон виден.
}
else
{
    // Полигон не виден.
}

Вот и все, дальше оптимизируйте как вам надо и все будет нормально.

Цитата:

я не совсем в теме, но если правильно понял там берeтся локальный треугольник и потому в какую сторону он 'закручен' в глобальных координатах делается вывод видна ли плоскость, выглядит просто и надежно
Самый медленный метод, много расчетов и самое главное много доступов к данным.

Есть еще один способ, если у вас нет понятия viewPort(области вывода).
1) Повернуть нормаль полигона на FOV/2 к камере.
2) Сравнить нормали скалярным произведением, если больше 0 значит видим полигон.

Alex Lexcuk 08.06.2009 02:11

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

MonkDead 08.06.2009 02:28

Цитата:

Чето-то ребятки вы перекручиваете... Проблема надуманная. Если полигон невидим, а вы подумайте как надо умудриться его поставить что-бы он стал невидим, и сразу станет ясно, что рассчет такой ситации - только лишняя нагрузка на медлительный flash процессор и быстрее будет визуализировать невидимы полигон, тем более что флеш тормозит в основном сильнее всего на отрисовке, а отрисовать невидимый полигон ему будет только в радость как быстро.
1) Alex Lexcuk Вы знаете что такое конвейерная обработка и зачем она нужна?
А нужна она для того что бы на каждом этапе избавляться от ненужной информации и данных. После проверки полигона на видимость могут быть еще куча алгоритмов (динамические деревья, обрезка полигонов, просчет света и теней и т.д.). И как вы понимаете все эти алгоритмы применять к полигону который не видим вот это трата ресурсов :)
2)
Цитата:

быстрее будет визуализировать невидимы полигон
Хех, а вы думаете flash сам по себе не будет рисовать полигон повернутый спиной к наблюдателю? Это не так он нарисует этот полигоны с инвертированной текстурой :)

Alex Lexcuk 08.06.2009 02:54

>>После проверки полигона на видимость могут быть еще куча алгоритмов (динамические деревья, обрезка полигонов, просчет света и теней и т.д.). И как вы понимаете все эти алгоритмы применять к полигону который не видим вот это трата ресурсов

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

MonkDead 08.06.2009 03:28

Alex Lexcuk, я как пример привел тени никто не говорит что их делать надо. Я сказал алгоритмы и привел примеры. А если вы не варитесь в этой кухне не надо пытаться пять копеек вставить :)
У вас все так просто, что и делать ничего не надо все само правильно отрисуеться и проверится магическим образом.
Цитата:

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

Вы ни в одном посте не дали алгоритм :), а лишь разглагольствовать на философские темы.

В общем вы меня извините, но когда вы будете понимать основные принципы даже не 3D, а хотя бы как устроен мир - продолжим дискуссию.

GentleFLASH 08.06.2009 05:24

Ребята, вы тут как то странно определяете виден полигон или нет, с незапамятных времен и даже на аппаратном уровне реализовано так: вначале растеризуются точки треугольника из 3Д в 2Д, затем обходим растеризованные точки по порядку: если получается обходить по часовой стрелке, то полигон виден, если нет, то соответственно не виден, ну или все наоборот, зависит от того в какую сторону нормали у объекта смотрят, смысл то такой. И там хоть какой FOV будет, хоть самый самый нестандартный - это всегда работало и работать будет.

Если надо то вот пример (выдернул из пары классов):

Код AS3:

// в классе Vertex.as
// класс Vertex имеет 3Д точку World и преобразовывает ее в 2Д, т.е Raster
// WIDTH и HEIGHT размер проекции, RATIO это пропорция проецируемого
function Rasterize(FOV:Number, WIDTH:Number, HEIGHT:Number, RATIO:Number):void
{
        Raster.x =        WIDTH * (RATIO * 0.5 + FOV * World.x / World.z) / RATIO;
        Raster.y = HEIGHT * (                0.5 - FOV * World.y / World.z);
}
 
 
// а это отрисовка в классе Face.as
// V0 V1 V2 - вершины треугольника (полигона)
// CullModes.CW - по часовой
// CullModes.CCW - против часовой
// drawable - виден или невиден
 
cullMode = device.RenderState.CullMode;
drawable = false;
 
if(cullMode == device.RenderState.CullModes.NONE)
        drawable = true;
else if( cullMode == device.RenderState.CullModes.CW && ( (V2.Raster.x - V0.Raster.x) * (V0.Raster.y - V1.Raster.y) - (V0.Raster.x - V1.Raster.x) * (V2.Raster.y - V0.Raster.y) ) > 0 )
        drawable = true;
else if( cullMode == device.RenderState.CullModes.CCW && ( (V2.Raster.x - V0.Raster.x) * (V0.Raster.y - V1.Raster.y) - (V0.Raster.x - V1.Raster.x) * (V2.Raster.y - V0.Raster.y) ) <= 0 )
        drawable = true;

Думаю вопросов больше не будет.

Alex Lexcuk 08.06.2009 10:18

>>Вы ни в одном посте не дали алгоритм , а лишь разглагольствовать на философские темы.

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

Ежели хотите заценить мои алгоритмы трехмерного флеша
http://www.murmadillo.tut.su/
там же и исходники, пара классов и ничего более.

MonkDead 08.06.2009 11:59

GentleFLASH, да алгоритм существует с незапамятных времен и он работает.
Но посмотрите сколько в нем расчетов, а главное сколько доступов к данным и сколько проверок.

GentleFLASH 08.06.2009 16:20

MonkDead, ну если присмотреться, то не так уж и много - все равно же придется преобразовывать вершины из 3Д в 2Д - т.е. половина кода исчезает, а вторая часть про видимость / невидимось, можно вообще все условия убрать и принять заранее - либо по часовой, либо против и тогда останется всего на всего:

(x2 - x0) * (y0 - y1) - (x0 - x1) * (y2 - y0) ) > 0 (в 2д пространстве разумеется)

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

Stargazer 08.06.2009 16:32

Цитата:

ну если присмотреться, то не так уж и много - все равно же придется преобразовывать вершины из 3Д в 2Д - т.е. половина кода исчезает
Зачем преобразовывать в 2д то, чего не будет видно? :)

GentleFLASH 08.06.2009 16:45

Цитата:

Зачем преобразовывать в 2д то, чего не будет видно?
Что интересно быстрее: преобразовать точки в 2д и проверить на видимость или супер-изощренными методами вычислять в 3Д "а стоит ли мне это преобразовывать в 2д?", где расчетов интересно меньше?
И потом одна вершина может принадлежать далеко не одному полигону (например в конусе макушка - сколько там треугольников в ней соединяется, растеризовали одну, а коснулось всех прилегающих треугольников), а вот нормаль можно построить только к одному единственному, вот и вывод, что целесообразнее вначале все вершины растеризовать, а уже потом обходить каждый треугольник по растеризованным вершинам и делать проверку его на видимость.

Stargazer 08.06.2009 17:00

Согласен (в целом).

И, всё-таки, утверждение
Цитата:

все равно же придется преобразовывать вершины из 3Д в 2Д - т.е. половина кода исчезает
некорректно.

С утверждением MonkDead о том, что слишком много элементов архитектуры задействовано одновременно - тоже согласен.

MonkDead 08.06.2009 17:07

Цитата:

ну если присмотреться, то не так уж и много - все равно же придется преобразовывать вершины из 3Д в 2Д - т.е. половина кода
1) Вам надо пройтись по всем вершинам полигона и перевести их в 2D;
2) Проверить обход вершин;

Цитата:

супер-изощренными методами вычислять в 3Д
- он очень простой и более того почти все данные предрасчетные. Динамически рассчитываем только скалярное произведение векторов, т.е. доступ нужен только к 2 векторам на полигон, а не к n вершинам причем повторяющихся.

Вы думаете мало времени тратится на доступ к вершинам? Очень много поверти, циклом обходить да еще и в рекурсии (а еще учитывайте что могут быть многоугольники :)).

Цитата:

И потом одна вершина может принадлежать далеко не одному полигону
в этом и преимущество нормалей нам нужен доступ только к 1 нормали на полигон, а не к n вершинам, мы не переводим одну и туже вершину разных полигон в 2D.

Цитата:

вот и вывод, что целесообразнее вначале все вершины растеризовать, а уже потом обходить каждый треугольник по растеризованным вершинам и делать проверку его на видимость.
А если есть алгоритмы построения теней и освещения придется переводить обратно вершины из 2D в 3D. Смотрите на проблему глубже, а не применяйте "лобовые" алгоритмы :)

Цитата:

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

Stargazer 08.06.2009 17:37

Цитата:

Цитата:

И потом одна вершина может принадлежать далеко не одному полигону
в этом и преимущество нормалей нам нужен доступ только к 1 нормали на полигон, а не к n вершинам
А как насчёт индексирования вершин? И использовать именно одну вершину для разных полигонов?

MonkDead 08.06.2009 17:43

Цитата:

А как насчёт индексирования вершин? И использовать именно одну вершину для разных полигонов?
У меня так и сделано в движке :)

GentleFLASH 08.06.2009 20:26

MonkDead, мы похоже слегка не понимаем друг друга :)

Цитата:

1) Вам надо пройтись по всем вершинам полигона и перевести их в 2D;
2) Проверить обход вершин;
Отнюдь нет. Все вершины хранятся в вершинном буфере, нет необходимости ходить по каждому треугольнику / многоугольнику, достаточно прокрутить буфер в цикле и растеризовать вершину.

Цитата:

в этом и преимущество нормалей нам нужен доступ только к 1 нормали на полигон, а не к n вершинам, мы не переводим одну и туже вершину разных полигон в 2D.
См. выше, никто и не переводит одну и туже вершишу, но в разных полигонах


Цитата:

А если есть алгоритмы построения теней и освещения придется переводить обратно вершины из 2D в 3D. Смотрите на проблему глубже, а не применяйте "лобовые" алгоритмы
Зачем обратно в 3Д? 3Д никуда и не девалась и ничем не заменялась после растеризации, просто класс Vertex содержит:

public var Local :Vector3D; // позиция в 3Д
public var World :Vector3D; // тоже самое, только трансформированная в мировом пространстве (согласно настройком активной камеры)
public var Raster :Point; // растеризованная точка в 2Д

Пожалуйста только не пишите что тут типы тормозные, я последний раз это год назад правил, когда под FlashPlayer 10 можно было скомпилировать только через mxml.exe из Flex SDK 3, там все еще что то вроде альфа или бета версии было, мне просто было интересно скорость узнать, кстати самолет из 1000 полигонов с текстурами и Z сортировкой крутился 100 кадров в секунду в разрешении 500х300, не думаю что медленно :)

Цитата:

Очень много поверьте, циклом обходить да еще и в рекурсии
совсем не понял про рекурсию.. просто же циклом по вершинному буферу


Цитата:

он очень простой и более того почти все данные предрасчетные
А если объект крутиться? а если там скелетная анимация с растяжением вершин? что тогда, тоже все прпедрасчетное? нужно по каждому треугольнику пройти и потом по каждым его трем точкам.

Вас послушать, так Direct3D мертвая технология, только вот пока ничего универсальнее и быстрее в RealTime 3D нет (RayTracing не в счет)

Добавлено через 16 минут
Цитата:

в этом и преимущество нормалей нам нужен доступ только к 1 нормали на полигон
Хотя знаешь, ты дело говоришь, если бы автор взял второй нормаль не туда куда камера смотрит, а просто бы построил вектор из позиции камеры к центру проверяемого треугольника, то у него багов бы не было. Так пожалуй действительно быстрее должно быть :)

MonkDead 08.06.2009 21:01

Цитата:

Отнюдь нет. Все вершины хранятся в вершинном буфере, нет необходимости ходить по каждому треугольнику / многоугольнику, достаточно прокрутить буфер в цикле и растеризовать вершину.
Хорошо, это уже оптимизация и вы не упоминали буфер раньше при написании алгоритма :).
Цитата:

Пожалуйста только не пишите что тут типы тормозные
А очень хочется ну да ладно :)

Цитата:

А если объект крутиться? а если там скелетная анимация с растяжением вершин? что тогда, тоже все прпедрасчетное? нужно по каждому треугольнику пройти и потом по каждым его трем точкам.
Пройдите по ссылке у меня в сообщение внизу, для моего движка нет абсолютно никакой разницы динамический объект или статический! Знаете что самое смешное у меня нет глобальной системы координат, только локальная и камеры. 5000 полигонов при разрешение 800х600 при 57 FPS и краш тест, один заказчик попросил 27000 полигонов (4 модели 6800 полигонов и все они крутились вокруг своей оси и вокруг друг друга имитируя динамику) при 37 FPS (все полигоны попадаю в область отрисовки).
Нигде я по точкам не хожу, разве что при отправки на отрисовку по буферу пробегаюсь.
Цитата:

Хотя знаешь, ты дело говоришь, если бы автор взял второй нормаль не туда куда камера смотрит, а просто бы построил вектор из позиции камеры к центру проверяемого треугольника, то у него багов бы не было. Так пожалуй действительно быстрее должно быть
- Я не говорю что ваш алгоритм плох, все алгоритмы нужны для чего-нибудь. Но надо учитывать, что нормали нужны не только для проверки на видимость но и для физики, culling алгоритмов, света, теней и для многих других алгоритмов. Поэтому убиваем сразу много зайцев вводя нормали :) тем самым повышая общую производительность.
Цитата:

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

gloomyBrain 09.06.2009 01:30

Прекрасное обсуждение, достойное всех библиотек мира =)
Спасибо, господа флешеры

Мое мнение - никаких определений "закрутки" полигона - это медленно (graphics.drawTriangles и свойство culling это наглядно показывают - 2 Silin)

Цитата:

А как насчёт индексирования вершин? И использовать именно одну вершину для разных полигонов?
Вот тут сомневаюсь... Ибо при таком подходе каждой вершине соответствует ОДНО значение uv координат. Если же есть 2 полигона, у которых есть одна общая вершина, НО! которым необходимо в этой вершине иметь различные участки текстуры... вот и косяк

Возвращаясь к проблематике: ... MonkDead, а Вы из какого формата модели парсите?

ЗЫ
подвисает демка с рептилией =(

GentleFLASH 09.06.2009 03:35

gloomyBrain, имей ввиду что через graphics.drawTriangles свойство culling работает тормозно, такое ощущение что флэш вначале все нарисует, а потом обдумывает - что же он собственно нарисовал, ну и делает проверку :)

MonkDead 09.06.2009 12:14

Цитата:

Вот тут сомневаюсь... Ибо при таком подходе каждой вершине соответствует ОДНО значение uv координат. Если же есть 2 полигона, у которых есть одна общая вершина, НО! которым необходимо в этой вершине иметь различные участки текстуры... вот и косяк
Никто не мешает сделать 2 буфера для vertex и для UV и ассоциировать их :)

Цитата:

Возвращаясь к проблематике: ... MonkDead, а Вы из какого формата модели парсите?
Пока в библиотеку входят форматы: ASE, OBJ, I3D(мой формат), а так еще много парсиров написал, но не включил пока в библиотеку.

Цитата:

подвисает демка с рептилией =(
Поподробнее сама модель появляется? В этой демки парсится файл 200000 строк (если модель не появляется значит файл не успел распарсится, надо перекомпилить демку под последнюю версию, в ней большие файлы дробятся и по частям парсятся отдельно с остановкой)

Цитата:

имей ввиду что через graphics.drawTriangles свойство culling работает тормозно
Не используете flash culling!!! Пишите свой. Например на основе алгоритма Сазерленда-Ходжмана.

Alex Lexcuk 09.06.2009 14:10

>>Поподробнее сама модель появляется? В этой демки парсится файл 200000 строк (если модель не появляется значит файл не успел распарсится, надо перекомпилить демку под последнюю версию, в ней большие файлы дробятся и по частям парсятся отдельно с остановкой)

Я не знаю минут десять ждал когда же появится рептилия, загружило 10 метров, и все время загрузка проца была 100%. Потом закрыл, недождался, наверно там были тени и детектировались невидимые полигоны.

MonkDead 09.06.2009 14:26

Цитата:

Я не знаю минут десять ждал когда же появится рептилия, загружило 10 метров, и все время загрузка проца была 100%. Потом закрыл, недождался, наверно там были тени и детектировались невидимые полигоны.
Давайте без ехидства чести вам это не делает.


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

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.