Войти
ПроектыФорумУтилиты

[v 1.1] UBFG - Генератор растровых шрифтов (29 стр)

Advanced: Тема повышенной сложности или важная.

Страницы: 128 29 30 3135 Следующая »
#420
18:31, 3 апр. 2014

Метод SDF прекрасно расширяется и на три измерения, раньше использовался в демосцене, сейчас демосценеры прекрасно адаптировали его к шейдерам. Экспертом в этом вопросе является Иньихо Килес:
iquilezles.org/www/index.htm

Если находить контур (outline) просто задиранием контрастности то, там где контуры проходят очень близко, могут вылезти заплывы; Иньихо предлагает другое решение, для обхода этой проблемы:
iquilezles.org/www/articles/distance/distance.htm

Изображение Изображение


#421
19:28, 3 апр. 2014

aczkasow
> Иньихо предлагает другое решение, для обхода этой проблемы:
Если я правильно понял статью автора, предлагается делать 4 дополнительные субвыборки. Это в пять раз больше операций чтения из текстуры - может быть медленно на старых видеокартах и в условиях ретины. Хотя мне кажется, данный метод можно применить не внутри шейдера, а внутри генератора SDF, так как в конце концов там всё равно тупо вытягивается контрастность от рассчитанного градиента - значит этот градиент можно рассчитать заранее (возможно это как раз уже реализовано в алгоритме от susageP). Надеюсь, опытные шейдерописатели смогут протестировать как производительность, так и эффективность метода. Тогда это фактически серебряная пуля текущих реализаций шрифтовых рендеров на OpenGL:)

#422
20:03, 3 апр. 2014

Результат хорош:
Изображение

Суть в более равномерном антиалиасинге.

#423
20:29, 3 апр. 2014

там не коректная карта расстояний
Изображение
видно по центру.

Да и сама карта расстояний говорит что на сдвиг x расстояние изменится на const*x.

RPG
> Результат хорош:
Если пантерка в векторе, то сделай карту расстояний в масштабе 16, и потом уменьш в 16 раз.

Во сколько раз отмаштобированна пантерка в твоем примере(относительно карты расстояний)?

#424
20:49, 3 апр. 2014

susageP
> Во сколько раз отмаштобированна пантерка в твоем примере(относительно карты
> расстояний)?
Исходник намного больше - где-то 1600 пикселей, то есть раз в 10.

Я сейчас провёл ещё один эксперимент, как выясняется, при уменьшении масштаба (я все эксперименты через ImageMagick гоняю) имеет значение, какой фильтр выбрать. То есть если взять фильтр Jinc для даунсемплинга, финальный результат уже меньше подвержен размазыванию.

susageP
> там не коректная карта расстояний
Да там вообще не SDF для векторного контура, но этот метод применим для коррекции градиента, чтобы убрать негативный эффект пикселизации. Чуть допилить шейдр и можно улучшить равномерность антиалиасинга.

#425
17:13, 4 апр. 2014

>Если я правильно понял статью автора, предлагается делать 4 дополнительные субвыборки. Это в пять раз больше операций чтения из текстуры - может быть медленно на старых видеокартах и в условиях ретины.

Для ускорения можно воспользоваться грязным трюком (который позволяет сделать конвеер видеокарты) при расчёте градиента, и заменить:

vec2 grad( in vec2 x )
{
    vec2 h = vec2( 0.01, 0.0 );
    return vec2( f(p+h.xy) - f(p-h.xy),
                 f(p+h.yx) - f(p-h.yx) )/(2.0*h.x);
}

на

vec2 grad( in vec2 x )
{
  float o = f(x);
  return vec2( dFdx(o), dFdy(o) )/(2.0*h.x);
}

(Надеюсь не глупость написал).

С высокой вероятностью могут вылезти квадратные артефакты связанные с тем что dFdx() и dFdy() расчитываются единожды для квадрата 4х4 текселя (если я не ошибаюсь). Возможно получится обойти артефакты грамотно расставив буквы внутри решётки 4х4... возможно и не получится :)

В HLSL вроде есть два варианта dFdx()  - ddx_fine() и ddx_coarse(). Возможно fine не даст артефактов.

#426
21:07, 4 апр. 2014

aczkasow
> С высокой вероятностью могут вылезти квадратные артефакты связанные с тем что
> dFdx() и dFdy() расчитываются единожды для квадрата 4х4 текселя (если я не
> ошибаюсь). Возможно получится обойти артефакты грамотно расставив буквы внутри
> решётки 4х4... возможно и не получится :)
Да, на адском масштабе вылезают (контрастность намеренно уменьшена):
Screenshot - 04.04.2014 - 20:45:45 | [v 1.1] UBFG - Генератор растровых шрифтов
Однако! Я написал шейдр (в своём движке, Kick.js выкинул нафиг, ибо глючная поделка и текстурные координаты через одно место):

#version 120
uniform sampler2D texture;
uniform float sharpness;
uniform float gamma;
varying vec2 TexCoord;

float f(vec2 x)
{
  return 0.5 - texture2D(texture, x);
}

vec2 grad2(vec2 p)
{
  return vec2(dFdx(f(p)), dFdy(f(p)));
}

void main() {
  vec2 p = TexCoord;
  float v = f(p);
  vec2  g = grad2(p);
  float c = (v)/length(g);
  float res = c;
  gl_FragColor = vec4(vec3(1.), res);
}

У меня нормальные локальные текстурные координаты в прострастве текстуры, то есть 1.0 - это один тексель. В браузерных shader-toy любят координаты простраства экрана из-за чего приходится делать поправки на размер окошка и т. п. - не удобно.

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

Вот результаты:

1 | [v 1.1] UBFG - Генератор растровых шрифтов
2 | [v 1.1] UBFG - Генератор растровых шрифтов
3 | [v 1.1] UBFG - Генератор растровых шрифтов

З.Ы. от размытости карты шейдр тоже как выяснилось не зависит. Интересно.

#427
21:25, 4 апр. 2014

Фигура угловатая при сильном приближении. Бикубическая фильтрация должна дать идеально гладкую фигуру.

#428
21:30, 4 апр. 2014

gammaker
> Фигура угловатая при сильном приближении. Бикубическая фильтрация должна дать
> идеально гладкую фигуру.
Скорее всего будет нагрузка на фрагментный шейдр. Бикубическая фильтрация - это минимум 4 выборки из текстуры (а то и все 16) со всеми вытекающими. Учитывая, что метод больше ориентирован на мобильные устройства с их ретинами и довольно поредственными возможностями в плане шейдеринга - нужно применять осторожно. Мне кажется бикубический фильтр уменьшит резкие переходы: квадрат станет круглым, так что палка о двух концах. Лучше просто увеличить исходную карту, эта уж совсем маленькая - 70 пикселей в ширину. Сделал её для демонстрации, насколько сильно можно сжимать картинки при необходимости. В реальной жизни такое приближение практически не нужно: разница в 2-3 раза от силы.

#429
21:52, 4 апр. 2014

RPG
> Учитывая, что метод больше ориентирован на мобильные устройства
Почему? Он везде хорош. Даже шрифт с высотой 256 пикселей без SDF выглядит некрасиво, а с sdf достаточно высоты 20, и будет даже лучше выглядеть.

RPG
> Мне кажется бикубический фильтр уменьшит резкие переходы: квадрат станет
> круглым
Ну если он занимает пару пикселей в длину, то может быть. А так будут просто немного скруглённые углы.
Я рендерил плавный по свой природе шрифт, где размер одной буковки всего 16 пикселей в высоту во весь экран и получал идеально гладкий текст. А без бикубической фильтрации он получался очень угловатым.

RPG
> Бикубическая фильтрация - это минимум 4 выборки из текстуры (а то и все 16) со
> всеми вытекающими
Пробовал оба варианта, различий не заметил. Поэтому смело можно использовать 4 выборки, а это несильно отличается от твоего шейдера с 3 выборками.

#430
22:05, 4 апр. 2014

gammaker
> Почему? Он везде хорош. Даже шрифт с высотой 256 пикселей без SDF выглядит
> некрасиво, а с sdf достаточно высоты 20, и будет даже лучше выглядеть.
На десктопах мониторы имеют предсказуемое разрешение: была когда-то эпоха 800х600, на смену пришли 1024х768, потом 1280х1024, сейчас 1920х1080. И это лет за 10 - масштаб от силы вытянулся в два раза. Поэтому достаточно сделать шрифт, который вообще не масштабируется (Valve на эту тему вообще не парится, как использовали 8 pt так до сих пор и используют). Другое дело мобильники - разрешение может отличаться почти на порядок на двух устройствах.

gammaker
> Ну если он занимает пару пикселей в длину, то может быть. А так будут просто
> немного скруглённые углы.
Всё зависит от резкости этих углов, качества SDF. В шрифтах как раз нужны резкие углы - многие буквы кириллицы по своей природе угловатые.

gammaker
> Пробовал оба варианта, различий не заметил. Поэтому смело можно использовать 4
> выборки, а это несильно отличается от твоего шейдера с 3 выборками.
У меня шейдры все примитивные с одним чтением текстуры. Где там 3 выборки?

#431
22:10, 4 апр. 2014

RPG
> Да, на адском масштабе вылезают (контрастность намеренно уменьшена):
Будь очень осторожен с dFdx() и dFdy(). Если у тебя не лезут квадраты, не значит, что на других видеочипсетах не повылезают ;) На сколько я понимаю стандарт не определяет как именно его должны видео карты расчитывать.

#432
22:33, 4 апр. 2014

RPG
> Однако! Я написал шейдр

Можно сэкономить на двух вызовах f(), если расписать расчёт градиента в самой функции main():

void main() {
...
  float v = f(p);
  vec2  g = grad2(p);
...
}

заменив на

void main() {
...
  float v = f(p);
  vec2  g = vec2(dFdx(v), dFdy(v));
...
}
#433
22:36, 4 апр. 2014

RPG
> У меня шейдры все примитивные с одним чтением текстуры. Где там 3 выборки?
Одна в main, две в градиенте. Или то, что под производными, не вычисляется?

Кстати, с sdf можно сделать мелкий текст? А то у меня алиасинг появляется. А если отрисовывать контур, то он появляется даже, когда текст крупный.

#434
22:39, 4 апр. 2014

RPG
> На десктопах мониторы имеют предсказуемое разрешение: была когда-то эпоха
> 800х600, на смену пришли 1024х768, потом 1280х1024, сейчас 1920х1080.
Но если текст висит в 3d, то тут SDF рулит.

Страницы: 128 29 30 3135 Следующая »
ПроектыФорумУтилиты