简体   繁体   English

OpenGL Cubemap:写入mipmap

[英]OpenGL Cubemap : Writing to mipmap

[Objectives] I need to write to a CubeMap's specific mipmap level in OpenGL 4+. [目标]我需要在OpenGL 4+中写入CubeMap的特定mipmap级别。 Each mipmap levels is blurrier the deeper the level is. 每个mipmap级别在级别越深时越模糊。

[Problem] The problem is that I have the same image over all mipmap levels if I write only on level 0, and nothing at all if I try to write only on other mipmap level. [问题]问题是如果我只在0级写入,我在所有mipmap级别上都有相同的图像,如果我只尝试在其他mipmap级别上写入,则什么都没有。

[Update] I'm pretty sure the problem is textureLod always clamp to the base LOD 0. Whatever mipmap level I try to get through it, it returns the base LOD. [更新]我很确定问题是textureLod总是钳位到基本LOD 0.无论mipmap级别我试图通过它,它返回基本LOD。

Here is my cubemap generation (I'm trying to have 6 mipmap levels, counting the base): 这是我的立方体贴图生成(我试图有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");

And here an example of my attempt to write to each mipmap levels : 这里是我尝试写入每个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");

I'm sure my shader is working, because if I'm looping over all mipmap levels and drawing only to the base level I have a good looking result : The result if I'm only writing to level 0 for all mipmap levels 我确定我的着色器正在工作,因为如果我循环遍历所有mipmap级别并仅绘制到基本级别,我会得到一个好看的结果: 结果如果我只是为所有mipmap级别写入0级

The cubemap is printed with the following fragment shader (TexCoords is modified according to the face I want to draw) : 立方体贴图使用以下片段着色器打印(TexCoords根据我想要绘制的面部进行修改):

#version 430

uniform int MipMapLevel;
uniform samplerCube CubeMap;
in vec3 TexCoords;
out vec4 Color;

void main()
{
    Color = textureLod(CubeMap, TexCoords, MipMapLevel);
}

And if I'm writing to all mipmap levels, I have the same image on all mipmap levels (actually if I write only to level 0 I have the same result on all mipmap levels as well ) 如果我写入所有mipmap级别,我在所有mipmap级别上都有相同的图像(实际上,如果我只写入级别0,我在所有mipmap级别上也有相同的结果)

Same result, different mipmap levels 相同的结果,不同的mipmap级别

My conclusion is as followed : 我的结论如下:

  • My mipmap generation is not good, but I've read the specs and glGenerateMipmap should have done the job 我的mipmap生成并不好,但我已经阅读了规范并且glGenerateMipmap应该已经完成​​了这项工作
  • I have a problem when trying to bind the mipmap level throught glFramebufferTexture, but once again it doesn't seems wrong to me 尝试通过glFramebufferTexture绑定mipmap级别时遇到问题,但是我再一次看起来没有错
  • My shader to draw the cubemap is not working as I think it should ? 我绘制立方体贴图的着色器不起作用,因为我认为应该如此? I've never used textureLod before, but as far as I know, I am using it right here, right ? 我之前从未使用过textureLod,但据我所知,我正在使用它,对吧?

If someone as already done something similar, I would really appreciate some help ! 如果有人已经做过类似的事情,我真的很感激一些帮助! After all the time I spent on it, I'm still not able to do this simple thing in OpenGL when I did it whithout problems in DX11 :( 在我花了所有时间之后,当我在DX11中没有出现问题时,我仍然无法在OpenGL中做这个简单的事情:(

PS : OpenGL does not report any errors PS:OpenGL不会报告任何错误

After trying almost everything, I've finally make it works by generating my cubemap as follow : 在尝试了几乎所有的东西后,我终于通过生成我的立方体贴图使其工作如下:

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

I've change the min filter to GL_LINEAR_MIPMAP_LINEAR and call glGenerateMipmap at the end, instead of doing like in this link . 我已将min过滤器更改为GL_LINEAR_MIPMAP_LINEAR并在最后调用glGenerateMipmap ,而不是在此链接中执行此操作

Thanks for your interest :) 谢谢你的关注 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM