const USER_WARP_FRAGMENT_PREFIX: &str = r#"
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
uv = in.uv;
// `uv_orig` is the *pre-warp* screen-space UV. Warp HLSL authors
// sometimes reference it to compare the displaced sample against
// the pixel's own coordinate (radial fades, vignette terms).
uv_orig = in.uv_screen;
rad = length(in.uv_screen - vec2<f32>(0.5)) * 1.4142135;
ang = atan2(in.uv_screen.y - 0.5, in.uv_screen.x - 0.5);
ret = textureSample(sampler_main_texture, sampler_main, uv).rgb;
_md2_color = ret;
texsize = uniforms.texsize;
aspect = uniforms.aspect;
time = uniforms.time;
fps = uniforms.fps;
frame = uniforms.frame;
progress = uniforms.progress;
bass = uniforms.bass;
mid = uniforms.mid;
treb = uniforms.treb;
vol = uniforms.vol;
bass_att = uniforms.bass_att;
mid_att = uniforms.mid_att;
treb_att = uniforms.treb_att;
vol_att = uniforms.vol_att;
rand_preset = uniforms.rand_preset;
rand_frame = uniforms.rand_frame;
slow_roam_cos = uniforms.slow_roam_cos;
slow_roam_sin = uniforms.slow_roam_sin;
roam_cos = uniforms.roam_cos;
roam_sin = uniforms.roam_sin;
blur1_min = uniforms.blur1_min;
blur1_max = uniforms.blur1_max;
blur2_min = uniforms.blur2_min;
blur2_max = uniforms.blur2_max;
blur3_min = uniforms.blur3_min;
blur3_max = uniforms.blur3_max;
hue_shader = vec3<f32>(1.0, 1.0, 1.0);
g_fTexSize = uniforms.texsize;
q1 = uniforms.q[0].x;
q2 = uniforms.q[0].y;
q3 = uniforms.q[0].z;
q4 = uniforms.q[0].w;
q5 = uniforms.q[1].x;
q6 = uniforms.q[1].y;
q7 = uniforms.q[1].z;
q8 = uniforms.q[1].w;
q9 = uniforms.q[2].x;
q10 = uniforms.q[2].y;
q11 = uniforms.q[2].z;
q12 = uniforms.q[2].w;
q13 = uniforms.q[3].x;
q14 = uniforms.q[3].y;
q15 = uniforms.q[3].z;
q16 = uniforms.q[3].w;
q17 = uniforms.q[4].x;
q18 = uniforms.q[4].y;
q19 = uniforms.q[4].z;
q20 = uniforms.q[4].w;
q21 = uniforms.q[5].x;
q22 = uniforms.q[5].y;
q23 = uniforms.q[5].z;
q24 = uniforms.q[5].w;
q25 = uniforms.q[6].x;
q26 = uniforms.q[6].y;
q27 = uniforms.q[6].z;
q28 = uniforms.q[6].w;
q29 = uniforms.q[7].x;
q30 = uniforms.q[7].y;
q31 = uniforms.q[7].z;
q32 = uniforms.q[7].w;
// ---- begin translated user body ----
"#;Expand description
Fragment-shader header for user-authored warp shaders. Same shape
as USER_COMP_FRAGMENT_PREFIX (seed every MD2 var<private> binding
from uniforms and per-invocation inputs), but uv/uv_orig come
from the rasterised warp UV — not from a fullscreen-triangle screen
UV — and ret is seeded from the previous-frame texture at that
warped UV. The renderer binds prev_texture to sampler_main_texture
so GetPixel(uv) (defined in the shared helpers) does the right thing.