WebVR에서 텍스트 렌더링

내부 세부정보

사이트 보기

내부 (https://with.in/)는 가상 현실에서 스토리텔링하기 위한 플랫폼입니다. 그래서 팀이 2015년에 WebVR에 대해 알게 되었을 때 즉시 WebVR의 잠재력에 관심을 보였습니다. 하지만 이러한 관심은 오늘날 Google 웹 플랫폼의 고유한 하위 도메인인 https://vr.with.in/에서 드러납니다. VR 지원 브라우저를 사용하는 사용자라면 누구나 사이트로 이동하여 버튼을 클릭한 후 헤드셋을 착용해 Google의 VR 영화 포트폴리오에 몰입할 수 있습니다.

현재, 여기에는 Daydream View용 Chrome이 포함되지만 이에 국한되지는 않습니다. 기기 및 헤드 마운트 디스플레이에 관한 자세한 내용은 https://webvr.info/를 참고하세요.

다른 가상 현실 전용 렌더링 환경과 마찬가지로 웹은 주로 장면의 3차원 표현에 의존합니다. 이 장면에는 카메라, 사용자의 시점, 여러 객체가 표시됩니다. 이 장면, 카메라, 객체를 관리하는 데 도움이 되도록 Google에서는 <canvas> 요소를 활용하여 컴퓨터 GPU에 렌더링을 발생시키는 Three.js라는 라이브러리를 사용합니다. WebVR에서 장면을 볼 수 있도록 하는 유용한 Three.js 부가기능이 많이 있습니다. 주요 두 가지 요소는 각 눈에 대해 표시 영역을 만들기 위한 THREE.VREffect와 원근법 (예: 머리 장착형 디스플레이의 회전 및 위치)을 장면에 맞게 변환하기 위한 THREE.VRControls입니다. 이를 구현하는 방법의 많은 예가 있습니다. 시작하는 방법은 Three.js WebVR 예를 참고하세요.

WebVR을 더 자세히 탐색해 가면서 문제가 발생했습니다. 우리가 웹 콘텐츠를 보면 텍스트는 중요한 부분입니다. 대부분의 콘텐츠는 동영상 기반이지만 사이트 내로 이동하면 콘텐츠 주위에 텍스트가 표시됩니다. 영화 또는 관련 영화에 대한 사용자 인터페이스와 추가 정보는 모두 텍스트로 구성됩니다. 또한 이러한 모든 텍스트는 DOM에서 만들어집니다. WebVR 탐색 및 https://vr.with.in/은 모두 <canvas>에 있습니다.

WebVR에 사용되는 텍스트 WebVR에 사용되는 텍스트
vr.with.in의 WebVR에 사용되는 텍스트

어떤 옵션이 있나요?

다행히 이를 실현하기 위한 작업이 진행 중입니다. 실제로 Google은 연구를 통해 <canvas> 요소를 기반으로 3차원 환경에서 텍스트를 렌더링하는 여러 가지 효과적인 방법을 찾았습니다. 다음은 각각의 장단점이 표시된 몇 가지 매트릭스입니다.

해상도와 무관 서체 기능 성능 용이한 구현
2D 캔버스 텍스트 지원됨 지원됨
삼각형 벡터 텍스트 지원됨 지원됨
돌출된 3D 텍스트 지원됨
서명된 거리 필드 비트맵 텍스트 지원됨 지원됨

Google의 결정: SDF 비트맵 글꼴

ctx.fillText()를 사용하는 2D 캔버스에서는 텍스트 줄바꿈, 문자 간격, 행 높이를 실행할 수 있지만 너무 멀리 확대하면 오버플로가 잘리고 텍스트가 흐려집니다. 캔버스 텍스처의 크기를 늘릴 수 있지만 텍스처 크기의 상한에 도달하여 텍스처가 너무 클 경우 성능이 저하될 수 있습니다.

돌출된 3D 텍스트는 삼각 벡터 텍스트와 본질적으로 동일하지만 깊이가 있고 경사면이 있을 수 있으므로 도형이 두 배 이상 많습니다. 이러한 방법 중 하나는 제목이나 로고에 소량으로 사용할 수 있지만 대량의 텍스트에서는 제대로 작동하지 않으며 둘 다 서체 기능이 없습니다.

글꼴에서 SDF 비트맵으로의 워크플로
SDF 비트맵별 글꼴 워크플로

비트맵 글꼴은 문자당 하나의 쿼드 (두 개의 삼각형)를 사용하므로 삼각형 벡터보다 도형을 적게 사용하며 성능이 더 우수합니다. 텍스처 맵 스프라이트를 사용하므로 여전히 래스터 기반이지만 SDF 셰이더를 사용하면 기본적으로 해상도에 독립적이므로 2D 캔버스 텍스처보다 더 보기 좋습니다. Matt DesLauriers의 세 bmfont-text에는 텍스트 줄바꿈, 글자 간격, 줄 간격, 정렬을 위한 안정적인 서체 기능도 포함되어 있습니다. 오버플로우가 잘리지 않습니다. 글꼴 크기는 배율을 통해 제어됩니다. 이 방법을 선택한 이유는 성능을 유지하면서 최고의 디자인을 얻을 수 있었기 때문입니다. 안타깝게도 구현이 쉽지 않았으므로 WebVR로 작업하는 다른 개발자를 돕기 위해 단계를 살펴보겠습니다.

1. 비트맵 글꼴 생성 (.png + .fnt)

Hiero 인터페이스
Hiero 인터페이스
Hiero 출력 (비트맵 PNG 및 .fnt 파일) Hiero 출력 (비트맵 PNG 및 .fnt 파일)
Hiero 출력 (비트맵 PNG 및 .fnt 파일)

Hiero는 자바로 실행되는 비트맵 글꼴 패킹 도구입니다. Hiero 문서에서는 복잡한 빌드 프로세스를 거치지 않고 실행하는 방법을 설명하지 않습니다. 아직 설치하지 않았다면 먼저 자바를 설치합니다. 그런 다음 runnable-hiero.jar를 더블클릭해도 Hiero가 열리지 않으면 콘솔에서 다음 명령어를 사용하여 실행해 보세요.

java -jar runnable-hiero.jar

Hiero가 실행되면 .ttf 또는 .otf 데스크톱 글꼴을 열고, 포함할 추가 문자를 입력하고, 효과를 사용하기 위해 Java로 렌더링을 변경하고, 문자가 전체 글리프 캐시 정사각형을 채우도록 크기를 늘리고, 거리 필드 효과를 추가하고, 거리 필드의 배율과 확산을 조정합니다. 배율 값은 해상도와 같습니다. 값이 높을수록 흐릿해지지만 Hiero가 미리보기를 렌더링하는 데 시간이 더 오래 걸립니다. 그런 다음 비트맵 글꼴을 저장합니다. .png 이미지와 AngelCode .fnt 글꼴 설명 파일로 구성된 비트맵 글꼴을 생성합니다.

2. AngelCode를 JSON으로 변환

비트맵 글꼴이 생성되었으므로 Matt DesLauriers의 load-bmfont npm 패키지를 사용하여 JavaScript 앱에 로드해야 합니다.

load-bmfont를 브라우저화하고 프런트엔드에서 사용할 수 있지만 대신 Node에서 load-bmfont.js를 실행하여 Hiero의 AngelCode .fnt를 변환하고 .json 파일로 저장합니다.

npm install
node load-bmfont.js
출력 JSON의 예
출력 JSON의 예

이제 load-bmfont를 우회하고 .json 글꼴 파일에 XHR (XMLHttpRequest) 요청을 실행하기만 하면 됩니다.

var r = new XMLHttpRequest();
r.open('GET', 'fonts/roboto/bitmap/roboto-bold.json');

r.onreadystatechange = function() {
    if (r.readyState === 4 && r.status === 200) {
    setup(JSON.parse(r.responseText));
    }
};

r.send();

function setup(font) {
    // pass font into TextBitmap object
}

3. Browserify 세 bmfont 텍스트

글꼴이 로드되면 Matt의 세 개의 bmfont-텍스트가 나머지를 처리합니다. 자체 앱에는 Node를 사용하지 않으므로 three-bmfont-text.js를 사용 가능한 three-bmfont-text-bundle.jsbrowserify합니다.

npm install -g browserify
browserify three-bmfont-text.js -o three-bmfont-text-bundle.js

4. SDF 셰이더

부호 있는 거리 필드 셰이더의 영향을 확인하려면 vr.with.in/archive/text-sdf-bitmap/에서 afwidththreshold 슬라이더를 조정합니다.

5. 사용

편의를 위해 브라우저화된 3-bmfont-text용 TextBitmap 래퍼 클래스를 만들었습니다.

Text-sdf-bitmap 실제 작동 방식
Text-sdf-bitmap 실제 사례
<script src="three-bmfont-text-bundle.js"></script>
<script src="sdf-shader.js"></script>
<script src="text-bitmap.js"></script>

.json 글꼴 파일에 대한 XHR 요청을 생성하고 콜백에서 텍스트 객체를 만듭니다.

var bmtext = new TextBitmap({ options });

텍스트를 변경하려면 다음 단계를 따르세요.

bmtext.text = 'The quick brown fox jumps over the lazy dog.';

scene.add( bmtext.group );
hitBoxes.push( bmtext.hitBox );

비트맵 글꼴의 .png가 text-bitmap.js에서 THREE.TextureLoader로 로드됨

TextBitmap에는 마우스, 카메라 또는 손 추적 모션 컨트롤러(예: Oculus Touch 또는 Vive 컨트롤러)를 통한 세.js 레이캐스트 상호작용을 위한 보이지 않는 히트박스도 포함되어 있습니다. 텍스트 옵션을 변경하면 히트박스의 크기가 자동으로 업데이트됩니다.

Bmtext.group이 third.js 장면에 추가됩니다. 하위 요소/Object3D에 액세스해야 하는 경우 텍스트의 장면 그래프는 다음과 같습니다.

파일 시스템 다이어그램

6. JSON 축소 및 xoffsets 수정

텍스트 GIF 내

커닝이 꺼져 있는 경우 json에서 xoffset을 수정해야 할 수 있습니다. json을 Jsbeautifier.org에 붙여넣어 파일의 축소된 버전을 가져옵니다.

xoffset은 기본적으로 한 문자에 대한 전역 커닝입니다. 커닝은 나란히 표시되는 두 개의 특정 문자에 사용됩니다. 커닝 배열의 기본값은 실제로 영향을 미치지 않으며 편집하기가 너무 번거롭기 때문에 해당 배열을 비우면 json 파일 크기를 줄일 수 있습니다. 그런 다음 커닝의 xoffset을 수정합니다.

먼저 json에서 어떤 문자가 어떤 문자 ID와 함께 연결되는지 파악해야 합니다. three-bmfont-text-bundle.js에서 240행 뒤에 console.log를 삽입합니다.

    var id = text.charCodeAt(i)
    // console.log(id);

그런 다음 https://vr.with.in/archive/text-sdf-bitmap/의 dat.gui 텍스트 필드에 문자를 입력하고 상응하는 문자 ID를 콘솔을 확인합니다.

예를 들어, 비트맵 글꼴에서 'j'가 일관되게 너무 오른쪽에 위치합니다. 문자 ID는 106입니다. 따라서 json에서 "id": 106을 찾아 xoffset을 -1에서 -10으로 변경합니다.

7. 레이아웃

텍스트 블록이 여러 개 있고 HTML처럼 위에서 아래로 흐르게 하려면 CSS를 사용해 모든 DOM 요소를 직접 배치하는 것과 마찬가지로 모든 것을 수동으로 배치해야 합니다. CSS에서 이 작업을 한다고 상상할 수 있나요?

    * { position: absolute; }

이것이 3D의 텍스트 레이아웃입니다. 세부정보 뷰에서 제목, 작성자, 설명, 기간은 각각 고유한 스타일, 색상, 배율 등이 있는 새로운 TextBitmap 객체입니다.

3D 레이아웃
author.group.position.y = title.group.position.y - title.height - padding;
description.group.position.y = author.group.position.y - author.height - padding;
duration.group.position.y = description.group.position.y - description.height - padding;

여기서는 각 TextBitmap 그룹의 로컬 원점이 TextBitmap 메시의 상단에 세로로 정렬되어 있다고 가정합니다 (text-bitmap.js 업데이트의 가운데 맞춤 참고). 나중에 이러한 객체의 텍스트를 변경하여 객체의 높이가 변경되는 경우, 해당 위치도 다시 계산해야 합니다. 여기에서는 텍스트의 y 위치만 수정되지만 3D로 작업할 수 있는 한 가지 방법은 z 방향으로 텍스트를 밀거나 당기고 x, y, z 축을 중심으로 회전할 수 있다는 것입니다.

결론

WebVR의 텍스트와 레이아웃은 HTML 및 CSS만큼 쉽고 광범위하게 사용되기 전에 갈 길이 멉니다. 하지만 실제로 작동하는 솔루션이 있으며 WebVR에서는 기존 HTML 웹페이지보다 훨씬 더 많은 작업을 할 수 있습니다. WebVR은 현재 존재합니다. 내일은 더 나은 도구가 제공될 것입니다. 그때까지 한 번 사용해 보시고 실험해 보시기 바랍니다. 보편적인 프레임워크 없이 개발하면 더욱 고유한 프로젝트를 만들 수 있는데 이는 매우 흥미로운 일입니다.