Як змусити об'єднати кола вибору одиниць?


16

Мені хотілося б знати, як зробити цей ефект об'єднаного вибору кола. Ось зображення для ілюстрації:

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

В основному я шукаю цей ефект:

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

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

Якщо можливо, я шукаю рішення для чисто шейдерів.


Чи можете ви пояснити, що ви маєте на увазі під «ефектом злиття»?
wondra

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

Ви наполягаєте на шайдерському розчині? Якщо ні, ви просто вирішили це в останньому малюнку.
wondra

Останній скріншот показує лише ефект, на який я орієнтований. Кінцевий результат повинен виглядати як попередні скріншоти.
MaT

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

Відповіді:


8

Ви можете виконати кілька хитрощів:

Z-буфер

Після того, як ви надали всі інші об'єкти, для кожної одиниці виведіть прозоре коло меншого розміру з максимальним значенням Z. Потім візьміть на місце відмітки кіл відбору. Оскільки вони знаходяться в нижньому порядку Z, вони будуть відкинуті, коли знаходяться під одиницями.

Бути повністю прозорим означає, що коло пишеться лише до Z-буфера (max Z значення). Тепер, коли ви надаєте відмітки, вони перевіряються на значення буфера Z, і якщо вони проходять тест, вони отримуються (що відбувається лише поза колами)

Трафарет

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


Техніка Z-Buffer цікава, але я не розумію, як перше прозоре коло може обрізати відмітки землі.
MaT

0

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


1
Я припускаю, що ви пропустили частину своєї відповіді - щоб передати всі кола та радіуси в шейдер.
Кромстер каже, що підтримує Моніку

@Krom Якщо ОП виявляє зацікавленість у вирішенні, я рада надати більше деталей.
JarkkoL

0

Ви маєте на увазі ті сині кола на землі?

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

Коли ви рендеруєте рельєф місцевості після попереднього кроку, ви можете взяти зразок раніше створеної текстури, використовуючи координати екрана в піксельній шейдері, як УФО. Тепер ви знаєте, що коло слід або не слід проектувати на заданий піксель місцевості. Однак таким чином він буде працювати так, ніби тест Z був відключений, тому місцевість не може приховати жодного кола. Якщо ви хочете, щоб місцевість заховала кола, що знаходяться за нею, проведіть глибинну перевірку, перш ніж поєднувати коло з текстурою рельєфу. Ви можете використовувати невеликий ухил, щоб увімкнути візуалізацію кіл, які знаходяться трохи під місцевістю, але ви все одно хочете, щоб вони відображалися.


Редагувати. Тепер для того, щоб отримати ефект об'єднаних кіл, потрібно зробити це: Коли ви надаєте окрему текстуру, вам потрібно перевірити, чи вже існує коло, де ви намагаєтеся зробити нове. (Перевірте, чи має там текстура значення), якщо так, видаліть цей піксель. Це повинно дати ефект "контуру", коли два чи більше кола перетинаються. Щоб це правильно працювало, проте вам потрібно буде зробити цей тест лише для внутрішньої частини кола, а не для кордону. Тому під час візуалізації кіл запишіть певне значення текстури виводу, що вказує, що це коло всередині. Тоді вам просто нічого не потрібно виводити на коло всередині, і ви повинні бути хорошими.

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

Якщо моя відповідь випадково занадто абстрактна, дайте мені знати.


Я розумію загальну думку, але, як ви кажете, для мене це трохи абстрагується щодо об'єднаних кіл :)
MaT

0

Є кілька варіантів. Як загальний метод, буфери трафаретів часто бувають дуже зручними, коли певний малюнок потрібно замаскувати, як контур, де кола перекриваються у вашому прикладі.

У цьому випадку я думаю, що це можна зробити так само легко без буфера трафарету. Ви можете використовувати буфер глибини, щоб усунути контур, де кола перетинаються. Ідея полягає в тому, щоб ви намалювали інтер'єр кіл лише в буфер глибини (оскільки ми не хочемо бачити інтер'єр), а потім намалюєте контур. Таким чином, частина контуру, яка перекривається іншим колом, буде усунена тестом на глибину.

Єдине застереження полягає в тому, що вам потрібно бути обережними щодо боротьби з глибиною. Ви можете скористатися невеликим зміщенням, щоб переконатися, що обриси насправді позаду інтер’єру, і усунути їх глибинним випробуванням. Альтернативою було б використання glPolygonOffset().

Скажімо, у вас є два кола, паралельні площині xy, з центрами у (x1, y1, z) та (x2, y2, z). І у вас є такі функції малювання:

// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

Послідовність малювання потім виглядає так, з deltaневеликим зміщенням:

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);

0

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


Так, я теж думав про це :), але, як ви сказали, це не шейдерне рішення, і це не дуже загальне рішення. Але дякую!
MaT

Це досить розпливчастий опис
Кромстер каже, що підтримує Моніку

0

Ви хочете трафарети тут. Ваш перший пропуск переводить кола в буфер трафарету. Другий прохід надає видимі обриси , де б не змінився буфер трафарету . Другий прохід повинен використовувати геометрію, яка більша за перший прохід, в цьому випадку достатньо простого лінійного скаляра.

Хоча рішення, яке я маю для накреслення контурів, тут більше, ніж вам потрібно (оскільки цей шейдер перетворює кожен край сітки в повний квадратик), він дотримується такого підходу: малювання оригінальної моделі до буфера трафарету, а потім надання більшої версії, де буфер трафарету все ще дорівнює 0.


Спасибі! Тому замість того, щоб спочатку намалювати видимі частини, я повинен почати з надання прозорих кіл у трафарет. Але як я візуалізую круглі прозорі кола? Я не можу обмежувати частини зображення, які мають бути відтворені в трафарет. Коли я видам трафарет, все йде там, я прав?
Doodlemeat

Так, тому другий прохід (видима частина) масштабується більше: тому його межі більше, ніж буфер трафарету. Вам просто потрібно застосувати вершину скалярів у другому проході (огляньтесь навколо контурних шейдерів, більшість із них використовують простіший скаляр, про який я маю на увазі). Також не можна змінювати буфер трафарету, якщо колір прозорий. У цьому випадку вам, мабуть, знадобиться друга текстурна маска, або ви можете зробити математику на відстані, щоб визначити коло. Мені потрібно пару годин і доступ до Unity, щоб надати будь-який код.
Draco18s більше не довіряє SE

Хм, а як бути з чорно-білим зображенням просто записати в буфер трафарету в першому проході, щоб чорний став 0, а білий став 1 в трафареті. Це навіть можливо?
Doodlemeat

Ось що я мав на увазі під маскою другої текстури. Я майже впевнений, що це спрацює, я просто не можу насправді перевірити, не маючи перед собою Єдність, якого я не матиму понад 24 години.
Draco18s більше не довіряє SE
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.