Saya baru saja mengaktifkan kembali wajah culling dan saya memperhatikan perilaku aneh: ketika semua simpul segitiga saya berada di luar pandangan dan 2 dari mereka ada di belakang saya (saya pikir) segitiga menghilang.
Jadi untuk melihatnya, ini GIF.
Saya menduga matriks proyeksi membalikkan urutan dua simpul ketika mereka jatuh di belakang saya, dan mengubah lilitan segitiga saya.
Tetapi tidak jelas mengapa segitiga menghilang hanya jika semua simpul tidak terlihat ...
Bagaimana saya bisa mengatasi masalah ini, jika memungkinkan?
Saya berkembang di Linux jika itu penting.
MEMPERBARUI:
Ini menunjukkan itu mungkin bukan karena pemusnahan wajah belakang. Saya menonaktifkannya dan saya memang bisa memperbanyaknya. Kubus 20 × 20 dan bidang pandang vertikal 90 °. Ukurannya yang terlihat vertikal hampir memenuhi jendela.
PEMBARUAN 2:
Ok saya akan memposting bagian yang relevan dari kode, proyeksi dan melihat matriks diatur menggunakan fungsi saya sendiri:
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);
}
Matriks proyeksi disiapkan dengan panggilan ini:
createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);
(VERTICAL_FOV = 90, ASPECT_RATIO = 4.0 / 3, Z_NEAR = 1)
Tingkat gambar sederhana:
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);
}
Kubus diberikan dinding dengan dinding (mengoptimalkan ini akan menjadi cerita lain):
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 fragmen:
#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;
}
Buffer kedalaman cukup diatur dengan mengaktifkannya.
Jawaban:
Meskipun masalah serupa sering disebabkan oleh kliping, pesawat dekat bukan masalah di sini. Jika ya, hilangnya akan menjadi per piksel dan bukan per segitiga.
Dalam animasi Anda, segitiga-segitiga itu benar-benar menghilang pada saat ketiga simpulnya berada di luar layar. Algoritme Anda mungkin didasarkan pada asumsi salah bahwa segitiga disembunyikan ketika semua simpulnya disembunyikan.
Berikut adalah artikel yang membahas implementasi culling frustum yang baik.
sumber
Sejauh ini tampaknya ini adalah masalah driver OpenGL. Saya tidak punya komputer lain untuk menguji ini untuk mengonfirmasi.
Jika saya memaksa perenderan perangkat lunak oleh
Masalahnya hilang. Mungkin saya perlu melihat-lihat bug dengan Mesa.
sumber
itu murni terkait dengan bidang kliping dekat untuk kamera dan tidak ada yang terkait dengan pemusnahan backface. Anda perlu mengurangi bidang kliping dekat dan kliping akan meledak.
sumber
Segitiga menghilang karena pesawat dekat frustrasi kamera. Segala sesuatu yang lebih dekat ke kamera daripada pesawat dekat secara otomatis terpotong. Anda hanya perlu menempatkan pesawat dekat Anda lebih dekat dari lokasi kamera. Bagaimana Anda dapat mengkonfigurasi pesawat dekat tergantung pada perpustakaan grafis Anda atau mesin. Di OpenGL, misalnya Anda harus mengatur parameter zNear dari gluPerspektif :
sumber