Mengapa segitiga di dekatnya cenderung menghilang?


8

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.

masukkan deskripsi gambar di sini

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.


Saya tidak tahu segitiga mana yang Anda bicarakan, di sini.
Trevor Powell

@TrevorPowell Wajah kotak kubus terdiri dari 2 segitiga, setengah dari kotak menghilang pada gambar ke-2.
Calmarius

Saya mengerti itu. Tapi kotak mana yang Anda maksud? Saya tidak tahu bagian mana dari gambar kedua yang seharusnya saya lihat, dan simpul mana pada gambar kedua yang sesuai dengan simpul mana pada gambar pertama. Sepertinya dinding biru paling kanan memotong klip dekat pesawat, mungkin? Atau apakah Anda berbicara tentang dinding putih paling kanan? Atau apa?
Trevor Powell

1
Bisakah Anda menunjukkan kepada kami kode yang menyebabkan ini?
akaltar

1
Jadi sepertinya segitiga menghilang saat titik di bagian bawah layar tidak terlihat. Apakah ini benar-benar mulai terjadi hanya ketika Anda mengaktifkan kembali wajah pemusnahan, atau apakah mungkin Anda baru saja memperhatikannya setelah itu? Apakah wajah kubus sangat besar relatif terhadap bagian yang dapat kita lihat (saya sedang memikirkan kemungkinan aritmatika melimpah)? Adakah kesempatan untuk mencobanya pada perangkat keras yang berbeda (bisa jadi itu adalah bug driver)?
GuyRT

Jawaban:


6

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.


Segitiga tidak selalu hilang saat semua simpul keluar dari tampilan. Bukankah ini memotong tugas OpenGL?
Calmarius

@Calmarius apa yang dikatakan danijar, apakah itu masalah dalam algoritma culling frustum Anda, yang saya pikir Anda bahkan tidak tampil, kan? Sejujurnya saya pikir ini masalah driver / bug.
concept3d

@Calmarius concept3d mungkin benar, Anda menggunakan Mesa dan mungkin ada bug yang menyebabkan masalah Anda. Bisakah Anda menjalankan kode pada mesin dengan driver Nvidia atau AMD resmi?
danijar

@danijar Mungkin nanti, ketika saya kembali bekerja setelah liburan. Saya menggunakan komputer bekas yang tidak memiliki kartu video tambahan hanya yang terpasang.
Calmarius

4

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

$ export LIBGL_ALWAYS_SOFTWARE=1

Masalahnya hilang. Mungkin saya perlu melihat-lihat bug dengan Mesa.


Saya menerima ini, masalahnya tidak terjadi pada kotak Desktop saya atau di komputer lain.
Calmarius

-1

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.


Jika Anda perhatikan dengan teliti, Anda dapat melihat bahwa segitiga menghilang begitu saja, tidak ada hubungannya dengan bidang guntingan yang dekat.
Calmarius

-1

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 :

void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

ya terlihat begitu, dan tidak ada hubungannya dengan pemusnahan backface.
concept3d

3
apakah itu akan menyebabkan seluruh segitiga yang melintasi bidang kliping dekat menghilang? bukankah seharusnya hanya memotong beberapa fragmen ?

3
Saya tidak berpikir ini dia; bahwa kamera tampak menghadap lurus ke depan, dan dinding-dinding itu vertikal, yang berarti bahwa apa pun yang terpotong dengan melintasi bidang kliping dekat harus membuat garis vertikal pada layar, bukan sudut dangkal ini. Gambar yang ditampilkan benar-benar terlihat seperti segitiga yang disingkirkan secara keliru.
Trevor Powell

@ TrevorPowell Ya saya pikir Anda benar, saya mencabut suara saya.
concept3d
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.