유니폼과 버퍼
유니폼 바인딩은 구조체이고, 생성기는 이것을 std140 블록으로 생성합니다. 스토리지 버퍼는 이 타깃에 아예 형태가 없어서, 그런 모듈은 기능 게이트가 돌기 전에 데이터 텍스처에서 읽도록 다시 쓰입니다.
layout(std140) uniform Block { float scale; vec3 tint;} u;declare const u: uniform<Block>클래스가 블록이고 declare가 그 인스턴스입니다. 필드 순서가 곧 레이아웃입니다.
uniform binding 'scale' must be a struct (a std140 UBO block)
declare const scale: uniform<f32>glUniform*로 값을 넣는 기본 블록 유니폼은 여기에 표기가 없습니다. 그래서 스칼라나 벡터나 행렬 하나를 담은 유니폼 바인딩은 WebGPU에만 닿습니다.
uniform sampler2D src;declare const src: storage<array<f32>>버퍼가 데이터 텍스처가 되고, 호스트는 같은 숫자를 텍셀로 올립니다.
float _sfetch(sampler2D t, int i) {src[i32(uv.x)]버퍼를 인덱스로 읽는 자리가 이 함수 호출이 됩니다. 생성기는 이 함수를 부르는 모듈에만 정의를 넣습니다.
#define tint 0.85const tint: override<f32> = 0.85특수화 상수에는 GLSL 형태가 없어서, 기본값을 전처리기 치환으로 적어 둡니다. 호스트는 스테이지를 컴파일하기 전에 그 값을 덮어쓸 수 있습니다.
precision highp float;적을 것이 없습니다.
생성기가 스테이지마다 맨 위에 한정자를 넣고, floatPrecision 옵션이 float 줄을 highp로 할지 mediump로 할지 정합니다. 정수 줄은 highp로 둡니다. 데이터 텍스처를 거쳐 되읽는 값에는 정수 범위가 온전히 필요하기 때문입니다.
varying
버텍스 스테이지에서 프래그먼트 스테이지로 넘어가는 값은 양쪽 모두에서 @location(n) 필드입니다. 이 타깃은 그 둘을 이름으로 잇고 WebGPU는 번호로 이으므로, 생성된 GLSL에서 맞아야 하는 것은 필드 이름입니다.
out vec2 uv;@location(0) uv: vec2버텍스 진입점이 반환하는 구조체의 필드에 적습니다.
in vec2 uv;@location(0) uv: vec2그 값을 읽는 프래그먼트 진입점 매개변수에 같은 이름으로 적습니다.
layout(location = 0) out vec4 _ret;: vec4프래그먼트가 단일 값을 반환하면 location 0을 가져가고, 출력 이름은 생성기가 직접 붙입니다.
확장과 기능
#extension 줄은 GPU 기능의 한쪽 절반이고, 호스트의 getExtension 호출이 나머지 절반입니다. 이 타깃의 프로파일에는 행이 4개 있고 그중 하나만 소스에 지시문을 넣습니다. 행이 아예 없는 기능은 텍스트를 쓰기도 전에 이 타깃에서 모듈을 차단합니다.
floatRenderTarget 없습니다. 프로그램을 링크하기 전에 호스트가 확장을 켭니다.
EXT_color_buffer_float float32Blend 없습니다. 프로그램을 링크하기 전에 호스트가 확장을 켭니다.
EXT_float_blend float32Filterable 없습니다. 프로그램을 링크하기 전에 호스트가 확장을 켭니다.
OES_texture_float_linear multiview #extension GL_OVR_multiview2 : requireOVR_multiview2 "use typeshade" 파일에는 이 네 가지를 적을 방법이 없습니다. "enable ..."은 WGSL 확장 이름을 받는데 넷 중 어느 것도 WGSL 확장이 아니므로, 이런 기능이 필요한 모듈은 fn() 인터페이스의 module({ enables: [...] })로 조립합니다. 스토리지 바인딩, 컴퓨트 진입점, @builtin("clip_distances")처럼 모듈의 모양에서 따라오는 기능은 파일에서 도출되며, 그중 어느 것도 이 표에 행이 없습니다.