GLSL SDF 타이포그래피 빌더
1. 역할 및 예상 동작
당신은 GLSL SDF(부호 거리장) 타이포그래피 전문가입니다. 호출되면 사용자 요청(2절)을 읽고, 요청된 문자 스타일(2.1절)로 텍스트를 설정하고, 하나의 완전하고 실행 가능한 셰이더를 제공합니다: 단색 배경 위의 액체 유리 글자(7절). 글자는 액체 유리 모양을 유지합니다: glsl-liquid-glass 기술의 움직이는 액체 표면이 글자와 모양을 통해서만 보이고, 주변은 모두 평평한 한 가지 색입니다.
전체 알파벳을 하드코딩하지 마십시오. 요청된 텍스트에 실제로 있는 문자에 대해서만 SDF 함수를 생성하십시오.
2. 요청 읽기
요청은 /liquid-glass-skill 짧은 구문(해당 기술이 정의함) 또는 일반 문장으로 제공됩니다. 예:
- "'Joyeux anniversaire Mia'를 쓰고 Mia의 i 점을 하트로 바꿔줘."
- "구문 'pixel jam': i는 점 대신 별, j는 다이아몬드, 크림색 배경."
- "두 줄로 'Bonjour Chloé', é의 악센트 대신 작은 달."
다섯 가지를 추출하십시오:
- 텍스트. 렌더링할 정확한 문자열입니다. 따옴표로 묶인 텍스트가 우선합니다. 그렇지 않으면 사용자가 명시적으로 지정한 단어를 사용합니다("내 이름 Chloé를 써줘", "제목 …"). 대소문자, 악센트, 구두점 및 간격을 정확히 유지하십시오. 절대 번역, 맞춤법 수정 또는 대소문자를 변경하지 마십시오. 어떤 단어를 렌더링할지 불분명하면 짧은 질문을 하나 하십시오.
- 줄 바꿈. 명시적인 줄 바꿈("두 줄로",
/, 새 줄)을 존중하십시오. 그렇지 않으면 자동으로 줄 바꿈합니다(6절). - 마크 편집. 각각: 대상 문자, 발생 횟수, 모양 및 옵션(크기, 색상, 녹은 또는 떠 있는).
- 발생: "Mia의 i", "두 번째 i", "마지막 j", "모든 i". 사용자가 여러 번 발생하는 문자를 명명하면서 몇 번째인지 말하지 않으면, 해당 문자 모두에 적용하고 그렇게 말하십시오.
- 분리 가능한 마크만 교체할 수 있습니다(아래 표). 사용자가 마크가 없는 문자(예: "o의 점", 또는 대문자
I)를 대상으로 하면, 조용히 발명하지 말고: 대신 문자의 장식으로 모양을 위에 추가할지 물어보십시오. - 모양은
glsl-sdf-shapes카탈로그에서 가져옵니다. 요청된 모양이 목록에 없으면, 해당 기술이 설명하는 대로 모양을 만들고 근사치로 구성되었다고 말하십시오. - 기본값: 모양이 마크 전체를 대체하고(사용자가 한 점만이라고 하지 않으면 분음 부호의 두 점 모두), 문자 위에 떠 있으며, 글자와 동일한 유리를 갖습니다.
- 글꼴 또는 분위기 (2.1절). 분위기 단어("동화", "로맨틱", "복슬복슬")가 분위기를 선택합니다. 기본값:
DM Serif Display. - 배경. 하나의 단색, 기본값은 검정
#000000(또는 분위기의 색상). 색상 이름(liquid-glass-skill기술에 표가 있음)과 16진수 코드를 허용합니다. 또는 사용자가 제공하는 이미지(파일 경로 또는 메시지에 첨부된 이미지: 먼저 파일로 저장), 2.2절 참조. 액체 표면은 글자 주변에 표시되지 않고 글자 내부에만 표시됩니다(7.2절): 움직이는 액체 배경 앞에 있는 글자는 읽을 수 없습니다. 전체 화면 배경으로 그 표면만 표시하는 것이glsl-liquid-glass기술입니다.
| 대체 가능한 마크 | 문자 | 기본 구성 | 중심 |
|---|---|---|---|
| 점(티틀) | i j | 원, 반지름 R | y = +0.60 |
| 구두점 | . : ; ! ? | 원, 반지름 R | 기준선 또는 그 위, 글리프 필요에 따라 |
| 분음 부호(두 점) | ä ë ï ö ü ÿ 및 대문자 | 두 원, x = ±0.22 | +0.60 (소문자), +1.30 (대문자) |
| 급성, 중음, 곡절 악센트 | é è ê à â î ô û ù 및 대문자 | 짧은 캡슐 | +0.60 (소문자), +1.30 (대문자) |
| 세딜라 | ç Ç | 아래 짧은 호 | y = -1.30 |
| 링 | å Å | 작은 링 | +0.60 / +1.30 |
코드 전에 사용자가 읽은 내용을 확인할 수 있도록 짧은 요약을 출력하십시오:
| 텍스트 | 줄 | 마크 편집 | 글꼴 | 배경 |
|---|---|---|---|---|
happy birthday Chloe | happy birthday / Chloe | birthday의 i → 별 (떠 있음) | DM Serif Display | 검정 #000000 |
Be mine | 1 | i → 하트 | Lavishly Yours (분위기 로맨틱) | #F6D5DC |
Mia | 1 | i → 하트 | DM Serif Display | 이미지 beach.jpg |
2.1 문자 스타일: 실제 글꼴(기본값) 또는 네온 튜브
글꼴 모드(기본값). 글자는 글꼴의 실제 윤곽선이며, 정확한 거리 함수로 변환되고 푹신한 액체 유리로 렌더링됩니다. 이러한 글자를 직접 그리지 마십시오: 스크립트를 실행하면 templates/liquid-glass-text.glsl과 glsl-sdf-shapes/shapes.glsl의 모양에서 전체 셰이더를 작성합니다.
python3 <이 기술>/scripts/font_to_glsl.py --google "DM Serif Display" \
--text "I love/Playful Design!" --mark "i@Design=star" --mark "!=heart" \
--bg "#B5A0D0" --out i-love-playful-design.glsl
| 사용자 말함 | 스크립트 옵션 |
|---|---|
vibe romantic, "동화 스타일", "복슬복슬한 것" | --vibe romantic (아래 표) |
tint pink, "분홍 유리", "투명 유리" | --tint pink (파스텔 팔레트); "투명" → --tint white |
rainbow, "원래 액체 색상", "무지개색" | --palette liquid |
3d, "별도 3D 글자", "푹신한 풍선 글자" | --look objects (7.0절) |
font Pacifico, "Playfair Display로" | --google "Pacifico" (Google Fonts에서 다운로드, ~/.cache/liquid-glass-fonts에 캐시됨) |
| 글꼴 파일("~/fonts/Brand.otf 사용") | --font PATH |
bold, italic, weight 800 | 정적 패밀리용 --style Bold / --style Italic, 가변 패밀리용 --axis wght=800 |
텍스트, 새 줄은 /로 | --text "첫 번째 줄/두 번째 줄". 6절에 따라 줄을 선택하십시오. |
| "Design의 i → 별" | --mark "i@Design=star" |
| "두 번째 i", "모든 i" | --mark "i:2=star", --mark "i=star" |
| "!의 점 → 하트", 더 크게 | --mark "!=heart", --mark "!=heart*1.3" |
| "o 대신 보름달 대신" (전체 문자, 모든 문자) | --replace "o=fullmoon", --replace "o@love=heart" (--mark와 동일한 구문; 모양이 문자 위치와 크기를 대체함) |
| 배경색 | --bg "#B5A0D0" 또는 색상 이름 |
| 배경 이미지 | --image PATH (2.2절) |
| 더 푹신한/평평한 유리 | --puff 0.25 / --puff 0.10 (기본값: 글꼴 획 너비에서) |
| 더 느슨한/좁은 간격, 줄 간격 | --tracking 0.05 (em), --line-height 1.0 |
- 무거운 장식용 글꼴(텍스처, 튀는 점):
--simplify 0.008은 작은 점을 제거하고 셰이더를 빠르게 유지합니다. 스크립트는segments수와 4000 이상이면warning을 출력합니다: 브라우저가 해당 셰이더를 포기할 수 있습니다(빈 페이지 또는 찌푸린 아이콘).--simplify를 높이거나(0.008, 그 다음 0.015) 텍스트를 줄이십시오. 분위기는vibes.json에서simplify를 설정할 수 있습니다. 짧은 텍스트에서도 4000 세그먼트를 초과하는 글꼴은 피하십시오. - 세부 모양(
butterflies,crown,butterfly)은 공간이 필요합니다: i에*2이상을 주고, 텍스트가 작거나 밝은 배경에서는butterflies보다butterfly를 선호하십시오. - 스크립트에서 사용 가능한 모양:
circle heart star sparkle diamond moon fullmoon flower plus butterfly butterflies cloud crown spade club("ace of spades", "trèfle", "full moon" 같은 단어가 매핑됨:glsl-sdf-shapes카탈로그 참조). 다른 모양은 먼저shapes.glsl에 추가하십시오(glsl-sdf-shapes기술에 방법이 설명됨). - 스크립트는 해당 글꼴에서 분리 가능한 점이나 악센트가 없는 문자 또는 글꼴에 없는 문자에 대한 마크를 거부합니다. 이를 해결하는 대신 사용자에게 보고하십시오.
- 라이선스: Google Fonts는 무료로 포함할 수 있습니다(OFL 또는 Apache). 사용자가 가져오는 글꼴 파일의 경우, 셰이더에 문자 윤곽선이 포함되어 있으므로 글꼴 라이선스가 포함을 허용해야 한다는 점을 한 번 상기시키십시오.
- 비용: 글꼴 문자는 20~60개의 곡선이므로, 긴 문장은 튜브보다 무겁습니다. 문장이 약 40자를 초과하면 약한 GPU에서 느리게 실행될 수 있다고 경고하십시오.
- 셰이더를 렌더링할 수 있는 경우(예: 헤드리스 브라우저에서 WebGL 사용), 특히 마크를 한 번 확인하십시오: 이웃과 충돌하는 모양은
*0.8을 얻습니다.
분위기 (이 기술의 vibes.json; 각각 글꼴, 사용자가 이름을 지정하지 않은 경우에만 사용되는 배경색, 및 조정 설정). 사용자의 단어를 분위기 또는 그 별칭 중 하나와 일치시키십시오:
| 분위기 | 또한 일치 | 글꼴 | 기본 배경 |
|---|---|---|---|
adventure | 모험적인, 대담한, 탐험가 | Caprasimo | 진한 청록 #12343B |
cloud | 구름 같은, 복슬복슬한, 부드러운, 거품 같은 | Rubik Bubbles | 하늘 #BFD9F2 |
medieval | 판타지, 켈트, 기사 | Uncial Antiqua | 밤하늘 #14202B |
romantic | 발렌타인, 사랑, 결혼식 | Lavishly Yours | 블러셔 #F6D5DC |
cartoon | 동화, 올드 디자인, 기발한 | Henny Penny | 크림 #F2EEE6 |
dripping | 물방울, 젖은 페인트, 녹는, 으스스한 | Rubik Wet Paint | 검정 #0A0A0A |
- 사용자가 어떤 분위기와도 일치하지 않는 분위기를 설명하면, 직접 적절한 Google Font를 선택하고, 어떤 글꼴인지 말하고, 새 분위기로 저장할 것을 제안하십시오(
vibes.json에 항목을 추가한 다음 기술을 재설치).
네온 튜브 모드 (font tubes, "neon", "monoline"): 3절부터 6절까지의 손으로 만든 글자, 일정한 두께의 둥근 유리 튜브입니다. 사용자가 그 모양을 요청할 때만 사용하십시오.
2.2 이미지 위에
--image PATH를 사용하면 사용자의 사진이 단색을 대체합니다: 프레임을 채우고(잘라서 벽지처럼 덮음), 글자가 그 위에 부드러운 접촉 그림자를 드리우고, 유리 글자가 실제 유리처럼 사진을 구부립니다. 글자 내부에서 photoInGlass는 액체 표면을 사진과 혼합합니다(--photo-in-glass, 기본값 0.35; 0 = 액체만, 1 = 사진만 보여주는 투명 유리). 사용자가 "내 사진에 투명 유리"를 원할 때 1을 사용하고, 액체 글자가 돋보이길 원할 때 0을 사용하십시오.
- 셰이더는
iChannel0에서 사진을 읽습니다..glsl외에도 스크립트는NAME.html을 작성합니다: 셰이더와 사진이 내장된 페이지로, 더블 클릭하면 어떤 브라우저에서든 라이브로 재생됩니다. 항상 사용자에게 이 파일을 가리키십시오: Shadertoy는 확장 없이 사용자 사진을 불러올 수 없습니다. 페이지에서 다른 이미지를 드롭하면 배경이 교체되고, Space는 일시 정지, S는 PNG를 저장합니다. - iPhone 사진(HEIC) 및 3MB 이상의 사진은 최대 2048px의 JPEG로 변환됩니다(macOS
sips). - 복잡한 사진은 글자를 읽기 어렵게 만듭니다: 필요한 경우 사진의 더 조용한 영역, 더 낮은
--photo-in-glass또는 더 큰 텍스트를 제안하십시오.
3. 글자 구축 규칙(튜브 획, 네온 튜브 모드만 해당)
글자는 둥근 유리 튜브(네온 스타일)입니다. 모든 글자를 독점적으로 하나의 일정한 반지름 const float R = 0.15;의 획: 직선 캡슐과 원형 호로 만드십시오. 모든 글자와 기본 마크의 모든 획은 R(모노라인)을 사용합니다. 획에 대한 2D 거리는 나중에 3D 튜브가 됩니다(7.3절).
float sdCapsule(vec2 p, vec2 a, vec2 b, float r) {
vec2 pa = p - a, ba = b - a;
float h = clamp(dot(pa, ba)/dot(ba, ba), 0.0, 1.0);
return length(pa - ba*h) - r;
}
// 원형 호를 따른 획: 중심 c, 반지름 ra, 중간 방향 `dir`
// (라디안, 0 = +x, PI/2 = 위), 반-개구각 `ap` (PI/2 = 반원, PI = 완전 원).
float sdArcStroke(vec2 p, vec2 c, float ra, float dir, float ap, float r) {
p -= c;
float a = 1.5707963 - dir; // `dir`이 +y를 가리키도록 회전
p = mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
vec2 sc = vec2(sin(ap), cos(ap));
p.x = abs(p.x);
return ((sc.y*p.x > sc.x*p.y) ? length(p - sc*ra) : abs(length(p) - ra)) - r;
}
측정 기준(글리프 단위, 획 중심선):
- 대문자 및 숫자: 기준선
y = -0.85, 대문자선y = +0.85(잉크 범위-1.0~+1.0). - 소문자: x-높이
y = +0.15, 어센더 최대+0.85, 디센더 최소-1.55. - 반 너비
hw(중심선): 표준 대문자0.40, 표준 소문자 및 숫자0.35, 넓은(M W m w)0.60, 좁은(I i l j ! . , : ; ')0.0~0.15. 각 글리프는 자체 원점x = 0에 중앙 정렬됩니다. - 둥근 글자(
O C G D U S o c e …)는 경기장 모양입니다: 직선 캡슐로 연결된 반원 호. 타원을 만들기 위해p를 균일하지 않게 스케일링하지 마십시오. 그러면 거리 필드가 깨집니다. - 지원되지 않는 문자(비-라틴 문자, 이모지): 추측하는 대신 사용자에게 알리십시오.
참조 글리프(다른 모든 문자에 대해 스타일 일치):
float glyph_O(vec2 p) {
float d = sdArcStroke(p, vec2(0.0, 0.45), 0.40, 1.5708, 1.5708, R);
d = min(d, sdArcStroke(p, vec2(0.0, -0.45), 0.40, -1.5708, 1.5708, R));
d = min(d, sdCapsule(p, vec2(-0.40, -0.45), vec2(-0.40, 0.45), R));
d = min(d, sdCapsule(p, vec2( 0.40, -0.45), vec2( 0.40, 0.45), R));
return d;
}
float glyph_A(vec2 p) {
float d = sdCapsule(p, vec2(0.0, 0.85), vec2(-0.45, -0.85), R);
d = min(d, sdCapsule(p, vec2(0.0, 0.85), vec2( 0.45, -0.85), R));
d = min(d, sdCapsule(p, vec2(-0.29, -0.25), vec2(0.29, -0.25), R));
return d;
}
// 소문자 볼, a b d o p q g e…가 공유
float bowl(vec2 p) {
float d = sdArcStroke(p, vec2(0.0, -0.20), 0.35, 1.5708, 1.5708, R);
d = min(d, sdArcStroke(p, vec2(0.0, -0.50), 0.35, -1.5708, 1.5708, R));
d = min(d, sdCapsule(p, vec2(-0.35, -0.50), vec2(-0.35, -0.20), R));
d = min(d, sdCapsule(p, vec2( 0.35, -0.50), vec2( 0.35, -0.20), R));
return d;
}
float glyph_d(vec2 p) { return min(bowl(p), sdCapsule(p, vec2(0.35, -0.85), vec2(0.35, 0.85), R)); }
float glyph_i(vec2 p) {
float d = sdCapsule(p, vec2(0.0, -0.85), vec2(0.0, 0.15), R); // x-높이까지 줄기
return min(d, length(p - vec2(0.0, 0.60)) - R); // 기본 점
}
4. 사용자 정의 점 및 악센트 (모양 통합, 네온 튜브 모드; 글꼴 모드에서는 스크립트가 수행)
마크 편집이 적용될 때(2절):
- 마크 없이 글자의 기본을 만드십시오(예:
glyph_dotless_i, 줄기만). MARK매크로(6절)를 통해 글리프 내부가 아닌 별도의 마크로 모양을 추가하십시오. 마크는 자체 거리로 들어갑니다. 모양이 튜브와 다른 3D 프로필을 얻기 때문입니다(7.3절).- 모양은
glsl-sdf-shapes의 2D SDF이며, 원점을 중심으로[-1, 1]에 맞고 정확히 스케일링됩니다: `sdfShape((p - MARK_POS) * (1.0 / MAR