Имеется triangle strip в 2d. На самом деле это quad strip, если чем-то поможет. Можно представить его как шлейф, например, или просто текстурированная извивающаяся полоска. Требуется его красиво оттекстурировать. Под "красиво" я понимаю отсутствие изломов на uv. Если использовать обычную линейную интерполяцию для uv-координат, то на изгибах получается то, что слева:

Отмечаю, что перспективная интерполяция через однородные координаты (вроде http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/) не подходит, так как мне нужна линейность вдоль каждой из сторон квада.
Очень похожая тема здесь: https://stackoverflow.com/questions/10839998/linear-nonlinear-tex… istorted-quad
Иллюстрация оттуда:
именно то, что мне нужно. Но ответа в той теме нет. Как такое можно сгенерить эффективно в шейдере?
Я когда-то эту задачу решал через билинейную интерполяцию. То есть если найти такие коэффициенты uv преобразования для вершин вида lerp(lerp(a, b, u), (c, d, u), v) = p, то они и будут ответом. Но это — квадратное уравнение и я всё ещё не помню, как выбирал нужный корень. Да и мороки много, может, как-то можно проще?
Недавно делал подобное:
С трапециями решается соотношением оснований на которое множишь и делишь текстурные координаты в vs/ps (передавать доп. коэффициент в uv вершин). Для общего случая придётся lerp'ами вычислять реальную UV (для каждой вершины тащить 3 смежные, жир)
http://iquilezles.org/www/articles/ibilinear/ibilinear.htm
http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/
http://www.reedbeta.com/blog/quadrilateral-interpolation-part-2/
https://github.com/pixijs/pixi.js/issues/4168
Suslik
Если замутишь адекватный "общий метод" - выложи плз сюда.
Пока самое простое что я нашел - это передавать целиком трапецию в фрагментный шейдер.
upd. Собственно xproger выше привел ссылки, которые я имел ввиду.
XProger
> Недавно делал подобное:
отмечу, что в 3д корректным решением будет обыкновенное перспективно-корректное текстурирование через однородные координаты. то есть линейно интерполируем величины uv/z и 1/z. далее во фрагментном шейдере просто делим первое на второе, получаем перспективно-корректное uv. мне же нужно именно то, что, судя по всему, называется inverse bilinear interpolation (спасибо за кейворд).
Suslik
> что в 3д корректным решением будет обыкновенное перспективно-корректное
> текстурирование через однородные координаты
Не, у него как раз случай, что там квады, а не перспективные искажения. Ларка писалась для железа, которое умело в хардварный рендер квадов.
окей. что если подойди к задаче немного с другой стороны? априори известно, что мой меш — это полоска. то есть теоретически её можно текстурировать не как множество независимых квадов, а как одно целое. каг?
Suslik
> то есть теоретически её можно текстурировать не как множество независимых
> квадов, а как одно целое. каг?
Допустим, а что это нам дает? Ну то есть какие ограничения возникают на топологию отдельного четырехугольника?
MrShoor
например, без ограничения общности можно считать, что каждый четырёхугольник — трапеция. как это эксплойтить максимально эффективно?
Suslik
> как это эксплойтить максимально эффективно?
Треугольник в четырехугольнике был бы правильно затекстурен, если бы четырехугольник был параллелограммом.
На рисунке черным нарисована наша трапеция. Представим, что мы рисуем нижний правый треугольник. Все бы хорошо смотрелось, если бы второй треугольник образовывал бы с нашим параллелограмм (дорисовано красным), но это не так. А значит, что текстурные координаты вверху надо домножить на некоторый K, чтобы они образовывали трапецию.
Пусть верхнее основение трапеции d1, а нижнее d2. Для нашего треугольника мы должны домножить текстурыные координаты вверху на K=d1/d2.
Для второго треугольника у нас другая картина:
И домножать нижние координаты надо уже на K=d2/d1
upd. Ах, да, ну и не забывать еще про смещение. Если текстурные координаты идут слева направо от 0 до 1, но после умножения их надо смещать
1. Для верхнего треугольника на 1-d1/d2
2. Для нижнего - на 0
Suslik
> нужна линейность вдоль каждой из сторон квада
А плавное искривление линий внутри полигона допустимо? Иначе дальше трапеций не уйти.
Был не прав, уйти. Но всё равно, вопрос в силе.
Mikle
да, конечно. какие-то линии в итоге в любом случае перестанут быть линейными, это нормально.
Во имя чёткости рассуждений.
Об инверсной билинейной интерполяции.
Есть 4 точки A, B, C, D (произвольные точки в ). Мы понимаем их как вершины 4-угольника ABDC.
Он может быть выпуклым, вырожденным, вогнутым, самопересекающимся.
Есть функция билинейной интерполяции:
Укажем некоторые её свойства:
1. ABDC принадлежит образу [0;1]x[0x1]: . Для выпуклого или вырожденного 4-угольника
, для вогнутого или самопересекающегося - могут (для вогнутого - гарантировано) существовать (u,v), образ которых лежит за пределами ABDC.
2. Функция линейна тогда и только тогда, когда . Для выпуклого 4-угольника это справедливо тогда и только тогда, когда ABDC - параллелограмм. Для вогнутого и самопересекающегося - не выполняется никогда.
3. Для линейного случая и невырожденного ABDC обратная функция - существует и единственна (уравнение имеет единственное решение); она также является линейной. Для вырожденного - решений может быть 0 или ∞.
4. Для нелинейного случая и невырожденного ABDC уравнение имеет либо 0 решений, либо 2, либо 1 (на границе между областями с 0 и 2 решениями; в сущности 2 решения совпадают).
5. Для выпуклого ABDC функция f обратима на [0;1]x[0;1], т. е. ровно 1 из решений уравнения лежит в [0;1]x[0;1].
Вроде так:
FordPerfect
ты это реально в техе на codecogs написал? наркоман :D
я так и не понял, почему тот парень называл cross product wedge product'ом. основной вопрос тут, как мне кажется, в том, как минимизироват объём дополнительной информации, передаваемой в вершинный шейдер. потому что решение с передачей для каждой вершины всех её соседей, считается не самым красивым.
Suslik
> потому что решение с передачей для каждой вершины всех её соседей, считается не
> самым красивым.
Для трапеции нужно всего лишь отношение оснований передать, и флаг оффсета. Т.е. это два поля в нагрузку. А флаг можно не передавать, если сдеалать wrap для текстуры и отрицательные текстурные координаты. И тогда остается вообще один флоат.
Тема в архиве.