2016-05-14 2 views
3

[Цели] Мне нужно написать конкретный уровень 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 не сообщает о каких-либо ошибок

+0

2 замечания: 1. Вы никогда не установите параметр шейдера 'MipMapLevel'. 2. Вы передаете константу «5» в качестве уровня glFrameBufferTexture вместо «j». – denniskb

+0

Извините за 2. должен был быть отредактирован, я фактически передал j, я тестировал с 5, чтобы увидеть, что-то написано в mipmap уровне 5, и это не так. Для 1. Возможно, я был не очень ясен, но шейдер, о котором вы говорите, - это только шейдер, который создавал образы вопроса (так, только моя «отладочная ничья»). Шейдер, используемый в программе, сложнее, но, как я уже сказал, я на 100% уверен, что он работает. – Toffanim

+0

ОК, я думаю, вам нужно [glFrameBufferTexture2D] (https://www.opengl.org/sdk/docs/man/html/glFramebufferTexture.xhtml), который позволяет вам указать лицо карты куба, на которое вы хотите обратить. Это означает, что у вас должно быть два вложенных цикла: для всех 6 лиц для всех уровней mipmap; в результате чего вызовы 6 * #mipmap_levels вызывают. – denniskb

ответ

0

После попытки почти все, что я, наконец, сделать это работает путем создания моего cubemap следующим образом:

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); 
} 
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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); 
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 

Я изменить мин фильтр GL_LINEAR_MIPMAP_LINEAR и вызвать glGenerateMipmap в конце концов, вместо того, чтобы делать, как в this link.

Благодарим Вас за интерес :)

Смежные вопросы