Реализация сглаживания (FSAA?) На Android, OpenGL - PullRequest
2 голосов
/ 09 ноября 2011

В настоящее время я использую OpenGL на Android для рисования линий с заданной шириной, что прекрасно работает, за исключением того факта, что OpenGL на Android изначально не поддерживает сглаживание таких линий.Я провел некоторые исследования, однако я застрял в том, как реализовать свой собственный AA.

FSAA

Первое возможное решение, которое я нашел, - это Full Screen Anti-Искажения.Я прочитал эту страницу на эту тему, но я пытаюсь понять, как я мог это реализовать.

  • Прежде всего, я не уверен во всей концепции реализации FSAA здесь.В статье говорится «Одним простым методом дрожания является изменение матрицы проекции с добавлением небольших переводов в x и y» .Означает ли это, что мне нужно очень быстро постоянно перемещать одну и ту же линию или рисовать одну и ту же линию несколько раз?
  • Во-вторых, в статье говорится: "Чтобы вычислить смещение джиттера в пикселях, разделитевеличина джиттера на размерность координатной сцены объекта, затем умножьте на соответствующий размер области просмотра ".В чем разница между размером сцены координат объекта и размером области просмотра?(Я использую разрешение 800 x 480)

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

float currentX = 50;
float currentY = 75;

// I'm assuming the "jitter" amount is essentially
// the amount of anti-aliasing (e.g 2x, 4x and so on)
int jitterAmount = 2;

// don't know what these two are
int coordSceneDimensionX;
int coordSceneDimensionY;

// I assume screen size
int viewportX = 800;
int viewportY = 480;

float newX = (jitterAmount/coordSceneDimensionX)/viewportX;
float newY = (jitterAmount/coordSceneDimensionY)/viewportY;

// and then I don't know what to do with these new coordinates

Это так же, как у меня с FSAA

Anti-Алиасинг с текстурами

В том же документе, на который я ссылался для FSAA, есть также страница, в которой кратко обсуждается реализация сглаживания с использованием текстур.Тем не менее, я не знаю, каким будет лучший способ реализации AA таким образом и будет ли он более эффективным, чем FSAA.

Надеюсь, кто-то знает о сглаживании намного больше, чем я, и может помочь мне достичь этого.Очень ценится!

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Прежде всего, в статье, на которую вы ссылаетесь, используется буфер накопления, в существовании которого я действительно сомневаюсь в OpenGL ES, но я могу ошибаться здесь. Если буфер накопления действительно поддерживается в ES, то, по крайней мере, вам нужно явно запросить его при создании контекста GL (однако это делается в Android).

Обратите внимание, что этот метод крайне неэффективен и не рекомендуется к использованию, поскольку в настоящее время графические процессоры обычно поддерживают сглаживание мультисэмплинга (MSAA). Вам следует выяснить, поддерживает ли ваша система / графический процессор / драйвер мультисэмплинг. Это может потребовать, чтобы вы запросили мультисэмпловый кадровый буфер во время создания контекста или что-то подобное.

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

Итак, у вас есть набор позиций сэмплов (в [0,1]), которые на самом деле являются субпиксельными позициями. Это означает, что если у вас есть примерное положение (0,25, 0,75), вы перемещаете всю сцену примерно на четверть пикселя в направлении x и на 3 четверти пикселя в направлении y (конечно, в пространстве экрана) при рендеринге. Когда вы сделали это для каждого отдельного образца, вы усредняете все эти визуализации вместе, чтобы получить окончательный сглаженный рендеринг.

Размерность координатной сцены объекта - это, в основном, размер экрана (фактически, ближняя плоскость объема просмотра) в пространстве объекта, или, что более точно, значения, которые вы передали в glOrtho или glFrustum (или аналогичная функция, но с gluPerspective это не так очевидно). Для изменения матрицы проекции для реализации этого дрожания вы можете использовать функции, представленные в статье.

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

Вы также можете достичь этого без накопительного буфера, используя смешивание (с glBlendFunc(GL_CONSTANT_COLOR, GL_ONE) и glBlendColor(1.0f/n, 1.0f/n, 1.0f/n, 1.0f/n), с n, являющимся коэффициентом сглаживания / количеством выборок). Но имейте в виду, что вся сцена должна выглядеть так, а не только эта строка.

Но, как уже говорилось, этот метод полностью устарел, и вам лучше искать способ включить MSAA на вашей платформе ES.

2 голосов
/ 09 ноября 2011

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

В настоящее время вы запрашиваете сглаженный кадровый буфер.Вот и все.Ключевое слово здесь - мультисэмплинг.Посмотрите этот SO-ответ: Как активировать мультисэмплинг в OpenGL ES на iPhone? - хотя написано для iOS, для Android это происходит аналогичным образом.AFAIK На Android это расширение используется вместо http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt

...