가까운 클립 평면보다 눈에 더 가까운 클리핑 정점을 어떻게 처리해야합니까?


13

JavaScript로 자체 3D 엔진을 롤링하고 WebGL이 아닌 캔버스 드로잉 만 사용합니다. 이것은 또 다른 마인 크래프트 클론입니다. 나는 상자를 좋아하고 나를 판단하지 않습니다.

지금까지 한 가지를 제외하고는 모든 것이 훌륭하게 작동합니다 .3D에서는 일부 정점이 거의 클리핑 평면 뒤에 가면 화면에서 투영이 이상하게 나타납니다 (평면을 추적하는 데 사용되는 다른 정점이 앞쪽에 있다고 가정).

이 점을 클리핑하려고 시도했지만이 정점을 사용하는 표면을 통해 볼 수 있습니다. WebGL / OpenGL에서 그래픽 카드는 이러한 점을 처리하고 평면이 올바르게 렌더링되지만 하드웨어에 액세스 할 수 없으므로 직접 코딩해야합니다.

무엇을 만들어야할지 잘 모르겠습니다. 현재 마지막으로 떠오르는 것은 플레이어의 가까운 클리핑 평면 뒤의 점 투영을 뒤집는 것입니다. 앞의 화면에 점을 투영해야하기 때문에 논리적 인 것 같습니다 정점

내 생각은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

다음은 어떤 일이 일어나는지 보여주는 이미지입니다.

여기에 이미지 설명을 입력하십시오

멀리서 보면 파란색 상자가 완벽하게 렌더링됩니다.

여기에 이미지 설명을 입력하십시오

정점 중 일부가 플레이어의 가까운 클리핑 평면 뒤에 가면 반전 투영을 수행하지만 올바르게 보이지 않습니다.

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

얼굴을 그리는 데 사용 된 모든 정점이 플레이어 뒤에 있기 때문에 뒤에있는 회색 상자가 완전히 제거됩니다.

여기에 이미지 설명을 입력하십시오

위 또는 아래를 볼 때 발생하는 현상입니다.

나는 이것 뒤에 수학을 무엇으로 만들어야할지 모르겠다. 누군가가 이미 같은 문제에 직면하여 나를 도울 수 있기를 바라고있다.


1
포인트 가까이 가까운 클립 비행기보다 눈에 있다면, 그들은 해야 잘릴 수 - 이것은 실제로 당신이 객체 "를 통해"을 참조 할 수 있습니다. 이것이 일반적인 동작입니다. 충돌은 일반적으로 특정 시각적 아티팩트를 방지합니다. 이것이 클리핑 솔루션에 유일한 문제입니까?

@ JoshPetrie : 점을 잘라야한다는 것을 이해하지만, 그렇게하면 드로잉 루틴이 통과 해야하는 정점 중 하나 또는 두 개가 누락되어 (2d에서) 플레이어가 볼 수 있기 때문에 전체 정사각형이 사라집니다 그 광장을 통해. 사각형이 여전히 그려 질 수 있도록 캔버스의 "외부"(투영에서)에 있기를 원합니다. 내가 충분히 명확한 지 잘 모르겠습니다.
솔레노이드

당신은있다 - 그게 정상적인 동작입니다 말인지 당신은에서 플레이어를 방지하여 문제가 발생하지 않도록 할 점점 큐브 중 하나가 가까이. 경우 당신이 정말로 이렇게하고 싶어 당신은 클립하지만, (아마도) 삼각형을 재구성해야한다. 특히 텍스처가있는 경우 여전히 비정상적으로 보입니다. 내가 말한 내용이 의미가없는 경우 채팅에 참여 하여 실제로 수다스러운 댓글 스레드를 만들지 않아도됩니다.

당신이 말하는 것은 말이됩니다. 재구성에는 너무 많은 시간이 걸리므로 해결책이 아닙니다. 나는 플레이어 뒤에 있는 2D 평면에 정점 그릴 수있는 방법이 있었기를 바랍니다. 그래서 lineTo(x,y)함수를 계속 호출 할 수 있었지만 어떻게 작동하는지 모르겠습니다 ... 기괴한 치수입니다.
솔레노이드

답변:


1

니어 클리핑 평면의 목적은 클리핑면 . 클리핑 평면을 벗어난 삼각형은 잘립니다 . 왼쪽으로 각 조각이 클리핑 영역 내에 있도록 조각으로 자릅니다.

원한다면 근거리 클립을 무시할 수 있습니다. 실제로 OpenGL과 D3D는 니어 플레인 클리핑을 끄는 방법을 가지고 있습니다 (심도 버퍼는 여전히 최소의 근접 값을 갖지만). 문제는 가까운 클립이 아닙니다.

문제는 정점에 있습니다. 카메라 뒤에 있는 .

카메라 뒤에있는 삼각형은 렌더링 할 수 없습니다. 투시 투영이 아닙니다. 이러한 삼각형은 원근 투영법의 수학에서 의미가 없습니다. 또한, 그들은 절두체 밖에 있습니다.

클리핑 근처에서 끄면 절두체가 피라미드로 바뀝니다. 피라미드가 점에서 멈추는 이유는 피라미드 위의 점이 피라미드의 네면 모두 뒤에 있기 때문입니다. 따라서 카메라 뒤의 피라미드 (피라미드의 끝)는 화면의 보이는 영역 위, 아래, 왼쪽 및 오른쪽에 있습니다. 동시에.

내가 말했듯이 : 카메라 뒤에있는 원근 투영에서 정점은 의미가 없습니다.

클리핑을 구현해야합니다. 당신은 감지해야 할 때 클립 공간에서 삼각형의 정점 ( 관점의 격차는) 카메라 뒤에. 그렇다면 삼각형을 자르고 카메라 앞에있는 삼각형 만 생성해야합니다.

이것은 간단한 과정이 아닙니다. 동종 좌표계를 완전히 이해 한 경우에만 의미가있는 수학이 필요합니다. 또는 정점이 카메라 뒤에 있으면 삼각형을 똑바로 깎을 수도 있습니다.


지금까지 나는 삼각형 전체를 꺾었지만 비행기를 봤습니다 (위 그림 참조). 왜 기하학적으로 이해가되지 않는지 이해하기 위해 그림이 필요했습니다. 유일한 해결책은 정점 중 하나가 클리핑 평면 뒤에있을 때 평면 선 교차점을 계산하고 그 정점을 사용하여 앞에있는 정점에서 선을 추적하는 것입니다. 불행히도 비용이 많이 듭니다.
솔레노이드

0

가까운 평면 뒤에있는 삼각형의 일부가 픽셀 당 검사를 통해 픽셀 위치가 클리핑 평면 뒤에 있는지 확인할 수 있습니까?

근거리 평면을 다른 클리핑 평면처럼 취급 할 수 있습니다. 예를 들어 클리핑 평면은 수면 (반사 및 굴절)과 같은 항목에 사용됩니다. 이 클리핑 평면은 가까운 클리핑 평면처럼 작동하고 픽셀 단위로 클리핑한다고 생각합니다.

DirectX를 사용하여 HLSL에서 클리핑 평면을 처리하는 방법을 알고 있지만 구현은 독점적 일 수 있습니다. 당신이 그것에 대한 정보를 보유 할 수 있다면 그것은 도움이 될 수 있습니다.

또한 여기에 도움이 될만한 링크가 있습니다 : http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html


픽셀 당 테스트는 Javascript와 같은 해석 언어에서 매우 비싸므로 지금은 거의 허용되지 않는 fps를 얻습니다.
솔레노이드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.