Почему mipmapping не работает на моей 3D текстуре? (OpenGL)

Итак, я создаю ландшафт и для текстурирования я хочу использовать 3D-текстуру (глубина 3), которая содержит 3 изображения (512×512) на каждом z-слое, чтобы я мог использовать интерполяцию GPU между этими слоями на основе только один фактор: 0/3 = изображение 1, 1/3 = изображение 2, 2/3 = изображение 3, и каждое промежуточное значение интерполируется со следующим уровнем (циклически).

Это работает отлично, пока я не включаю MIP-карты для этой 3D-текстуры. Когда я включаю его, моя местность получает одно и то же изображение повсюду, если я не подойду ближе, как если бы изображения сместились с z-слоев на слои mip-map.

Я не понимаю этого, может кто-нибудь сказать мне, что я делаю не так?

Вот где я генерирую текстуру:

glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_3D, m_textureId);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 512, 512, 3, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);

Это шаг, который я выполняю для каждого Z:

glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, Z, 512, 512, 1, GL_BGR, GL_UNSIGNED_BYTE, imageData);

После этого я делаю:

glGenerateMipmap(GL_TEXTURE_3D);

В шейдере я определяю текстуру как:

uniform sampler3D tGround;

и просто сэмплируйте это с помощью:

texture(tGround, vec3(texcoord, f));

где texcoord — это 2D координата, а f — необходимый нам слой, просто основанный на высоте в данный момент.

0

Решение

Есть способ сделать что-то вроде того, что вы хотите, но это требует работы. И вы не можете использовать 3D текстуру, чтобы сделать это.

Вы должны использовать Array Textures вместо. Обычный способ представить текстуру 2D-массива — это набор 2D-текстур одинакового размера. Но вы также можете думать об этом как о 3D текстуре, где каждый уровень mipmap имеет одинаковое количество Z слоев. Тем не менее, есть также проблема, где есть нет смешивания между слоями массива.

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

vec4 ArrayTextureBlend(in vec3 texCoord)
{
float frac = fract(texCoord.z);
texCoord.z = floor(texCoord.z);
vec4 top = texture(arrayTex, texCoord);
vec4 bottom = texture(arrayTex, texCoord + vec3(0, 0, 1));
return mix(top, bottom, frac); //Linearly interpolate top and bottom.
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]