Pergunta

De acordo com a ARB_geometry_shader4 é possível renderizar uma cena para o 6 faces de um mapa de cubo com um sombreador geometria e o mapa de cubo ligado a um objecto buffer de quadros. Eu quero criar um mapa de sombra usando este caminho. No entanto, parece haver um conflito que não posso resolver:

  1. Eu só pode anexar uma textura com GL_DEPTH_COMPONENT como tipo interno para o GL_DEPTH_ATTACHMENT_EXT.
  2. A profundidade de textura só pode ser 1D ou 2D.
  3. Se eu quiser anexar um mapa de cubo, todas as outras texturas anexadas deve ser cubo mapeia também.

Portanto, parece que eu não posso usar qualquer teste de profundidade quando eu quero render a um mapa de cubo. Ou o que exatamente eu falto aqui?

EDIT:. Parece que os drivers mais recentes da Nvidia mapas cubo (180,48) profundidade apoio

Foi útil?

Solução

Ok, para responder a algumas outras questões aqui:

Claro que é possível usar 6 hangares, um para cada face. Ou, para usar um FBO e anexar cada face antes de desenhar a ele. Em ambos os casos o mapa face do cubo será tratada como qualquer outra textura 2D e você pode usá-lo em conjunto com texturas 2D normais ou Renderbuffers. E provavelmente não há muita diferença em todas as formas possíveis (se os suportes de hardware deles).

No entanto, também é possível desenhar tudo em uma única etapa e como eu estava curioso para saber como isso é feito eu fiz alguma pesquisa.

Para criar um OBF com todas as faces de um mapa de cubo ligado a um único ponto de fixação I utilizado este código (escrito em 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;
}
  • Se você quiser ter apenas uma profundidade mapear você tem que mudar glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); e glDrawBuffer (GL_NONE); antes de validar (e antes de desenhar a ele )
  • filtros
  • MIN e MAG deve ser definido como algo válido (default seria GL_NEAREST_MIPMAP_LINEAR)
  • largura e altura de todas as texturas deve ser o mesmo

Para tornar as faces de um cubo mapear você precisa de um shader de geometria. A seguir shader perde algumas rotações, mas deve ficar claro que ele faz. gl_Layer é usado para dirigir o primitivo para a face correcta (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();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top