[Цели] Мне нужно написать конкретный уровень mipmap CubeMap в OpenGL 4+. Каждый уровень mipmap является более грубым, чем глубже уровень.OpenGL Cubemap: Запись в mipmap
[Проблема] Проблема в том, что у меня одинаковое изображение по всем уровням mipmap, если я пишу только на уровне 0, и ничего вообще не пытаюсь писать только на другом уровне mipmap.
[Update] Я уверен, что проблема textureLod
всегда зажимают к основанию LOD 0. На каком бы уровне я стараюсь, чтобы получить через него мипмап, он возвращает базовый LOD.
Вот мое cubemap поколение (я пытаюсь иметь 6 мипмап уровней, считая основы):
GLuint PreFilteredEnvTex;
glGenTextures(1, &PreFilteredEnvTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, PreFilteredEnvTex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 5);
for (int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Utils::checkGlError("Generate PreFilteredEnvMap");
А вот пример моей попытке записи каждого уровня MIPMAP:
//Compute pre filtered environnement maps
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, fboManager["fx"]);
glViewport(0, 0, screenWidth, screenHeight);
glClear(GL_COLOR_BUFFER_BIT);
const int MIPMAPLEVELS = 6;
const int MIPMAPBASELEVELSIZE = 512;
int MipMapTextureSize;
glBindVertexArray(vaoManager["cube"]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture_id);
Shader* PreEnvFilter = shaderManager["PreEnvFilter"];
PreEnvFilter->use();
glm::vec3 EyePosition = glm::vec3(0.f);
// Light space matrices
glm::mat4 CubeMapProjection = glm::perspective(glm::radians(90.f), 1.f, 1.f, 100.f);
std::vector<glm::mat4> worldToLight;
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
for (GLuint i = 0; i < 6; ++i)
PreEnvFilter->SetMatrix4(("ViewMatrix[" + to_string(i) + "]").c_str(), worldToLight[i]);
PreEnvFilter->SetInt("EnvMapSampler", 0);
PreEnvFilter->SetMatrix4("Model", glm::mat4());
//For each faces compute all mipmaps levels
for (unsigned int j = 0; j < MIPMAPLEVELS; ++j)
{
//For each mipmap level, render the filtered environnement in it
MipMapTextureSize = std::max(1, MIPMAPBASELEVELSIZE/(1 << j));
glViewport(0, 0, MipMapTextureSize, MipMapTextureSize);
//glViewport(0, 0, MIPMAPBASELEVELSIZE, MIPMAPBASELEVELSIZE);
float roughness = (j + 0.5f)/MIPMAPLEVELS;
PreEnvFilter->SetFloat("Roughness", roughness);
//Bind to the current buffer
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, PreFilteredEnvTex, j);
glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, (void*)0);
}
PreEnvFilter->unuse();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
Utils::checkGlError("Initialize PreFilteredEnvMap");
Я уверен, что мой шейдер работает, потому что если я зацикливание на все уровни MIPMAP и рисунок только на базовом уровне, у меня есть хорошо выглядящий результат: The result if I'm only writing to level 0 for all mipmap levels
cubemap печатается со следующим фрагментом шейдера (TexCoords модифицируется в соответствии с лицом, я хочу нарисовать):
#version 430
uniform int MipMapLevel;
uniform samplerCube CubeMap;
in vec3 TexCoords;
out vec4 Color;
void main()
{
Color = textureLod(CubeMap, TexCoords, MipMapLevel);
}
И если я пишу на всех уровнях MIPMAP, у меня есть один и тот же образ на всех уровни MIPMAP (на самом деле, если я пишу только для уровня 0 у меня есть один и тот же результат на всех уровнях MIPMAP а)
Same result, different mipmap levels
Мой вывод, как следует:
- Моя генерация mipmap не очень хорошая, но я прочитал спецификации, и glGenerateMipmap должен был выполнить задание
- У меня проблема при попытке привязать уровень mipmap через glFramebufferTexture, но еще раз это не кажется неправильным me
- Мой шейдер, чтобы нарисовать куб-файл, не работает, как я думаю, он должен? Я никогда раньше не использовал textureLod, но, насколько я знаю, я использую его прямо здесь, верно?
Если кто-то уже сделал что-то подобное, я был бы очень признателен за помощь! После того, как все время я потратил на это, я до сих пор не в состоянии сделать эту простую вещь в OpenGL, когда я сделал это Whithout проблемы в DX11 :(
PS: OpenGL не сообщает о каких-либо ошибок
2 замечания: 1. Вы никогда не установите параметр шейдера 'MipMapLevel'. 2. Вы передаете константу «5» в качестве уровня glFrameBufferTexture вместо «j». – denniskb
Извините за 2. должен был быть отредактирован, я фактически передал j, я тестировал с 5, чтобы увидеть, что-то написано в mipmap уровне 5, и это не так. Для 1. Возможно, я был не очень ясен, но шейдер, о котором вы говорите, - это только шейдер, который создавал образы вопроса (так, только моя «отладочная ничья»). Шейдер, используемый в программе, сложнее, но, как я уже сказал, я на 100% уверен, что он работает. – Toffanim
ОК, я думаю, вам нужно [glFrameBufferTexture2D] (https://www.opengl.org/sdk/docs/man/html/glFramebufferTexture.xhtml), который позволяет вам указать лицо карты куба, на которое вы хотите обратить. Это означает, что у вас должно быть два вложенных цикла: для всех 6 лиц для всех уровней mipmap; в результате чего вызовы 6 * #mipmap_levels вызывают. – denniskb