sharp.go
← 뒤로

· Sharp.go Team

엔진 내부: sharp.go가 361개의 돌을 60fps로 렌더링하는 방법

5년 전, 완전한 3D 검사를 갖춘 60fps 바둑판은 렌더러의 꿈이었습니다. 오늘은 렌더러의 오후 작업입니다. 이 글은 우리가 시작할 때 존재했으면 했던 주석付き 해설 — 아키텍처 선택, 막다른 길, 그리고 차이를 만든 작은 디테일들 — 입니다.

● 문제

01

왜 어려운가

3D 엔진을 형성한 세 가지 제약.

바둑은 선이 아니라 나무입니다. 어느 순간이든 플레이어는 수천 가지 대안적 연속으로 분기하며, 각각은 19×19 판 위에 자신만의 돌 환상을 가집니다. 우리는 셋을 동시에 원했습니다. 인터랙티브한 3D 카메라, 100ms 미만의 분석 지연, 그리고 200수 이후에도 무너지지 않는 기보.

각각은 단독으로 해결 가능합니다. 문제는 셋 모두 같은 핫패스 — 돌이 판에 놓이는 순간 — 를 건드리고, 각각이 서로 다른 시간을 원한다는 것입니다.

● 착수 인코딩

02

21바이트 와이어 포맷

컴팩트하고 결정적이며 버전을 넘어 재생 가능.

sharp.go의 모든 착수는 21바이트 페이로드입니다. JSON, CBOR, protobuf를 시도한 뒤 손으로 만든 바이너리로 정착했습니다. 포맷은 충분히 작아서 400수의 실제 대국이 8.4 KB에 들어갑니다 — 판 자체의 압축 JPEG과 거의 같은 크기입니다.

  • 01.

    바이트 0 — 색

    흑은 0x00, 백은 0x01. 한 바이트, 협상 없음.

  • 02.

    바이트 1–2 — 좌표

    두 개의 리틀 엔디안 바이트: 행 (0–18)과 열 (0–18). 19×19 격자의 361개 유효 위치.

  • 03.

    바이트 3–6 — 시퀀스

    부호 없는 32비트 착수 인덱스. 대국 내에서는 연속적이며, 재생 간에는 결정적.

  • 04.

    바이트 7–10 — 시계 타임스탬프

    대국 시작 이후의 밀리초. 재생 스크러빙에 사용.

  • 05.

    바이트 11–14 — 국면 해시

    32비트 Zobrist 해시. 판 전체를 스캔하지 않고 중복 국면과 수퍼코를 탐지 가능.

  • 06.

    바이트 15–20 — 엔진 신호용 예약

    포획된 돌, 코 마커, 패스 플래그. 미래 호환성을 위해 예약.

섹션 구분

"

바이너리 포맷을 발명하러 나간 것이 아닙니다. 분석을 즉각적으로 느끼게 하러 나갔고, 바이트 수가 가장 늦게 풀기 쉬운 제약임이 드러났습니다.

"

Naomi S. / 리드 엔진 엔지니어

● 렌더링 파이프라인

03

세 패스, 한 캔버스

순서가 비용보다 중요합니다.

렌더러는 엄격한 3패스 파이프라인입니다. 패스 사이에서 정렬·블렌딩·반사를 하지 않습니다 — 각 패스는 자체 텍스처에 쓰고, 다음 패스가 그것을 읽습니다.

● Tabs

각 돌은 PBR 머티리얼을 가진 단일 인스턴스 큐브. 361개 위치를 모두 오프스크린 판 깊이 텍스처에 렌더링. 빈 위치는 완전히 건너뛰고, 점유된 위치만 인스턴스별 변환을 받음.
정상 상태 프레임 속도 60fps
착수 포맷 디코드 처리량 1.1GB/s
와이어상 착수당 바이트 21B

● 설계 결정

04

왜 3D 부터 출시하는가

2D 를 배제하는 것이 아니라, 첫 제품의 설계 근거.

● Comparison

엔진 비교

● Feature sharp.go 2D 클라이언트 휴대폰 앱
3D 바둑판 검사 ✓ ✗ ✗
100ms 미만 AI 피드백 ✓ ✗ ✓
열린 기보 포맷 ✓ ✓ ✗
협력 복기 ✓ ✗ ✗
두 번 클릭 공유 링크 ✓ ✗ ✓
브라우저 전용 모드 ✓ ✗ ✗
  • ✓

    판 전체의 인스턴스 렌더링

    361 인스턴스, 1 드로우 콜. 다른 모든 것은 더 느렸음.

  • ✓

    실시간이 아닌 캐시된 반사

    5°를 초과하는 카메라 이동에서 재렌더링. 플레이어는 알아채지 못함.

  • ✓

    디스크 위의 바이너리 착수 포맷

    컴팩트하고 결정적, 2026년의 대국 재생이 2027년에도 로드됨.

  • ✓

    일등 시민 URL로서의 딥링크

    모든 국면이 안정적 URL을 가짐. 바둑판 공유는 스크린샷이 아닌 복사·붙여넣기.

자주 묻는 질문

● 자주 묻는 질문

01 왜 엔진은 국면 해싱에 Zobrist를 사용하나요? ▾

Zobrist 해시는 매 착수에서 O(1)로 갱신되며 (변경 비트를 xor), 단일 32비트 비교로 수퍼코와 중복 국면을 탐지할 수 있습니다. 매수마다 판 전체를 스캔하는 것은 19×19에서는 괜찮지만, 지원 예정인 25×25에는 확장되지 않습니다.

02 다른 기기에서 URL로 대국을 재생할 수 있나요? ▾

예. 모든 대국은 착수 시퀀스를 경로에 인코딩한 안정적 URL을 가집니다. 어떤 기기, 어떤 브라우저에서든 URL을 열면, 같은 국면에서 재생이 시작됩니다.

03 오프라인에서도 AI가 같은 수준으로 두나요? ▾

예. 기기 내 AI 는 완전히 오프라인으로 동작하며 기본은 초급 수준으로 보정되어 있습니다. 메뉴에서 더 강한 설정으로 올릴 수 있으며, 네트워크 왕복은 필요하지 않습니다.

04 바이너리 착수 포맷이 공개 사양에 문서화되지 않은 이유는? ▾

안정성 때문입니다. 이 포맷은 우리의 재생 호환성 약속의 일부입니다. 1.0 엔진이 출시되는 대로 안정적인 v1 사양을 공개할 것입니다. 그 전까지는 마이너 버전 간에 변경될 수 있습니다.

● 다음 단계

05

로드맵, 약속이 아님

현재 작업 중인 것들, 예상 비용 순서.

향후 6개월은 재생 이식성에 관한 것입니다. 플레이한 모든 대국은 그것을 플레이한 클라이언트보다 오래 살아남아야 합니다.

● 엔진 사용

진짜 3D 바둑판에서 두기

설치 불필요. 브라우저에서 대국을 열고, 보정된 AI와 대국하며, 한 번의 클릭으로 국면을 공유.

"

최고의 바둑 UI는 사라지는 UI입니다. 보는 것은 앱이 아니라 바둑판입니다.

"

The sharp.go team / 홍콩, 2026년 5월
enginerenderingperformance