2016-10-10 59 views
0

我有一個HDR輻射環境地圖作爲我想要轉換爲立方體貼圖的LatLong 2D紋理圖像。我通過將HDR貼圖加載爲2D浮動紋理,將其投影到立方體上,然後從6個不同方向渲染該立方體內的場景,直接填充具有各自立方體貼圖面的glFramebufferTexture2D的立方體貼圖作爲函數的紋理目標。從HDRi LatLong地圖直接渲染到浮點立方圖 - 不是HDR

生成立方體貼圖是產生如下浮點立方體貼圖:

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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); 

for (unsigned int i = 0; i < 6; ++i) 
{ 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, NULL); 
} 
if (mipmap) 
    glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 

注意,類型參數是GL_FLOAT所以應適當接受HDR值。 HDR圖像是使用stb_image.h如下加載:

if (stbi_is_hdr(path.c_str())) 
{ 
    stbi_set_flip_vertically_on_load(true); 

    int width, height, nrComponents; 
    float *data = stbi_loadf(path.c_str(), &width, &height, &nrComponents, 0); 
    if (data) 
    { 
     GLenum format; 
     if (nrComponents == 3) 
      format = GL_RGB; 
     else if (nrComponents == 4) 
      format = GL_RGBA; 

     Bind(); 
      glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_FLOAT, data); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
      if (Mipmapping) 
       glGenerateMipmap(GL_TEXTURE_2D); 
     Unbind(); 
     stbi_image_free(data); 
    } 
} 

我也試過遍歷數組和獲取最大浮點值,看看是否HDR正確地加載和我目前的HDR地圖的最高浮點值是288這遠遠高於我期望的1.0

基於輸入紋理(HDR浮點圖)和輸出立方體貼圖(作爲浮點數),我認爲事情會變得棘手,我期望立方體貼圖的面部可以正確對待爲浮點紋理並直接複製HDR值。然而,當我添加色調映射(具有可變曝光)時,立方體貼圖出現LDR。我得到了相當多的條帶,並且我明顯缺少HDR的精度,如下圖所示(曝光爲〜7.5)

LDR image of what should be HDR

我不知道是否有什麼我失蹤,我找不到太多關於OpenGL的有關直接渲染到浮點幀緩衝的文檔;我認爲這是可能的,因爲如果不是這樣,它是沒有意義的。

爲了完整起見,這裏是產生距離的LatLong圖像的立方體貼圖(與renderCustomCommand渲染適當採樣立方體設置)的相關代碼:

glGenFramebuffers(1, &m_FramebufferCubemap); 
glGenRenderbuffers(1, &m_CubemapDepthRBO); 

Camera faceCameras[6] = { 
    Camera(position, vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, -1.0f, 0.0f)), 
    Camera(position, vec3(-1.0f, 0.0f, 0.0f), vec3(0.0f, -1.0f, 0.0f)), 
    Camera(position, vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f)), 
    Camera(position, vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f,- 1.0f)), 
    Camera(position, vec3(0.0f, 0.0f, 1.0f), vec3(0.0f, -1.0f, 0.0f)), 
    Camera(position, vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, -1.0f, 0.0f)) 
}; 

glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferCubemap); 
glBindRenderbuffer(GL_RENDERBUFFER, m_CubemapDepthRBO); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_CubemapDepthRBO); 

glViewport(0, 0, width, height); 
glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferCubemap); 

for (unsigned int i = 0; i < 6; ++i) 
{ 
    Camera *camera = &faceCameras[i]; 
    camera->SetPerspective(90.0f, width/height, 0.1f, 100.0f); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeTarget->ID, 0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    for (unsigned int i = 0; i < renderCommands.size(); ++i) 
    { 
     renderCustomCommand(&renderCommands[i], camera); 
    } 
} 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glViewport(0, 0, m_RenderSize.x, m_RenderSize.y); 

下面是用於採樣的LatLong二維碼圖片 - >立方體:

#version 330 core 
out vec4 FragColor; 
in vec3 wPos; 

#include sample.glsl 

uniform sampler2D environment; 

void main() 
{ 
    vec2 uv = SampleLatLong(normalize(wPos)); 
    vec3 color = texture(environment, uv).rgb; 
    FragColor = vec4(color, 1.0); 
} 

注意,LatLong網到立方體貼圖轉換順利,作爲2D環境上正常渲染一個立方體貼圖,而是簡單地夾到[0,1]區間上它呈現爲一個瞬間天空盒,就好像某個地方一樣很長的過程中,它失去了它的浮點數據。

我一直在這個問題上停留了一段時間,並希望你們中的任何一個人都能夠發現一些見解(甚至有可能直接渲染浮動立方體像這樣?)。謝謝。


編輯:這裏是相同的圖像具有高曝光從Photoshop設置,你可以看到很多細節浮現,我在渲染器已經失去了。

HDR image from Photoshop with high exposure

+0

您是否嘗試在原始.hdr文件上推送曝光。 (在Photoshop或其他)。你有沒有看到相同的人造物品? Radiance文件以RGBE編碼。由於RGB共享相同的指數,因此可能會導致色彩質量差,亮度或暗色像素較多。另外,HDR照片通常是從不同曝光拍攝的相同照片創建的。根據相機質量的不同,低曝光版本也可能具有較差的色彩質量。 – pleup

+0

第一個圖像來自渲染器本身,來自浮點值,所以'stb_image.h'已經將RGBE格式解碼爲浮點。我還從Photoshop中添加了高曝光度的圖像,您可以確實看到以前用默認曝光度看不到的細節。 – Djemon

+0

好的。如果它不是源圖像,它可能來自着色器。你是否在片段着色器中指定浮點精度?您可能會嘗試添加「精度最高的浮點數」;在碎片着色器的開始處。 – pleup

回答

1

您的通話glTexImage2D的第三個參數需要GL_RGB16F或GL_RGB32F。 它指定了內部格式。

最後兩個參數GL_RGB和GL_FLOAT僅用於指定可選數據指針的內存佈局。他們不影響內部格式。

+0

就是這樣!非常感謝! – Djemon