서명 된 거리 필드가있는 날카로운 모서리 글꼴


49

SDF (Signed Distance Fields)는 이 논문에서 Valve 해상도 독립적 글꼴 렌더링을 달성하는 빠른 솔루션으로 제시되었습니다 .

밸브 솔루션이 이미 작동하지만 모서리 주위의 선명도를 유지하고 싶습니다. 밸브는 그들의 방법이 두 번째 텍스처 채널을 기본 채널과 함께 사용하여 날카로운 모서리를 얻을 수 있지만이 두 번째 채널이 어떻게 생성 될지는 설명 할 수 없다고 말합니다.

실제로이 백서에는 구현 세부 사항이 많이 남아 있습니다.

날카로운 모서리가있는 SDF 글꼴 렌더링을 얻을 수있는 방향을 알려 주실 수 있는지 알고 싶습니다.


사실상 Adam은 이미 shadertoy에 소스 코드를 게시했습니다. 링크는 다음과 같습니다. shadertoy.com/view/ltXSDB
Felipe Lira

당신은 나를 흥분시켰다. 그는 bezier 재료를 shadertoy에 게시했지만 텍스처 거리 필드 재료는 게시하지 않았습니다!
Alan Wolfe

@AlanWolfe 나는 그가 절차 적으로 설정된 베 지어 곡선에 대해서만 수행했다고 생각합니다. 이것을 ttf render lib에 통합하는 데 필요한 노력이 확실하지 않습니다. 시간이 있으면 살펴 보겠습니다.
Felipe Lira

실제로 텍스처에서 거리를 저장하고 검색하는 측면에 매직 소스가있는 것 같습니다. 텍스처가 없으면 셰이더 토이 예제에는 방정식의 해당 부분이 없습니다.
Alan Wolfe

파티에 조금 늦었지만 reddit 의이 오래된 스레드는 SDF 기반 렌더링의 선명도를 향상시키는 다양한 방법에 대한 많은 정보를 가지고 있습니다 : reddit.com/r/gamedev/comments/2879jd/…
Necrolis

답변:


7

Adam Simmons는이 분야에서 몇 가지 흥미로운 작업을 수행했습니다. 그가 어떻게 달성했는지 구체적으로 알지 못하지만 그의 SDF 기반 벡터 렌더링은 Valve 외부에서 실제로 본 것 중 가장 선명합니다. http://twitter.com/adamjsimmons/status/611677036545863680


물론 자세한 내용은 없지만이 사람은 2006 년에 진, 맥쿨, 카플란에 의해 이미 증명 된 규칙적인 필드 대신 의사 거리 필드를 사용한 것 같습니다. 실시간 텍스처 매핑 벡터 글리프 "(밸브 용지에도 참조) 그것은 윤곽선의 연귀에만 영향을 미치고 모서리의 모양을 개선하기 위해 아무것도하지 않습니다. 나는 그것이 날카 로워 보이는 이유는 그가 실제로는 장거리 필드 텍스처를 사용하기 때문이라고 생각합니다. 그래도 잘못되었을 수 있습니다.
Detheroc

69

편집 : 구체적인 솔루션으로 다른 답변을 참조하십시오.

나는 1 년 전에 나의 석사 논문에서이 정확한 문제를 해결했다. 밸브 페이퍼에서, 그들은 당신이 이것을 달성하기 위해 두 개의 거리 필드를 가질 수 있고 볼록 코너가 하나만있는 한 작동한다는 것을 보여줍니다. 오목한 모서리에는 OR 연산도 필요합니다. 이 사람은 실제로 네 개의 텍스처 채널을 사용하여 두 작업 사이를 전환하는 모호한 시스템을 개발했습니다.

그러나 상황에 따라 AND와 OR을 모두 촉진 할 수있는 훨씬 간단한 연산이 있으며 이것이 제 논문의 주요 아이디어 인 3의 중앙값입니다 . 따라서 기본적으로 정확히 3 개의 채널 (RGB에 이상적)을 사용하고 완전히 교환 할 수 있으며 중간 연산을 사용하여 결합합니다 (3 개 중 중간 값 선택).

앤티 앨리어싱을 수용하기 위해 부울 만 사용하는 것이 아니라 부동 소수점 값을 사용하여 AND 연산이 최소가되고 OR이 최대 값이됩니다. 세 가지의 메디안 실제로 모두를 수행 할 수 있다면 < b를 위해 ( A는 , A는 , B ), 중앙값이 최소이며, 경우 ( A는 , B는 , B )는 최대이다.

렌더링 프로세스는 여전히 매우 간단합니다. 앤티 앨리어싱을 포함한 전체 조각 셰이더는 다음과 같습니다.

int main() {
    // Bilinear sampling of the distance field
    vec3 s = texture2D(sdf, p).rgb;
    // Acquire the signed distance
    float d = median(s.r, s.g, s.b) - 0.5;
    // Weight between inside and outside (anti-aliasing)
    float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
    // Combining the background and foreground color
    gl_FragColor = mix(outsideColor, insideColor, w);
}

따라서 원래 방법과의 유일한 차이점은 텍스처를 샘플링 한 직후 중앙값을 계산하는 것입니다. 그래도 중간 함수를 구현해야합니다. 중앙 함수는 4 분 / 최대 작업으로 수행 할 수 있습니다 .

물론 문제는 어떻게 이러한 3 채널 거리 필드를 구축 할 것인가입니다.그리고 이것은 까다로운 부분입니다. 처음에 취한 가장 확실한 접근 방식은 입력 모양 / 문자 모양을 세 가지 구성 요소로 분해 한 다음 각각의 거리 필드를 생성하는 것입니다. 이 분해에 대한 규칙은 그렇게 복잡하지 않습니다. 먼저, 3 개 중 2 개 이상의 채널이 켜져있는 영역이 내부입니다. 그런 다음 RGB 색상 채널로 생각하면 볼록한 모서리는 2 차 색상으로 만들어 져야하며 2 개의 기본 구성 요소는 바깥쪽으로 계속됩니다. 오목한 모서리는 그 반대입니다. 두 개의 보조 색상이 공통 기본 색상을 둘러싸고 두 가장자리가 안쪽으로 계속 연결되는 쐐기가 흰색입니다. 또한 2 차 원색 또는 2 차 2 차 색상이 인공물을 피하기 위해 닿는 부분 (예 : "N"

다음 이미지는 내 논문에서 프로그램에 의해 생성 된 분해 예입니다.

글리프의 다중 채널 분해

그러나이 방법에는 몇 가지 단점이 있습니다. 그중 하나는 윤곽선 및 그림자와 같은 특수 효과가 더 이상 올바르게 작동하지 않는다는 것입니다. Fortunatelly, 나는 또한 거리 필드를 직접 생성하고 모든 그래픽 효과를 지원하는 훨씬 더 우아한 두 번째 방법을 고안했습니다. 또한 논문에 포함되어 있으며 1 년이 넘었습니다. 현재이 두 번째 기법에 대해 자세히 설명하는 논문을 작성하고 있기 때문에 더 이상 자세한 내용은 밝히지 않겠습니다. 그러나 완료 되 자마자 여기에 게시하겠습니다.

어쨌든, 여기에 품질 차이의 예가 있습니다. 텍스처 해상도는 각 이미지에서 동일하지만 왼쪽은 일반 텍스처를 사용하고 가운데는 일반 거리 필드를 사용하며 오른쪽은 3 채널 거리 필드를 사용합니다. 성능 오버 헤드는 RGB 텍스처와 흑백 텍스처 사이의 차이입니다.

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


5
훌륭한 첫 번째 대답, Computer Graphics SE에 오신 것을 환영합니다! :) 논문을 공개적으로 사용할 수 있습니까? (또는 논문을 마친 후에도 가능할까요?) 그렇다면 그렇게하는 것이 도움이 될 것입니다.
Martin Ender

공개적으로 사용 가능해야하지만 학교에서 아직 사용하지 않은 것 같습니다. 어쨌든, 나는 지금 쓰고있는 기사가 실제로 중요한 부분을 훨씬 더 잘 설명하고 그것을 구현하는 방법에 초점을 맞추고 곧 완료 될 것이기 때문에 지금 그것을 퍼 뜨리고 싶지 않다.
Detheroc

@Detheroc 기사를 다 마치면 여기와 gamedev Q에 알려주십시오. 설명은 여전히 ​​100 % 명확하지 않습니다. 이미지에서 구성을 단계별로 보여주는 것이 좋습니다.
엔지니어

1
미래의 결과만큼 좋지 않은 경우에도 현재 결과를 복제 할 수 있기를 원하며 가능한 모든 세부 정보를 공유하기 위해 +1하십시오. 매우 흥미로운. 광선 마칭 (구 추적)에 대한 기술의 적용을 고려 했습니까? 볼륨 텍스처 또는 유사 ...
Alan Wolfe

4
논문은 여기에 공개되어 있습니다 : dspace.cvut.cz/bitstream/handle/10467/62770/…
Romain Guy

43

오래 기다려서 죄송하지만 약속 한 기사가 기본적으로 완료되었지만 게시 프로세스에는 다소 시간이 걸린다는 것이 분명해졌습니다. 따라서 대신 새로운 다중 채널 거리 필드 구성 알고리즘 인 msdfgen 을 사용하여 오픈 소스 프로그램을 준비 했습니다.

GitHub에서 사용할 수 있습니다 : https://github.com/Chlumsky/msdfgen

(이것이 처음이므로 저장소에 문제가 있는지 알려주십시오.)

누군가가 더 큰 흑백 거리 필드와 비교하는 방법에 대해서도 물었으므로 여기에 품질 차이의 티저가 있습니다. 그러나 실제로 특정 글꼴에 따라 다르며 항상 추가 데이터의 가치가 있다고는 말할 수 없습니다.

다중 채널 거리 필드 16x16 흑백 거리 필드 32x32


3

꽤 흥미로운! 나는 밸브 사인 거리 종이의 저자입니다. 구현 세부 정보가 약간 부족합니다. 나는 미래의 작업으로 두 가지 채널 예제 만 포함했습니다. 제너레이터가 없었습니다. 나는 고해상도 sdf를 생성 한 다음 sdf의 그라디언트 각도에 따라 분할하는 것이 합리적인 전술이라고 생각했습니다. 그러나 결코 그것을 얻지 못했습니다. 앱에 필요한 확대 비율에 대해 동일한 메모리 풋 프린트의 고해상도 단일 채널 데이터를 사용하여 모든 멀티 채널 체계를 평가해야합니다.


0

나는 결코 주제에 대한 전문가는 아니지만 적어도 이론적으로 표준 Bilinear 필터 대신 Bilateral 필터를 Directional Bicubic 필터를 사용하면 단색 의사 SDF에서 날카로운 모서리를 유지할 수 있습니다. 메모리 절약이라는 명백한 이점 외에도 여러 가지 색상의 SDF 데칼을위한 여러 채널이있을 수 있습니다.

또는 두 번째 채널을 사용하는 것이 마음에 들지 않으면 수평 거리와 수직 거리에 대해 다른 채널을 사용하고 중복 정보 (DoL) 에너지 피라미드를 사용하여 중복 정보를 얻지 못하도록 텍스처를 압축 할 수도 있습니다 기록되지 않습니다.

세 번째이자 마지막 이론적 솔루션은 배열 세트 주소 지정을 통해 6 각 샘플링 텍스처를 실험하는 것입니다.

불행히도 현재 아이디어를 테스트 할 수단이 없으며 아이디어와 유사한 것을 설명하거나 테스트하는 문서를 찾지 못했습니다. 정보 / 아이디어를 얻은 관련 기사를 모두 곧 연결합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.