Итак, я создаю ландшафт и для текстурирования я хочу использовать 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 — необходимый нам слой, просто основанный на высоте в данный момент.
Есть способ сделать что-то вроде того, что вы хотите, но это требует работы. И вы не можете использовать 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.
}
Других решений пока нет …