OpenGL : 3D (렌더링 된) 지점이 그 앞에 다른 3D (렌더링 된) 프리미티브에 의해 폐색되는지 확인하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1311869

  •  19-09-2019
  •  | 
  •  

문제

OpenGL 프로그램에서 나는 다음을 순서대로하고 있습니다.

// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it

포인트 정보 (예 : 포인트 식별자/번호)를 표시하기 위해 포인트의 3D 좌표를 사용한 2D 창 좌표로 변환합니다. Gluproject(). 나는 2D 창 위치에 포인트 식별자를 작성합니다. Glrasterpos() 및 2D 문자 렌더링 코드.

다른 원시에 의해 렌더링 된 지점이 폐쇄되면 자동으로 ~ 아니다 OpenGL 파이프 라인에서 발생하는 자동 폐색 테스트 및 깊이 테스트로 인해 표시됩니다. 그러나이 폐색 정보를 얻지 못하므로 폐색 된 경우에도 포인트 식별자 텍스트가 포인트 옆에 표시됩니다.

3D (렌더링 된) 지점이 그 앞에 다른 3D (렌더링 된) 프리미티브에 의해 폐쇄되는지 여부를 결정하는 방법은 무엇입니까? 아니면 그 옆에 포인트 정보 텍스트를 표시하는 더 좋은 방법이 있습니까? 폐색되지 않은 경우?

참고 : 추가 렌더링 패스가 필요한 방법을 알고 있습니다. 나는 그것들이 내 목적으로 비싸다고 생각합니다.

도움이 되었습니까?

해결책

폐색 쿼리 두 번째 패스를 기꺼이 사용하지 않으려면 z- 버퍼를 샘플링하여 테스트 포인트와 비교할 수 있습니다.

포인트 옆에 텍스트를 추가하기 때문에 포인트의 정규화 된 Z 버퍼 값 (예 : Gluproject)을 잡은 다음 해당 값을 샘플링 된 Z- 버퍼 (Glreadpixels 사용) 값과 비교하십시오. 요점이 샘플링 한 깊이 값 뒤에있는 경우 (보다 큰 경우) 포인트를 폐쇄해야하며 텍스트를 그리지 않도록 선택할 수 있습니다.

물론 이것은 텍스트 앞에 모든 지오메트리를 렌더링해야하지만 문제가되지 않아야합니다.

샘플 코드 :

// Assumed to already hold 3D coordinates of point
GLdouble point3DX, point3DY, point3DZ;

// Project 3D point coordinates to 2D
GLdouble point2DX, point2DY, point2DZ;  // 2D coordinates of point
gluProject( point3DX, point3DY, point3DZ,
            mMatrix, pMatrix, vMatrix,      // MVP matrices
            &point2DX, &point2DY, &point2DZ);

// Read depth buffer at 2D coordinates obtained from above
GLfloat bufDepth = 0.0;
glReadPixels(   static_cast<GLint>( point2DX ), static_cast<GLint>( point2DY ),     // Cast 2D coordinates to GLint
                1, 1,                                                               // Reading one pixel
                GL_DEPTH_COMPONENT, GL_FLOAT,
                &bufDepth);

// Compare depth from buffer to 2D coordinate "depth"
GLdouble EPSILON = 0.0001;  // Define your own epsilon
if (fabs(bufDepth - point2DZ) < EPSILON)
    // 3D point is not occluded
else
    // 3D point is occluded by something

다른 팁

현대 하드웨어에서는 Z- 버퍼를 읽는 것이 매우 느릴 수 있습니다. 이것이 바로 폐색 쿼리가 발명 된 이유입니다. ARB-Occlusion-Query 확장을 찾아보십시오. 결과를 얻기 전에 몇 프레임의 지연 프레임이 있지만 성능에 영향을 미치지는 않습니다.

폐색 쿼리가 어떤 이유로 든 작동하지 않으면 다음 폴백 옵션은 BSP 트리 (GL을 전혀 사용하지 않음)를 사용하여 소프트웨어 Ray-Intersect-World 작업을 수행하는 것입니다.

Alan의 답변에 따르면, 카메라 위치에서 광선을 지점까지 돌려서 수학적으로 폐색을 테스트하고 기하학이 교차하는지 여부를 결정할 수 있습니다. 인터넷에 Ray-Object 교차로 테스트를 수행하기위한 많은 참조가 있습니다 (예 : 객체/객체 교차 페이지). 지오메트리가 많으면 경계 볼륨이나 BSP 트리를 사용하여 속도를 높이고 싶을 수 있습니다.

보너스로서, 폐색 코드는 OpenGL에서 값을 추출하는 데 의존하지 않기 때문에 장치 테스트가 훨씬 쉬워야합니다.

Ashwin Nanjappa의 답변은 매우 도움이되었습니다. 나는 OpenGL 전문가가 아니기 때문에 MVP 행렬을 얻는 방법을 찾는 데 시간이 걸렸습니다. 그의 게시물을 보완하기 위해 여기에서 코드를 공유하고 있습니다.

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top