Текстура плитки в шейдере - PullRequest
5 голосов
/ 25 июня 2011

Я перехожу к вершинному шейдеру (glsl) 2 текстуры: с экрана и меньше, карта нормалей.Карта нормалей масштабируется по размеру экрана.Так что, если первая текстура 1152×864 пикселей, а normalmap - 256×256, она будет масштабирована от ее размера к большему.

Как мне сделать ее мозаичной?Например, сделайте его размером 256×256 и перетяните всю текстуру.


UPD :

Например, моя основная (большая) текстура отображается какэто:

[0.17, 0.61, 0.33, 0.83]

Вместо:

[0, 0, 1, 1]

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

1 Ответ

6 голосов
/ 25 июня 2011

он будет масштабирован от его размера к большему.

Нет, это точно не будет. Это распространенное заблуждение о текстурах. Текстуры - не что иное, как модные справочные таблицы. Текстуры не «масштабируются» относительно друг друга; это просто вопрос того, какие текстурные координаты вы используете.

По всей вероятности, вы используете ту же координату текстуры для текстуры экрана, что и ваша карта нормалей. Поскольку мы, вероятно, говорим о нормализованных текстурных координатах, это означает, что вы отображаете одинаковый диапазон [0, 1] для них обоих.

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

Есть несколько способов сделать это. Ручной способ состоит в том, чтобы вычислить соотношение размеров текстур друг к другу на процессоре, а затем передать его шейдеру. Используя числа, которые вы дали, соотношение размеров будет:

(1152.0/256.0, 864.0/256.0) = (4.5, 3.375).

Убедитесь, что это сделано в математике с плавающей точкой. Сделав это, просто передайте это в форме и умножьте координаты текстуры на это соотношение в шейдере перед выборкой:

uniform vec2 textureRatio;

void main() {
//Get the texture coordinate.
vec4 screenTexColor = texture(screenTex, texCoord);
vec2 normTexCoord = textureRatio * texCoord;
vec4 normalValue = texture(normalTex, normTexCoord);
//Do something with these.
}

Автоматический способ в GLSL - сделать это прямо в шейдере. Это требует GLSL 1,30 или выше. В основном вы используете доступные функции языка для вычисления отношения:

void main() {
//Get the texture coordinate.
vec2 textureRatio = textureSize(screenTex) / textureSize(normalTex);
vec4 screenTexColor = texture(screenTex, texCoord);
vec2 normTexCoord = textureRatio * texCoord;
vec4 normalValue = texture(normalTex, normTexCoord);
//Do something with these.
}

В обоих этих случаях я предполагаю, что для GL_TEXTURE_WRAP_S / T установлено значение GL_REPEAT с соответствующими параметрами текстуры или сэмплера.

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

...