2016-05-14 143 views
3

[目標]我需要在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的沒有報告任何錯誤

+0

2意見:1.您從未設置着色器參數'MipMapLevel'。 2.你傳遞一個常量'5'作爲level到glFrameBufferTexture而不是'j'。 – denniskb

+0

對不起,應該已被編輯,我實際上傳遞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

嘗試後幾乎所有的東西,我終於使它的工作原理是我的立方體貼圖如下:

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

感謝您的關注:)