Розрив координати текстури з маппами створює шви


9

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

потворний шов http://cdn.imghack.se/images/6bbe0ad0173cac003cd5dddc94bd43c7.png

Тож я спробував вручну змінити градієнти за допомогою текстураGrad:

//fragVert is the original vertex from the vertex shader
vec2 ll = vec2((atan(fragVert.y, fragVert.x) / 3.1415926 + 1.0) * 0.5, (asin(fragVert.z) / 3.1415926 + 0.5));
vec2 ll2 = ll;
if (ll.x < 0.01 || ll.x > 0.99)
    ll2.x = .5;
vec4 surfaceColor = textureGrad(material.tex, ll, dFdx(ll2), dFdy(ll2));

Тепер я отримую два шви замість одного. Як я можу їх позбутися? І чому код вище породжує 2 шви?

2 eams http://cdn.imghack.se/images/44a38ef13cc2cdd801967c9223fdd2d3.png

Ви не можете розпізнати два зображення, але два шви є по обидва боки від початкового шва.


2
Чи є ваша сфера сіткою, чи ви аналізуєте сферу аналітично в шейдері чи подібні? Якщо це сітка, люди зазвичай вирішують це шляхом дублювання вершин уздовж шва, так що вершини на одній стороні можуть мати u = 0, а на іншій стороні u = 1.
Натан Рід

Що стосується того, чому ваш код генерує два шви, я думаю, це тому, що він створює два розриви - той, де u переходить від 0,01 до 0,5, і той, де u стрибає від 0,99 до 0,5. Це та сама проблема, як коли ви перестрибуєте від 0 до 1 - не настільки великий стрибок, але все-таки великий стрибок.
Натан Рід

У мене сітка для сфери. Це декаедр, тому вершини не вирівнюються до шва. Найцікавіше про два шви - це оригінальний шов пропав. Крім того, я отримую ті самі 2 шви, навіть якщо затискаю його до .01 або .99.
omikun

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

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

Відповіді:


4

Виходячи з опублікованого вами шейдерного коду, ви не інтерполюєте УФ-вершини з вершин - швидше здається, ви інтерполюєте 3D-положення ( fragVert), а потім обчислюєте УФ-сигнали, перетворюючи на сферичні координати.

Ваш аналіз правильний тим, що найменша мірна карта вибирається тоді, коли є розрив, оскільки вибір mipmap заснований на похідних, які оцінюються чисельно за УФ-випромінюваннями, що використовуються в сусідніх пікселях. Коли один піксель має u = 0, а інший u = 1, ви отримуєте дуже велику похідну. У вашій спробі виправлення виникає та сама проблема, що великі похідні трапляються приблизно u = 0,01 і u = 0,99, тому два шви з’являються з того боку, де був початковий шов.

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

Більш "правильним" підходом було б обчислення деяких похідних вищої якості. Замість використання dFdxта ультрафіолетових випромінювань dFdy, які мають розриви внаслідок atan2, ви можете застосувати dFdxта dFdyдо fragVert(який буде безперервним навколо усієї сфери), а потім скористайтесь деяким обчисленням (ланцюговим правилом), щоб знайти формулу для отримання похідних УФ від похідних позицій. Це буде складніше і повільніше, але має ту перевагу, що анізотропна фільтрація повинна працювати.

Нарешті, оскільки ви новачок у OpenGL, я лише зазначу, що обчислення УФ-спектрів за сферичними координатами є ідеально правильним способом текстурування сфери, більшість людей вибирає це не «звичайний» спосіб. Частіше побудувати сферичну сітку, яка має ультрафіолетові випромінювання, вказані на вершину, і просто передається від вершинного шейдера до піксельного шейдера (лінійно інтерпольованого через кожен трикутник). Вершини розміщують уздовж шва, як це , таким чином, що є дві копії кожної вершини, в абсолютно однакових положеннях, але половина з u = 0, з'єднана з трикутниками з одного боку, а інша половина з u = 1, з'єднана з трикутники з іншого боку. Це виключає будь-який видимий шов і не вимагає жодних хитрощів у піксельній шейдері.

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