2011-07-31 6 views
2

비행 시뮬레이터를 쓰고 있는데이 장르의 고전적인 문제에 매달 렸습니다. 뷰잉 프러스 텀의 가까운 비행기는 항공기 조종실을 볼 수있을 정도로 가까이 있어야하며, 먼 비행기는 멀리 보이는 거리를 허용해야합니다. 최대 40km.OpenGL에서 z-fighting 문제를 없애려면 어떻게해야합니까?

가시 거리 또는 근거리/원거리 비율은 실제로 OpenGL의 z 버퍼 정밀도 능력을 뛰어 넘고 멀리있는 물체는 심하게 깜박입니다. 멋진 3D 엔진으로 문제가 해결되고 OpenGL에 대한 진정한 지식이 필요합니다. :) 아마도 내가 문제를 해결할 올바른 방법을 찾았을 것입니다. (내가 틀렸다면 OpenGL 전문가가 저를 바로 잡습니다.)하지만 내 솔루션은 중요한 부분을 놓칩니다. 변경된 렌더러 더블 패스 렌더링을 수행 표시되어야하는 첫 번째 패스 먼 물체에

  1. 및 배경 근처 평면 멀어, Z 버퍼는 지형 좋지만 가까운 오브젝트가 얻어 클리핑 보이는 행복하다.
  2. 두 번째 단계에서 투영 행렬은 근거리 개체에 맞게 조정되어 조종실을 표시해야합니다.

미해결 문제 : 모든 멀리있는 물체와 배경이 보이지 않는 두 번째 패스에서은, 그러므로 나는 조종석과 그 뒤에 검은 배경을 가지고있다. 두 번째 패스의 결과는 첫 번째 패스의 결과를 완전히 낭비합니다. Ergo 계획 오버레이가 발생하지 않습니다. 질문 : 두 번째 패스에서 배경색을 무시하도록 OpenGL을 강제하는 방법 두 패스 결과가 원하는 오버레이를 만들 수 있습니까?

P. 현상의 이미지가 있습니다 (가까운/먼 평면은 모든 세부 사항을 볼 수 있도록 극단에 있으며, 투사 조정없이 단일 패스를 나타냅니다).

http://www.flickr.com/photos/[email protected]/5995604542/sizes/l/in/photostream/

버퍼 클리어 렌더링 사이클 당 한 번만 발생하고, 2 개 패스 사이에 관여하지. 여기에 청산 코드 :

JoglContext jctx = (JoglContext) ctx; 
GLContext context = context(ctx); 
GL gl = context.getGL(); 
// Mask of which buffers to clear, this always includes color & depth 
int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT; 
gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); 
gl.glDepthMask(true); 
gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); 
gl.glClear(clearMask); 
gl.glPopAttrib(); 

당신이 설명하는 접근 방식은 또한 2 개 패스에 사용되는 : 1. "장거리"투사와 지형 2. "짧은 거리"와 조종실 사이에 청소하지만 두 번째 이후 조종석 뒤에 배경을 통과 검은 색입니다. 아마도 glDepthRange 함수가 도움이 될 것이고, 매뉴얼을 확인해야 할 것입니다.

z 버퍼 깊이는 24 비트입니다.

답변

6

두 패스 사이에서 화면을 지우지 마십시오. 깊이 버퍼를 지우고 싶다면 을 그냥 깊이 버퍼를 지우십시오. GL_COLOR_BUFFER_BITglClear에 전달하지 마세요.

어쨌든 더 좋은 방법은 (모든 것을 다시 렌더링 할 필요가 없도록) 적절한 깊이 범위를 사용하는 것입니다. 조종석이 장면과 교차 할 수 없으므로 장면의 깊이 범위로 그릴 이유가 없습니다.

그래서 먼저 합리적인 원근감 행렬을 사용하여 장면을 그립니다 (즉, z- 근처가 상당히 큰 것, 몇 피트 정도의 순서로). 당신의 장면은 조종석으로 구성되지 않습니다. 이 렌더링을위한 glDepthRange은 [0.05, 1.0]과 비슷해야합니다.

그런 다음 조종실 만의 합리적인 전망 매트릭스를 사용하여 조종석을 그립니다. 이 경우 glDepthRange은 [0, 0.05]입니다. 이렇게하면 장면과 조종석 모두에 대한 정밀도가 충분히 제공됩니다.

아, 24 비트 깊이 버퍼가 있는지 확인하십시오.

+0

신속한 응답을 보내 주셔서 감사합니다. Nicol. 내 의견은 길었고 원래 게시물에 붙여 넣어야했습니다. glDepthRange를 자세히 살펴볼 것입니다. – Paul

2

콕핏 대 외부는 스텐실 버퍼의 전형적인 경우이며 HUD 대 장면과 비슷합니다. 스텐실의 장점은 z가 전혀 필요 없다는 것입니다. 따라서 가까운면을 훨씬 더 멀리 설정할 수 있습니다. 또한, 여러분이 보게되는 윈도우는 변경되지 않습니다 (조종석 내부에서 가상 헤드를 회전시킬 때를 제외하고). 그리하여 한 번 재사용 할 수 있습니다.

logarithmic z 또한 재미있을 것입니다.

+0

Damon 감사합니다. 매우 유용합니다. 스텐실 버퍼/sb 함수를 적용하는 방법, OpenGL 초보자를위한 힌트? – Paul

+0

스텐실은 당신이해야 할 일이 즉각적으로 명백하지 않기 때문에 다소 혼란 스럽습니다. 적어도 처음으로 어떻게 인식했는지입니다. 다양한 옵션이 있습니다. 주요 기능 [glStencilFunc] (http://www.opengl.org/sdk/docs/man3/xhtml/glStencilFunc.xml) 및 [glStencilOp] (http://www.opengl.org/sdk/docs/man3/) xhtml/glStencilOp.xml). 실제 테스트 (음영 조각 파기)에는'glStencilFunc'을 사용하고, 스텐실 버퍼의 내용을 실제로 정의하기 위해서는'glStencilOP' _first_를 사용합니다. – Damon

+0

GL_REPLACE 스텐실 op를 가능한 싼 셰이더 (조명/텍스처링 사용 안 함)로 사용하고 GL_EQUAL 스텐실 기능을 사용하는 것이 좋습니다. 조종실을 그릴 때 z 버퍼링을 사용하면 깊이 실패에 대한 GL_KEEP도 옵션이 될 수 있습니다 (대역폭을 절약 할 수 있음). – Damon

관련 문제