struct Params { src_size: vec2, content_offset: vec2, content_size: vec2, } @group(0) @binding(0) var params: Params; @group(0) @binding(1) var src_indices: texture_2d; @group(0) @binding(2) var palette_tex: texture_2d; @vertex fn vs_main(@builtin(vertex_index) vid: u32) -> @builtin(position) vec4 { var pos = array, 3>( vec2(-1.0, -1.0), vec2( 3.0, -1.0), vec2(-1.0, 3.0) ); return vec4(pos[vid], 0.0, 1.0); } @fragment fn fs_main(@builtin(position) frag_xy: vec4) -> @location(0) vec4 { let uv = (frag_xy.xy - params.content_offset) / params.content_size; let sx = clamp(i32(floor(uv.x * params.src_size.x)), 0, i32(params.src_size.x) - 1); let sy = clamp(i32(floor(uv.y * params.src_size.y)), 0, i32(params.src_size.y) - 1); let idx: u32 = textureLoad(src_indices, vec2(sx, sy), 0).r & 0xFFu; let rgb = textureLoad(palette_tex, vec2(i32(idx), 0), 0).rgb; return vec4(rgb, 1.0); }