[目標]我需要在OpenGL 4+中寫入CubeMap特定的mipmap級別。每個mipmap級別都會讓級別更深。OpenGL Cubemap:寫入mipmap
[問題]問題是,如果我只在0級寫入,則所有mipmap級別的圖像都是相同的,如果我只寫入其他mipmap級別,則什麼也不做。
[更新]我很肯定問題是textureLod
總是夾在底層的LOD 0.無論我嘗試通過它的mipmap級別,它都會返回基本的LOD。
這裏是我的立方體貼圖代(我想有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");
在這裏,我試圖寫入每個紋理映射層級的例子:
//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");
我敢肯定,我的渲染工作,因爲如果我遍歷所有紋理映射層級,只畫到基礎水平我有一個漂亮的結果: 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水平,我對所有相同的圖像紋理映射層級(其實如果我只寫爲0級我對所有紋理映射層級相同的結果也一樣)
Same result, different mipmap levels
我的結論是如下:
- 我的mipmap生成不好,但我已經閱讀了specs,glGenerateMipmap應該已經完成了這個工作
- 我在嘗試通過glFramebufferTexture綁定mipmap級別時遇到了問題,但它再次出現錯誤我
- 我的着色器繪製立方體貼圖不工作,因爲我認爲它應該?我從來沒有使用過textureLod,但據我所知,我在這裏使用它,對吧?
如果有人已經做了類似的事情,我會非常感謝一些幫助!所有我在上面花的時間後,我還是沒能在內部消除DX11 :(
PS問題,做這個簡單的事情在OpenGL中,當我做到了:OpenGL的沒有報告任何錯誤
2意見:1.您從未設置着色器參數'MipMapLevel'。 2.你傳遞一個常量'5'作爲level到glFrameBufferTexture而不是'j'。 – denniskb
對不起,應該已被編輯,我實際上傳遞j,我正在測試5,看看是否有東西寫在mipmap級別5,它不。對於1,也許我不是很清楚,但你所指的着色器只是產生問題圖像的着色器(所以,只有我的「調試繪製」)。程序中使用的着色器更復雜,但正如我所說的,我100%肯定它的工作原理。 – Toffanim
好的,我想你需要[glFrameBufferTexture2D](https://www.opengl.org/sdk/docs/man/html/glFramebufferTexture.xhtml),它允許你指定你要繪製的立方體貼圖面。這意味着你應該有兩個嵌套循環:對於所有6個面,對於所有mipmap級別;導致6 * #mipmap_levels繪製調用。 – denniskb