Tại sao hình tam giác gần đó có xu hướng biến mất?


8

Tôi vừa kích hoạt tính năng loại bỏ mặt sau và tôi nhận thấy một hành vi kỳ lạ: khi tất cả các đỉnh của tam giác của tôi nằm ngoài tầm nhìn và 2 trong số chúng nằm phía sau tôi (tôi nghĩ) hình tam giác biến mất.

Vì vậy, để xem nó, đây là một GIF.

nhập mô tả hình ảnh ở đây

Tôi nghi ngờ ma trận chiếu đảo ngược thứ tự của hai đỉnh khi chúng nằm phía sau tôi và thay đổi cuộn dây của tam giác của tôi.

Nhưng không rõ tại sao các hình tam giác biến mất chỉ khi tất cả các đỉnh ngoài tầm nhìn ...

Làm thế nào tôi có thể làm việc xung quanh vấn đề này, nếu có thể?

Tôi phát triển trên Linux nếu điều đó quan trọng.

CẬP NHẬT:

Nó chỉ ra rằng nó có thể không phải là do mặt sau bị loại bỏ. Tôi đã vô hiệu hóa nó và tôi thực sự có thể tái tạo nó. Các hình khối là 20 × 20 và chế độ xem trường dọc là 90 °. Kích thước rõ ràng theo chiều dọc của nó gần như lấp đầy cửa sổ.

CẬP NHẬT 2:

Ok tôi sẽ đăng phần có liên quan của mã, phép chiếu và ma trận xem được thiết lập bằng các hàm riêng của tôi:

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);
}

Ma trận chiếu được thiết lập với lệnh gọi này:

createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);

(VERTICS_FOV = 90, ASPECT_RATIO = 4.0 / 3, Z_NEAR = 1)

Vẽ mức độ đơn giản là:

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);
}

Các hình khối được kết xuất bằng tường (tối ưu hóa đây sẽ là một câu chuyện khác):

    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__);
    }

Máy tạo bóng Vertex:

#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;
}

Mảnh vỡ mảnh:

#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;
}

Bộ đệm sâu chỉ đơn giản là thiết lập bằng cách kích hoạt nó.


Tôi không thể tìm ra tam giác nào bạn đang nói ở đây.
Trevor Powell

@TrevorPowell Các mặt vuông của khối lập phương gồm 2 hình tam giác, một nửa hình vuông biến mất trên hình thứ 2.
Calmarius

Tôi đã hiểu rằng. Nhưng bạn đang đề cập đến hình vuông nào? Tôi không thể biết được bit nào của hình ảnh thứ hai mà tôi phải nhìn và các đỉnh trong hình ảnh thứ hai tương ứng với các đỉnh trong hình thứ nhất. Nó trông giống như bức tường màu xanh ngoài cùng bên phải đang cắt qua mặt phẳng clip gần, có lẽ vậy? Hay bạn đang nói về bức tường trắng bên phải? Hay cái gì?
Trevor Powell

1
Bạn có thể chỉ cho chúng tôi mã gây ra điều này?
akaltar

1
Vì vậy, có vẻ như các hình tam giác biến mất thời điểm đỉnh ở dưới cùng của màn hình đi ra khỏi tầm nhìn. Điều này chắc chắn chỉ bắt đầu xảy ra khi bạn kích hoạt tính năng loại bỏ mặt sau, hoặc có thể bạn chỉ nhận thấy nó sau đó? Có phải các mặt của khối lập phương rất lớn so với phần chúng ta có thể nhìn thấy (Tôi đang nghĩ về một tràn số học có thể)? Bất kỳ cơ hội để thử nó trên phần cứng khác nhau (nó có thể là một lỗi trình điều khiển)?
GuyRT 27/12/13

Câu trả lời:


6

Mặc dù các vấn đề tương tự thường được gây ra bởi việc cắt, máy bay gần không phải là vấn đề ở đây. Nếu có, sự biến mất sẽ là trên mỗi pixel chứ không phải trên mỗi tam giác.

Trong hoạt hình của bạn, các hình tam giác biến mất chính xác tại thời điểm cả ba đỉnh của nó nằm ngoài màn hình. Thuật toán của bạn có thể dựa trên giả định sai lầm rằng các tam giác bị ẩn khi tất cả các đỉnh của chúng bị ẩn.

Dưới đây là một bài viết nói về một thực hiện loại bỏ bực bội tốt.


Tam giác không luôn biến mất khi tất cả các đỉnh ra khỏi tầm nhìn. Đây không phải là cắt nhiệm vụ của OpenGL sao?
Calmarius 27/12/13

@Calmarius những gì danijar đang nói, đó có phải là một vấn đề trong thuật toán loại bỏ bực bội của bạn, mà tôi nghĩ rằng bạn thậm chí không thực hiện, phải không? Thành thật mà nói tôi nghĩ đó là một vấn đề / lỗi trình điều khiển.
Concept3d

@Calmarius concept3d có thể đúng, bạn đang sử dụng Mesa và nó có thể có lỗi gây ra sự cố của bạn. Bạn có thể chạy mã của mình trên một máy có trình điều khiển Nvidia hoặc AMD chính thức không?
danijar

@danijar Có lẽ sau này, khi tôi đi làm về sau kỳ nghỉ. Tôi đang sử dụng các máy tính bị loại bỏ cũ không có thẻ video bổ sung được tích hợp chỉ có trên máy tính bảng.
Calmarius

4

Cho đến nay có vẻ như đó là một vấn đề trình điều khiển OpenGL. Tôi không có máy tính khác để kiểm tra điều này để xác nhận.

Nếu tôi buộc kết xuất phần mềm bằng

$ export LIBGL_ALWAYS_SOFTWARE=1

Vấn đề biến mất. Có lẽ tôi cần phải xem xét các lỗi với Mesa.


Tôi chấp nhận điều này, sự cố không xảy ra trên hộp Máy tính để bàn của tôi cũng như trên các máy tính khác.
Calmarius

-1

nó hoàn toàn liên quan đến mặt phẳng cắt gần cho máy ảnh và không có gì liên quan đến việc loại bỏ backface. Bạn cần giảm mặt phẳng cắt gần và cắt sẽ tắt.


Nếu bạn nhìn kỹ, bạn có thể thấy rằng một hình tam giác đơn giản biến mất, nó không liên quan gì đến mặt phẳng cắt gần.
Calmarius 27/12/13

-1

Các hình tam giác đang biến mất vì sự thất vọng của máy ảnh gần mặt phẳng. Mọi thứ gần camera hơn so với mặt phẳng gần sẽ tự động được cắt bớt. Bạn chỉ cần đặt máy bay gần của bạn gần hơn với vị trí máy ảnh. Cách bạn có thể định cấu hình mặt phẳng gần tùy thuộc vào thư viện đồ họa hoặc công cụ của bạn. Trong OpenGL, ví dụ, bạn nên đặt tham số zNear của gluPers perspective :

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

có vẻ như vậy, và không có gì để làm với việc loại bỏ backface.
khái niệm3

3
điều đó có làm cho toàn bộ tam giác đi qua mặt phẳng cắt gần biến mất không? không nên chỉ cắt một số đoạn ?

3
Tôi không nghĩ rằng đây là nó; máy ảnh đó có vẻ hướng thẳng về phía trước và những bức tường đó thẳng đứng, điều đó có nghĩa là bất cứ thứ gì được cắt bằng cách vượt qua mặt phẳng cắt gần sẽ tạo thành một đường thẳng đứng trên màn hình, không phải là những góc nông này. Các hình ảnh hiển thị thực sự trông giống như một hình tam giác bị loại bỏ một cách sai lầm.
Trevor Powell

@TrevorPowell Có Tôi nghĩ bạn đúng, tôi đã rút lại phiếu bầu của mình.
khái niệm3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.