기하 도형 인식 개요
이 항목에서는 Direct2D geometry 실현을 사용하여 특정 시나리오에서 앱의 기하 도형 렌더링 성능을 개선하는 방법을 설명합니다.
여기에는 다음 단원이 포함되어 있습니다.
- 기하 도형 실현이란?
- 기하 도형 실현을 사용하는 이유는 무엇인가요?
- 기하 도형 실현을 사용하는 경우
- 기하 도형 실현 만들기
- 그리기 기하 도형 실현
- 기하 도형 실현 크기 조정
- 관련 항목
기하 도형 실현이란?
Windows 8.1 도입된 기하 도형 실현은 Direct2D 앱이 특정 경우에 기하 도형 렌더링 성능을 쉽게 개선할 수 있도록 하는 새로운 유형의 그리기 기본 형식입니다. 기하 도형 실현은 ID2D1GeometryRealization 인터페이스로 표시됩니다.
기하 도형 실현을 사용하는 이유는 무엇인가요?
Direct2D가 ID2D1Geometry 개체를 렌더링하는 경우 해당 기하 도형을 테셀레이션이라는 프로세스를 통해 그래픽 하드웨어가 이해하는 형태로 변환해야 합니다. 일반적으로 Direct2D는 기하 도형이 변경되지 않더라도 그려질 때마다 기하 도형을 분할해야 합니다. 앱이 프레임마다 동일한 기하 도형을 렌더링하는 경우 반복되는 다시 분할은 낭비된 계산 작업을 나타냅니다. 기하 도형의 테셀레이션 또는 전체 래스터화를 캐시하고 반복적으로 다시 테셀레이션하는 대신 각 프레임에 캐시된 표현을 그리는 것이 더 계산 효율적입니다.
개발자가 이 문제를 해결하는 일반적인 방법은 기하 도형의 전체 래스터화를 캐시하는 것입니다. 특히 새 비트맵을 만들고, 기하 도형을 해당 비트맵으로 래스터화한 다음, 필요에 따라 해당 비트맵을 장면에 그리는 것이 일반적입니다. (이 방법은 Direct2D 앱의 성능 향상의 기하 도형 렌더링 섹션에 설명되어 있습니다.) 이 방법은 계산 효율이 매우 높지만 몇 가지 단점이 있습니다.
- 캐시된 비트맵은 장면에 적용된 변환의 변경 내용에 민감합니다. 예를 들어 래스터화 크기를 조정하면 눈에 띄는 크기 조정 아티팩트가 발생할 수 있습니다. 고품질 크기 조정 알고리즘을 사용하여 이러한 아티팩트 완화는 계산 비용이 많이 들 수 있습니다.
- 캐시된 비트맵은 특히 고해상도로 래스터화된 경우 상당한 양의 메모리를 사용합니다.
기하 도형 실현은 위의 단점을 방지하는 기하 도형을 캐시하는 다른 방법을 제공합니다. 기하 도형 실현은 픽셀(전체 래스터화의 경우와 같이)이 아니라 수학적 평면의 포인트로 표시됩니다. 이러한 이유로 크기 조정 및 기타 조작에 대한 전체 래스터화보다 덜 민감하며 메모리를 훨씬 적게 사용합니다.
기하 도형 실현을 사용하는 경우
앱에서 셰이프가 자주 변경되지 않지만 변형이 변경될 수 있는 복잡한 기하 도형을 렌더링할 때 기하 도형 실현을 사용하는 것이 좋습니다.
예를 들어 정적 맵을 표시하지만 사용자가 확대 및 축소할 수 있는 매핑 애플리케이션을 고려해 보세요. 이 앱은 기하 도형 실현을 사용하면 이점을 얻을 수 있습니다. 렌더링되는 기하 도형은 정적 상태로 유지되므로 테셀레이션 작업을 저장하기 위해 캐시하는 것이 유용합니다. 그러나 사용자가 확대/축소할 때 맵의 크기가 조정되므로 아티팩트 크기 조정으로 인해 전체 래스터화를 캐싱하는 것이 이상적이지 않습니다. 기하 도형 실현을 캐싱하면 크기 조정 중에 높은 시각적 품질을 유지하면서 앱이 다시 분할 작업을 방지할 수 있습니다.
반면에 애니메이션 기하 도형이 지속적으로 변경되는 만화경 앱을 고려해 보세요. 이 앱은 기하 도형 실현을 사용하면 도움이 되지 않을 것입니다. 셰이프 자체는 프레임에서 프레임으로 변경되므로 테셀레이션을 캐시하는 것은 유용하지 않습니다. 이 앱의 가장 좋은 방법은 ID2D1Geometry 개체를 직접 그리는 것입니다.
기하 도형 실현 만들기
ID2D1GeometryRealization 개체는 기존 ID2D1Geometry 개체에서 만들어야 합니다. 기하 도형 실현을 만들려면 CreateFilledGeometryRealization 메서드 또는 CreateStrokedGeometryRealization 메서드를 호출하고 ID2D1Geometry 를 전달하여 실현합니다.
- CreateFilledGeometryRealization 은 FillGeometry를 호출하여 그릴 영역인 셰이프의 내부를 실현합니다.
- CreateStrokedGeometryRealization 은 DrawGeometry를 호출하여 그릴 영역인 셰이프의 스트로크를 실현합니다.
두 종류의 기하 도형 실현은 모두 ID2D1GeometryRealization 인터페이스로 표시됩니다.
기하 도형 실현을 만들 때 Direct2D 는 제공된 기하 도형의 모든 곡선을 다각형 근사값으로 평면화해야 합니다. 생성 방법에 평면화 허용 오차 매개 변수를 제공해야 합니다. 이 매개 변수는 기하 도형의 실제 곡선과 다각형 근사값 사이의 최대 거리(DIP)를 지정합니다. 제공하는 평면화 허용 오차가 낮을수록 결과 기하 도형 실현 개체의 충실도가 높습니다. 마찬가지로, 더 높은 평면화 허용 오차를 제공하면 더 낮은 충실도 기하 도형 실현이 생성됩니다. 충실도가 높은 기하 도형 실현은 낮은 충실도보다 그리는 데 비용이 더 많이 들지만, 표시되는 아티팩트가 도입되기 전에 더 확장할 수 있습니다. 평면화 허용 오차 사용에 대한 지침은 아래 기하 도형 실현 크기 조정을 참조하세요 .
참고
Geometry 실현 개체는 특정 그래픽 디바이스와 연결됩니다. 디바이스 종속 리소스입니다.
그리기 기하 도형 실현
기하 도형 실현을 그리는 것은 비트맵과 같은 다른 Direct2D 기본 형식을 그리는 것과 비슷합니다. 이렇게 하려면 DrawGeometryRealization 메서드를 호출하고 그릴 geometry realization 개체와 사용할 브러시를 전달합니다. 다른 Direct2D 그리기 메서드와 마찬가지로 BeginDraw 및 EndDraw 호출 간에 DrawGeometryRealization을 호출해야 합니다.
기하 도형 실현 크기 조정
다른 Direct2D 기본 형식과 마찬가지로 기하 도형 실현은 디바이스 컨텍스트에서 설정된 변환을 존중합니다. 변환 및 회전 변환은 기하 도형 실현의 시각적 품질에 영향을 주지 않지만 크기 조정 변환은 시각적 아티팩트 생성을 수행할 수 있습니다.
특히 기하 도형 실현에 충분히 큰 배율을 적용하면 실제 곡선의 다각형 근사값이 드러날 수 있습니다. 여기에 있는 이미지는 너무 멀리 확장된 타원형 기하 도형 실현(채우기 및 스트로크)의 쌍을 보여줍니다. 곡선 평면화 아티팩트가 표시됩니다.
시각적 품질에 민감한 앱은 이러한 문제가 발생하지 않도록 조치를 취해야 합니다. 크기 조정을 처리하는 방법은 앱의 요구 사항에 따라 달라집니다. 다음은 여러 유형의 앱에 권장되는 몇 가지 접근 방식입니다.
크기 조정되지 않는 앱에서 기하 도형 실현 사용
앱이 기하 도형 실현에 대한 스케일링을 수행하지 않는 경우 단일 평면화 허용 오차를 사용하여 한 번만 실현을 만드는 것이 안전합니다. 비 크기 조정 변환은 렌더링된 기하 도형 실현의 시각적 품질에 영향을 미치지 않습니다. ComputeFlatteningTolerance 함수를 사용하여 DPI에 대한 적절한 평면화 허용 오차를 계산합니다.
float dpiX, dpiY;
deviceContext->GetDpi(&dpiX, &dpiY);
float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
D2D1::Matrix3x2F::Identity(), // apply no additional scaling transform
dpiX, // horizontal DPI
dpiY // vertical DPI
);
작은 크기로 스케일링되는 앱에서 기하 도형 실현 사용
앱이 기하 도형 실현을 소량(예: 최대 2x 또는 3배)으로 확장할 수 있는 경우 기하 도형 실현을 기본값보다 비례적으로 낮은 평면화 허용 오차로 한 번 만드는 것이 적절할 수 있습니다. 이렇게 하면 크기 조정 아티팩트가 발생하기 전에 크게 확장할 수 있는 더 높은 충실도 실현이 만들어집니다. 절충은 더 높은 충실도 실현을 그리려면 더 많은 작업이 필요하다는 것입니다.
예를 들어 앱이 기하 도형 실현의 크기를 2배 이상 조정하지 않는다는 것을 알고 있다고 가정해 보겠습니다. 앱은 기본값의 절반인 평면화 허용 오차를 사용하여 기하 도형 실현을 만들고 필요에 따라 최대 2배까지 실현 크기를 조정할 수 있습니다. ComputeFlatteningTolerance 함수를 사용하여 maxZoomFactor 매개 변수로 2.0을 전달하여 적절한 평면화 허용 오차를 계산합니다.
float dpiX, dpiY;
deviceContext->GetDpi(&dpiX, &dpiY);
float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
D2D1::Matrix3x2F::Identity(), // apply no additional scaling transform
dpiX, // horizontal DPI
dpiY, // vertical DPI
2.0f // realization can be scaled by an additional 2x
);
대량으로 스케일링되는 앱에서 기하 도형 실현 사용
앱이 기하 도형 실현을 대량으로 확장 또는 축소할 수 있는 경우(예: 10배 이상) 크기 조정을 적절하게 처리하는 것이 더 복잡합니다.
이러한 앱 대부분에서 권장되는 방법은 시각적 충실도를 유지하고 아티팩트 크기를 조정하지 않도록 장면이 확장됨에 따라 평면화 허용 오차를 점진적으로 낮추면서 기하 도형 실현을 다시 만드는 것입니다. 마찬가지로 장면이 축소됨에 따라 앱은 보이지 않는 세부 정보를 낭비적으로 렌더링하지 않도록 점진적으로 더 높은 평면화 허용 오차에서 기하 도형 실현을 다시 만들어야 합니다. 이렇게 하면 테셀레이션 작업을 캐싱하는 목적이 무효화되므로 크기 조정이 변경 될 때마다 앱에서 기하 도형 실현을 다시 만들지 않아야 합니다. 대신, 앱은 기하 도형 실현을 덜 자주 다시 만들어야 합니다( 예: 2배 증가 또는 감소할 때마다).
사용자 상호 작용에 대한 응답으로 앱에서 크기 조정이 변경 될 때마다 앱은 기하 도형 실현이 마지막으로 만들어진 눈금(예: m_lastScale 멤버에 저장됨)과 새 눈금을 비교할 수 있습니다. 두 값이 닫히면(이 경우 2의 요소 내에서) 추가 작업이 수행되지 않습니다. 그러나 두 값이 닫히지 않으면 기하 도형 실현이 다시 만들어집니다. ComputeFlatteningTolerance 함수는 새 배율에 적합한 평면화 허용 오차를 계산하는 데 사용되며 m_lastScale 새 눈금으로 업데이트됩니다.
또한 앱은 maxZoomFactor 매개 변수로 2 값을 ComputeFlatteningTolerance에 전달하여 새 눈금에 일반적으로 사용되는 것보다 더 작은 허용 오차를 사용하여 항상 실현을 만듭니다. 이렇게 하면 크기 조정 아티팩트를 발생시키지 않고 새 기하 도형 실현을 2의 추가 요소로 확장할 수 있습니다.
참고
여기에 설명된 접근 방식은 모든 앱에 적합하지 않을 수 있습니다. 예를 들어 앱에서 매우 큰 요소로 장면을 매우 빠르게 스케일링할 수 있도록 허용하는 경우(예: 몇 프레임 범위에서 100%에서 1,000,000%로 이동할 수 있는 "확대/축소" 슬라이더가 포함된 경우) 이 접근 방식은 모든 프레임마다 기하 도형 실현을 다시 만들어 과도한 작업을 초래할 수 있습니다. 다른 방법은 장면 눈금의 각 조작이 완료된 후에만 기하 도형 실현을 다시 만드는 것입니다(예: 사용자가 손가락 모으기 제스처를 완료한 후).