예제
저장소에는 실행할 수 있는 예제가 36개 있습니다. 지도용 패스, ShaderToy 시절의 화면 공간 효과, 에뮬레이션 배정밀도 계열, 컴퓨트 커널 하나를 다룹니다. 그중 35개는 한 소스에서 WGSL과 GLSL ES 3.00을 모두 냅니다. 컴퓨트 커널은 GLSL ES 3.00으로 낼 버텍스나 프래그먼트 단계가 없어서 WGSL과 리플렉션만 내고, WebGL2 경로는 옵션으로 켜는 에뮬레이션입니다. 13개는 에뮬레이션 배정밀도를 씁니다. 렌더링 가능한 예제는 examples/index.ts가 내보내고, 예제 디렉터리에서 둘러볼 수 있습니다.
| 예제 | 분류 | 출력 | 설명 |
|---|---|---|---|
| Graticule | 지도 | WGSL과 GLSL ES 3.00 | 지도라면 다 그리는 경위선 격자. |
| Hillshade | 지도 | WGSL과 GLSL ES 3.00 | 음영 기복. |
| fp64 deep zoom | 지도 | WGSL과 GLSL ES 3.00 | 에뮬레이션 배정밀도(f32 두 개로 만든 df64). |
| fp64 checker plane | 지도 | WGSL과 GLSL ES 3.00 | 월드 평면 위의 1단위 체커보드. |
| fp64 hyperbolic navigation | 지도 | WGSL과 GLSL ES 3.00 | LORAN 방식의 해도 격자. |
| fp64 Mercator tiles | 지도 | WGSL과 GLSL ES 3.00 | 타일 엔진이 쓰는 그 계산식. |
| fp64 relative-to-center | 지도 | WGSL과 GLSL ES 3.00 | 행성 규모 엔진이 시점 기준으로 렌더링하는 이유. |
| Colour ramp | 지도 | WGSL과 GLSL ES 3.00 | 데이터로 색을 정하는 단계구분도 색상 램프. |
| Discard cutout | 화면 공간 | WGSL과 GLSL ES 3.00 | 가운데 원 바깥에서는 픽셀을 버리고 안쪽에서는 채움 색을 돌려주는 프래그먼트 헬퍼입니다. 프래그먼트 IO 구조체 생성자에 인자로 한 번 넣습니다. |
| Plasma | 화면 공간 | WGSL과 GLSL ES 3.00 | 사인파를 여러 개 더해 만든 고전 플라스마에 RGB 팔레트로 색을 입혔습니다. |
| Voronoi | 화면 공간 | WGSL과 GLSL ES 3.00 | 움직이는 셀룰러 노이즈. |
| Julia set | 화면 공간 | WGSL과 GLSL ES 3.00 | 탈출 시간으로 그리는 줄리아 프랙탈. |
| Mandelbrot set | 화면 공간 | WGSL과 GLSL ES 3.00 | 탈출 시간을 매끄럽게 이어 칠한 만델브로 집합. |
| fBm clouds | 화면 공간 | WGSL과 GLSL ES 3.00 | 프랙탈 브라운 운동. |
| Domain warping | 화면 공간 | WGSL과 GLSL ES 3.00 | fbm 출력을 다시 fbm에 넣습니다. |
| Raymarched sphere | 화면 공간 | WGSL과 GLSL ES 3.00 | 구의 부호 있는 거리 필드입니다. 카메라 광선에서 스피어 트레이싱으로 찾고, 궤도를 도는 광원으로 블린퐁 셰이딩합니다. |
| Raymarched box field | 화면 공간 | WGSL과 GLSL ES 3.00 | 도메인 반복. |
| Tunnel | 화면 공간 | WGSL과 GLSL ES 3.00 | 데모신 시절의 터널. |
| Metaballs | 화면 공간 | WGSL과 GLSL ES 3.00 | 음함수로 그린 방울. |
| Ocean horizon | 화면 공간 | WGSL과 GLSL ES 3.00 | 원리부터 계산해 그린 바다 풍경. |
| Starfield | 화면 공간 | WGSL과 GLSL ES 3.00 | 텍스처 없이 그린 밤하늘. |
| Truchet tiles | 화면 공간 | WGSL과 GLSL ES 3.00 | 타일 하나. |
| Kaleidoscope | 화면 공간 | WGSL과 GLSL ES 3.00 | 극좌표로 접는 거울 반사. |
| Beating heart | 화면 공간 | WGSL과 GLSL ES 3.00 | 하트 곡선 (x²+y²-1)³ = x²y³입니다. 부호로 안쪽을 채우고 fwidth로 가장자리를 다듬었으며, 뾰족하게 만든 사인파 박동에 맞춰 뛰고 박자에 맞춰 빛납니다. |
| fp64 Mandelbrot | 화면 공간 | WGSL과 GLSL ES 3.00 | f32 두 개로 만든 배정밀도의 고전 데모. |
| fp64 Julia set | 화면 공간 | WGSL과 GLSL ES 3.00 | 같은 배정밀도 기법을 줄리아 집합으로 보인 예제. |
| fp64 Burning Ship | 화면 공간 | WGSL과 GLSL ES 3.00 | 버닝 십 프랙탈입니다. 제곱하기 전에 |Re z|, |Im z|로 접고, 바늘처럼 뾰족한 부분을 확대합니다. |
| fp64 Newton fractal | 화면 공간 | WGSL과 GLSL ES 3.00 | z³ = 1을 푸는 뉴턴 방법입니다. 색은 그 픽셀이 어느 세제곱근으로 수렴하는지 나타냅니다. |
| fp64 distance estimate | 화면 공간 | WGSL과 GLSL ES 3.00 | 거리 추정(d = ½·|z|·ln|z|/|dz|)으로 만델브로 경계를 그립니다. 정밀도는 식 중간에서 나눕니다. |
| fp64 long-uptime clock | 화면 공간 | WGSL과 GLSL ES 3.00 | 오래 켜 두면 생기는 애니메이션 버그. |
| fp64 catastrophic cancellation | 화면 공간 | WGSL과 GLSL ES 3.00 | 수치해석 교과서의 그 그래프를 GPU로 그립니다. |
| fp64 sine sweep | 화면 공간 | WGSL과 GLSL ES 3.00 | 큰 기준값에 화면에서 조금씩 움직이는 값을 더한 x로 sin(x)를 구합니다. |
| Gradient pass | 화면 공간 | WGSL과 GLSL ES 3.00 | 섞는 비율을 조절할 수 있는 세로 방향 두 색 그러데이션. |
| Specialization constant | 화면 공간 | WGSL과 GLSL ES 3.00 | 파이프라인에서 덮어쓸 수 있는 quality 상수. |
| 2D array texture | 화면 공간 | WGSL과 GLSL ES 3.00 | 타일 아틀라스를 texture_2d_array<f32> 바인딩 하나로 씁니다. |
| Compute reduction | 컴퓨트 | WGSL | @workgroup_size가 붙은 컴퓨트 커널입니다. 입력 스토리지 버퍼의 한 구간을 reduce()로 접어 출력 원소 하나로 만듭니다. |
저장소를 받아 둔 디렉터리에서 실행합니다. 첫 번째 명령은 모든 예제의 WGSL, GLSL, 리플렉션을 인쇄하고, 두 번째는 id로 하나만 인쇄합니다.
npx tsx examples/print.tsnpx tsx examples/print.ts hillshadegradient 패스의 GLSL ES 3.00 출력
첫 페이지에는 gradient-pass.ts의 프래그먼트 단계와 거기서 나오는 WGSL 진입점이 있습니다. 같은 함수에서 이 GLSL ES 3.00 main이 나옵니다.
void main() { _ret = vec4(mix(u.bottom.rgb, u.top.rgb, (uv.y + u.mix_bias)), 1.0);}모듈 전체는 WGSL로 28줄이고, GLSL은 버텍스 단계 17줄, 프래그먼트 단계 15줄입니다. 유니폼 타입, 바이트 오프셋, 바인드 그룹 항목, 진입점 시그니처는 reflect()에서 나옵니다. reflect()는 같은 중간 표현을 읽지만 출력 경로에는 관여하지 않으므로, 호스트는 그 레이아웃대로 유니폼 버퍼를 채우면 됩니다. 검증 페이지에는 유니폼 블록의 복원된 레이아웃이 잘못 쓴 필드의 진단과 나란히 있습니다.
에뮬레이션 배정밀도
WGSL에도 GLSL ES 3.00에도 배정밀도 부동소수점은 없습니다. TypeShade는 f32 값 두 개를 합치지 않고 나란히 든 쌍으로 이를 에뮬레이션하고, 산술, 비교, 일부 내장 함수를 그 쌍에 대한 호출로 바꿔 냅니다. 그 범위 밖의 연산은 출력할 때 코드가 붙은 오류로 실패합니다. 쓰는 코드는 그대로이고 선언한 타입만 다릅니다. deep-zoom 예제에서 origin 필드는 소스에서 f64로 선언되고 유니폼 블록에서는 vec2<f32> 자리를 차지하며, 호스트가 그 자리를 분리한 쌍으로 채웁니다.
f64 산술을 하는 모듈에는 가드 텍스처 바인딩도 주입되는데, 호스트는 이 텍스처를 흰색 텍셀 하나로 채워야 합니다. GPU 드라이버의 셰이더 컴파일러는 텍셀 읽기를 미리 계산해 버릴 수 없는데, 그 읽기가 없으면 오차 보정 항을 마음대로 최적화해 없앨 수 있기 때문입니다. 연산마다 f32의 몇 배가 들므로 이 타입은 값 하나하나에 대해 골라서 씁니다. 예제는 fp64-deep-zoom.ts입니다.