GPU에서 공유 정점 법선 만들기


9

나는 주로 Marching Cubes의 구현을 CPU에서 OpenGL 컴퓨팅 쉐이더로 이식하는 데 성공했지만 아직 법선을 다루지 않았으며 그것에 대해 가장 좋은 방법을 궁금해했습니다.

내 구현은 특히 이진 값 필드를 다루고 있습니다 (아직 거리 추정 기가없는 3D 프랙탈 함수를 모델링하려고합니다). 그라디언트 및 앞으로 차이 방법은 작동하지 않습니다. 나는 정점을 공유하고 있으며 CPU 구현은 여기 에 설명 된 Quilez의 방법을 사용 하여 각 인접 정점에 얼굴 법선을 축적합니다.

이 구현을 다른 셰이더로 이식 할 수는 있지만, 이것으로 볼 수있는 문제는 필요한 수많은 원자입니다. 우리는 스칼라 정수 유형에서만 원자를 사용할 수 있고 3 개의 부호있는 정수를 1로 요약 할 수있는 방법을 생각할 수 없으므로 쉐이더 호출 당 3 개의 축 * 3 개의 정점 = 9 개의 원자가 추가됩니다. 그것들은 물론 메모리 전체에 퍼져서 단일 원자 카운터를 9 번 누르는 것과 같지 않지만 여전히 많은 지옥처럼 보입니다.

다른 대안은 폴리곤마다 쉐이더 호출을 실행하고면 법선 목록을 작성하는 것입니다 (아마도이 ​​방법으로 x10y10z10으로 압축 할 수 있음). 정점 당 쉐이더는 이웃 얼굴의 모든 법선을 축적합니다. 이것은 거대한 메모리 호그 일 것입니다. 얼굴 인덱스의 저장 공간은 최악의 경우를 처리하기 위해 정점 당 12 int가 필요합니다. 또한 특정 정점에 이미 몇 개의면이 쓰여 졌는지 알아 내기 위해 원자에 의지하지 않고이 저장소에 쓰는 방법에 대한 문제도 있습니다.

이 작업을 수행하는 방법에 대한 더 나은 아이디어가 있습니까?

답변:


5

nVidia 전용 솔루션의 경우 NvInterlockedAddFp32와 같은 부동 소수점 원자 추가 내장 함수를 사용할 수 있습니다 . HLSL에서 GPU 내장 잠금 해제 | 엔비디아 개발자

80.000 버텍스 메시에서 이것을 시도했는데 매우 빠릅니다 (정확하게 기억한다면 GTX980M에서 1 또는 2 ms와 같은 것)

내장 기능이 작동하도록 릴리스에서 셰이더를 컴파일하는 것에주의하십시오 (Nvidia 버그 / 제한으로 인해)

또한 정점 분할 (예 : UV 불연속으로 인해)에주의해야합니다 (예 : UV 불연속으로 인해).


질문이 오래 되었기 때문에 대신 물어볼 것입니다 :-) 각 정점에 대한 단순 정보를 갖는 것이 rus에 충분하지 않다는 것을 이해합니다.
Andreas

이것은 작년 내 논문 프로젝트를위한 것이었고, 나는 바보 같은 방식으로 정수 원자 추가를 사용하고 정밀도를 최대화하기 위해 확장 된 다음 부동 벡터로 정규화했습니다. 최악의 공간을 할당하지 않고 원자 카운터를 사용하여 목록을 작성하지 않고 각 정점 주위의면을 나열하는 방법을 알 수 없었습니다. 그것은 지옥으로 아마 비효율적하지만 난 아직도 내가 :) 그것으로 행복 충분했다 있도록 CPU 버전과 일류 마크에서 크기 속도 향상의 주문 몇있어
러스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.