Acabei de ativar a seleção do rosto para trás e estou percebendo um comportamento estranho: quando todos os vértices do meu triângulo estão fora da vista e 2 deles estão atrás de mim (acho), o triângulo desaparece.
Então, para vê-lo, aqui está um GIF.
Suspeito que a matriz de projeção inverta a ordem dos dois vértices quando eles ficam atrás de mim e altera o enrolamento do meu triângulo.
Mas não está claro por que os triângulos desaparecem apenas se todos os vértices estão fora de vista ...
Como posso solucionar esse problema, se possível?
Eu desenvolvo no Linux, se isso importa.
ATUALIZAR:
É indicado que pode não ser devido ao abate da face traseira. Eu o desativei e posso reproduzi-lo. Os cubos são 20 × 20 e a vista do campo vertical é 90 °. Seu tamanho aparente vertical enche aproximadamente a janela.
ATUALIZAÇÃO 2:
Ok, eu vou postar a parte relevante do código, as matrizes de projeção e visualização são configuradas usando minhas próprias funções:
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);
}
Matriz de projeção configurada com esta chamada:
createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);
(VERTICAL_FOV = 90, ASPECT_RATIO = 4.0 / 3, Z_NEAR = 1)
O desenho de nível é simplesmente:
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);
}
Os cubos são renderizados parede a parede (otimizar isso será outra história):
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__);
}
Shader de vértice:
#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 fragmento:
#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;
}
O buffer de profundidade simplesmente é configurado ativando-o.
Respostas:
Embora problemas semelhantes geralmente sejam causados por recortes, o plano próximo não é o problema aqui. Se assim fosse, o desaparecimento seria por pixel e não por triângulo.
Na sua animação, os triângulos desaparecem exatamente no momento em que todos os seus três vértices saem da tela. Seu algoritmo pode ser baseado na falsa suposição de que triângulos estão ocultos quando todos os seus vértices estão ocultos.
Aqui está um artigo falando sobre uma boa implementação de seleção de frustum.
fonte
Até agora, parece que é um problema de driver do OpenGL. Não tenho outro computador para testar isso para confirmar.
Se eu forçar a renderização de software por
O problema desaparece. Provavelmente eu preciso olhar em volta de bugs com o Mesa.
fonte
está puramente relacionado ao plano de recorte próximo da câmera e não tem nada relacionado ao abate da face posterior. Você precisa reduzir o plano de recorte próximo e o recorte será disparado.
fonte
Os triângulos estão desaparecendo devido ao plano próximo do frustrum da câmera. Tudo o que está mais próximo da câmera do que o plano próximo é automaticamente cortado. Você só precisa colocar o seu plano próximo ainda mais próximo da localização da câmera. Como você pode configurar o plano próximo depende da sua biblioteca ou mecanismo gráfico. No OpenGL, por exemplo, você deve definir o parâmetro zNear de gluPerspective :
fonte