문자열 키와 Record
정해진 채널 이름을 u32 id로 바꾸고, Record는 id 순서의 배열로 표현합니다. 호스트가 호출하는 커널 함수는 키 타입 매개변수로 게인을 고릅니다. 프래그먼트 진입점은 픽셀 위치로 채널을 고르고 같은 테이블을 읽습니다. 호스트는 커널에 채널 문자열을, 헬퍼에 객체를 넘깁니다. WebGPU, WebGL2, CPU tier에서 같은 값이 나옵니다.
실행 tier WebGPUWebGL2CPU tier
이 목록은 컴파일러가 확인합니다. tier(호출이 실행되는 백엔드)는 호스트의 실행 전체가 그 tier 하나만으로 기준값을 낼 때만 목록에 오릅니다. 컴파일러의 저니 게이트가 호스트마다 WebGPU와 WebGL2에서 실행하고, 단위 테스트가 CPU tier에서 실행합니다.
"use typeshade";
/* @example{ "title": "String keys and Record", "blurb": "A closed set of channel names becomes u32 ids, and a Record becomes an array in id order (change 0081). A key-type parameter selects the gain in a kernel function called by the host. The fragment entry chooses a channel from the pixel position and reads the same table. The host passes a channel string to the kernel and an object to the helper, with identical values on WebGPU, WebGL2 and the CPU tier.", "renderable": true}*/
type Channel = "r" | "g" | "b";const GAIN: Record<Channel, f32> = { r: 1.5, g: 1.0, b: 0.5 };
export function gain(c: Channel, x: f32, by: Record<Channel, f32>): f32 { switch (c) { case "r": return x * GAIN[c] * by[c]; case "g": return x * GAIN[c] * by[c]; default: return x * GAIN[c] * by[c]; }}
export function boost(pixels: array<f32>, c: Channel, scale: f32) { for (let i: u32 = 0; i < pixels.length; i++) { const by: Record<Channel, f32> = { r: scale, g: scale, b: scale }; pixels[i] = gain(c, pixels[i], by); }}
class Clip { @builtin("position") pos: vec4;}
class Color { @location(0) color: vec4;}
@vertexexport function vs(@builtin("vertex_index") i: u32): Clip { let p = vec2(-1., -1.); if (i === 1) { p = vec2(3., -1.); } if (i === 2) { p = vec2(-1., 3.); } return { pos: vec4(p, 0., 1.) };}
@fragmentexport function fs(@builtin("position") p: vec4): Color { const c: Channel = p.x < 16. ? "r" : p.x < 32. ? "g" : "b"; const by: Record<Channel, f32> = { b: 0.5, r: 0.5, g: 0.5 }; return { color: vec4(gain(c, 1., by), 0.25, 0.5, 1.) };}// The call converts a channel string and an object to a u32 id and an array (surface §75).import { boost, gain } from './string-keys-record.shade.ts';
/** Scale the same pixels through each channel, and call the helper with a computed host key. */export async function run(): Promise<{ pixels: Float32Array; selected: number }> { const pixels = new Float32Array([1, 2, 4, 8]); const by = { r: 2, g: 0.5, b: 4 }; await boost(pixels, 'g', by.g); await boost(pixels, 'r', by.r); await boost(pixels, 'b', by.b); const channel = pixels[0]! > 1 ? 'b' : 'r'; return { pixels, selected: gain(channel, 2, by) };}두 파일 모두 커밋 91c2fe31의 컴파일러에 있는 그대로이며, 예제 디렉터리에서 읽어 왔습니다.