2P by GN⁺ 7일전 | ★ favorite | 댓글 1개
  • 이미지의 윤곽과 형태를 보존하는 ASCII 렌더링 기법을 개발해, 기존 방식의 흐릿한 가장자리 문제를 해결
  • 픽셀 단위의 단순 명암 매핑 대신, 각 문자의 시각적 형태(shape) 를 수치화해 매칭하는 고차원 벡터 기반 접근법을 사용
  • 문자별로 상·하·좌·우 영역의 밀도를 측정해 2차원에서 6차원으로 확장된 shape vector를 생성, 더 정밀한 문자 선택 구현
  • 경계선의 선명도를 높이기 위해 글로벌 및 방향성 대비 강화(contrast enhancement) 알고리듬을 적용
  • GPU 가속과 캐싱, k-d 트리 탐색 등을 통해 실시간 ASCII 렌더링 성능을 확보, 고품질 시각 효과를 실현

이미지에서 ASCII로의 변환

  • ASCII에는 95개의 인쇄 가능한 문자가 있으며, 모노스페이스 폰트를 사용해 이미지를 격자로 분할
    • 각 셀의 밝기를 계산해 문자 밀도에 따라 매핑
  • 단순한 최근접 이웃 보간(nearest-neighbor interpolation) 은 경계가 들쭉날쭉한 jaggies 현상을 유발
  • 슈퍼샘플링(supersampling) 을 통해 셀 내부에서 여러 샘플을 취해 평균 밝기를 계산하면 부드러워지지만, 여전히 흐릿한 경계 발생
  • 문제의 핵심은 문자를 픽셀처럼 취급하는 데 있으며, 문자의 고유한 형태를 고려하지 않는다는 점

문자 형태(Shape)의 활용

  • 각 문자는 셀 내에서 시각적 밀도 분포가 다름
    • 예: T는 상단이 무겁고, L은 하단이 무거움
  • 이를 수치화하기 위해 셀 내부에 샘플링 원(circle) 을 배치하고, 각 영역의 문자 점유 비율을 계산
  • 상·하 두 영역의 점유율을 벡터로 표현해 2차원 shape vector 생성
  • 각 문자의 shape vector를 사전 계산해두고, 이미지의 샘플링 벡터와 유클리드 거리(Euclidean distance) 로 가장 가까운 문자를 선택

6차원 형태 벡터로의 확장

  • 상·하 2차원만으로는 -, p, q 등 중간·좌우 중심 문자를 표현하기 어려움
  • 셀을 6개의 샘플링 원으로 확장해 상·중·하, 좌·우 차이를 모두 포착
  • 6차원 shape vector는 문자 형태를 훨씬 정밀하게 반영하며, 원형·대각선 문자도 잘 표현
  • 3D 장면 렌더링 시 외곽선은 선명하지만, 면 간 경계가 흐릿해지는 문제 발생

대비 강화(Contrast Enhancement)

  • 샘플링 벡터의 각 요소를 지수(exponent) 로 조정해 어두운 값은 더 어둡게, 밝은 값은 유지
    • 벡터를 정규화 후 지수 적용, 다시 원래 범위로 복원
  • 이 과정을 통해 경계선의 시각적 구분이 강화, 문자 선택이 더 명확해짐
  • 균일한 밝기 영역에서는 변화가 거의 없어, 부드러운 그라데이션 유지
  • 그러나 일부 경계에서 계단형(staircasing) 현상이 발생

방향성 대비 강화(Directional Contrast Enhancement)

  • 각 셀 외부에도 외부 샘플링 원을 배치해 주변 밝기 정보를 수집
  • 외부 샘플링 벡터의 밝은 값이 내부 벡터의 대응 요소를 어둡게 조정, 경계 방향의 대비 강화
  • 외부 샘플링을 확장해 상단·중단·하단 간 영향을 넓히면, 부드럽고 선명한 경계 표현 가능
  • 글로벌 대비 강화와 결합 시, 3D 장면의 경계선이 뚜렷하고 가독성 높은 ASCII 렌더링 구현

성능 최적화

  • 문자 선택 시 최근접 탐색을 단순 반복하면 느리므로, k-d 트리를 사용해 다차원 공간에서 빠른 탐색 수행
  • 캐싱을 통해 동일한 샘플링 벡터의 결과를 재사용
    • 각 벡터를 5비트 단위로 양자화해 메모리 효율적 캐시 키 생성
    • 범위를 8로 설정해 품질과 메모리 사용량 균형 유지
  • 캐시된 탐색은 매우 빠르며, 수천 개 문자도 실시간 처리 가능
  • 샘플링 벡터 계산은 GPU로 이전해, 내부·외부 샘플링, 대비 강화 연산을 셰이더 파이프라인으로 처리
    • CPU 대비 수배의 성능 향상

결론

  • 문자의 형태를 벡터로 수치화해 활용하는 접근법은 ASCII 렌더링의 해상도와 선명도를 크게 향상
  • 이 방식은 워드 임베딩(word embedding) 과 유사한 개념으로, 다른 시각적 문제에도 응용 가능성 있음
  • 초기 구현은 느렸으나, GPU 가속과 캐싱, k-d 트리 탐색으로 모바일에서도 부드러운 FPS 확보
  • 색상 기반 ASCII 표현은 다루지 않았으며, 향후 더 다양한 형태·대비 조합 실험 가능성 언급
  • ASCII 렌더링은 단순한 시각 효과를 넘어, 형태 인식과 벡터 표현의 확장 가능성을 보여주는 사례임
Hacker News 의견들
  • 벡터를 정규화한 뒤 유클리드 거리를 계산한다면, 단순한 행렬 곱(matmul)로도 같은 결과를 얻을 수 있음
    정규화된 벡터에서는 유클리드 거리가 코사인 거리의 선형 변환이기 때문임
    실제 거리값이 아니라 순위(ranking) 만 중요하다면 sqrt 연산을 생략해도 동일한 결과를 얻을 수 있고, 약간 더 빠르게 계산됨

    • 이런 걸 90년대에 게임 엔진 개발할 때 알았더라면 정말 좋았을 것 같음
  • 이런 종류의 글을 정말 좋아함. 겉보기엔 단순해 보여도, 멋지게 만들려면 깊이 있는 탐구가 필요함
    Lucas Pope이 Return of The Obra Dinn의 디더링 시스템을 개발하며 쓴 글도 추천함
    Lucas Pope의 개발기

  • “토성 이미지를 ChatGPT로 생성했다”는 문장을 보고 놀람
    실제 토성 사진은 공개 도메인에 널려 있는데, 왜 굳이 가짜 이미지를 만들어 인터넷을 오염시키는지 의문임

    • 삼성의 ‘가짜 달 사진’ 논란 기사를 떠올리게 됨. 혹시 행성들도 진짜가 아닐지도?
    • 왜 굳이 학습 데이터에 이미 포함됐을 법한 이미지를 재생산하게 만드는지 모르겠음
    • “토성 이미지를 ChatGPT로 만들었다”는 건 시작에 불과함
      언젠가 위키나 웹사이트, 포럼조차 직접 안 쓰게 될지도 모름
      “X×Y 크기의 고대비 토성 이미지”를 즉시 생성할 수 있다면, 그건 마법 같은 변화일 것임
      계산기나 인터넷이 창의성을 죽이지 않았듯, 인간은 언제나 마찰이 가장 적은 도구를 선택하며 계속 별을 향해 나아갈 것임
  • 예시를 볼 때마다 “좋긴 한데 더 개선할 수 있겠는데?”라고 생각했는데, 저자가 실제로 그걸 해결해줘서 감탄했음
    정말 아름다운 글이며, 블로그 전체가 이런 깊이 있는 수준이라 구독할 가치가 있음
    alexharri.com/blog

  • ascii-side-of-the-moon 프로젝트를 만들 때 ASCII 렌더러를 직접 구현해볼까 고민했었음
    결국 chafa를 사용했지만, 언젠가 다시 시도해볼 생각임
    혹시 이걸 라이브러리로 공개할 계획이 있는지, 아니면 웹사이트 코드를 참고해도 되는지 궁금함

    • ASCII Moon 도구는 정말 재밌게 써봤음
      지금은 라이브러리 계획은 없지만, 필요하면 웹사이트 코드를 자유롭게 가져가도 됨
      만약 만든다면 WebGL 2 → WebGL 1 변환으로 호환성을 높이고, 폰트별로 shape vector를 미리 계산하는 도구도 필요할 것 같음
  • “ASCII 아트에서 shape을 활용한 예는 본 적이 없다”는 말에 대해, 실제로 shape을 사용하는 생성기가 있음
    ascii-silhouettify라는 프로젝트로, 색 영역의 외곽선에 맞춰 가장 큰 문자를 선택하는 알고리즘을 사용함

    • 모노크롬 갤러리의 예시들이 정말 멋짐
    • 다만 속도는 약 150배 느린 듯함. 샘플링 해상도를 높이면 비슷한 선명도를 얻을 수 있을 것 같음
  • Acerola가 2024년에 엣지 감지 기반 ASCII 렌더링을 시도했음
    밝기 기반 패스 위에 방향성 있는 기호(| / - )를 겹쳐 표현하는 방식이었음
    관련 영상 참고

    • 이 영역에도 스타일의 여지가 많을 것 같음
      예를 들어 전통 2D 아트처럼 굵은 경계선을 쓰거나, Chiaroscuro처럼 부드러운 명암 대비를 표현하는 식으로 다양하게 시도 가능함
  • 대부분의 ASCII 필터는 글리프의 형태(shape) 를 고려하지 않음
    chafa는 각 글리프를 8×8 비트맵으로 처리하는데, 이 접근이 인상적이었음
    chafa 소스갤러리를 보면 그 정교함을 느낄 수 있음

    • chafa 갤러리에는 ASCII 텍스트 렌더링 예시는 없던데, 혹시 그런 예시도 있는지 궁금함
    • 나도 대학 시절 8×8 비트맵을 64비트 정수로 변환해 popcnt로 비교하는 방식을 썼었음
      방향성 중심 접근이 더 큰 형태를 잘 표현할 수 있을지 궁금함
    • 개인적으로는 IBM Code Page 437 글리프들이 가장 마음에 듦
      oldschool PC fonts를 보면 정말 끝없는 토끼굴 같음
  • 여가 시간에 점자 기반 컬러 그래픽을 실험 중임
    해상도는 충분하지만 색상 표현의 정밀도가 부족해, 샘플링 후 대비 보정(contrast fixup) 이 필요함
    작성자의 샘플링 기법을 색상 대비 강화에 적용해보면 좋을 것 같음
    이전에는 Sobel 필터로 대비를 높이려 했지만, 문자 격자와 정렬이 맞지 않아 실패했음

  • 정말 훌륭한 기술적 접근과 깊이 있는 분석이었음
    마지막에 Cognition cube array의 개선 버전을 볼 수 있을까 기대했는데 없어서 아쉬웠음
    예전에 유튜브에서 서브픽셀 컬러 대비로 더 나은 파비콘을 구현한 디자이너가 떠올랐음
    관련 글 (Web Archive)

    • 나도 그 Cognition 로고의 대비 강화 버전을 보고 싶었음
      그래도 글 자체는 훌륭했고, 동적 예시들은 정말 인상적이었음