Как сделать OpenGL MIPMAP более четким? - PullRequest
4 голосов
/ 13 мая 2011

Я переписываю основанную на opengl программу ГИС / картографирование. Помимо прочего, программа позволяет загружать растровые изображения морских карт, фиксировать их в координатах lon / lat, масштабировать и перемещаться по ним.

В предыдущей версии программы использовалась настраиваемая система листов, по сути, она вручную создавала мипмапы исходного изображения в виде плиток размером 256x256 пикселей с различными уровнями масштабирования с двумя степенями масштабирования. Ячейка для уровня масштабирования n - 1 состоит из четырех плиток от уровня масштабирования n с использованием простого алгоритма среднего из четырех точек. Таким образом, он отключает мипмаппирование OpenGL, и вместо этого, когда приходит время рисовать какую-то часть диаграммы при некотором уровне масштабирования, он использует плитки с уровнем масштабирования с ближайшим соответствием (т. Е. Плитки имеют степень увеличения 2). уровней, но программа допускает произвольные уровни масштабирования), а затем масштабирует плитки в соответствии с фактическим уровнем масштабирования. И, конечно, он должен управлять кешем всех этих тайлов на разных уровнях.

Мне показалось, что эта система листов была слишком сложной. Казалось, что я должен позволить графическому оборудованию выполнить всю эту работу по отображению. Поэтому в новой программе, когда я читаю изображение, я делю его на текстуры размером 1024x1024 пикселей каждая. Затем я фиксирую каждую текстуру в ее координатах lon / lat, а затем позволяю opengl обрабатывать все остальное при масштабировании и панорамировании.

Это работает, но проблема в том, что мои результаты немного размыты, чем в исходной программе, что важно для этого приложения, потому что вы хотите иметь возможность читать текст на графиках как можно раньше, с увеличением. Таким образом, похоже, что простой алгоритм среднего из четырех точек, который использует оригинальная программа, дает лучшие результаты, чем opengl + мой GPU, с точки зрения резкости.

Я знаю, что есть несколько настроек glTexParameter для управления некоторыми аспектами работы mipmaps. Я пробовал различные комбинации GL_TEXTURE_MAX_LEVEL (от 0 до 10) с различными настройками для GL_TEXTURE_MIN_FILTER. Когда я устанавливаю GL_TEXTURE_MAX_LEVEL в 0 (без mipmaps), я, конечно, получаю «резкие» результаты, но они слишком острые, в том смысле, что пиксели просто падают здесь и там, поэтому числа не читаются на промежуточном уровне масштабирование. Когда я устанавливаю для GL_TEXTURE_MAX_LEVEL более высокое значение, изображение выглядит довольно хорошо, когда вы увеличиваете масштаб (например, когда весь график умещается на экране), но при увеличении до промежуточного увеличения вы заметите размытость, особенно когда смотрите на текст на графиках. (То есть, если бы не текст, который вы могли бы подумать «вау, opengl хорошо справляется с плавным масштабированием моего изображения». Но с текстом вы думаете «почему эта диаграмма не в фокусе?»)

Насколько я понимаю, в основном вы говорите opengl генерировать мип-карты, а затем, когда вы увеличиваете его, выбираете подходящие мип-карты для использования, и есть некоторые ограниченные варианты для интерполяции между двумя ближайшими уровнями мип-карт и с использованием ближайших пикселей или усреднение ближайших пикселей. Однако, как я уже сказал, ни одна из этих комбинаций, по-видимому, не дает столь четких результатов при одном и том же уровне масштабирования на диаграмме (т. Е. Уровне масштабирования, когда текст небольшой, но не крошечный, как эквивалент «7 точек» или « 8 пунктов), как и предыдущая версия на основе плиток.

Мой вывод таков: мип-карты, которые создает opengl, просто более размытые, чем те, которые были созданы в предыдущей программе с помощью алгоритма усреднения по четырем точкам, и ни один выбор правильного мип-карты или LINEAR против NEAREST не даст резкости, которую я необходимо.

Конкретные вопросы :

(1) Представляется ли правильным, что opengl на самом деле создает размытые карты, чем алгоритм средних четырех точек из исходной программы?

(2) Есть ли что-то, что я мог упустить из виду при использовании glTexParameter, которое могло бы дать более четкие результаты при использовании mipmaps, которое делает opengl?

(3) Есть ли какой-нибудь способ заставить opengl создавать более резкие мипмапы, например, с помощью «кубического» фильтра или иным образом контролировать процесс создания мипмапа?Или в этом отношении кажется, что я мог бы использовать тот же самый код из четырех точек, чтобы вручную генерировать мип-карты и передавать их в opengl.Но я не знаю, как это сделать ...

Ответы [ 2 ]

10 голосов
/ 13 мая 2011

(1) это кажется маловероятным;Я ожидаю, что он просто использует фильтр коробки, который в среднем составляет четыре балла.Возможно, это просто переключение с одной текстуры на более высокое разрешение в другой момент - например, он «выбирает мип-карту, наиболее точно соответствующую размеру текстурируемого пикселя», поэтому карта 256x256 будет использоваться для текстурирования области 383x383, тогда какручная система, которую она заменяет, может всегда уменьшаться с 512x512 до тех пор, пока целевой размер не станет 256x256 или менее.

(2) не то, о чем я знаю в базовой GL, но если бы вы переключились на GLSL ипрограммируемый конвейер, тогда вы можете использовать параметр 'bias' для texture2D, если проблема в том, что карта с более низким разрешением используется, когда вы этого не хотите.Аналогично, расширение GL_EXT_texture_lod_bias может сделать то же самое в фиксированном конвейере.Это расширение NVidia, выпущенное десять лет назад, и это то, что могут делать все программируемые карты, поэтому вполне вероятно, что оно у вас будет.

(РЕДАКТИРОВАТЬ: более детальное чтение расширения, смещение текстуры перешло в основную спецификациюOpenGL в версии 1.4; очевидно, что мои справочные страницы очень устарели. Проверяя 1.4 spec , стр. 279, вы можете указать GL_TEXTURE_LOD_BIAS)

(3) yes - если вы отключите GL_GENERATE_MIPMAPзатем вы можете использовать glTexImage2D для предоставления любого изображения, которое вам нравится, для каждого уровня масштаба, то есть того, что предписывает параметр 'level'.Таким образом, вы можете предоставить совершенно не связанные карты MIP, если хотите.

1 голос
/ 21 октября 2011

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

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

...