총 12 자만 렌더링하지 않는 한 렌더링 외곽선은 곡률을 추정하기 위해 문자 당 필요한 정점 수로 인해 "없음"으로 유지됩니다. 픽셀 쉐이더에서 베 지어 곡선을 평가하는 접근 방법이 있었지만, 이들은 앤티 앨리어싱이 쉽지 않기 때문에 거리 맵 텍스쳐 쿼드를 사용하는 것이 쉽지 않으며 쉐이더의 곡선을 평가하는 데 여전히 필요한 것보다 훨씬 비쌉니다.
"빠른"품질과 "품질"간의 최상의 균형은 여전히 서명 된 거리 필드 텍스처를 가진 텍스처 쿼드입니다. 그것은이다 아주 약간 하지만 너무 느린 일반 정상적인 질감 쿼드를 사용하는 것보다. 반면에 품질은 완전히 다른 야구장에 있습니다. 결과는 정말 놀랍고, 최대한 빨리 얻을 수 있으며, 글로우와 같은 효과도 쉽게 추가 할 수 있습니다. 또한 필요한 경우이 기술을 이전 하드웨어로 다운 그레이드 할 수 있습니다.
이 기술에 대한 유명한 밸브 용지 를 참조하십시오 .
이 기법은 다각형을 생성하지 않지만 암시 적 표면 (메타 볼 등)의 작동 방식과 개념적으로 유사합니다. 전적으로 픽셀 쉐이더에서 실행되며 텍스처에서 샘플링 된 거리를 거리 함수로 사용합니다. 선택한 임계 값 (일반적으로 0.5)을 초과하는 모든 항목은 "in"이고 다른 모든 항목은 "out"입니다. 가장 간단한 경우, 10 살짜리 셰이더가없는 하드웨어에서 알파 테스트 임계 값을 0.5로 설정하면 정확한 효과를 얻을 수 있습니다 (특수 효과 및 앤티 앨리어싱 제외).
글꼴 (가짜 굵은 체)에 약간 더 많은 가중치를 추가하려면 한 줄의 코드를 수정하지 않고도 임계 값이 조금 더 작습니다 ( "font_weight"유니폼 변경). 글로우 효과의 경우, 단순히 하나의 임계 값을 초과하는 모든 것을 "in"으로 간주하고 다른 (작은) 임계 값을 초과하는 모든 것을 "out, but in glow"로 간주하고 LERP는 둘 사이를 고려합니다. 앤티 앨리어싱도 비슷하게 작동합니다.
단일 비트가 아닌 8 비트 부호있는 거리 값을 사용하여이 기법은 텍스처 맵의 유효 해상도를 각 차원에서 16 배 증가시킵니다 (흑백 대신 모든 가능한 음영이 사용되므로 256 배 동일한 저장소를 사용하는 정보). 그러나 16 배 이상으로 확대하더라도 결과는 여전히 타당합니다. 긴 직선은 결국 약간 흔들리지 만 전형적인 "블록킹"샘플링 아티팩트는 없습니다.
점에서 쿼드를 생성하기 위해 지오메트리 쉐이더를 사용할 수 있지만 (버스 대역폭 감소) 솔직히 게인은 다소 미미합니다. GPG8에 설명 된 인스턴스화 된 문자 렌더링의 경우에도 마찬가지입니다. 인스 턴싱의 오버 헤드는 많은 그릴 텍스트가 . 필자의 의견으로는 추가 된 복잡성과 비 다운 그레이드 가능성과 관련이 없다고 생각합니다. 또한 상수 레지스터의 양에 제한을 받거나 캐시 일관성에 대해 최적이 아닌 텍스처 버퍼 객체에서 읽어야합니다 (및 의도는 처음부터 최적화하는 것입니다!). 경우에만 상각됩니다
. 단순하고 평범한 오래된 정점 버퍼는 업로드 시간을 조금 앞당겨 예약하고 지난 15 년 동안 구축 된 모든 하드웨어에서 실행되는 것처럼 빠릅니다 (아마도 빠릅니다). 또한 글꼴의 특정 문자 수 또는 렌더링 할 특정 문자 수로 제한되지 않습니다.
글꼴에 256자를 초과하지 않는 경우 텍스처 셰이더는 지오메트리 셰이더의 포인트에서 쿼드를 생성하는 것과 유사한 방식으로 버스 대역폭을 제거하는 것이 좋습니다. 배열 텍스처를 사용할 때 모든 쿼드의 텍스처 좌표는 동일하고, 상수 s
이며, t
좌표 는 동일 하며 좌표 만 다릅니다 r
. 이는 렌더링 할 문자 인덱스와 같습니다.
그러나 다른 기술과 마찬가지로 이전 세대 하드웨어와 호환되지 않으면 예상되는 이득은 미미합니다.
거리 텍스처를 생성하기위한 Jonathan Dummer의 편리한 도구가 있습니다 : description page
업데이트 :
최근에 프로그래밍 가능한 정점 풀링 (D. Rákos, "OpenGL Insights", pp. 239) 에서 지적했듯이 최신 GPU의 셰이더에서 프로그래밍 방식으로 정점 데이터를 가져 오는 것과 관련된 추가 대기 시간이나 오버 헤드는 없습니다. 표준 고정 기능을 사용하여 동일한 작업을 수행하는 것과 비교할 때
또한 최신 세대의 GPU는 점점 더 합리적인 크기의 범용 L2 캐시 (예 : 엔비디아 케플러의 1536kiB)를 가지므로 버퍼 텍스처에서 쿼드 코너에 대한 임의의 오프셋을 가져올 때 비 일관적인 액세스 문제가 발생할 수 있습니다. 문제.
따라서 버퍼 텍스처에서 일정한 데이터 (예 : 쿼드 크기)를 가져 오는 아이디어가 더 매력적입니다. 따라서 가상 구현은 다음과 같은 접근 방식으로 GPU 메모리뿐만 아니라 PCIe 및 메모리 전송을 최소로 줄일 수 있습니다.
- 이 색인을 통과하는 정점 셰이더에 대한 유일한 입력으로 문자 색인 (표시 할 문자 당 하나) 만 업로드
gl_VertexID
하고을 형상 쉐이더의 4 점으로 증폭하여 문자 색인과 정점 ID를 유지하십시오. "버텍스 쉐이더에서 사용할 수있는 gl_primitiveID")가 유일한 속성으로 변환 피드백을 통해이를 캡처합니다.
- 두 가지 출력 속성 (GS의 주요 병목 현상) 만 있고 두 단계 모두에서 "no-op"에 가깝기 때문에 이것은 빠릅니다.
- 글꼴의 각 문자에 대해 기준점을 기준으로 질감 처리 된 쿼드의 정점 위치를 포함하는 버퍼 텍스처를 바인딩합니다 (기본적으로 "글꼴 메트릭"임). 이 데이터는 왼쪽 하단 정점의 오프셋 만 저장하고 축 정렬 상자의 너비와 높이를 인코딩하여 쿼드 당 4 개의 숫자로 압축 할 수 있습니다 (반 부동 수를 가정하면 문자 당 8 바이트의 상수 버퍼 임). 일반적인 256 문자 글꼴은 2kiB의 L1 캐시에 완전히 들어갈 수 있습니다).
- 기준선에 유니폼을 설정
- 버퍼 오프셋을 수평 오프셋과 바인딩합니다. 이것들 은 아마도 GPU에서 계산 될 수도 있지만, CPU에서 이런 종류의 작업에 훨씬 쉽고 효율적입니다. 왜냐하면 엄격하게 순차적 인 작업이므로 전혀 중요하지 않습니다 (커닝에 대한 생각). 또한 다른 피드백 포인트가 필요하며 이는 다른 동기 점입니다.
- 피드백 버퍼에서 이전에 생성 된 데이터를 렌더링하면 정점 셰이더는 기준점의 수평 오프셋과 버퍼 객체에서 코너 정점의 오프셋을 가져옵니다 (기본 ID 및 문자 색인 사용). 제출 된 정점의 원래 정점 ID는 이제 "기본 ID"입니다 (GS가 정점을 쿼드로 바꾼 것을 기억하십시오).
이와 같이, 단일 정점 만 렌더링 할 수는 있지만 필요한 정점 대역을 75 %까지 줄일 수 있습니다. 한 번의 호출로 여러 줄을 렌더링하려면 유니폼을 사용하는 대신 버퍼 텍스처에 기준선을 추가해야합니다 (대역폭이 더 작아짐).
그러나 "합리적인"양의 텍스트를 표시하는 정점 데이터가 약 50-100kiB (실제로 0)GPU 또는 PCIe 버스에 해당) 이기 때문에 75 % 감소를 가정하더라도 여전히 복잡성이 추가되는 것은 의심됩니다. 이전 버전과의 호환성을 잃는 것은 실제로 문제가 될만한 가치가 있습니다. 0을 75 % 줄이면 여전히 0입니다. 나는 위의 접근법을 시도하지 않았으며, 진정한 자격을 갖춘 진술을하기 위해서는 더 많은 연구가 필요할 것입니다. 그러나 여전히 누군가가 정말 놀라운 성능 차이 (수십억자가 아닌 "일반적인"양의 텍스트를 사용함)를 보여줄 수 없다면, 내 관점은 정점 데이터의 경우 단순하고 평범한 오래된 정점 버퍼가 충분히 훌륭하다는 것입니다. "최신 솔루션"의 일부로 간주됩니다. 간단하고 간단합니다.
위에서 " OpenGL Insights " 를 이미 참조 했으므로 Stefan Gustavson의 "거리 필드 별 2D 모양 렌더링" 장을 참조하여 거리 필드 렌더링에 대해 자세히 설명합니다.
2016 업데이트 :
한편, 극단적 인 배율에서 방해되는 코너 라운딩 인공물을 제거하는 것을 목표로하는 몇 가지 추가 기술이 존재한다.
한 가지 접근 방식은 단순히 거리 필드 대신 의사 거리 필드를 사용합니다 (차이는 실제 윤곽선이 아니라 가장자리 또는 가장자리 위로 튀어 나오는 가상 선 까지의 최단 거리라는 차이점이 있습니다). 이것은 약간 더 좋으며 같은 양의 텍스처 메모리를 사용하여 같은 속도 (동일한 셰이더)로 실행됩니다.
다른 접근법은 github에서 사용 가능한 3 채널 텍스처 세부 사항 및 구현에서 3 중위를 사용합니다 . 이는 이전에 문제를 해결하기 위해 사용 된 해킹 및 / 또는 해킹에 비해 개선되는 것입니다. 좋은 품질, 약간, 거의 눈에 띄지는 않지만 느리지 만 텍스처 메모리의 3 배를 사용합니다. 또한 추가 효과 (예 : 광선)를 제대로 맞추기가 더 어렵습니다.
마지막으로, 캐릭터를 구성하는 실제 베 지어 곡선을 저장하고 프래그먼트 셰이더로 평가하는 것은 약간 열악한 성능 (그러나 문제가되지는 않지만)과 가장 높은 배율에서도 놀라운 결과를 제공하여 실용적이되었습니다 .
이 기술을 사용하여 대형 PDF를 실시간으로 렌더링하는 WebGL 데모는 여기 에서 볼 수 있습니다 .