Question

Selon ARB_geometry_shader4 , il est possible de restituer une scène sur le 6 faces d'une carte de cube avec un shader de géométrie et la carte de cube attachée à un objet framebuffer. Je veux créer une carte d'ombre en utilisant cette façon. Cependant, il semble y avoir un conflit que je ne peux pas résoudre:

  1. Je ne peux que joindre une texture avec GL_DEPTH_COMPONENT en tant que type interne au GL_DEPTH_ATTACHMENT_EXT.
  2. Une texture de profondeur ne peut être que 1D ou 2D.
  3. Si je souhaite attacher une carte de cube, toutes les autres textures attachées doivent également être des cartes de cube.

Il semble donc que je ne peux utiliser aucun test de profondeur lorsque je souhaite effectuer un rendu sur une carte de cube. Ou qu'est-ce qui me manque ici exactement?

EDIT: les nouveaux pilotes Nvidia (180.48) prennent en charge les cartes de cube en profondeur.

Était-ce utile?

La solution

Ok, pour répondre à d'autres questions ici:

Bien sûr, il est possible d’utiliser 6 FBO, un pour chaque visage. Ou utilisez un FBO et attachez chaque visage avant de dessiner dessus. Dans les deux cas, la face de la carte de cube sera traitée comme toute autre texture 2D et vous pourrez l’utiliser avec des textures 2D normales ou des Renderbuffers. Et il n'y a probablement pas beaucoup de différence de toutes les manières possibles (si le matériel les prend en charge).

Cependant, il est également possible de tout dessiner en une seule étape et, curieux de savoir comment cela se fait, j'ai effectué des recherches.

Pour créer un FBO avec toutes les faces d’une carte de cube attachée à un seul point d’attachement, j’ai utilisé ce code (écrit en 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;
}
  • Si vous voulez avoir uniquement une carte de profondeur, vous devez changer glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); en glDrawBuffer (GL_NONE); avant de le valider (et avant de le dessiner). )
  • Les filtres MIN et MAG doivent avoir une valeur valide (par défaut, GL_NEAREST_MIPMAP_LINEAR)
  • la largeur et la hauteur de toutes les textures doivent être identiques

Pour rendre les faces d'une carte de cube, vous devez utiliser un shader de géométrie. Le shader suivant manque quelques rotations mais son rôle doit être clair. gl_Layer est utilisé pour diriger la primitive vers la bonne face (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();
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top