2009-01-20 62 views
11

根據ARB_geometry_shader4,可以在具有幾何着色器的立方體貼圖的6個面上渲染場景,並將該立方體貼圖附加到幀緩衝區對象。我想用這種方式創建一個陰影貼圖。然而,有似乎是我無法解決衝突:渲染到立方體貼圖

  1. 我只能GL_DEPTH_COMPONENT附加紋理內部類型的GL_DEPTH_ATTACHMENT_EXT。
  2. 深度紋理只能是1D或2D。
  3. 如果我想附加立方體貼圖,所有其他附加紋理也必須是立方體貼圖。

所以它看起來像我不能使用任何深度測試時,我想渲染到立方體貼圖。或者我在這裏錯過了什麼?

編輯:它看起來像新的Nvidia司機(180.48)支持深度立方體地圖。

+0

我不確定渲染立方體貼圖與幾何着色器有什麼關係,但感覺完全獨立,但我沒有答案。 – falstro 2009-01-21 10:57:12

+1

幾何着色器可以爲每個輸入三角形創建6個輸出三角形,並將其重定向到每個立方體貼圖面(請參閱「分層渲染」)。如果沒有着色器,我必須附加每個面並渲染幾何圖形。 – 2009-01-22 21:35:48

回答

12

好了,在這裏回答一些其他問題:

當然是可以使用6個宗教組織,每一個面孔。或者在繪製之前使用一個FBO並附上每張臉。在這兩種情況下,立方體貼圖面都將像其他任何2D貼圖一樣對待,並且可以將其與普通的2D貼圖或渲染緩衝區一起使用。在所有可能的方式中(如果硬件支持它們),可能沒有多大區別。

但是,也可以在一個步驟中繪製所有內容,因爲我很好奇這是如何完成的,所以我做了一些研究。

要創建連接到我用這個代碼將一個連接點的立方體地圖的所有面的FBO(寫在d):

// depth cube map 
glGenTextures(1, &tDepthCubeMap); 
glBindTexture(GL_TEXTURE_CUBE_MAP, tDepthCubeMap); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
for (uint face = 0; face < 6; face++) { 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT24, 
     width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null); 
} 

// color cube map 
glGenTextures(1, &tColorCubeMap); 
glBindTexture(GL_TEXTURE_CUBE_MAP, tColorCubeMap); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
for (uint face = 0; face < 6; face++) { 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 
     width, height, 0, GL_RGBA, GL_FLOAT, null); 
} 

// framebuffer object 
glGenFramebuffersEXT(1, &fbo); 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, tDepthCubeMap, 0); 
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, tColorCubeMap, 0); 

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 

if (!isValidFBO()) { 
    glDeleteFramebuffersEXT(1, &fbo); 
    fbo = 0; 
} 
  • 如果你想只有一個深度圖你必須改變glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);glDrawBuffer(GL_NONE);前驗證它
  • MIN和MAG過濾器必須設置的東西有效(默認是GL_NEAREST_MIPMAP_LINEAR)
  • 寬度和所有紋理的高度必須相同

(並繪製之前)渲染到立方體貼圖的表面,您需要幾何着色器。以下着色器錯過了一些旋轉,但它應該清楚它的作用。 gl_Layer用於將原語指向正確的人臉(0 = + X,1 = -X,...)。

#version 120 
#extension GL_EXT_geometry_shader4 : enable 

void main(void) { 
    int i, layer; 
    for (layer = 0; layer < 6; layer++) { 
     gl_Layer = layer; 
     for (i = 0; i < 3; i++) { 
      gl_Position = gl_PositionIn[i]; 
      EmitVertex(); 
     } 
     EndPrimitive(); 
    } 
}