OpenGL에서 투명도를 렌더링하는 몇 가지 방법은 무엇입니까


14

다음과 같이 알파 블렌딩을 켜서 표면을 투명하게 만들 수 있습니다.

glDisable(GL_DEPTH_TEST); //or glDepthMask(GL_FALSE)? depth tests break blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

그러나 이것은 객체가 앞뒤로 렌더링되는 경우에만 작동합니다. 그렇지 않으면 배경 이미지가 아래 이미지의 바닥과 같이 더 가까운 물체 앞에 나타납니다. 파티클과 GUI 요소의 경우 정렬은 괜찮지 만 삼각형 메쉬의 경우 https://www.opengl.org/wiki/Transparency_Sorting에서 논의한 것처럼 너무 많은 노력과 속도가 느린 것처럼 보입니다 .

이것을 처리하는 일반적인 방법은 무엇입니까? 나는 이것이 매우 광범위하고 심도있는 구현 세부 사항, 일부 접근 방식 및 관련 사항에 대한 간단한 설명을 따르는 것이 아니라는 것을 알고 있습니다.

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


이것이 대답으로 가야할지 확실하지 않지만 이미지의 오류는 모든 기본 요소 에 대한 깊이 테스트없이 렌더링으로 인해 발생합니다 . 장면을 2 패스로 렌더링해야합니다. 먼저 일반적으로 모든 솔리드 형상을 렌더링합니다. 그런 다음 깊이 쓰기 (GL_DEPTH_TEST 아님)를 비활성화 하고 반투명 지오메트리를 대략 앞뒤 순서로 렌더링하십시오. 그러면 투명한 형상이 앞에있는 솔리드 형상 앞에 그려지지 않습니다.
yuriks

@yuriks이 경우 아마도 저의 예는 좋지 않지만 모든 것이 투명해야합니다. 나는 잘못했을 때 투명성이 어떻게 보일지 보여줄 무언가를 원했습니다. 또한 지오메트리 정렬이 놀랍도록 어려운 예도 있습니다 (예를 들어 바닥은 하나의 거대한 다각형이며 전체 깊이 범위를 포함 함).
jozxyqk

답변:


10

명시 적 순서를 피하는 일련의 기술은 OIT (Order Independent Transparency)라는 이름으로 사용됩니다.

많은 OIT 기술이 있습니다.

역사적으로 하나는 Depth Peeling 입니다. 이 방법에서는 먼저 가장 앞부분의 조각 / 픽셀을 렌더링 한 다음 이전 단계에서 찾은 것과 가장 가까운 부분을 찾아 필요한만큼 많은 "레이어"를 사용합니다. 각 패스마다 한 층의 깊이를 "박리 기"때문에 깊이 박리라고합니다. 그런 다음 모든 레이어를 일반적으로 뒤에서 앞으로 재결합 할 수 있습니다. 이 알고리즘을 구현하려면 깊이 버퍼의 사본이 있어야합니다.

또 다른 기술 세트는 블렌드 엔드 OIT 기술입니다. 가장 최근의 흥미로운 것 중 하나는 McGuire와 Bavoil이 제안한 Weighted Blended OIT 입니다. 기본적으로 주어진 조각을 차지하는 모든 표면에 가중치 합계를 적용합니다. 그들이 제안한 가중치 체계는 카메라 공간 Z (폐색에 ​​대한 근사치)와 불투명도를 기반으로합니다. 아이디어는 문제를 가중 합계로 줄일 수 있다면 실제로 주문에 신경 쓰지 않는다는 것입니다.

원본 논문 이외에도 Weighted Blended OIT의 구현 세부 사항 및 문제에 대한 훌륭한 자료는 Matt Pettineo의 블로그에 있습니다. 그의 게시물에서 읽을 수 있듯이이 기술은 은색 총알이 아닙니다. 가장 큰 문제는 가중치 체계가 중심적이며 장면 / 콘텐츠에 따라 조정되어야한다는 것입니다. 그의 실험에서,이 기법은 상대적으로 낮고 중간 정도의 불투명도에서는 잘 작동하는 것처럼 보이지만 불투명도가 1에 가까워지면 실패하기 때문에 표면의 큰 부분이 불투명 한 재료에서는 사용할 수 없습니다 (그는 잎의 예를 만듭니다).

다시 말하지만, 모두 깊이 가중치를 조정하는 방법에 따라 달라지며 사용 사례에 완벽하게 맞는 무게를 찾는 것이 반드시 사소한 것은 아닙니다.

Weighted Blended OIT에 필요한 사항은 추가 렌더 타겟이 두 개뿐입니다. 미리 곱한 알파 색상 (컬러 * 알파)과 알파로 채워지는 색상은 모두 그에 따라 가중치가 적용됩니다. 다른 하나는 분동에만 해당됩니다.


6

하나의 옵션은 깊이 박리를 사용하는 것입니다.

본질적으로, n가장 근접한, 두 번째로 가장 가까운 것을 결정하기 위해 장면을 정해진 횟수 (예 : 시간)로 처리합니다.n 가장 가까운 프래그먼트에 번째로 가장 가까운 조각 장면을 처리한다.

이 처리는 먼저 전체 장면에 자연스럽게 가장 가까운 표면을 반환하는 규칙적인 깊이 테스트를 적용하여 수행됩니다. 그런 다음 깊이 테스트 결과를 사용하여 깊이 테스트에서 반환 된 것보다 깊이가 낮은 모든 것을 무시하여 첫 번째 레이어를 필터링합니다.

깊이 테스트를 다시 적용하면 두 번째 레이어가 반환됩니다. 필요에 따라 반복하십시오.

레이어가 있으면 레이어가 앞뒤로 정렬되므로 모든 레이어를 역순으로 그릴 수 있습니다 (각 레이어의 RGBA 색상을 추적한다고 가정).


1
감사! 이를 위해 두 개의 깊이 버퍼가 필요한 것 같습니다. 즉, 마지막 깊이를 저장 및 필터링하고 다른 하나는 현재 렌더에 대한 깊이 테스트를 수행하는 것입니다. 내가 틀렸다면 수정하지만 각 필링 패스 사이를 교체하는 FBO에 대해 두 가지 깊이 텍스처가 필요하다고 가정합니다.
jozxyqk

1
@jozxyqk이 절차에는 두 개의 깊이 버퍼가 필요합니다.
es1024

1

단일 패스의 크림 드라 크림은 OpenGL의 투명성을 손상시키지 않습니다. 최신 OpenGL을 사용하면 다음을 구현할 수 있습니다.

http://blog.icare3d.org/2010/06/fast-and-accurate-single-pass-buffer.html

여러 번의 심도 필링을 피하고 번거로운 정렬이 필요하지 않습니다.


3
이상적으로 답변은 독립적이며 외부 링크에 크게 의존해야합니다. 링크가 있으면 보충 자료에 유용하지만 답변은 키워드로만 구성되어서는 안됩니다. A- 버퍼가 무엇이며 어떻게 작동하는지에 대한 세부 사항을 포함시킬 수 있다면 답을 크게 향상시킬 수 있습니다.
Martin Ender
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.