Настройка текстурирования

Последнее обновление: 1.11.2015

Функция gl.texImage2D

Данный метод загружает текстуру в GPU (графический процессор на видеокарте). Он имеет следующий синтаксис: texImage2D(target, level, internalformat, format, type, elem)

  • target: указывает целевой объект для загрузки текстуры

  • level: уровень множественного отображения текстуры

  • internalformat и format: формат и внутренний формат. В WebGL должны иметь одно и то же значение. Так, формат gl.RGBA, к примеру, показывает, что для каждого текселя на текстуре должны быть установлены цветовые каналы для красного, зеленого и синего цветов, а также альфа-канал.

  • type: тип данных, которых сохраняет все данные текселей текстуры. Например, gl.UNSIGNED_BYTE указывает, что для каждого цветового канала в gl.RGBA для сохранения данных выделяется один байт.

  • elem: указывает на элемент, который содержит источник текстурирования. Это может быть элемент img или Image. Это также может быть элемент HTML5 video или canvas.

Все возможные сочетания форматов и типов:

Формат

Тип

gl.RGBA

gl.UNSIGNED_BYTE

gl.RGB

gl.UNSIGNED_BYTE

gl.RGBA

gl.UNSIGNED_SHORT_4_4_4_4

gl.RGBA

gl.UNSIGNED_SHORT_5_5_5_1

gl.RGB

gl.UNSIGNED_SHORT_5_6_5

gl.LUMINANCE_ALPHA

gl.UNSIGNED_BYTE

gl.LUMINANCE

gl.UNSIGNED_BYTE

gl.ALPHA

gl.UNSIGNED_BYTE

Я думаю, формат gl.RGBA понятен: каждый тексель текстуры имеет канал красного, зеленого и синего цветов, а также альфа-канал. Формат gl.RGB - то же самое, только без альфа-канала.

Формат gl.LUMINANCE_ALPHA имеет канал яркости и альфа-канал. И формат gl.LUMINANCE имеет только канал яркости, а формат gl.ALPHA - только альфа-канал.

Например, настройка gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE_ALPHA, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, image); даст следующий эффект:

Касательно типов тоже все просто. Тип gl.UNSIGNED_BYTE предоставляет по одному байту на каждый канал.

Тип gl.UNSIGNED_SHORT_4_4_4_4 предоставляет для каждого канала в формате RGBA по четыре байта.

Тип gl.UNSIGNED_SHORT_5_5_5_1 предоставляет для каждого каналов красного, зеленого и синего цветов в формате RGBA по пять байт, а для альфа-канала - один байт.

И тип gl.UNSIGNED_SHORT_5_6_5 предоставляет для каналов красного и синего цветов по пять байт и для зеленого цвета - шесть байт в формате RGB.

Определение параметров текстуры

Метод gl.texParameteri() позволяет определить параметры текстуры. Он имеет следующий формальный синтаксис: texParameteri(target, pname, param). Сочетания параметров бывают разными и могут влиять на используемые значения.

  • target: в зависимости от направления текстурирования может принимать значения gl.TEXTURE_2D, либо gl.TEXTURE_CUBE_MAP

  • pname: указывает на фильтр, который мы хотим установить. Может принимать следующие значения: gl.TEXTURE_MAG_FILTER, gl.TEXTURE_MIN_FILTER, gl.TEXTURE_WRAP_S и gl.TEXTURE_WRAP_T

  • param: предоставляет значение для фильтра pname. То есть в выражении gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); фильтру текстуры gl.TEXTURE_MAG_FILTER устанавливается значение gl.NEAREST.

    Значения, передаваемые параметром param, разнообразны и позволяют создавать определенные эффекты, которые далее мы подробно разберем.

Зачем вообще нужна настройка этих параметров? В реальности текстуры имею определенные размеры, например, 128х128. Однако поверхность объекта, на которую накладывается текстура, может иметь как большие, так и меньшие размеры. Использование фильтра gl.TEXTURE_MAG_FILTER фактически помогает определить рендеринг текстуры, если она меньше размера объекта, то ее надо увеличить.

И фильтр gl.TEXTURE_MIN_FILTER, наоборот, указывает, каким образом надо проводить рендеринг, если размеры поверхности объекта меньше размеров текстуры.

gl.NEAREST

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

Это значение может быть установлено как для фильтра gl.TEXTURE_MIN_FILTER, так и для фильтра gl.TEXTURE_MAG_FILTER.

gl.LINEAR

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

Это значение может быть установлено как для фильтра gl.TEXTURE_MIN_FILTER, так и для фильтра gl.TEXTURE_MAG_FILTER.

Сравнение двух фильтров

Mip-текстурирование

Концепция mip-текстурирования предполагает использование нескольких копий одной текстуры, но с разной детализацией. Это позволяет увеличивать качество отображения, например, при удалении от объекта.

Mip-текстурирование в WebGL использует ряд фильтров. Подобные фильтры могут использоваться только в качестве значения для фильтра gl.TEXTURE_MIN_FILTER:

  • gl.NEAREST_MIPMAP_NEAREST: фильтр использует одну копию текстуры, которая наиболее подходит под размеры текстуры на экране. Выборка семплером значений происходит по алгоритму NEAREST. Самый быстрый способ текстурирования, но при этом менее качественный

  • gl.LINEAR_MIPMAP_NEAREST: фильтр использует одну копию текстуры, которая наиболее подходит под размеры текстуры на экране. Выборка семплером значений происходит по алгоритму LINEAR

  • gl.NEAREST_MIPMAP_LINEAR: фильтр использует две копии текстуры, которые наиболее подходят под размеры текстуры на экране. Выборка семплером значений происходит по алгоритму NEAREST. Выборка цвета пикселя идет параллельно сразу из двух копий, а финальное значение цвета представляет средневзвешенное значение двух выборок

  • gl.LINEAR_MIPMAP_LINEAR: фильтр использует две копии текстуры, которые наиболее подходят под размеры текстуры на экране. Выборка семплером значений происходит по алгоритму LINEAR. Выборка цвета пикселя идет параллельно сразу из двух копий, а финальное значение цвета представляет средневзвешенное значение двух выборок. Наиболее медленный способ, но при этом дающий наибольшее качество

Само использование этих значений для фильтров еще предполагает, что у нас будет использоваться mip-текстурирование. Перед этим нам надо сгенерировать мипмапы, то есть копии текстуры, с помощью метода gl.generateMipmap(gl.TEXTURE_2D);. Этот метод должен вызываться после метода gl.texImage2D(). То есть, возьмем из ранее использованный примеров текстурирования функцию handleTextureLoaded и изменим ее так, чтобы использовались мипмапы:

function handleTextureLoaded(image, texture) {

	gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
	gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
}

Это даст нам следующий результат:

Надо отметить, что мип-текстурирование имеет некоторые ограничения: используемые изображения должны иметь размеры, которые равны степени двойки. Например, 16px, 32px, 64px, 128px и т.д. При этом необязательно, чтобы высота и ширина были равные, главное, чтобы их значения были равны степени двойки.

Texture wrapping

Еще один способ текстурирования называется texture wrapping. Этот термин можно перевести как обертывание текстурой. То есть данный способ определяет поведение семплера при отборе цветов пикселей с текстуры, если заданные координаты текстуры находятся вне диапазона [0.0, 1.0].

В данном случае нам потребуется установить значения для фильтров gl.TEXTURE_WRAP_S и gl.TEXTURE_WRAP_T, которые отвечают за рендеринг текстуры вдоль осей s и t.

Например, у нас определены следующие координаты текстуры в буфере координат текстуры:

// Координаты текстуры
var textureCoords = [
			0.0, 0.0,
			0.0, 2.0,
			2.0, 2.0,
			2.0, 0.0,
				
			0.0, 0.0,
			0.0, 2.0,
			2.0, 2.0,
			2.0, 0.0,
				
			0.0, 0.0,
			0.0, 2.0,
			2.0, 2.0,
			2.0, 0.0,
				
			0.0, 0.0,
			0.0, 2.0,
			2.0, 2.0,
			2.0, 0.0 
		];

А функция handleTextureLoaded выглядела бы следующим образом:

 function handleTextureLoaded(image, texture) {

	gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
	gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}

То мы можем получить следующий результат:

Для параметров мы можем использовать следующие значения:

  • gl.CLAMP_TO_EDGE: все координаты текстуры, которые больше 1 и меньше 0, сжимаются до диапазона [0, 1]

  • gl.REPEAT: происходит повторение текстуры после выхода вне диапазона [0, 1]

  • gl.MIRRORED_REPEAT: повторение текстуры с зеркальным отображением

Можно комбинировать данные значения, как в вышеприведенном примере, где одновременно используются gl.REPEAT и gl.CLAMP_TO_EDGE.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850