Je viens d'activer l'abattage de la face arrière et je remarque un comportement étrange: lorsque tous les sommets de mon triangle sont en dehors de la vue et que 2 d'entre eux sont derrière moi (je pense), le triangle disparaît.
Alors pour le voir, voici un GIF.
Je soupçonne que la matrice de projection inverse l'ordre des deux sommets lorsqu'ils tombent derrière moi et modifie l'enroulement de mon triangle.
Mais on ne sait pas pourquoi les triangles disparaissent uniquement si tous les sommets sont hors de vue ...
Comment contourner ce problème, si possible?
Je développe sur Linux si cela compte.
MISE À JOUR:
Il a été souligné que cela n'était peut-être pas dû à l'abattage de la face arrière. Je l'ai désactivé et je peux en effet le reproduire. Les cubes sont de 20 × 20 et la vue de champ verticale est de 90 °. Sa taille apparente verticale remplit grossièrement la fenêtre.
MISE À JOUR 2:
Ok je posterai la partie pertinente du code, les matrices de projection et de vue sont configurées en utilisant mes propres fonctions:
void createViewMatrix(
GLfloat matrix[16],
const Vector3 *forward,
const Vector3 *up,
const Vector3 *pos
)
{
/* Setting up perpendicular axes */
Vector3 rright;
Vector3 rup = *up;
Vector3 rforward = *forward;
vbonorm(&rright, &rup, &rforward); /* Orthonormalization (right is computed from scratch) */
/* Filling the matrix */
matrix[0] = rright.x;
matrix[1] = rup.x;
matrix[2] = -rforward.x;
matrix[3] = 0;
matrix[4] = rright.y;
matrix[5] = rup.y;
matrix[6] = -rforward.y;
matrix[7] = 0;
matrix[8] = rright.z;
matrix[9] = rup.z;
matrix[10] = -rforward.z;
matrix[11] = 0;
matrix[12] = -vdp(pos, &rright);
matrix[13] = -vdp(pos, &rup);
matrix[14] = vdp(pos, &rforward);
matrix[15] = 1;
}
void createProjectionMatrix(
GLfloat matrix[16],
GLfloat vfov,
GLfloat aspect,
GLfloat near,
GLfloat far
)
{
GLfloat vfovtan = 1 / tan(RAD(vfov * 0.5));
memset(matrix, 0, sizeof(*matrix) * 16);
matrix[0] = vfovtan / aspect;
matrix[5] = vfovtan;
matrix[10] = (near+far)/(near-far);
matrix[11] = -1;
matrix[14] = (2*near*far)/(near-far);
}
Matrice de projection configurée avec cet appel:
createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);
(VERTICAL_FOV = 90, ASPECT_RATIO = 4.0 / 3, Z_NEAR = 1)
Le dessin de niveau est simplement:
void drawStuff()
{
GLfloat projectView[16];
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
createViewMatrix(viewMatrix, &camera.forward, &camera.up, &camera.pos);
multiplyMatrix(projectView, viewMatrix, projMatrix); /*< Row mayor multiplication. */
glUniformMatrix4fv(renderingMatrixId, 1, GL_FALSE, projectView);
bailOnGlError(__FILE__, __LINE__);
renderLevel(&testLevel);
}
Les cubes sont rendus mur par mur (l'optimisation sera une autre histoire):
for (j = 0; j < 6; j++)
{
glBindTexture(GL_TEXTURE_2D, cube->wallTextureIds[j]);
bailOnGlError(__FILE__, __LINE__);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * 4 * j));
bailOnGlError(__FILE__, __LINE__);
glUniform4f(extraColorId, 1, 1, 1, 1);
bailOnGlError(__FILE__, __LINE__);
}
Vertex shader:
#version 110
attribute vec3 position;
attribute vec3 color;
attribute vec2 texCoord;
varying vec4 f_color;
varying vec2 f_texCoord;
uniform mat4 renderingMatrix;
void main()
{
gl_Position = renderingMatrix * vec4(position, 1);
f_color = vec4(color, 1);
f_texCoord = texCoord;
}
Shader de fragment:
#version 110
varying vec4 f_color;
varying vec2 f_texCoord;
uniform sampler2D tex;
uniform vec4 extraColor;
void main()
{
gl_FragColor = texture2D(tex, f_texCoord) * vec4(f_color) * extraColor;
}
Le tampon de profondeur est simplement configuré en l'activant.
Réponses:
Bien que des problèmes similaires soient souvent causés par l'écrêtage, l'avion proche n'est pas le problème ici. Si tel était le cas, la disparition se ferait par pixel et non par triangle.
Dans votre animation, les triangles disparaissent exactement au moment où ses trois sommets sortent de l'écran. Votre algorithme peut être basé sur l'hypothèse fausse que les triangles sont cachés lorsque tous leurs sommets sont cachés.
Voici un article qui parle d'une bonne implémentation du tri sélectif.
la source
Jusqu'à présent, il semble que ce soit un problème de pilote OpenGL. Je n'ai pas d'autre ordinateur pour tester cela pour confirmer.
Si je force le rendu logiciel par
Le problème disparaît. J'ai probablement besoin de regarder autour des bugs avec Mesa.
la source
son purement lié au plan de détourage proche pour la caméra et n'a rien à voir avec l'abattage de face arrière. Vous devez réduire le plan de détourage proche et le détourage se déclenchera.
la source
Les triangles disparaissent à cause de l'avion proche de la caméra. Tout ce qui est plus proche de la caméra que du plan proche est automatiquement coupé. Il vous suffit de placer votre avion proche encore plus près de l'emplacement de la caméra. La façon dont vous pouvez configurer le plan proche dépend de votre bibliothèque graphique ou de votre moteur. Dans OpenGL, par exemple, vous devez définir le paramètre zNear de gluPerspective :
la source