Острые углы со шрифтами со знаком поля расстояния

49

Подпись Расстояние Поле (СФД) , было представлено в качестве быстрого решения для достижения независимой отрисовки шрифтов разрешения от Valve в этой статье .

У меня уже работает решение Valve, но я бы хотел сохранить резкость по углам. Valve заявляет, что их метод может достичь острых углов, используя вторые каналы текстуры AND с базовым, но не объясняет, как будет создан этот второй канал.

На самом деле из этой статьи осталось много деталей реализации.

Я хотел бы знать, может ли кто-нибудь из вас указать мне направление для получения шрифтов SDF с четкими углами.

Фелипе Лира
источник
По сути Адам уже разместил исходный код на шадертой. Вот ссылка: shadertoy.com/view/ltXSDB
Фелипе Лира
Вы меня взволновали. Он делал посты безье на шадертой, но не на текстурном поле!
Алан Вулф
@AlanWolfe Я думаю, что он сделал только для процедурно установленных кривых Безье. Я не уверен в усилиях, необходимых для интеграции этого в библиотеку ttf render. Когда у меня будет время, я посмотрю на это.
Фелипе Лира
похоже, у него есть какой-то волшебный соус для хранения и извлечения расстояний из текстуры. Без текстуры в играх, примеры шейдерной пропускают эту часть уравнения.
Алан Вулф
Немного опоздал на вечеринку, но этот старый поток из reddit содержит массу информации о различных методах повышения резкости рендеринга на основе SDF: reddit.com/r/gamedev/comments/2879jd/…
Necrolis

Ответы:

7

Адам Симмонс проделал интересную работу в этой области. Я не знаю точно, как он этого добивается, но его векторное рендеринг на основе SDF является самым ярким, что я видел на практике вне Valve. http://twitter.com/adamjsimmons/status/611677036545863680

warrenm
источник
Конечно, у меня нет всех деталей, но мне кажется, что этот человек просто использовал поле псевдодальности вместо обычного, что уже было продемонстрировано в статье 2006 года Цинь, Маккулом и Капланом ". Векторные глифы с текстурным отображением в реальном времени », на которые также ссылаются в документе Valve. Он влияет только на очертания контуров и не улучшает внешний вид углов. Я подозреваю, что причина, по которой он выглядит четким, заключается в том, что он использует непрактично большие текстуры поля расстояния. Я могу ошибаться, хотя.
Detheroc
69

РЕДАКТИРОВАТЬ: Пожалуйста, посмотрите мой другой ответ с конкретным решением.

Я действительно решил эту проблему более года назад для моей магистерской диссертации. В документе Valve они показывают, что вы можете И два поля расстояния для достижения этого, что работает, пока у вас есть только один выпуклый угол. Для вогнутых углов вам также понадобится операция ИЛИ. Этот парень на самом деле разработал какую-то непонятную систему для переключения между двумя операциями, используя четыре текстурных канала.

Однако есть намного более простая операция, которая может облегчить И и ИЛИ в зависимости от ситуации, и это главная идея моего тезиса: медиана трех . Таким образом, в основном вы используете ровно три канала (идеально для RGB), которые полностью взаимозаменяемы, и объединяете их, используя медианную операцию (выберите среднее значение из трех).

Чтобы приспособиться к сглаживанию, мы работаем не только с логическими значениями, а со значениями с плавающей запятой, и операция И становится минимальной, а ИЛИ становится максимальной двух значений. Медиана трех может действительно сделать и то и другое: если a < b , для ( a , a , b ) медиана является минимумом, а для ( a , b , b ) это максимум.

Процесс рендеринга все еще чрезвычайно прост. Весь фрагментный шейдер, включая сглаживание, может выглядеть примерно так:

int main() {
    // Bilinear sampling of the distance field
    vec3 s = texture2D(sdf, p).rgb;
    // Acquire the signed distance
    float d = median(s.r, s.g, s.b) - 0.5;
    // Weight between inside and outside (anti-aliasing)
    float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
    // Combining the background and foreground color
    gl_FragColor = mix(outsideColor, insideColor, w);
}

Таким образом, единственное отличие от оригинального метода - вычисление медианы сразу после выборки текстуры. Вы должны будете реализовать функцию медианы, которая может быть сделана всего за 4 минуты / макс .

Теперь, конечно, вопрос в том, как мне построить такое трехканальное поле расстояния?И это сложная часть. Самый очевидный подход, который я использовал в начале, состоял в том, чтобы выполнить разложение входной фигуры / глифа на три компонента, а затем сгенерировать обычное поле расстояния из каждого. Правила для этого разложения не так сложны. Во-первых, область с как минимум 2 из 3 каналов находится внутри. Затем, если вы представляете это как цветовые каналы RGB, выпуклые углы должны быть сделаны из вторичного цвета, и его два основных компонента продолжаются наружу. Вогнутые углы являются обратными: два вторичных цвета заключают в себе свой основной основной цвет, а клин между тем, где оба края продолжаются внутрь, является белым. Я также обнаружил, что некоторые отступы необходимы там, где два основных или два вторичных цвета в противном случае соприкасались бы, чтобы избежать артефактов (например, в середине штриха "N").

Следующее изображение является примером декомпозиции, сгенерированной программой из моей диссертации:

Многоканальное разложение глифов

Этот подход, однако, имеет некоторые недостатки. Одним из них является то, что специальные эффекты, такие как контуры и тени, больше не будут работать правильно. К счастью, я также придумал второй, гораздо более элегантный метод, который напрямую генерирует поля расстояний и даже поддерживает все графические эффекты. Это также включено в мою диссертацию и так же старше года. Я не буду сейчас вдаваться в подробности, потому что сейчас я пишу статью, в которой подробно описывается этот второй метод, но я опубликую его здесь, как только он будет закончен.

Во всяком случае, вот пример разницы в качестве. Разрешение текстуры одинаково на каждом изображении, но в левом используется обычная текстура, в среднем - обычное поле расстояния, а в правом - мое трехканальное поле расстояния. Снижение производительности - это только разница между дискретизацией текстуры RGB и монохромной.

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

Detheroc
источник
5
Отличный первый ответ, добро пожаловать в компьютерную графику SE! :) Ваш тезис общедоступен? (Или это будет после того, как вы закончили указанную статью?) Если так, то, вероятно, было бы очень полезно также сослаться на это.
Мартин Эндер
Предполагается, что он будет общедоступным, но, похоже, школа еще не выставила его. В любом случае, я бы предпочел не распространять это прямо сейчас, так как статья, которую я пишу, действительно лучше объяснит важные части и сосредоточится на том, как ее реализовать, и она должна быть завершена очень скоро.
Detheroc
@Detheroc Пожалуйста, сообщите здесь и на gamedev Q, когда вы закончите со статьей. Объяснение для меня все еще не ясно на 100%. Я бы предложил показывать композицию шаг за шагом в изображениях.
Инженер
1
хотел бы иметь возможность копировать ваши текущие результаты, даже если они не так хороши, как ваши будущие результаты, +1 к тому, чтобы поделиться любыми подробностями, которые вы можете. очень волнующе. Рассматривали ли вы применение какой-либо техники для лучевого марширования (отслеживание сферы)? В объеме текстуры или аналогичные ...
Алан Вулф
4
Тезис доступен для общественности здесь: dspace.cvut.cz/bitstream/handle/10467/62770/…
Romain Guy
43

Извините за долгое ожидание, но стало очевидно, что, хотя обещанная мною статья в основном завершена, процесс публикации займет некоторое время. Поэтому я вместо этого подготовил программу с открытым исходным кодом с моим новым многоканальным алгоритмом построения поля расстояния, msdfgen , который вы можете попробовать прямо сейчас.

Он доступен на GitHub: https://github.com/Chlumsky/msdfgen

(Я новичок в этом, поэтому, пожалуйста, дайте мне знать, если что-то не так с хранилищем.)

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

Многоканальное поле расстояния 16x16 Монохромное дистанционное поле 32x32

Detheroc
источник
3

Довольно интересно! Я являюсь автором клапана с подписанной дистанционной бумагой. Извините, что это немного мало на деталях реализации. Я включил только двухканальный пример в качестве будущей работы - у меня не было генератора. Я подумал что-то вроде генерации sdf с высоким разрешением, а затем сегментирование на основе угла наклона sdf будет разумной тактикой. Но так и не добрался до этого. Любая многоканальная схема должна быть сопоставлена ​​с использованием одноканальных данных с высоким разрешением и одной и той же занимаемой памяти, для коэффициентов увеличения, необходимых вашему приложению.

Крис Грин
источник
0

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

В качестве альтернативы, если вы не возражаете против использования второго канала, вы также можете попробовать использовать один канал для горизонтального расстояния и другой для вертикального расстояния и использовать пирамиду разности лапласовых (DoL) энергий для сжатия текстуры, чтобы избыточная информация не не будет записано.

Третьим и последним теоретическим решением было бы поэкспериментировать с текстурой с шестигранной выборкой с помощью адресации массива.

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

Amaroq Starwind
источник