【问题标题】:OpenGL Cubemap : Writing to mipmapOpenGL Cubemap:写入 mipmap
【发布时间】:2016-05-14 21:32:05
【问题描述】:

[Objectives] 我需要在 OpenGL 4+ 中写入 CubeMap 的特定 mipmap 级别。级别越深,每个 mipmap 级别越模糊。

[问题]问题是,如果我只在级别 0 上写入,我在所有 mipmap 级别上都有相同的图像,而如果我尝试只在其他 mipmap 级别上写入,则什么都没有。

[更新]我很确定问题是 textureLod 总是钳制到基本 LOD 0。无论我尝试通过什么 mipmap 级别,它都会返回基本 LOD。

这是我的立方体贴图生成(我试图有 6 个 mipmap 级别,计算基数):

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

立方体贴图用以下片段着色器打印(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 应该可以完成这项工作
  • 我在尝试通过 glFramebufferTexture 绑定 mipmap 级别时遇到问题,但我再次认为这并没有错
  • 用于绘制立方体贴图的着色器无法正常工作?我以前从未使用过textureLod,但据我所知,我在这里使用它,对吧?

如果有人已经做过类似的事情,我真的很感激一些帮助!在我花了这么多时间之后,当我在 DX11 中没有问题的情况下,我仍然无法在 OpenGL 中做这个简单的事情:(

P.S : OpenGL 不报告任何错误

【问题讨论】:

  • 2 个观察结果: 1. 您从未设置着色器参数“MipMapLevel”。 2. 将常量“5”作为级别传递给 glFrameBufferTexture 而不是“j”。
  • 抱歉 2. 应该被编辑了,我实际上通过了 j,我正在用 5 进行测试,看看是否在 mipmap 级别 5 中写入了某些内容,但它没有。对于1.,也许我不是很清楚,但是您所指的着色器只是产生问题图像的着色器(所以,只有我的“调试绘图”)。程序中使用的着色器更复杂,但正如我所说,我 100% 确定它可以工作。
  • 好的,我想你需要glFrameBufferTexture2D,它允许你指定你想要绘制的立方体贴图面。这意味着您应该有两个嵌套循环:对于所有 6 个面,对于所有 mipmap 级别;导致 6 * #mipmap_levels 绘制调用。
  • 实际上我正在使用几何着色器一次渲染所有面(这就是为什么我有 6 个视图矩阵并渲染一个单位立方体)。我可以尝试渲染到一张面 mipmap 并查看它是否有效,但我认为这只是 mipmap 的问题,而不是渲染到立方体贴图的问题(因为您可以在图片上看到,如果我只使用它,它实际上正在工作mipmap 的基本级别)。
  • "我在所有 mipmap 级别上都有相同的图像" “相同的图像”是什么意思?您不能拥有相同的图像; mipmap 更小,因此不一样。

标签: c++ opengl


【解决方案1】:

在尝试了几乎所有方法之后,我终于通过如下生成我的立方体贴图使其工作:

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);

我已将 min 过滤器更改为 GL_LINEAR_MIPMAP_LINEAR 并在最后调用 glGenerateMipmap,而不是像 this link 那样做。

感谢您的关注:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 2011-12-25
    • 2012-12-29
    相关资源
    最近更新 更多