Як можна зігнути об'єкт у OpenGL?


11

Чи є спосіб, коли можна зігнути предмет, наприклад циліндр чи площину, за допомогою OpenGL?

Я початківець OpenGL (я використовую OpenGL ES 2.0, якщо це має значення, хоча я підозрюю, що математика найбільше має значення в цьому випадку, тому це якось незалежно від версії), я розумію основи: перекладати, обертати, перетворення матриці тощо Мені було цікаво, чи існує техніка, яка дозволяє фактично змінити геометрію ваших предметів (в даному випадку шляхом їх згинання)?

Будь-які посилання, навчальні посібники чи інші посилання вітаються!

Відповіді:


11

Те, що вам потрібно зробити, щоб "зігнути" об'єкт, - це застосувати якусь відповідну комбінацію перекладу / обертання / масштабування лише до деякого підмножини вершин відповідного об'єкта - ймовірно, зважування цього перетворення відповідно.

Зробити це приємно виглядає мода потребує використання більше вершин, ніж може бути в іншому випадку суворо необхідним для опису оригінальної сітки. Наприклад, простий циліндр може мати вершини лише на будь-якому кінці, але якщо ви хочете, щоб цей циліндр згинався посередині, вам також знадобляться вершини.

Якщо все, що вас цікавить, є дуже специфічними, одноразовими деформаціями дуже простих форм (як ваша вищезгадана площина), ви, ймовірно, можете це зробити вручну. Наприклад, визначте "вісь вигину" для вашої площини та обчисліть відповідні перетворення для кожного ряду площин вершин, щоб досягти відповідного обертання навколо цієї осі вигину залежно від їх відстані від неї, а потім застосуйте це до геометрії (можливо, на Процесор, як це було б найпростіше, хоча б спочатку). Але такий прийом не міг би масштабуватись і був би дуже стомлюючим.

Оскільки може бути настільки громіздко правильно зрозуміти, як зважити перетворення кожної окремої вершини у наборі для досягнення бажаної деформації (особливо для більш практичних і складних об'єктів), багато ігор використовують техніку, яку називають скелетною анімацією . На високому рівні це пов'язане з асоціюванням окремого набору геометрії ("скелета") з вашою сіткою. Ця геометрія представляє кістки вашого об'єкта, і ви визначаєте (часто в інструментах для моделювання) зіставлення вершин реальної моделі та кісток скелета - які кістки пов'язані з кожною вершиною і наскільки ця кістка впливає на деформацію цієї вершини. Потім скелет анімується безпосередньо, а анімація переноситься на реальну модель через взаємозв'язок між кістками та їх вершинами.

Зазвичай у цій техніці відображення між скелетом та реальною сіткою визначається під час виробництва активів. Анімації також можуть бути побудовані тоді, або вони можуть бути побудовані процедурно під час виконання. Застосування анімаційних перетворень до реальної сітки відбувається під час виконання. Як правило, під час виконання не утворюються нові вершини, а це означає, що діапазон гарних деформацій неявно фіксується в сітці при її первинному створенні.

Теоретично можна також застосувати тесселяцію та підрозділ до сітки під час виконання на основі аналізу перетворень в анімації, і таким чином створити відповідні вершини для створення анімації, яка не обов'язково планувалася. Я не знаю, напевно, жодних робіт на цю тему.

Дивись також:


9

Для фактичної математики викривлення це може стати дуже складним, чому б вам не почати тут? .

Зараз я розповім про те, як ви можете це застосувати, припускаючи, що ви вже отримали математику щодо того, як ви будете знижувати свої деформації.

2 способи:

1) Кожен кадр, відвідуйте кожну вершину в моделі циліндра і певним чином її зміщуйте.

2) Зміщення вершин у вершинній шейдері під час візуалізації. OpenGL ES 2.0 підтримує вершинні шейдери. Значить, вам пощастило, певним чином.

Ви хочете, щоб викривити об'єкт лише так, як він з'являється на екрані , або ви хочете викривити об'єкт, щоб кожен предмет у грі знав, що він деформований?

Якщо ви обмотуєте об'єкт у вершинній шейдері, це відбувається лише безпосередньо перед показом / растерізацією , тому це означає, що жоден з ігрових об’єктів не знатиме про деформацію . Це добре, якщо ви просто робите заставку або якщо деформації настільки малі, що не впливають на форму предмета, що стикається.

Коли ви перекручуєте геометрію у вершинній шейдері, оригінальні вершини моделі насправді не рухаються (вони, як видається, рухаються ).

Деформація у вершинній шейдері

Неоформлений:

недеформований

Деформований

деформовані

Це з розділу 6 підручника cg , (програма №14).

Код шейдера для отримання цієї деформації є чимось подібним

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

Отже, ви можете бачити, що це трапляється ПРАВО ДО ПЕРЕД дисплея (вершинний шейдер трапляється на GPU), тому код CPU практично не має можливості отримати доступ до перетвореної вершинної позиції (є способи надсилання даних з GPU до процесора (насамперед за допомогою текстур), але ми не піду туди).


8

Те, що ви намагаєтеся досягти, - це, як правило, підмножина теми деформації сітки. Але оскільки ви є початковою особою, я боюся, що цей тип інформації наразі може бути занадто дивним. Я спробую скласти основні поняття.

Для цього вам знадобляться дві речі:

  1. Ваша сітка повинна мати достатню кількість вершин для перетворення. Наприклад, якщо це площина, вам потрібно переконатися, що вона фактично створена як своєрідна сітка, з багатьма вершинами для вас деформуватися. Те саме з циліндром. Можливо, можна досягти цього під час виконання за допомогою тесселяції, але я не знаю багато про це.
  2. Для деформації вершин потрібно використовувати вершиновий шейдер. В основному вершина шейдера піклується про обчислення остаточного перетвореного положення кожної вершини, тому ви можете скористатися можливістю застосувати до них будь-які деформації.

Я не впевнений, наскільки це буде корисно, але погляньте на цей ресурс OpenGL, оскільки, здається, це правильно те, що вам потрібно:

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

Знімок екрана за цим посиланням:

введіть тут опис зображення

Редагувати

Щойно побачив відповідь Джоша, і я погоджуюся, скелетна анімація - це також дуже елегантний спосіб інкапсулювати цю проблему, особливо коли ваші деформації починають ставати складнішими і важче представляти математично.

Але пам’ятайте, що обидві точки вище все-таки застосовуються - ви можете деформувати лише вершини, тому очевидно, що вони повинні існувати в першу чергу, тому ваша сітка повинна мати пристойну кількість вершини. І це, як правило, вершинний шейдер, який керує скелетною анімацією та робить змішування вершин і таке інше.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.